diff --git a/src/command/handlers/save_topic.rs b/src/command/handlers/save_topic.rs index 0301cee..a78282c 100644 --- a/src/command/handlers/save_topic.rs +++ b/src/command/handlers/save_topic.rs @@ -1,4 +1,5 @@ use crate::agent::{SystemPrompt, SystemPromptContext, SystemPromptProvider}; +use crate::bus::ChatMessage; use crate::command::context::CommandContext; use crate::command::handler::{CommandHandler, CommandMetadata}; use crate::command::handlers::{ @@ -7,6 +8,7 @@ use crate::command::handlers::{ }; use crate::command::response::{CommandError, CommandResponse, MessageKind}; use crate::command::Command; +use crate::gateway::session::SessionManager; use crate::storage::{SessionStore, TopicRecord}; use async_trait::async_trait; use chrono::Local; @@ -19,6 +21,7 @@ pub async fn save_topic_to_file( filepath: Option, store: &SessionStore, system_prompt_provider: &dyn SystemPromptProvider, + messages: &[ChatMessage], // ← 从外部传入的消息(已压缩的 active history) ) -> Result { // 获取话题记录 let topic = store @@ -26,11 +29,6 @@ pub async fn save_topic_to_file( .map_err(|e| format!("Failed to get topic: {}", e))? .ok_or_else(|| "Topic not found".to_string())?; - // 加载话题消息 - let messages = store - .load_messages_for_topic(topic_id) - .map_err(|e| format!("Failed to load messages: {}", e))?; - // 获取 session 信息(用于系统提示词) let session = store .get_session(&topic.session_id) @@ -41,7 +39,7 @@ pub async fn save_topic_to_file( let system_prompt = build_system_prompt(system_prompt_provider, &session, user_message_count); // 生成 Markdown 内容 - let markdown = generate_topic_markdown(&topic, &system_prompt, &messages); + let markdown = generate_topic_markdown(&topic, &system_prompt, messages); // 确定输出路径 let output_path = resolve_topic_filepath(filepath, &topic); @@ -156,6 +154,7 @@ fn resolve_topic_filepath(filepath: Option, topic: &TopicRecord) -> Path pub struct SaveTopicCommandHandler { store: Arc, system_prompt_provider: Arc, + session_manager: Option, } impl SaveTopicCommandHandler { @@ -166,8 +165,14 @@ impl SaveTopicCommandHandler { Self { store, system_prompt_provider, + session_manager: None, } } + + pub fn with_session_manager(mut self, session_manager: SessionManager) -> Self { + self.session_manager = Some(session_manager); + self + } } #[async_trait] @@ -213,7 +218,37 @@ async fn handle_save_topic( .as_deref() .ok_or_else(|| CommandError::new("NO_TOPIC", "No active topic".to_string()))?; - tracing::debug!(topic_id = %topic_id, "Attempting to save topic"); + let chat_id = ctx + .chat_id + .as_deref() + .ok_or_else(|| CommandError::new("NO_CHAT_ID", "No chat id".to_string()))?; + + tracing::debug!(topic_id = %topic_id, chat_id = %chat_id, "Attempting to save topic"); + + // 从 Session 获取当前 history(包含已压缩的消息) + let messages = if let Some(ref session_manager) = handler.session_manager { + match session_manager.get(&ctx.channel_name).await { + Some(session) => { + let guard = session.lock().await; + guard.get_history(chat_id) + .map(|m| m.clone()) + .unwrap_or_default() + } + None => { + return Err(CommandError::new( + "SESSION_NOT_FOUND", + format!("Session not found for channel: {}", ctx.channel_name), + )); + } + } + } else { + return Err(CommandError::new( + "SESSION_MANAGER_NOT_SET", + "Session manager not configured".to_string(), + )); + }; + + tracing::debug!(message_count = messages.len(), "Got messages from session"); // 调用保存函数 let output_path = save_topic_to_file( @@ -221,16 +256,12 @@ async fn handle_save_topic( filepath, &*handler.store, &*handler.system_prompt_provider, + &messages, ) .await .map_err(|e| CommandError::new("SAVE_ERROR", e))?; - // 获取消息数量 - let message_count = handler - .store - .load_messages_for_topic(topic_id) - .map_err(|e| CommandError::new("LOAD_MESSAGES_ERROR", e.to_string()))? - .len(); + let message_count = messages.len(); Ok(CommandResponse::success(ctx.request_id) .with_message( diff --git a/src/gateway/processor.rs b/src/gateway/processor.rs index fa62f0a..31c78a5 100644 --- a/src/gateway/processor.rs +++ b/src/gateway/processor.rs @@ -81,7 +81,7 @@ impl InboundProcessor { command_router.register(Box::new(SaveTopicCommandHandler::new( store.clone(), system_prompt_provider, - ))); + ).with_session_manager(session_manager.clone()))); // 注册 help 处理器(最后注册,获取所有已注册命令的元数据) let metadata = command_router.metadata_arc();