diff --git a/crates/goose/src/agents/agent.rs b/crates/goose/src/agents/agent.rs index 98629f8e4398..9f63d057fb9e 100644 --- a/crates/goose/src/agents/agent.rs +++ b/crates/goose/src/agents/agent.rs @@ -940,6 +940,7 @@ impl Agent { let _ = reply_span.enter(); let mut turns_taken = 0u32; let max_turns = session_config.max_turns.unwrap_or(DEFAULT_MAX_TURNS); + let mut compaction_attempts = 0; loop { if is_token_cancelled(&cancel_token) { @@ -991,6 +992,8 @@ impl Agent { match next { Ok((response, usage)) => { + compaction_attempts = 0; + // Emit model change event if provider is lead-worker let provider = self.provider().await?; if let Some(lead_worker) = provider.as_lead_worker() { @@ -1202,6 +1205,19 @@ impl Agent { } Err(ref provider_err @ ProviderError::ContextLengthExceeded(_)) => { crate::posthog::emit_error(provider_err.telemetry_type()); + compaction_attempts += 1; + + if compaction_attempts >= 2 { + error!("Context limit exceeded after compaction - prompt too large"); + yield AgentEvent::Message( + Message::assistant().with_system_notification( + SystemNotificationType::InlineMessage, + "Unable to continue: Context limit still exceeded after compaction. Try using a shorter message, a model with a larger context window, or start a new session." + ) + ); + break; + } + yield AgentEvent::Message( Message::assistant().with_system_notification( SystemNotificationType::InlineMessage, @@ -1222,15 +1238,10 @@ impl Agent { conversation = compacted_conversation; did_recovery_compact_this_iteration = true; yield AgentEvent::HistoryReplaced(conversation.clone()); - continue; + break; } Err(e) => { - error!("Error: {}", e); - yield AgentEvent::Message( - Message::assistant().with_text( - format!("Ran into this error trying to compact: {e}.\n\nPlease retry if you think this is a transient or recoverable error.") - ) - ); + error!("Compaction failed: {}", e); break; } } diff --git a/crates/goose/src/context_mgmt/mod.rs b/crates/goose/src/context_mgmt/mod.rs index 4e312a48fafd..af4a81b7f1a1 100644 --- a/crates/goose/src/context_mgmt/mod.rs +++ b/crates/goose/src/context_mgmt/mod.rs @@ -320,8 +320,7 @@ async fn do_compact( continue; } else { return Err(anyhow::anyhow!( - "Failed to compact messages: context length still exceeded after {} attempts with maximum removal", - removal_percentages.len() + "Failed to compact: context limit exceeded even after removing all tool responses" )); } }