ui writer fixes

This commit is contained in:
Dhanji Prasanna
2025-10-10 15:38:13 +11:00
parent 1bae19abd4
commit 13236a1be5
2 changed files with 67 additions and 12 deletions

View File

@@ -53,10 +53,21 @@ impl UiWriter for ConsoleUiWriter {
fn print_tool_arg(&self, key: &str, value: &str) { fn print_tool_arg(&self, key: &str, value: &str) {
// Collect arguments instead of printing immediately // Collect arguments instead of printing immediately
self.current_tool_args // Filter out any keys that look like they might be agent message content
// (e.g., keys that are suspiciously long or contain message-like content)
let is_valid_arg_key = key.len() < 50 &&
!key.contains('\n') &&
!key.contains("I'll") &&
!key.contains("Let me") &&
!key.contains("Here's") &&
!key.contains("I can");
if is_valid_arg_key {
self.current_tool_args
.lock() .lock()
.unwrap() .unwrap()
.push((key.to_string(), value.to_string())); .push((key.to_string(), value.to_string()));
}
} }
fn print_tool_output_header(&self) { fn print_tool_output_header(&self) {
@@ -200,10 +211,21 @@ impl UiWriter for RetroTuiWriter {
} }
fn print_tool_arg(&self, key: &str, value: &str) { fn print_tool_arg(&self, key: &str, value: &str) {
self.current_tool_output // Filter out any keys that look like they might be agent message content
.lock() // (e.g., keys that are suspiciously long or contain message-like content)
.unwrap() let is_valid_arg_key = key.len() < 50 &&
.push(format!("{}: {}", key, value)); !key.contains('\n') &&
!key.contains("I'll") &&
!key.contains("Let me") &&
!key.contains("Here's") &&
!key.contains("I can");
if is_valid_arg_key {
self.current_tool_output
.lock()
.unwrap()
.push(format!("{}: {}", key, value));
}
// Build caption from first argument (usually the most important one) // Build caption from first argument (usually the most important one)
let mut caption = self.current_tool_caption.lock().unwrap(); let mut caption = self.current_tool_caption.lock().unwrap();

View File

@@ -24,7 +24,7 @@ use tracing::{debug, error, info, warn};
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ToolCall { pub struct ToolCall {
pub tool: String, pub tool: String,
pub args: serde_json::Value, pub args: serde_json::Value, // Should be a JSON object with tool-specific arguments
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@@ -167,14 +167,47 @@ impl StreamingToolParser {
let json_str = &json_text[..=i]; let json_str = &json_text[..=i];
debug!("Attempting to parse JSON tool call: {}", json_str); debug!("Attempting to parse JSON tool call: {}", json_str);
// First try to parse as a ToolCall
if let Ok(tool_call) = serde_json::from_str::<ToolCall>(json_str) { if let Ok(tool_call) = serde_json::from_str::<ToolCall>(json_str) {
debug!("Successfully parsed JSON tool call: {:?}", tool_call); // Validate that this is actually a proper tool call
// The args should be a JSON object with reasonable keys
if let Some(args_obj) = tool_call.args.as_object() {
// Check if any key looks like it contains agent message content
// This would indicate a malformed tool call where the message
// got mixed into the args
let has_message_like_key = args_obj.keys().any(|key| {
key.len() > 100 ||
key.contains('\n') ||
key.contains("I'll") ||
key.contains("Let me") ||
key.contains("Here's") ||
key.contains("I can") ||
key.contains("I need") ||
key.contains("First") ||
key.contains("Now") ||
key.contains("The ")
});
// Reset JSON parsing state if has_message_like_key {
self.in_json_tool_call = false; debug!("Detected malformed tool call with message-like keys, skipping");
self.json_tool_start = None; // This looks like a malformed tool call, skip it
self.in_json_tool_call = false;
self.json_tool_start = None;
break;
}
return Some(tool_call); // Also check if the values look reasonable
// Tool arguments should typically be file paths, commands, or content
// Not entire agent messages
debug!("Successfully parsed valid JSON tool call: {:?}", tool_call);
// Reset JSON parsing state
self.in_json_tool_call = false;
self.json_tool_start = None;
return Some(tool_call);
}
// If args is not an object, skip this as invalid
debug!("Tool call args is not an object, skipping");
} else { } else {
debug!("Failed to parse JSON tool call: {}", json_str); debug!("Failed to parse JSON tool call: {}", json_str);
// Reset and continue looking // Reset and continue looking