refactor: simplify context thinning status message

Change format from verbose emoji-based message to cleaner status line:
  Before:  🥒 Context thinned at 70%: 7 tool results, ~33839 chars saved 
  After:  g3: thinning context ... 70% -> 40% ... [done]

The new format shows before/after percentages and uses bold green for
'g3:' and '[done]' to match other status messages.

Also removes unused emoji() and label() methods from ThinScope.
This commit is contained in:
Dhanji R. Prasanna
2026-01-17 04:47:16 +05:30
parent c7984fd4c2
commit 74b1b9bea3
3 changed files with 41 additions and 55 deletions

View File

@@ -23,20 +23,6 @@ pub enum ThinScope {
} }
impl ThinScope { impl ThinScope {
fn label(&self) -> &'static str {
match self {
ThinScope::FirstThird => "thinned",
ThinScope::All => "skinnified",
}
}
fn emoji(&self) -> &'static str {
match self {
ThinScope::FirstThird => "🥒",
ThinScope::All => "🦴",
}
}
fn file_prefix(&self) -> &'static str { fn file_prefix(&self) -> &'static str {
match self { match self {
ThinScope::FirstThird => "leaned", ThinScope::FirstThird => "leaned",
@@ -419,10 +405,14 @@ Format this as a detailed but concise summary that can be used to resume the con
// Recalculate token usage after thinning // Recalculate token usage after thinning
self.recalculate_tokens(); self.recalculate_tokens();
// Get new percentage after thinning
let new_percentage = self.percentage_used() as u32;
// Build result message // Build result message
self.build_thin_result_message( self.build_thin_result_message(
scope, scope,
current_percentage, current_percentage,
new_percentage,
leaned_count, leaned_count,
tool_call_leaned_count, tool_call_leaned_count,
chars_saved, chars_saved,
@@ -711,35 +701,29 @@ Format this as a detailed but concise summary that can be used to resume the con
&self, &self,
scope: ThinScope, scope: ThinScope,
current_percentage: u32, current_percentage: u32,
new_percentage: u32,
leaned_count: usize, leaned_count: usize,
tool_call_leaned_count: usize, tool_call_leaned_count: usize,
chars_saved: usize, chars_saved: usize,
) -> (String, usize) { ) -> (String, usize) {
let scope_desc = match scope {
ThinScope::FirstThird => "",
ThinScope::All => " across entire history",
};
// Nothing was thinned // Nothing was thinned
if leaned_count == 0 && tool_call_leaned_count == 0 { if leaned_count == 0 && tool_call_leaned_count == 0 {
let scope_desc = match scope {
ThinScope::FirstThird => "",
ThinScope::All => " (full)",
};
let msg = format!( let msg = format!(
" Context {} triggered at {}% but no large tool results or tool calls found{}", "\x1b[1;32mg3:\x1b[0m thinning context{} ... {}% ... \x1b[1;32m[no changes]\x1b[0m",
scope.error_action(), current_percentage, scope_desc scope_desc, current_percentage
); );
return (msg, 0); return (msg, 0);
} }
// Build description of what was thinned // Format: "g3: thinning context ... 70% -> 40% ... [done]"
let what_thinned = match (leaned_count > 0, tool_call_leaned_count > 0) { // with "g3:" and "[done]" in bold green
(true, true) => format!("{} tool results + {} tool calls", leaned_count, tool_call_leaned_count),
(true, false) => format!("{} tool results", leaned_count),
(false, true) => format!("{} tool calls", tool_call_leaned_count),
(false, false) => unreachable!(), // handled above
};
let msg = format!( let msg = format!(
"{} Context {} at {}%: {}{}, ~{} chars saved", "\x1b[1;32mg3:\x1b[0m thinning context ... {}% -> {}% ... \x1b[1;32m[done]\x1b[0m",
scope.emoji(), scope.label(), current_percentage, what_thinned, scope_desc, chars_saved current_percentage, new_percentage
); );
(msg, chars_saved) (msg, chars_saved)
} }
@@ -877,9 +861,9 @@ mod tests {
#[test] #[test]
fn test_thin_scope_properties() { fn test_thin_scope_properties() {
assert_eq!(ThinScope::FirstThird.emoji(), "🥒"); assert_eq!(ThinScope::FirstThird.file_prefix(), "leaned");
assert_eq!(ThinScope::All.emoji(), "🦴"); assert_eq!(ThinScope::All.file_prefix(), "skinny");
assert_eq!(ThinScope::FirstThird.label(), "thinned"); assert_eq!(ThinScope::FirstThird.error_action(), "thinning");
assert_eq!(ThinScope::All.label(), "skinnified"); assert_eq!(ThinScope::All.error_action(), "skinnifying");
} }
} }

View File

@@ -73,13 +73,10 @@ fn test_thin_context_basic() {
println!("Thinning summary: {}", summary); println!("Thinning summary: {}", summary);
// Should have thinned at least 1 large tool result in the first third // Should show the new format with percentage change
assert!( assert!(summary.contains("g3:"), "Summary was: {}", summary);
summary.contains("1 tool result"), assert!(summary.contains("thinning context"));
"Summary was: {}", assert!(summary.contains("[done]"));
summary
);
assert!(summary.contains("50%"));
// Check that the large tool results were replaced // Check that the large tool results were replaced
let first_third_end = context.conversation_history.len() / 3; let first_third_end = context.conversation_history.len() / 3;
@@ -134,8 +131,10 @@ fn test_thin_write_file_tool_calls() {
println!("Thinning summary: {}", summary); println!("Thinning summary: {}", summary);
// Should have thinned the write_file tool call // Should show the new format with percentage change
assert!(summary.contains("tool call") || summary.contains("chars saved")); assert!(summary.contains("g3:"));
assert!(summary.contains("thinning context"));
assert!(summary.contains("[done]"));
// Check that the large content was replaced with a file reference // Check that the large content was replaced with a file reference
let first_third_end = context.conversation_history.len() / 3; let first_third_end = context.conversation_history.len() / 3;
@@ -194,8 +193,10 @@ fn test_thin_str_replace_tool_calls() {
println!("Thinning summary: {}", summary); println!("Thinning summary: {}", summary);
// Should have thinned the str_replace tool call // Should show the new format with percentage change
assert!(summary.contains("tool call") || summary.contains("chars saved")); assert!(summary.contains("g3:"));
assert!(summary.contains("thinning context"));
assert!(summary.contains("[done]"));
// Check that the large diff was replaced with a file reference // Check that the large diff was replaced with a file reference
let first_third_end = context.conversation_history.len() / 3; let first_third_end = context.conversation_history.len() / 3;
@@ -227,7 +228,9 @@ fn test_thin_context_no_large_results() {
let (summary, _chars_saved) = context.thin_context(None); let (summary, _chars_saved) = context.thin_context(None);
// Should report no large results found // Should report no large results found
assert!(summary.contains("no large tool results or tool calls found")); assert!(summary.contains("g3:"));
assert!(summary.contains("thinning context"));
assert!(summary.contains("[no changes]"));
} }
#[test] #[test]
@@ -255,9 +258,9 @@ fn test_thin_context_only_affects_first_third() {
context.used_tokens = 5000; context.used_tokens = 5000;
let (summary, _chars_saved) = context.thin_context(None); let (summary, _chars_saved) = context.thin_context(None);
// First third is 4 messages (indices 0-3), so only indices 1 and 3 should be thinned // Should show the new format with percentage change
// That's 2 tool results assert!(summary.contains("g3:"));
assert!(summary.contains("2 tool results")); assert!(summary.contains("[done]"));
// Check that messages after the first third are NOT thinned // Check that messages after the first third are NOT thinned
let first_third_end = context.conversation_history.len() / 3; let first_third_end = context.conversation_history.len() / 3;

View File

@@ -139,11 +139,10 @@ fn test_non_todo_results_still_thinned() {
println!("Thinning summary: {}", summary); println!("Thinning summary: {}", summary);
// Should have thinned the non-TODO result // Should show the new format with percentage change (indicating thinning happened)
assert!( assert!(summary.contains("g3:"), "Non-TODO results should be thinned");
summary.contains("1 tool result") || summary.contains("chars saved"), assert!(summary.contains("thinning context"));
"Non-TODO results should be thinned" assert!(summary.contains("[done]"));
);
// Check that the result was actually thinned // Check that the result was actually thinned
let first_third_end = context.conversation_history.len() / 3; let first_third_end = context.conversation_history.len() / 3;