tweaks for streaming toolcalls

This commit is contained in:
Dhanji Prasanna
2025-09-22 14:25:04 +10:00
parent cae16a7daf
commit 64d2ac53a8
2 changed files with 27 additions and 8 deletions

View File

@@ -580,6 +580,7 @@ IMPORTANT: You must call tools to complete tasks. When you receive a request:
For shell commands: Use the shell tool with the exact command needed. Avoid commands that produce a large amount of output, and consider piping those outputs to files. Example: If asked to list files, immediately call the shell tool with command parameter \"ls\". For shell commands: Use the shell tool with the exact command needed. Avoid commands that produce a large amount of output, and consider piping those outputs to files. Example: If asked to list files, immediately call the shell tool with command parameter \"ls\".
For task completion: Use the final_output tool with a summary. For task completion: Use the final_output tool with a summary.
IMPORTANT: If the user asks you to just respond with text (like \"just say hello\" or \"tell me about X\"), do NOT use tools. Simply respond with the requested text directly. Only use tools when you need to execute commands or complete tasks that require action.
Do not explain what you're going to do - just do it by calling the tools.".to_string() Do not explain what you're going to do - just do it by calling the tools.".to_string()
} else { } else {
@@ -1068,8 +1069,10 @@ The tool will execute immediately and you'll receive the result (success or erro
.replace("<</SYS>>", ""); .replace("<</SYS>>", "");
if !clean_content.is_empty() { if !clean_content.is_empty() {
debug!("Printing clean content: '{}'", clean_content);
print!("{}", clean_content); print!("{}", clean_content);
io::stdout().flush()?; let _ = io::stdout().flush(); // Force immediate output
debug!("Flushed {} characters to stdout", clean_content.len());
current_response.push_str(&clean_content); current_response.push_str(&clean_content);
} }
} }

View File

@@ -338,20 +338,35 @@ impl AnthropicProvider {
match content_block { match content_block {
AnthropicContent::ToolUse { id, name, input } => { AnthropicContent::ToolUse { id, name, input } => {
debug!("Found tool use in content_block_start: id={}, name={}, input={:?}", id, name, input); debug!("Found tool use in content_block_start: id={}, name={}, input={:?}", id, name, input);
debug!("Input JSON string: {}", serde_json::to_string(&input).unwrap_or_else(|_| "failed to serialize".to_string()));
// Create initial tool call - we'll update the args later from streaming JSON // For native tool calls, create the tool call immediately if we have complete args
// If args are empty, we'll wait for partial_json to accumulate them
let tool_call = ToolCall { let tool_call = ToolCall {
id: id.clone(), id: id.clone(),
tool: name.clone(), tool: name.clone(),
args: input, // This might be empty initially args: input.clone(),
}; };
debug!("Created initial tool call: {:?}", tool_call);
current_tool_calls.push(tool_call);
// Reset partial JSON accumulator for this tool // Check if we already have complete arguments
if !input.is_null() && input != serde_json::Value::Object(serde_json::Map::new()) {
// We have complete arguments, send the tool call immediately
debug!("Tool call has complete args, sending immediately: {:?}", tool_call);
let chunk = CompletionChunk {
content: String::new(),
finished: false,
tool_calls: Some(vec![tool_call]),
};
if tx.send(Ok(chunk)).await.is_err() {
debug!("Receiver dropped, stopping stream");
return;
}
} else {
// Arguments are empty, we'll accumulate them from partial_json
debug!("Tool call has empty args, will accumulate from partial_json");
current_tool_calls.push(tool_call);
partial_tool_json.clear(); partial_tool_json.clear();
} }
}
_ => { _ => {
debug!("Non-tool content block: {:?}", content_block); debug!("Non-tool content block: {:?}", content_block);
} }
@@ -361,6 +376,7 @@ impl AnthropicProvider {
"content_block_delta" => { "content_block_delta" => {
if let Some(delta) = event.delta { if let Some(delta) = event.delta {
if let Some(text) = delta.text { if let Some(text) = delta.text {
debug!("Sending text chunk of length {}: '{}'", text.len(), text);
let chunk = CompletionChunk { let chunk = CompletionChunk {
content: text, content: text,
finished: false, finished: false,