fix: handle empty arguments in tool call (#1111)

Co-authored-by: Salman Mohammed <smohammed@squareup.com>
This commit is contained in:
Yingjie He
2025-02-06 10:34:57 -08:00
committed by GitHub
parent 8eddc40b94
commit 8dad86dc5f
2 changed files with 33 additions and 2 deletions

View File

@@ -183,10 +183,14 @@ pub fn response_to_message(response: Value) -> anyhow::Result<Message> {
.as_str()
.unwrap_or_default()
.to_string();
let arguments = tool_call["function"]["arguments"]
let mut arguments = tool_call["function"]["arguments"]
.as_str()
.unwrap_or_default()
.to_string();
// If arguments is empty, we will have invalid json parsing error later.
if arguments.is_empty() {
arguments = "{}".to_string();
}
if !is_valid_function_name(&function_name) {
let error = ToolError::NotFound(format!(
@@ -581,4 +585,23 @@ mod tests {
Ok(())
}
#[test]
fn test_response_to_message_empty_argument() -> anyhow::Result<()> {
let mut response: Value = serde_json::from_str(OPENAI_TOOL_USE_RESPONSE)?;
response["choices"][0]["message"]["tool_calls"][0]["function"]["arguments"] =
serde_json::Value::String("".to_string());
let message = response_to_message(response)?;
if let MessageContent::ToolRequest(request) = &message.content[0] {
let tool_call = request.tool_call.as_ref().unwrap();
assert_eq!(tool_call.name, "example_fn");
assert_eq!(tool_call.arguments, json!({}));
} else {
panic!("Expected ToolRequest content");
}
Ok(())
}
}

View File

@@ -13,7 +13,7 @@ use goose::providers::{
};
use goose::providers::{google::GoogleProvider, groq::GroqProvider};
#[derive(Debug)]
#[derive(Debug, PartialEq)]
enum ProviderType {
Azure,
OpenAi,
@@ -136,6 +136,14 @@ async fn run_truncate_test(
println!("Responses: {responses:?}\n");
assert_eq!(responses.len(), 1);
// Ollama and OpenRouter truncate by default even when the context window is exceeded
// We don't have control over the truncation behavior in these providers
if provider_type == ProviderType::Ollama || provider_type == ProviderType::OpenRouter {
println!("WARNING: Skipping test for {:?} because it truncates by default when the context window is exceeded", provider_type);
return Ok(());
}
assert_eq!(responses[0].content.len(), 1);
let response_text = responses[0].content[0].as_text().unwrap();