cli(config): Add GOOSE_CONTEXT_STRATEGY setting (#2666)

Co-authored-by: Michael Neale <michael.neale@gmail.com>
This commit is contained in:
Raduan Al-Shedivat
2025-06-03 19:32:44 +02:00
committed by GitHub
parent 601744518d
commit 78234fb103
3 changed files with 120 additions and 49 deletions

View File

@@ -774,23 +774,27 @@ impl Session {
} else if let Some(MessageContent::ContextLengthExceeded(_)) = message.content.first() {
output::hide_thinking();
// Check for user-configured default context strategy
let config = Config::global();
let context_strategy = config.get_param::<String>("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, ask the user what to do
// 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();
let selected_result = cliclack::select(prompt)
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
.interact()?
} else {
return Err(e.into());
// In headless mode, default to summarize
"summarize"
}
}
};
@@ -798,33 +802,41 @@ impl Session {
match selected {
"clear" => {
self.messages.clear();
let msg = format!("Session cleared.\n{}", "-".repeat(50));
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 = format!("Context maxed out\n{}\nGoose tried its best to truncate messages for you.", "-".repeat(50));
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
Self::summarize_context_messages(&mut self.messages, &self.agent, "Goose summarized messages for you.").await?;
}
"cancel" => {
break; // Return to main prompt
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!()
}
}
} 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?;
}
// Restart the stream after handling ContextLengthExceeded
stream = self

View File

@@ -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.

View File

@@ -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`)
<Tabs>
<TabItem value="automatic" label="Automatic" default>
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.
--------------------------------------------------
```
</TabItem>