Fix error when Copilot calls tools without arguments (cherry-pick #30371) (#30375)

Cherry-picked Fix error when Copilot calls tools without arguments
(#30371)

Fixes https://github.com/zed-industries/zed/issues/30346

The model can output an empty string to indicate the absence of
arguments, which can't be parsed as a `serde_json::Value`. When that
happens, we now create an empty object instead on behalf of the model.

Release Notes:

- Fixed a bug that prevented Copilot models from calling the
`diagnostic` tool.

Co-authored-by: Antonio Scandurra <me@as-cii.com>
This commit is contained in:
gcp-cherry-pick-bot[bot] 2025-05-09 14:17:35 +02:00 committed by GitHub
parent c0e128e8db
commit a9e5beda8b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -368,25 +368,34 @@ pub fn map_to_language_model_completion_events(
} }
Some("tool_calls") => { Some("tool_calls") => {
events.extend(state.tool_calls_by_index.drain().map( events.extend(state.tool_calls_by_index.drain().map(
|(_, tool_call)| match serde_json::Value::from_str( |(_, tool_call)| {
&tool_call.arguments, // The model can output an empty string
) { // to indicate the absence of arguments.
Ok(input) => Ok(LanguageModelCompletionEvent::ToolUse( // When that happens, create an empty
LanguageModelToolUse { // object instead.
id: tool_call.id.clone().into(), let arguments = if tool_call.arguments.is_empty() {
name: tool_call.name.as_str().into(), Ok(serde_json::Value::Object(Default::default()))
is_input_complete: true, } else {
input, serde_json::Value::from_str(&tool_call.arguments)
raw_input: tool_call.arguments.clone(), };
}, match arguments {
)), Ok(input) => Ok(LanguageModelCompletionEvent::ToolUse(
Err(error) => { LanguageModelToolUse {
Err(LanguageModelCompletionError::BadInputJson { id: tool_call.id.clone().into(),
id: tool_call.id.into(), name: tool_call.name.as_str().into(),
tool_name: tool_call.name.as_str().into(), is_input_complete: true,
raw_input: tool_call.arguments.into(), input,
json_parse_error: error.to_string(), raw_input: tool_call.arguments.clone(),
}) },
)),
Err(error) => {
Err(LanguageModelCompletionError::BadInputJson {
id: tool_call.id.into(),
tool_name: tool_call.name.as_str().into(),
raw_input: tool_call.arguments.into(),
json_parse_error: error.to_string(),
})
}
} }
}, },
)); ));