fix(memory): stop autosaving assistant summaries and filter legacy entries

This commit is contained in:
Chummy 2026-02-20 00:35:48 +08:00
parent 6d745e9cb3
commit d714d3984e
8 changed files with 173 additions and 34 deletions

View file

@ -1,4 +1,4 @@
use crate::memory::Memory;
use crate::memory::{self, Memory};
use async_trait::async_trait;
use std::fmt::Write;
@ -45,6 +45,9 @@ impl MemoryLoader for DefaultMemoryLoader {
let mut context = String::from("[Memory context]\n");
for entry in entries {
if memory::is_assistant_autosave_key(&entry.key) {
continue;
}
if let Some(score) = entry.score {
if score < self.min_relevance_score {
continue;
@ -67,8 +70,12 @@ impl MemoryLoader for DefaultMemoryLoader {
mod tests {
use super::*;
use crate::memory::{Memory, MemoryCategory, MemoryEntry};
use std::sync::Arc;
struct MockMemory;
struct MockMemoryWithEntries {
entries: Arc<Vec<MemoryEntry>>,
}
#[async_trait]
impl Memory for MockMemory {
@ -131,6 +138,56 @@ mod tests {
}
}
#[async_trait]
impl Memory for MockMemoryWithEntries {
async fn store(
&self,
_key: &str,
_content: &str,
_category: MemoryCategory,
_session_id: Option<&str>,
) -> anyhow::Result<()> {
Ok(())
}
async fn recall(
&self,
_query: &str,
_limit: usize,
_session_id: Option<&str>,
) -> anyhow::Result<Vec<MemoryEntry>> {
Ok(self.entries.as_ref().clone())
}
async fn get(&self, _key: &str) -> anyhow::Result<Option<MemoryEntry>> {
Ok(None)
}
async fn list(
&self,
_category: Option<&MemoryCategory>,
_session_id: Option<&str>,
) -> anyhow::Result<Vec<MemoryEntry>> {
Ok(vec![])
}
async fn forget(&self, _key: &str) -> anyhow::Result<bool> {
Ok(true)
}
async fn count(&self) -> anyhow::Result<usize> {
Ok(self.entries.len())
}
async fn health_check(&self) -> bool {
true
}
fn name(&self) -> &str {
"mock-with-entries"
}
}
#[tokio::test]
async fn default_loader_formats_context() {
let loader = DefaultMemoryLoader::default();
@ -138,4 +195,36 @@ mod tests {
assert!(context.contains("[Memory context]"));
assert!(context.contains("- k: v"));
}
#[tokio::test]
async fn default_loader_skips_legacy_assistant_autosave_entries() {
let loader = DefaultMemoryLoader::new(5, 0.0);
let memory = MockMemoryWithEntries {
entries: Arc::new(vec![
MemoryEntry {
id: "1".into(),
key: "assistant_resp_legacy".into(),
content: "fabricated detail".into(),
category: MemoryCategory::Daily,
timestamp: "now".into(),
session_id: None,
score: Some(0.95),
},
MemoryEntry {
id: "2".into(),
key: "user_fact".into(),
content: "User prefers concise answers".into(),
category: MemoryCategory::Conversation,
timestamp: "now".into(),
session_id: None,
score: Some(0.9),
},
]),
};
let context = loader.load_context(&memory, "answer style").await.unwrap();
assert!(context.contains("user_fact"));
assert!(!context.contains("assistant_resp_legacy"));
assert!(!context.contains("fabricated detail"));
}
}