diff --git a/crates/goose-cli/src/session/mod.rs b/crates/goose-cli/src/session/mod.rs index 2695b366d6bf..9eab36b1ebe8 100644 --- a/crates/goose-cli/src/session/mod.rs +++ b/crates/goose-cli/src/session/mod.rs @@ -774,56 +774,68 @@ impl Session { } else if let Some(MessageContent::ContextLengthExceeded(_)) = message.content.first() { output::hide_thinking(); - if interactive { - // In interactive mode, ask the user what to do - let prompt = "The model's context length is maxed out. You will need to reduce the # msgs. Do you want to?".to_string(); - let selected_result = cliclack::select(prompt) - .item("clear", "Clear Session", "Removes all messages from Goose's memory") - .item("truncate", "Truncate Messages", "Removes old messages till context is within limits") - .item("summarize", "Summarize Session", "Summarize the session to reduce context length") - .item("cancel", "Cancel", "Cancel and return to chat") - .interact(); - - let selected = match selected_result { - Ok(s) => s, - Err(e) => { - if e.kind() == std::io::ErrorKind::Interrupted { - "cancel" // If interrupted, set selected to cancel - } else { - return Err(e.into()); - } - } - }; - - match selected { - "clear" => { - self.messages.clear(); - let msg = format!("Session cleared.\n{}", "-".repeat(50)); - output::render_text(&msg, Some(Color::Yellow), true); - break; // exit the loop to hand back control to the user - } - "truncate" => { - // Truncate messages to fit within context length - let (truncated_messages, _) = self.agent.truncate_context(&self.messages).await?; - let msg = format!("Context maxed out\n{}\nGoose tried its best to truncate messages for you.", "-".repeat(50)); - output::render_text("", Some(Color::Yellow), true); - output::render_text(&msg, Some(Color::Yellow), true); - self.messages = truncated_messages; - } - "summarize" => { - // Use the helper function to summarize context - Self::summarize_context_messages(&mut self.messages, &self.agent, "Goose summarized messages for you.").await?; - } - "cancel" => { - break; // Return to main prompt - } - _ => { - unreachable!() + // Check for user-configured default context strategy + let config = Config::global(); + let context_strategy = config.get_param::("GOOSE_CONTEXT_STRATEGY") + .unwrap_or_else(|_| if interactive { "prompt".to_string() } else { "summarize".to_string() }); + + let selected = match context_strategy.as_str() { + "clear" => "clear", + "truncate" => "truncate", + "summarize" => "summarize", + _ => { + if interactive { + // In interactive mode with no default, ask the user what to do + let prompt = "The model's context length is maxed out. You will need to reduce the # msgs. Do you want to?".to_string(); + cliclack::select(prompt) + .item("clear", "Clear Session", "Removes all messages from Goose's memory") + .item("truncate", "Truncate Messages", "Removes old messages till context is within limits") + .item("summarize", "Summarize Session", "Summarize the session to reduce context length") + .interact()? + } else { + // In headless mode, default to summarize + "summarize" } } - } else { - // In headless mode (goose run), automatically use summarize - Self::summarize_context_messages(&mut self.messages, &self.agent, "Goose automatically summarized messages to continue processing.").await?; + }; + + match selected { + "clear" => { + self.messages.clear(); + let msg = if context_strategy == "clear" { + format!("Context maxed out - automatically cleared session.\n{}", "-".repeat(50)) + } else { + format!("Session cleared.\n{}", "-".repeat(50)) + }; + output::render_text(&msg, Some(Color::Yellow), true); + break; // exit the loop to hand back control to the user + } + "truncate" => { + // Truncate messages to fit within context length + let (truncated_messages, _) = self.agent.truncate_context(&self.messages).await?; + let msg = if context_strategy == "truncate" { + format!("Context maxed out - automatically truncated messages.\n{}\nGoose tried its best to truncate messages for you.", "-".repeat(50)) + } else { + format!("Context maxed out\n{}\nGoose tried its best to truncate messages for you.", "-".repeat(50)) + }; + output::render_text("", Some(Color::Yellow), true); + output::render_text(&msg, Some(Color::Yellow), true); + self.messages = truncated_messages; + } + "summarize" => { + // Use the helper function to summarize context + let message_suffix = if context_strategy == "summarize" { + "Goose automatically summarized messages for you." + } else if interactive { + "Goose summarized messages for you." + } else { + "Goose automatically summarized messages to continue processing." + }; + Self::summarize_context_messages(&mut self.messages, &self.agent, message_suffix).await?; + } + _ => { + unreachable!() + } } // Restart the stream after handling ContextLengthExceeded diff --git a/documentation/docs/guides/environment-variables.md b/documentation/docs/guides/environment-variables.md index 7888b813ba01..4f29ff0e8629 100644 --- a/documentation/docs/guides/environment-variables.md +++ b/documentation/docs/guides/environment-variables.md @@ -62,6 +62,24 @@ export GOOSE_PLANNER_PROVIDER="openai" export GOOSE_PLANNER_MODEL="gpt-4" ``` +## Session Management + +These variables control how Goose manages conversation sessions and context. + +| Variable | Purpose | Values | Default | +|----------|---------|---------|---------| +| `GOOSE_CONTEXT_STRATEGY` | Controls how Goose handles context limit exceeded situations | "summarize", "truncate", "clear", "prompt" | "prompt" (interactive), "summarize" (headless) | + +**Examples** + +```bash +# Automatically summarize when context limit is reached +export GOOSE_CONTEXT_STRATEGY=summarize + +# Always prompt user to choose (default for interactive mode) +export GOOSE_CONTEXT_STRATEGY=prompt +``` + ## Tool Configuration These variables control how Goose handles [tool permissions](/docs/guides/tool-permissions) and their execution. diff --git a/documentation/docs/guides/smart-context-management.md b/documentation/docs/guides/smart-context-management.md index 2421d929916e..81238bb17ee9 100644 --- a/documentation/docs/guides/smart-context-management.md +++ b/documentation/docs/guides/smart-context-management.md @@ -58,10 +58,33 @@ You can proactively summarize your conversation before reaching context limits: The CLI offers three context management options: summarize, truncate, or clear your session. +### Default Context Strategy + +You can configure Goose to automatically handle context limits without prompting by setting the `GOOSE_CONTEXT_STRATEGY` environment variable: + +```bash +# Set default strategy (choose one) +export GOOSE_CONTEXT_STRATEGY=summarize # Automatically summarize (recommended) +export GOOSE_CONTEXT_STRATEGY=truncate # Automatically remove oldest messages +export GOOSE_CONTEXT_STRATEGY=clear # Automatically clear session +export GOOSE_CONTEXT_STRATEGY=prompt # Always prompt user (default) +``` + +Or configure it permanently: +```bash +goose configure set GOOSE_CONTEXT_STRATEGY summarize +``` + +**Default behavior:** +- **Interactive mode**: Prompts user to choose (equivalent to `prompt`) +- **Headless mode** (`goose run`): Automatically summarizes (equivalent to `summarize`) + -When you hit the context limit, you'll see this prompt to choose a management option, allowing you to continue your session: +When you hit the context limit, the behavior depends on your configuration: + +**With default settings (no `GOOSE_CONTEXT_STRATEGY` set)**, you'll see this prompt to choose a management option: ```sh ◇ The model's context length is maxed out. You will need to reduce the # msgs. Do you want to? @@ -76,6 +99,24 @@ final_summary: [A summary of your conversation will appear here] Context maxed out -------------------------------------------------- Goose summarized messages for you. +``` + +**With `GOOSE_CONTEXT_STRATEGY` configured**, Goose will automatically apply your chosen strategy: + +```sh +# Example with GOOSE_CONTEXT_STRATEGY=summarize +Context maxed out - automatically summarized messages. +-------------------------------------------------- +Goose automatically summarized messages for you. + +# Example with GOOSE_CONTEXT_STRATEGY=truncate +Context maxed out - automatically truncated messages. +-------------------------------------------------- +Goose tried its best to truncate messages for you. + +# Example with GOOSE_CONTEXT_STRATEGY=clear +Context maxed out - automatically cleared session. +-------------------------------------------------- ``` @@ -118,4 +159,4 @@ Key information has been preserved while reducing context length. This functionality is not available in the Goose CLI. - \ No newline at end of file +