use std::path::Path;
use crate::cm_types::path_utils::absolutize_relative_under_root;
pub fn load_memory_snippet(
workspace_root: &Path,
rel_path: &str,
max_chars: usize,
) -> Option<String> {
if workspace_root.as_os_str().is_empty() {
return None;
}
let rel = rel_path.trim();
if rel.is_empty() || max_chars == 0 {
return None;
}
let file_path = absolutize_relative_under_root(workspace_root, rel).ok()?;
let raw = std::fs::read_to_string(&file_path).ok()?;
let t = raw.trim();
if t.is_empty() {
return None;
}
let mut body: String = t.chars().take(max_chars).collect();
if t.chars().count() > max_chars {
body.push_str("\n\n[... 备忘文件过长,已按 agent_memory_file_max_chars 截断 ...]");
}
Some(format!(
"[用户/项目长期备忘(工作区内 {rel},可直接编辑该文件更新)]\n{body}"
))
}
#[cfg(test)]
mod tests {
use super::*;
use std::io::Write;
#[test]
fn memory_snippet_wraps_path_hint() {
let dir =
std::env::temp_dir().join(format!("crabmate_agent_memory_test_{}", std::process::id()));
let _ = std::fs::remove_dir_all(&dir);
std::fs::create_dir_all(&dir).unwrap();
let sub = dir.join("memo.md");
let mut f = std::fs::File::create(&sub).unwrap();
writeln!(f, " use edition 2024 ").unwrap();
let got = load_memory_snippet(&dir, "memo.md", 1000).unwrap();
assert!(got.contains("工作区内 memo.md"));
assert!(got.contains("edition 2024"));
let _ = std::fs::remove_dir_all(&dir);
}
}