新增: MemoryAdapter trait + ContextManager 默认实现

crates/df-ai/src/memory_adapter.rs:
- MemoryAdapter trait: 15 个核心方法(写入/读取/压缩/生命周期)
- ContextManager 作为默认实现(行为零变化)
- 预留 VectorMemoryAdapter 接入点

lib.rs: pub mod memory_adapter 导出
This commit is contained in:
lxy
2026-07-20 09:51:12 +08:00
parent c8f35a7211
commit 7594a5b7f3
2 changed files with 87 additions and 0 deletions
+86
View File
@@ -0,0 +1,86 @@
//! MemoryAdapter trait — 上下文记忆层抽象
//!
//! 将 ContextManager 的核心接口提取为 trait,支持多种记忆后端:
//! - InMemoryAdapter(当前 ContextManager 的包装,默认实现)
//! - VectorMemoryAdapter(未来:接入向量检索,支持语义记忆)
//!
//! 使用方式:`Box<dyn MemoryAdapter>` 替代 `ContextManager`。
use crate::context::ContextManager;
use crate::context_helpers::{ContextConfig, TrackedMessage};
use crate::provider::ChatMessage;
/// 上下文记忆层抽象接口
///
/// 覆盖 agentic loop / IPC 最常用的 15 个方法。
/// 保留 `ContextManager` 作为默认实现(`InMemoryAdapter`),行为零变化。
pub trait MemoryAdapter: Send + Sync {
// ── 写入 ──
fn push(&mut self, msg: ChatMessage);
fn clear(&mut self);
fn insert_at(&mut self, index: usize, message: ChatMessage);
fn replace_tool_result_content(&mut self, tool_call_id: &str, new_content: &str) -> bool;
fn pop_last_assistant_round(&mut self) -> bool;
fn truncate_after_user_message(&mut self, target_content: &str) -> Result<usize, ()>;
fn replace_last_active_user_content(&mut self, new_content: &str) -> Result<(), ()>;
// ── 读取 ──
fn build_for_request(&self, sys_tokens: u32) -> (Vec<ChatMessage>, bool);
fn all_messages_clone(&self) -> Vec<ChatMessage>;
fn len(&self) -> usize;
fn is_empty(&self) -> bool;
fn history_tokens(&self) -> u32;
fn budget_limit(&self) -> u32;
fn config(&self) -> &ContextConfig;
// ── 压缩 ──
fn compress_old_messages(&mut self, end: usize) -> Vec<ChatMessage>;
fn has_compressible_messages(&self, protect_start: usize) -> bool;
fn is_compressing(&self) -> bool;
fn set_compressing(&mut self, v: bool);
// ── 生命周期 ──
fn restore_from_messages(&mut self, messages: Vec<ChatMessage>);
fn take_topic_marker(&mut self) -> Option<String>;
fn messages_mut(&mut self) -> &mut [TrackedMessage];
fn iter(&self) -> Box<dyn Iterator<Item = &ChatMessage> + '_>;
}
/// ContextManager 作为默认 MemoryAdapter 实现
impl MemoryAdapter for ContextManager {
fn push(&mut self, msg: ChatMessage) { self.push(msg); }
fn clear(&mut self) { self.clear(); }
fn insert_at(&mut self, index: usize, message: ChatMessage) { self.insert_at(index, message); }
fn replace_tool_result_content(&mut self, tool_call_id: &str, new_content: &str) -> bool {
self.replace_tool_result_content(tool_call_id, new_content)
}
fn pop_last_assistant_round(&mut self) -> bool { self.pop_last_assistant_round() }
fn truncate_after_user_message(&mut self, target_content: &str) -> Result<usize, ()> {
self.truncate_after_user_message(target_content)
}
fn replace_last_active_user_content(&mut self, new_content: &str) -> Result<(), ()> {
self.replace_last_active_user_content(new_content)
}
fn build_for_request(&self, sys_tokens: u32) -> (Vec<ChatMessage>, bool) {
self.build_for_request(sys_tokens)
}
fn all_messages_clone(&self) -> Vec<ChatMessage> { self.all_messages_clone() }
fn len(&self) -> usize { self.len() }
fn is_empty(&self) -> bool { self.is_empty() }
fn history_tokens(&self) -> u32 { self.history_tokens() }
fn budget_limit(&self) -> u32 { self.budget_limit() }
fn config(&self) -> &ContextConfig { self.config() }
fn compress_old_messages(&mut self, end: usize) -> Vec<ChatMessage> { self.compress_old_messages(end) }
fn has_compressible_messages(&self, protect_start: usize) -> bool { self.has_compressible_messages(protect_start) }
fn is_compressing(&self) -> bool { self.is_compressing() }
fn set_compressing(&mut self, v: bool) { self.set_compressing(v); }
fn restore_from_messages(&mut self, messages: Vec<ChatMessage>) { self.restore_from_messages(messages); }
fn take_topic_marker(&mut self) -> Option<String> { self.take_topic_marker() }
fn messages_mut(&mut self) -> &mut [TrackedMessage] { self.messages_mut() }
fn iter(&self) -> Box<dyn Iterator<Item = &ChatMessage> + '_> {
Box::new(self.iter())
}
}