tighten tool output in normal cli
This commit is contained in:
@@ -1,15 +1,21 @@
|
|||||||
use crate::retro_tui::RetroTui;
|
use crate::retro_tui::RetroTui;
|
||||||
use g3_core::ui_writer::UiWriter;
|
use g3_core::ui_writer::UiWriter;
|
||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
use std::time::Instant;
|
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
/// Console implementation of UiWriter that prints to stdout
|
/// Console implementation of UiWriter that prints to stdout
|
||||||
pub struct ConsoleUiWriter;
|
pub struct ConsoleUiWriter {
|
||||||
|
current_tool_name: Mutex<Option<String>>,
|
||||||
|
current_tool_args: Mutex<Vec<(String, String)>>,
|
||||||
|
}
|
||||||
|
|
||||||
impl ConsoleUiWriter {
|
impl ConsoleUiWriter {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self
|
Self {
|
||||||
|
current_tool_name: Mutex::new(None),
|
||||||
|
current_tool_args: Mutex::new(Vec::new()),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,15 +46,53 @@ impl UiWriter for ConsoleUiWriter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn print_tool_header(&self, tool_name: &str) {
|
fn print_tool_header(&self, tool_name: &str) {
|
||||||
println!("┌─ {}", tool_name);
|
// Store the tool name and clear args for collection
|
||||||
|
*self.current_tool_name.lock().unwrap() = Some(tool_name.to_string());
|
||||||
|
self.current_tool_args.lock().unwrap().clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_tool_arg(&self, key: &str, value: &str) {
|
fn print_tool_arg(&self, key: &str, value: &str) {
|
||||||
println!("│ {}: {}", key, value);
|
// Collect arguments instead of printing immediately
|
||||||
|
self.current_tool_args
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.push((key.to_string(), value.to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_tool_output_header(&self) {
|
fn print_tool_output_header(&self) {
|
||||||
println!("├─ output:");
|
// Now print the tool header with the most important arg
|
||||||
|
if let Some(tool_name) = self.current_tool_name.lock().unwrap().as_ref() {
|
||||||
|
let args = self.current_tool_args.lock().unwrap();
|
||||||
|
|
||||||
|
// Find the most important argument
|
||||||
|
let important_arg = args
|
||||||
|
.iter()
|
||||||
|
.find(|(k, _)| k == "command" || k == "file_path" || k == "path" || k == "diff")
|
||||||
|
.or_else(|| args.first());
|
||||||
|
|
||||||
|
if let Some((_, value)) = important_arg {
|
||||||
|
// Truncate long values for display
|
||||||
|
let display_value = if value.len() > 80 {
|
||||||
|
format!("{}...", &value[..77])
|
||||||
|
} else {
|
||||||
|
value.clone()
|
||||||
|
};
|
||||||
|
println!("┌─ {} | {}", tool_name, display_value);
|
||||||
|
} else {
|
||||||
|
println!("┌─ {}", tool_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print any additional arguments (optional - can be removed if not wanted)
|
||||||
|
for (key, value) in args.iter() {
|
||||||
|
if Some(key.as_str()) != important_arg.map(|(k, _)| k.as_str()) {
|
||||||
|
// Only show additional args if they're short or important
|
||||||
|
if value.len() < 50 {
|
||||||
|
println!(" {}: {}", key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// println!("┌─────");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_tool_output_line(&self, line: &str) {
|
fn print_tool_output_line(&self, line: &str) {
|
||||||
@@ -57,7 +101,7 @@ impl UiWriter for ConsoleUiWriter {
|
|||||||
|
|
||||||
fn print_tool_output_summary(&self, hidden_count: usize) {
|
fn print_tool_output_summary(&self, hidden_count: usize) {
|
||||||
println!(
|
println!(
|
||||||
"│ ... ({} more line{} hidden)",
|
"│ ... ({} more line{})",
|
||||||
hidden_count,
|
hidden_count,
|
||||||
if hidden_count == 1 { "" } else { "s" }
|
if hidden_count == 1 { "" } else { "s" }
|
||||||
);
|
);
|
||||||
@@ -66,6 +110,9 @@ impl UiWriter for ConsoleUiWriter {
|
|||||||
fn print_tool_timing(&self, duration_str: &str) {
|
fn print_tool_timing(&self, duration_str: &str) {
|
||||||
println!("└─ ⚡️ {}", duration_str);
|
println!("└─ ⚡️ {}", duration_str);
|
||||||
println!();
|
println!();
|
||||||
|
// Clear the stored tool info
|
||||||
|
*self.current_tool_name.lock().unwrap() = None;
|
||||||
|
self.current_tool_args.lock().unwrap().clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_agent_prompt(&self) {
|
fn print_agent_prompt(&self) {
|
||||||
@@ -160,7 +207,11 @@ impl UiWriter for RetroTuiWriter {
|
|||||||
let mut caption = self.current_tool_caption.lock().unwrap();
|
let mut caption = self.current_tool_caption.lock().unwrap();
|
||||||
if caption.is_empty() && (key == "file_path" || key == "command" || key == "path") {
|
if caption.is_empty() && (key == "file_path" || key == "command" || key == "path") {
|
||||||
// Truncate long values for the caption
|
// Truncate long values for the caption
|
||||||
let truncated = if value.len() > 50 { format!("{}...", &value[..47]) } else { value.to_string() };
|
let truncated = if value.len() > 50 {
|
||||||
|
format!("{}...", &value[..47])
|
||||||
|
} else {
|
||||||
|
value.to_string()
|
||||||
|
};
|
||||||
*caption = truncated;
|
*caption = truncated;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -170,14 +221,9 @@ impl UiWriter for RetroTuiWriter {
|
|||||||
// Send the initial tool header to the TUI now
|
// Send the initial tool header to the TUI now
|
||||||
if let Some(tool_name) = self.current_tool_name.lock().unwrap().as_ref() {
|
if let Some(tool_name) = self.current_tool_name.lock().unwrap().as_ref() {
|
||||||
let caption = self.current_tool_caption.lock().unwrap().clone();
|
let caption = self.current_tool_caption.lock().unwrap().clone();
|
||||||
let caption = if caption.is_empty() { "Executing...".to_string() } else { caption };
|
|
||||||
|
|
||||||
// Send the tool output with initial header
|
// Send the tool output with initial header
|
||||||
self.tui.tool_output(
|
self.tui.tool_output(tool_name, &caption, "");
|
||||||
tool_name,
|
|
||||||
&caption,
|
|
||||||
""
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.current_tool_output.lock().unwrap().push(String::new());
|
self.current_tool_output.lock().unwrap().push(String::new());
|
||||||
@@ -196,7 +242,7 @@ impl UiWriter for RetroTuiWriter {
|
|||||||
|
|
||||||
fn print_tool_output_summary(&self, hidden_count: usize) {
|
fn print_tool_output_summary(&self, hidden_count: usize) {
|
||||||
self.current_tool_output.lock().unwrap().push(format!(
|
self.current_tool_output.lock().unwrap().push(format!(
|
||||||
"... ({} more line{} hidden)",
|
"... ({} more line{})",
|
||||||
hidden_count,
|
hidden_count,
|
||||||
if hidden_count == 1 { "" } else { "s" }
|
if hidden_count == 1 { "" } else { "s" }
|
||||||
));
|
));
|
||||||
@@ -219,7 +265,11 @@ impl UiWriter for RetroTuiWriter {
|
|||||||
if let Some(tool_name) = self.current_tool_name.lock().unwrap().as_ref() {
|
if let Some(tool_name) = self.current_tool_name.lock().unwrap().as_ref() {
|
||||||
let content = self.current_tool_output.lock().unwrap().join("\n");
|
let content = self.current_tool_output.lock().unwrap().join("\n");
|
||||||
let caption = self.current_tool_caption.lock().unwrap().clone();
|
let caption = self.current_tool_caption.lock().unwrap().clone();
|
||||||
let caption = if caption.is_empty() { "Completed".to_string() } else { caption };
|
let caption = if caption.is_empty() {
|
||||||
|
"Completed".to_string()
|
||||||
|
} else {
|
||||||
|
caption
|
||||||
|
};
|
||||||
|
|
||||||
// Update the tool detail panel with the complete output without adding a new header
|
// Update the tool detail panel with the complete output without adding a new header
|
||||||
// This keeps the original header in place to be updated by tool_complete
|
// This keeps the original header in place to be updated by tool_complete
|
||||||
@@ -227,10 +277,13 @@ impl UiWriter for RetroTuiWriter {
|
|||||||
|
|
||||||
// Determine success based on whether there's an error in the output
|
// Determine success based on whether there's an error in the output
|
||||||
// This is a simple heuristic - you might want to make this more sophisticated
|
// This is a simple heuristic - you might want to make this more sophisticated
|
||||||
let success = !content.contains("error") && !content.contains("Error") && !content.contains("ERROR");
|
let success = !content.contains("error")
|
||||||
|
&& !content.contains("Error")
|
||||||
|
&& !content.contains("ERROR");
|
||||||
|
|
||||||
// Send the completion status to update the header
|
// Send the completion status to update the header
|
||||||
self.tui.tool_complete(tool_name, success, duration_ms, &caption);
|
self.tui
|
||||||
|
.tool_complete(tool_name, success, duration_ms, &caption);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear the buffers
|
// Clear the buffers
|
||||||
|
|||||||
Reference in New Issue
Block a user