use crate::command::context::CommandContext; use crate::command::handler::{CommandHandler, CommandMetadata}; use crate::command::response::{CommandError, CommandResponse}; use crate::command::Command; use crate::storage::{MemoryUpsert, SessionStore, GLOBAL_SCOPE_KEY}; use async_trait::async_trait; use std::sync::Arc; pub struct MemoryCrudCommandHandler { store: Arc, } impl MemoryCrudCommandHandler { pub fn new(store: Arc) -> Self { Self { store } } } /// 通过 ID 查找记忆的 namespace 和 memory_key fn find_by_id( store: &SessionStore, id: &str, ) -> Result, CommandError> { let records = store .list_memories_for_scope("user", GLOBAL_SCOPE_KEY) .map_err(|e| CommandError::new("LIST_ERROR", e.to_string()))?; Ok(records .iter() .find(|r| r.id == id) .map(|r| (r.namespace.clone(), r.memory_key.clone()))) } #[async_trait] impl CommandHandler for MemoryCrudCommandHandler { fn can_handle(&self, cmd: &Command) -> bool { matches!( cmd, Command::CreateMemory { .. } | Command::UpdateMemory { .. } | Command::DeleteMemory { .. } ) } fn metadata(&self) -> Option { Some(CommandMetadata { name: "memory_crud", description: "创建、更新、删除记忆", usage: "/memory_crud", }) } async fn handle( &self, cmd: Command, ctx: CommandContext, ) -> Result { let scope_key = GLOBAL_SCOPE_KEY.to_string(); match cmd { Command::CreateMemory { namespace, key, content, } => { let input = MemoryUpsert { scope_kind: "user".to_string(), scope_key, namespace, memory_key: key, content, source_type: "manual".to_string(), source_session_id: None, source_message_id: None, source_message_seq: None, source_channel_name: None, source_chat_id: None, }; self.store .put_memory(&input) .map_err(|e| CommandError::new("CREATE_ERROR", e.to_string()))?; } Command::UpdateMemory { id, content } => { let Some((namespace, memory_key)) = find_by_id(&self.store, &id)? else { return Err(CommandError::new("NOT_FOUND", "记忆不存在")); }; let input = MemoryUpsert { scope_kind: "user".to_string(), scope_key, namespace, memory_key, content, source_type: "manual".to_string(), source_session_id: None, source_message_id: None, source_message_seq: None, source_channel_name: None, source_chat_id: None, }; self.store .update_memory(&input) .map_err(|e| CommandError::new("UPDATE_ERROR", e.to_string()))?; } Command::DeleteMemory { id } => { let Some((namespace, memory_key)) = find_by_id(&self.store, &id)? else { return Err(CommandError::new("NOT_FOUND", "记忆不存在")); }; self.store .delete_memory("user", &scope_key, &namespace, &memory_key) .map_err(|e| CommandError::new("DELETE_ERROR", e.to_string()))?; } _ => unreachable!(), } Ok(CommandResponse::success(ctx.request_id) .with_metadata("memory_updated", "true")) } }