pub const MEMORY_TYPE_CAPTURE_DESCRIPTION: &str =
"\"profile\" (about the user) or \"knowledge\" (about the world) — or precise: \
\"identity\", \"preference\", \"decision\", \"lesson\", \"gotcha\", \"fact\" — \
auto-classified if omitted";
pub const MEMORY_TYPE_FILTER_DESCRIPTION: &str =
"Filter by type. Two-level filter: \"profile\" (user-facing) or \
\"knowledge\" (world-facing), or precise: \"identity\", \"preference\", \
\"decision\", \"lesson\", \"gotcha\", \"fact\".";
#[cfg(test)]
mod tests {
use super::*;
use crate::sources::MemoryType;
#[test]
fn capture_description_lists_every_canonical_type() {
for ty in MemoryType::all_values() {
let needle = format!("\"{ty}\"");
assert!(
MEMORY_TYPE_CAPTURE_DESCRIPTION.contains(&needle),
"MEMORY_TYPE_CAPTURE_DESCRIPTION missing \"{ty}\""
);
}
}
#[test]
fn filter_description_lists_every_canonical_type() {
for ty in MemoryType::all_values() {
let needle = format!("\"{ty}\"");
assert!(
MEMORY_TYPE_FILTER_DESCRIPTION.contains(&needle),
"MEMORY_TYPE_FILTER_DESCRIPTION missing \"{ty}\""
);
}
}
#[test]
fn descriptions_omit_legacy_goal() {
for desc in [
MEMORY_TYPE_CAPTURE_DESCRIPTION,
MEMORY_TYPE_FILTER_DESCRIPTION,
] {
assert!(
!contains_word(desc, "goal"),
"description must not advertise legacy \"goal\": {desc}"
);
}
}
pub(crate) fn contains_word(haystack: &str, needle: &str) -> bool {
haystack
.split(|c: char| !c.is_ascii_alphanumeric() && c != '_')
.any(|tok| tok == needle)
}
#[test]
fn contains_word_rejects_partial_matches() {
assert!(contains_word("goal", "goal"));
assert!(contains_word("/ goal /", "goal"));
assert!(contains_word("goal,", "goal"));
assert!(contains_word("(goal)", "goal"));
assert!(!contains_word("goals", "goal"));
assert!(!contains_word("their goals here", "goal"));
assert!(!contains_word("subgoal", "goal"));
}
}