From 349bdd79849223adc57db4d627573971029e5c36 Mon Sep 17 00:00:00 2001 From: "Rodrigo Rodriguez (Pragmatismo)" Date: Tue, 11 Nov 2025 19:23:04 -0300 Subject: [PATCH] feat(automation): refactor prompt compaction logic - Remove unused imports and redundant session progress tracking - Reorder session progress check to after initial validation - Replace `summarize` with `generate` for LLM interaction - Add more detailed logging for summarization process - Improve error handling and fallback behavior - Move session cleanup guard to end of processing - Update log levels for better observability (trace -> info for key events) The changes streamline the prompt compaction flow and improve reliability while maintaining the same core functionality. --- src/automation/compact_prompt.rs | 59 +++++++++++++++++--------------- src/bot/mod.rs | 2 +- src/session/mod.rs | 12 ------- 3 files changed, 32 insertions(+), 41 deletions(-) diff --git a/src/automation/compact_prompt.rs b/src/automation/compact_prompt.rs index 1b5067fc..8472916a 100644 --- a/src/automation/compact_prompt.rs +++ b/src/automation/compact_prompt.rs @@ -1,9 +1,7 @@ use crate::config::ConfigManager; use crate::llm_models; -use crate::shared::models::Automation; use crate::shared::state::AppState; -use diesel::prelude::*; -use log::{error, trace}; +use log::{error, info, trace}; use std::collections::HashSet; use std::sync::Arc; use tokio::time::{interval, Duration}; @@ -33,18 +31,6 @@ async fn compact_prompt_for_bots( session_manager.get_user_sessions(Uuid::nil())? }; for session in sessions { - { - let mut session_in_progress = SESSION_IN_PROGRESS.lock().await; - if session_in_progress.contains(&session.id) { - trace!( - "Skipping session {} - compaction already in progress", - session.id - ); - continue; - } - session_in_progress.insert(session.id); - } - let config_manager = ConfigManager::new(state.conn.clone()); let compact_threshold = config_manager .get_config(&session.bot_id, "prompt-compact", None)? @@ -60,12 +46,6 @@ async fn compact_prompt_for_bots( ); } let session_id = session.id; - let _session_cleanup = guard((), |_| { - tokio::spawn(async move { - let mut in_progress = SESSION_IN_PROGRESS.lock().await; - in_progress.remove(&session_id); - }); - }); let history = { let mut session_manager = state.session_manager.lock().await; session_manager.get_conversation_history(session.id, session.user_id)? @@ -103,11 +83,24 @@ async fn compact_prompt_for_bots( continue; } + { + let mut session_in_progress = SESSION_IN_PROGRESS.lock().await; + if session_in_progress.contains(&session.id) { + trace!( + "Skipping session {} - compaction already in progress", + session.id + ); + continue; + } + session_in_progress.insert(session.id); + } + trace!( "Compacting prompt for session {}: {} messages since last summary", session.id, messages_since_summary ); + let mut compacted = String::new(); // Include messages from start_index onward @@ -120,19 +113,21 @@ async fn compact_prompt_for_bots( compacted.push_str(&format!("{}: {}\n", role, content)); } let llm_provider = state.llm_provider.clone(); - let compacted_clone = compacted.clone(); - let summarized = match llm_provider.summarize(&compacted_clone).await { + trace!("Starting summarization for session {}", session.id); + let summarized = match llm_provider.generate(&compacted, &serde_json::Value::Null).await { Ok(summary) => { trace!( - "Successfully summarized conversation for session {}, summary length: {}", + "Successfully summarized session {} ({} chars)", session.id, summary.len() ); + // Use handler to filter content let handler = llm_models::get_handler( - &config_manager + config_manager .get_config(&session.bot_id, "llm-model", None) - .unwrap_or_default(), + .unwrap().as_str(), ); + let filtered = handler.process_content(&summary); format!("SUMMARY: {}", filtered) } @@ -141,10 +136,11 @@ async fn compact_prompt_for_bots( "Failed to summarize conversation for session {}: {}", session.id, e ); - format!("SUMMARY: {}", compacted) + trace!("Using fallback summary for session {}", session.id); + format!("SUMMARY: {}", compacted) // Fallback } }; - trace!( + info!( "Prompt compacted {}: {} messages", session.id, history.len() @@ -153,6 +149,13 @@ async fn compact_prompt_for_bots( let mut session_manager = state.session_manager.lock().await; session_manager.save_message(session.id, session.user_id, 9, &summarized, 1)?; } + + let _session_cleanup = guard((), |_| { + tokio::spawn(async move { + let mut in_progress = SESSION_IN_PROGRESS.lock().await; + in_progress.remove(&session_id); + }); + }); } Ok(()) } diff --git a/src/bot/mod.rs b/src/bot/mod.rs index 4a7b89c7..51b0a025 100644 --- a/src/bot/mod.rs +++ b/src/bot/mod.rs @@ -371,7 +371,7 @@ impl BotOrchestrator { for (role, content) in &history { prompt.push_str(&format!("{}:{}\n", role, content)); } - prompt.push_str(&format!("Human: {}\nBot:", message.content)); + prompt.push_str(&format!("\nbot:")); trace!( "Stream prompt constructed with {} history entries", history.len() diff --git a/src/session/mod.rs b/src/session/mod.rs index 12df5e48..c4ae248c 100644 --- a/src/session/mod.rs +++ b/src/session/mod.rs @@ -171,18 +171,6 @@ impl SessionManager { msg_type: i32, ) -> Result<(), Box> { use crate::shared::models::message_history::dsl::*; - let exists = message_history - .filter(session_id.eq(sess_id)) - .filter(user_id.eq(uid)) - .filter(role.eq(ro)) - .filter(content_encrypted.eq(content)) - .filter(message_type.eq(msg_type)) - .select(id) - .first::(&mut self.conn) - .optional()?; - if exists.is_some() { - return Ok(()); - } let next_index = message_history .filter(session_id.eq(sess_id)) .count()