diff --git a/src/agent/agent_loop.rs b/src/agent/agent_loop.rs index 9071db0..ea9bec2 100644 --- a/src/agent/agent_loop.rs +++ b/src/agent/agent_loop.rs @@ -383,7 +383,7 @@ impl AgentLoop { // Build and inject system prompt if not present let has_system = messages.first().is_some_and(|m| m.role == "system"); if !has_system { - let system_prompt = build_system_prompt(&self.workspace_dir, &self.model_name, &self.tools, None, None); + let system_prompt = build_system_prompt(&self.workspace_dir, &self.model_name, &self.tools, None, None, false); #[cfg(debug_assertions)] tracing::debug!("System prompt injected:\n{}", system_prompt); messages.insert(0, ChatMessage::system(system_prompt)); diff --git a/src/agent/system_prompt.rs b/src/agent/system_prompt.rs index bcc6d30..a23611e 100644 --- a/src/agent/system_prompt.rs +++ b/src/agent/system_prompt.rs @@ -21,6 +21,8 @@ pub struct PromptContext<'a> { pub session_id: Option<&'a str>, /// Pre-fetched memory context string to inject. pub memory_context: Option<&'a str>, + /// Whether this session has compressed history available via timeline_recall. + pub has_compressed_history: bool, } /// Trait for system prompt sections. @@ -46,6 +48,7 @@ impl SystemPromptBuilder { Box::new(WorkspaceSection), Box::new(UserProfileSection), Box::new(MemorySection), + Box::new(HistorySection), Box::new(DateTimeSection), Box::new(RuntimeSection), Box::new(CrossChannelSection), @@ -303,6 +306,23 @@ impl PromptSection for MemorySection { } } +/// Prompt agent to use timeline_recall if compressed history exists. +pub struct HistorySection; + +impl PromptSection for HistorySection { + fn name(&self) -> &str { + "history" + } + + fn build(&self, ctx: &PromptContext<'_>) -> String { + if ctx.has_compressed_history { + "## 历史会话\n之前的对话摘要已归档。如需回顾历史上下文,使用 `timeline_recall` 工具搜索。".to_string() + } else { + String::new() + } + } +} + // === Helper Functions === /// Get user config directory (~/.picobot/). @@ -346,6 +366,7 @@ pub fn build_system_prompt( tools: &ToolRegistry, session_id: Option<&str>, memory_context: Option<&str>, + has_compressed_history: bool, ) -> String { let ctx = PromptContext { workspace_dir, @@ -353,6 +374,7 @@ pub fn build_system_prompt( tools, session_id, memory_context, + has_compressed_history, }; SystemPromptBuilder::with_defaults().build(&ctx) } @@ -373,6 +395,7 @@ mod tests { tools: &tools, session_id: None, memory_context: None, + has_compressed_history: false, }; let prompt = SystemPromptBuilder::with_defaults().build(&ctx); @@ -402,7 +425,7 @@ mod tests { let temp_dir = std::env::temp_dir(); let tools = ToolRegistry::new(); - let prompt = build_system_prompt(&temp_dir, "test-model", &tools, None, None); + let prompt = build_system_prompt(&temp_dir, "test-model", &tools, None, None, false); assert!(!prompt.is_empty()); assert!(prompt.contains("test-model")); @@ -419,6 +442,7 @@ mod tests { tools: &tools, session_id: None, memory_context: Some("- user_pref: Prefers Rust"), + has_compressed_history: false, }; let prompt = SystemPromptBuilder::with_defaults().build(&ctx); @@ -437,6 +461,7 @@ mod tests { tools: &tools, session_id: None, memory_context: None, + has_compressed_history: false, }; let prompt = SystemPromptBuilder::with_defaults().build(&ctx); diff --git a/src/tools/chat_manager.rs b/src/tools/chat_manager.rs index 2c18604..51cdcfb 100644 --- a/src/tools/chat_manager.rs +++ b/src/tools/chat_manager.rs @@ -264,6 +264,7 @@ mod tests { routing_info: None, deleted_at: None, last_consolidated_at: None, + last_compressed_message_at: None, }; storage.upsert_session(&meta).await.unwrap(); } @@ -298,6 +299,7 @@ mod tests { routing_info: None, deleted_at: None, last_consolidated_at: None, + last_compressed_message_at: None, }; storage.upsert_session(&meta).await.unwrap();