Add print_g3_progress/print_g3_status methods for consistent status messages

This commit is contained in:
Dhanji R. Prasanna
2026-01-16 20:28:24 +05:30
parent 95f89d3f8e
commit 0e33465342
7 changed files with 123 additions and 21 deletions

View File

@@ -338,16 +338,16 @@ async fn handle_command<W: UiWriter>(
Ok(true) Ok(true)
} }
"/compact" => { "/compact" => {
output.print("g3: compacting session ..."); output.print_g3_progress("compacting session");
match agent.force_compact().await { match agent.force_compact().await {
Ok(true) => { Ok(true) => {
output.print("g3: compacting session ... done"); output.print_g3_status("compacting session", "done");
} }
Ok(false) => { Ok(false) => {
output.print("g3: compacting session ... failed"); output.print_g3_status("compacting session", "failed");
} }
Err(e) => { Err(e) => {
output.print(&format!("g3: compacting session ... error: {}", e)); output.print_g3_status("compacting session", &format!("error: {}", e));
} }
} }
Ok(true) Ok(true)

View File

@@ -1,3 +1,5 @@
use crossterm::style::{Attribute, Color, ResetColor, SetAttribute, SetForegroundColor};
/// Simple output helper for printing messages /// Simple output helper for printing messages
#[derive(Clone)] #[derive(Clone)]
pub struct SimpleOutput; pub struct SimpleOutput;
@@ -14,6 +16,49 @@ impl SimpleOutput {
pub fn print_smart(&self, message: &str) { pub fn print_smart(&self, message: &str) {
println!("{}", message); println!("{}", message);
} }
/// Print a g3 status message with colored tag and status
/// Format: "g3: <message> ... [status]"
/// - "g3:" is bold green
/// - "done" status is normal
/// - "failed" and "error" statuses are red
pub fn print_g3_status(&self, message: &str, status: &str) {
let status_colored = match status {
s if s.starts_with("error") || s == "failed" => {
format!(
"{}[{}]{}",
SetForegroundColor(Color::Red),
status,
ResetColor
)
}
_ => format!("[{}]", status),
};
println!(
"{}{}g3:{}{} {} ... {}",
SetAttribute(Attribute::Bold),
SetForegroundColor(Color::Green),
ResetColor,
SetAttribute(Attribute::Reset),
message,
status_colored
);
}
/// Print a g3 status message in progress (no status yet)
/// Format: "g3: <message> ..."
/// - "g3:" is bold green
pub fn print_g3_progress(&self, message: &str) {
println!(
"{}{}g3:{}{} {} ...",
SetAttribute(Attribute::Bold),
SetForegroundColor(Color::Green),
ResetColor,
SetAttribute(Attribute::Reset),
message
);
}
} }
impl Default for SimpleOutput { impl Default for SimpleOutput {

View File

@@ -211,6 +211,41 @@ impl UiWriter for ConsoleUiWriter {
println!("{}", message); println!("{}", message);
} }
fn print_g3_progress(&self, message: &str) {
use crossterm::style::{Attribute, Color, ResetColor, SetAttribute, SetForegroundColor};
println!(
"{}{}g3:{}{} {} ...",
SetAttribute(Attribute::Bold),
SetForegroundColor(Color::Green),
ResetColor,
SetAttribute(Attribute::Reset),
message
);
}
fn print_g3_status(&self, message: &str, status: &str) {
use crossterm::style::{Attribute, Color, ResetColor, SetAttribute, SetForegroundColor};
let status_colored = if status.starts_with("error") || status == "failed" {
format!(
"{}[{}]{}",
SetForegroundColor(Color::Red),
status,
ResetColor
)
} else {
format!("[{}]", status)
};
println!(
"{}{}g3:{}{} {} ... {}",
SetAttribute(Attribute::Bold),
SetForegroundColor(Color::Green),
ResetColor,
SetAttribute(Attribute::Reset),
message,
status_colored
);
}
fn print_context_thinning(&self, message: &str) { fn print_context_thinning(&self, message: &str) {
// Animated highlight for context thinning // Animated highlight for context thinning
// Use bright cyan/green with a quick flash animation // Use bright cyan/green with a quick flash animation

View File

@@ -892,12 +892,14 @@ impl<W: UiWriter> Agent<W> {
// Check if we need to do 90% auto-compaction // Check if we need to do 90% auto-compaction
if self.pending_90_compaction { if self.pending_90_compaction {
self.ui_writer
.print_context_status("\ng3: compacting session ...\n");
if let Err(e) = self.force_compact().await {
warn!("Failed to auto-compact at 90%: {}", e);
} else {
self.ui_writer.println(""); self.ui_writer.println("");
self.ui_writer.print_g3_progress("compacting session");
match self.force_compact().await {
Ok(true) => self.ui_writer.print_g3_status("compacting session", "done"),
Ok(false) => self.ui_writer.print_g3_status("compacting session", "failed"),
Err(e) => {
self.ui_writer.print_g3_status("compacting session", &format!("error: {}", e));
}
} }
self.pending_90_compaction = false; self.pending_90_compaction = false;
} }
@@ -1071,12 +1073,11 @@ impl<W: UiWriter> Agent<W> {
self.ui_writer.print_context_thinning(&thin_summary); self.ui_writer.print_context_thinning(&thin_summary);
if !self.context_window.should_compact() { if !self.context_window.should_compact() {
self.ui_writer self.ui_writer.print_g3_status("thinning", "resolved");
.print_context_status("g3: thinning resolved capacity issue\n");
return Ok(false); return Ok(false);
} }
self.ui_writer self.ui_writer.print_g3_status("thinning", "insufficient");
.print_context_status("g3: thinning insufficient, compacting ...\n"); self.ui_writer.print_g3_progress("compacting session");
} }
// Compaction still needed // Compaction still needed
@@ -1086,10 +1087,10 @@ impl<W: UiWriter> Agent<W> {
use crate::compaction::{perform_compaction, CompactionConfig}; use crate::compaction::{perform_compaction, CompactionConfig};
self.ui_writer.print_context_status(&format!( self.ui_writer.println("");
"\ng3: compacting session ({}%) ...", self.ui_writer.print_g3_progress(
self.context_window.percentage_used() as u32 &format!("compacting session ({}%)", self.context_window.percentage_used() as u32)
)); );
let provider_name = self.providers.get(None)?.name().to_string(); let provider_name = self.providers.get(None)?.name().to_string();
let latest_user_msg = request let latest_user_msg = request
@@ -1115,14 +1116,13 @@ impl<W: UiWriter> Agent<W> {
.await?; .await?;
if result.success { if result.success {
self.ui_writer self.ui_writer.print_g3_status("compacting session", "done");
.print_context_status("g3: compacting session ... done\n");
self.compaction_events.push(result.chars_saved); self.compaction_events.push(result.chars_saved);
request.messages = self.context_window.conversation_history.clone(); request.messages = self.context_window.conversation_history.clone();
return Ok(true); return Ok(true);
} }
self.ui_writer.print_context_status("⚠️ Unable to compact context. Consider starting a new session if you continue to see errors.\n"); self.ui_writer.print_g3_status("compacting session", "failed");
Err(anyhow::anyhow!( Err(anyhow::anyhow!(
"Context window at capacity and compaction failed. Please start a new session." "Context window at capacity and compaction failed. Please start a new session."
)) ))

View File

@@ -17,6 +17,16 @@ pub trait UiWriter: Send + Sync {
/// Print a context window status message /// Print a context window status message
fn print_context_status(&self, message: &str); fn print_context_status(&self, message: &str);
/// Print a g3-style status message in progress
/// Format: "g3: <message> ..."
/// - "g3:" should be bold green
fn print_g3_progress(&self, message: &str);
/// Print a g3-style status message with completion status
/// Format: "g3: <message> ... [status]"
/// - "g3:" should be bold green, "failed"/"error" status should be red
fn print_g3_status(&self, message: &str, status: &str);
/// Print a context thinning success message with highlight and animation /// Print a context thinning success message with highlight and animation
fn print_context_thinning(&self, message: &str); fn print_context_thinning(&self, message: &str);
@@ -124,6 +134,8 @@ impl UiWriter for NullUiWriter {
fn print_inline(&self, _message: &str) {} fn print_inline(&self, _message: &str) {}
fn print_system_prompt(&self, _prompt: &str) {} fn print_system_prompt(&self, _prompt: &str) {}
fn print_context_status(&self, _message: &str) {} fn print_context_status(&self, _message: &str) {}
fn print_g3_progress(&self, _message: &str) {}
fn print_g3_status(&self, _message: &str, _status: &str) {}
fn print_context_thinning(&self, _message: &str) {} fn print_context_thinning(&self, _message: &str) {}
fn print_tool_header(&self, _tool_name: &str, _tool_args: Option<&serde_json::Value>) {} fn print_tool_header(&self, _tool_name: &str, _tool_args: Option<&serde_json::Value>) {}
fn print_tool_arg(&self, _key: &str, _value: &str) {} fn print_tool_arg(&self, _key: &str, _value: &str) {}

View File

@@ -52,6 +52,8 @@ impl UiWriter for MockUiWriter {
.unwrap() .unwrap()
.push(format!("STATUS: {}", message)); .push(format!("STATUS: {}", message));
} }
fn print_g3_progress(&self, _message: &str) {}
fn print_g3_status(&self, _message: &str, _status: &str) {}
fn print_context_thinning(&self, _message: &str) {} fn print_context_thinning(&self, _message: &str) {}
fn print_tool_header(&self, _tool_name: &str, _tool_args: Option<&serde_json::Value>) {} fn print_tool_header(&self, _tool_name: &str, _tool_args: Option<&serde_json::Value>) {}
fn print_tool_arg(&self, _key: &str, _value: &str) {} fn print_tool_arg(&self, _key: &str, _value: &str) {}

View File

@@ -234,6 +234,14 @@ impl g3_core::ui_writer::UiWriter for PlannerUiWriter {
println!("📊 {}", message); println!("📊 {}", message);
} }
fn print_g3_progress(&self, message: &str) {
println!("g3: {} ...", message);
}
fn print_g3_status(&self, message: &str, status: &str) {
println!("g3: {} ... [{}]", message, status);
}
fn print_context_thinning(&self, message: &str) { fn print_context_thinning(&self, message: &str) {
println!("🗜️ {}", message); println!("🗜️ {}", message);
} }