Manual compaction counting fix + cli cleanup (#5480)
This commit is contained in:
@@ -20,7 +20,7 @@ pub enum InputResult {
|
||||
EndPlan,
|
||||
Clear,
|
||||
Recipe(Option<String>),
|
||||
Summarize,
|
||||
Compact,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -120,7 +120,8 @@ fn handle_slash_command(input: &str) -> Option<InputResult> {
|
||||
const CMD_ENDPLAN: &str = "/endplan";
|
||||
const CMD_CLEAR: &str = "/clear";
|
||||
const CMD_RECIPE: &str = "/recipe";
|
||||
const CMD_SUMMARIZE: &str = "/summarize";
|
||||
const CMD_COMPACT: &str = "/compact";
|
||||
const CMD_SUMMARIZE_DEPRECATED: &str = "/summarize";
|
||||
|
||||
match input {
|
||||
"/exit" | "/quit" => Some(InputResult::Exit),
|
||||
@@ -180,7 +181,11 @@ fn handle_slash_command(input: &str) -> Option<InputResult> {
|
||||
s if s == CMD_ENDPLAN => Some(InputResult::EndPlan),
|
||||
s if s == CMD_CLEAR => Some(InputResult::Clear),
|
||||
s if s.starts_with(CMD_RECIPE) => parse_recipe_command(s),
|
||||
s if s == CMD_SUMMARIZE => Some(InputResult::Summarize),
|
||||
s if s == CMD_COMPACT => Some(InputResult::Compact),
|
||||
s if s == CMD_SUMMARIZE_DEPRECATED => {
|
||||
println!("{}", console::style("⚠️ Note: /summarize has been renamed to /compact and will be removed in a future release.").yellow());
|
||||
Some(InputResult::Compact)
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@@ -305,7 +310,7 @@ fn print_help() {
|
||||
/endplan - Exit plan mode and return to 'normal' goose mode.
|
||||
/recipe [filepath] - Generate a recipe from the current conversation and save it to the specified filepath (must end with .yaml).
|
||||
If no filepath is provided, it will be saved to ./recipe.yaml.
|
||||
/summarize - Summarize the current conversation to reduce context length while preserving key information.
|
||||
/compact - Compact the current conversation to reduce context length while preserving key information.
|
||||
/? or /help - Display this help message
|
||||
/clear - Clears the current chat history
|
||||
|
||||
@@ -541,17 +546,6 @@ mod tests {
|
||||
assert!(matches!(result, Some(InputResult::Retry)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_summarize_command() {
|
||||
// Test the summarize command
|
||||
let result = handle_slash_command("/summarize");
|
||||
assert!(matches!(result, Some(InputResult::Summarize)));
|
||||
|
||||
// Test with whitespace
|
||||
let result = handle_slash_command(" /summarize ");
|
||||
assert!(matches!(result, Some(InputResult::Summarize)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_input_prompt_string() {
|
||||
let prompt = get_input_prompt_string();
|
||||
|
||||
@@ -28,7 +28,7 @@ use anyhow::{Context, Result};
|
||||
use completion::GooseCompleter;
|
||||
use goose::agents::extension::{Envs, ExtensionConfig};
|
||||
use goose::agents::types::RetryConfig;
|
||||
use goose::agents::{Agent, SessionConfig};
|
||||
use goose::agents::{Agent, SessionConfig, MANUAL_COMPACT_TRIGGER};
|
||||
use goose::config::{Config, GooseMode};
|
||||
use goose::providers::pricing::initialize_pricing_cache;
|
||||
use goose::session::SessionManager;
|
||||
@@ -641,16 +641,16 @@ impl CliSession {
|
||||
|
||||
continue;
|
||||
}
|
||||
InputResult::Summarize => {
|
||||
InputResult::Compact => {
|
||||
save_history(&mut editor);
|
||||
|
||||
let prompt = "Are you sure you want to summarize this conversation? This will condense the message history.";
|
||||
let prompt = "Are you sure you want to compact this conversation? This will condense the message history.";
|
||||
let should_summarize =
|
||||
match cliclack::confirm(prompt).initial_value(true).interact() {
|
||||
Ok(choice) => choice,
|
||||
Err(e) => {
|
||||
if e.kind() == std::io::ErrorKind::Interrupted {
|
||||
false // If interrupted, set should_summarize to false
|
||||
false
|
||||
} else {
|
||||
return Err(e.into());
|
||||
}
|
||||
@@ -658,81 +658,13 @@ impl CliSession {
|
||||
};
|
||||
|
||||
if should_summarize {
|
||||
println!("{}", console::style("Summarizing conversation...").yellow());
|
||||
self.push_message(Message::user().with_text(MANUAL_COMPACT_TRIGGER));
|
||||
output::show_thinking();
|
||||
|
||||
let (summarized_messages, _token_counts, summarization_usage) =
|
||||
goose::context_mgmt::compact_messages(
|
||||
&self.agent,
|
||||
&self.messages,
|
||||
false,
|
||||
)
|
||||
self.process_agent_response(true, CancellationToken::default())
|
||||
.await?;
|
||||
|
||||
// Update the session messages with the summarized ones
|
||||
self.messages = summarized_messages.clone();
|
||||
|
||||
// Persist the summarized messages and update session metadata
|
||||
if let Some(session_id) = &self.session_id {
|
||||
// Replace all messages with the summarized version
|
||||
SessionManager::replace_conversation(session_id, &summarized_messages)
|
||||
.await?;
|
||||
|
||||
// Update session metadata with the new token counts from summarization
|
||||
if let Some(usage) = summarization_usage {
|
||||
let session =
|
||||
SessionManager::get_session(session_id, false).await?;
|
||||
|
||||
// Update token counts with the summarization usage
|
||||
let summary_tokens = usage.usage.output_tokens.unwrap_or(0);
|
||||
|
||||
// Update accumulated tokens (add the summarization cost)
|
||||
let accumulate = |a: Option<i32>, b: Option<i32>| -> Option<i32> {
|
||||
match (a, b) {
|
||||
(Some(x), Some(y)) => Some(x + y),
|
||||
_ => a.or(b),
|
||||
}
|
||||
};
|
||||
|
||||
let accumulated_total = accumulate(
|
||||
session.accumulated_total_tokens,
|
||||
usage.usage.total_tokens,
|
||||
);
|
||||
let accumulated_input = accumulate(
|
||||
session.accumulated_input_tokens,
|
||||
usage.usage.input_tokens,
|
||||
);
|
||||
let accumulated_output = accumulate(
|
||||
session.accumulated_output_tokens,
|
||||
usage.usage.output_tokens,
|
||||
);
|
||||
|
||||
SessionManager::update_session(session_id)
|
||||
.total_tokens(Some(summary_tokens))
|
||||
.input_tokens(None)
|
||||
.output_tokens(Some(summary_tokens))
|
||||
.accumulated_total_tokens(accumulated_total)
|
||||
.accumulated_input_tokens(accumulated_input)
|
||||
.accumulated_output_tokens(accumulated_output)
|
||||
.apply()
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
|
||||
output::hide_thinking();
|
||||
println!(
|
||||
"{}",
|
||||
console::style("Conversation has been summarized.").green()
|
||||
);
|
||||
println!(
|
||||
"{}",
|
||||
console::style(
|
||||
"Key information has been preserved while reducing context length."
|
||||
)
|
||||
.green()
|
||||
);
|
||||
} else {
|
||||
println!("{}", console::style("Summarization cancelled.").yellow());
|
||||
println!("{}", console::style("Compaction cancelled.").yellow());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user