diff --git a/src/command/handlers/get_current.rs b/src/command/handlers/get_current.rs index 4d963b3..23ff79a 100644 --- a/src/command/handlers/get_current.rs +++ b/src/command/handlers/get_current.rs @@ -1,8 +1,10 @@ use crate::agent::context_compressor::estimate_tokens; use crate::command::context::CommandContext; use crate::command::handler::{CommandHandler, CommandMetadata}; +use crate::command::handlers::get_messages_from_session; use crate::command::response::{CommandError, CommandResponse, MessageKind}; use crate::command::Command; +use crate::gateway::session::SessionManager; use crate::storage::SessionStore; use async_trait::async_trait; use std::sync::Arc; @@ -10,11 +12,20 @@ use std::sync::Arc; /// 获取当前话题命令处理器 pub struct GetCurrentSessionCommandHandler { store: Arc, + session_manager: Option, } impl GetCurrentSessionCommandHandler { pub fn new(store: Arc) -> Self { - Self { store } + Self { + store, + session_manager: None, + } + } + + pub fn with_session_manager(mut self, session_manager: SessionManager) -> Self { + self.session_manager = Some(session_manager); + self } } @@ -51,17 +62,23 @@ async fn handle_get_current_session( let topic_id = ctx.topic_id.as_deref() .ok_or_else(|| CommandError::new("NO_CURRENT_TOPIC", "No current topic"))?; + let chat_id = ctx.chat_id.as_deref() + .ok_or_else(|| CommandError::new("NO_CHAT_ID", "No chat id".to_string()))?; + let topic = handler .store .get_topic(topic_id) .map_err(|e| CommandError::new("GET_TOPIC_ERROR", e.to_string()))? .ok_or_else(|| CommandError::new("TOPIC_NOT_FOUND", format!("Topic not found: {}", topic_id)))?; - // Load messages and estimate tokens - let messages = handler - .store - .load_messages_for_topic(topic_id) - .map_err(|e| CommandError::new("LOAD_MESSAGES_ERROR", e.to_string()))?; + // Load messages from session memory + let messages = get_messages_from_session( + &handler.session_manager, + &ctx.channel_name, + chat_id, + ).await?; + + let actual_message_count = messages.len(); let estimated_tokens = estimate_tokens(&messages); let last_active = format_time_ago(topic.last_active_at); @@ -71,7 +88,7 @@ async fn handle_get_current_session( "Current Topic:\n\n Topic ID: {}\n Title: {}\n Messages: {}\n Tokens: ~{}\n Created: {}\n Last Active: {}", topic.id, topic.title, - topic.message_count, + actual_message_count, estimated_tokens, created_at, last_active @@ -81,7 +98,7 @@ async fn handle_get_current_session( .with_message(MessageKind::Notification, &message) .with_metadata("topic_id", &topic.id) .with_metadata("title", &topic.title) - .with_metadata("message_count", &topic.message_count.to_string()) + .with_metadata("message_count", &actual_message_count.to_string()) .with_metadata("estimated_tokens", &estimated_tokens.to_string())) } diff --git a/src/command/handlers/mod.rs b/src/command/handlers/mod.rs index f9e4763..b0d4f93 100644 --- a/src/command/handlers/mod.rs +++ b/src/command/handlers/mod.rs @@ -12,3 +12,35 @@ pub use save_session::{ escape_yaml_string, format_message_content, format_timestamp, generate_messages_markdown, generate_system_prompt_markdown, }; + +use crate::bus::ChatMessage; +use crate::command::response::CommandError; +use crate::gateway::session::SessionManager; + +/// 从 Session 内存获取消息历史(供命令使用) +pub async fn get_messages_from_session( + session_manager: &Option, + channel_name: &str, + chat_id: &str, +) -> Result, CommandError> { + let session_manager = session_manager.as_ref().ok_or_else(|| { + CommandError::new( + "SESSION_MANAGER_NOT_SET", + "Session manager not configured".to_string(), + ) + })?; + + match session_manager.get(channel_name).await { + Some(session) => { + let guard = session.lock().await; + Ok(guard + .get_history(chat_id) + .map(|m| m.clone()) + .unwrap_or_default()) + } + None => Err(CommandError::new( + "SESSION_NOT_FOUND", + format!("Session not found for channel: {}", channel_name), + )), + } +} diff --git a/src/command/handlers/save_topic.rs b/src/command/handlers/save_topic.rs index a78282c..07dfa64 100644 --- a/src/command/handlers/save_topic.rs +++ b/src/command/handlers/save_topic.rs @@ -4,7 +4,7 @@ use crate::command::context::CommandContext; use crate::command::handler::{CommandHandler, CommandMetadata}; use crate::command::handlers::{ escape_yaml_string, format_timestamp, generate_messages_markdown, - generate_system_prompt_markdown, + generate_system_prompt_markdown, get_messages_from_session, }; use crate::command::response::{CommandError, CommandResponse, MessageKind}; use crate::command::Command; @@ -226,27 +226,11 @@ async fn handle_save_topic( 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(), - )); - }; + let messages = get_messages_from_session( + &handler.session_manager, + &ctx.channel_name, + chat_id, + ).await?; tracing::debug!(message_count = messages.len(), "Got messages from session"); diff --git a/src/gateway/processor.rs b/src/gateway/processor.rs index 31c78a5..430b2c0 100644 --- a/src/gateway/processor.rs +++ b/src/gateway/processor.rs @@ -56,7 +56,9 @@ impl InboundProcessor { command_router.register(Box::new(switch_handler)); // 注册 get_current 处理器 - command_router.register(Box::new(GetCurrentSessionCommandHandler::new(store.clone()))); + command_router.register(Box::new(GetCurrentSessionCommandHandler::new( + store.clone(), + ).with_session_manager(session_manager.clone()))); // 注册 load_session 处理器 command_router.register(Box::new(LoadSessionCommandHandler::new(store.clone())));