diff --git a/crates/language_models/src/provider/copilot_chat.rs b/crates/language_models/src/provider/copilot_chat.rs index 036d29bdf2b878f1caf4c545bb2e96310c75d149..f1cf43c061e8ac26d208ecae938d1fe72e0c41d0 100644 --- a/crates/language_models/src/provider/copilot_chat.rs +++ b/crates/language_models/src/provider/copilot_chat.rs @@ -436,6 +436,7 @@ impl CopilotChatLanguageModel { } } + let mut tool_called = false; let mut messages: Vec = Vec::new(); for message in request_messages { let text_content = { @@ -476,6 +477,7 @@ impl CopilotChatLanguageModel { let mut tool_calls = Vec::new(); for content in &message.content { if let MessageContent::ToolUse(tool_use) = content { + tool_called = true; tool_calls.push(ToolCall { id: tool_use.id.to_string(), content: copilot::copilot_chat::ToolCallContent::Function { @@ -503,7 +505,7 @@ impl CopilotChatLanguageModel { } } - let tools = request + let mut tools = request .tools .iter() .map(|tool| Tool::Function { @@ -513,7 +515,21 @@ impl CopilotChatLanguageModel { parameters: tool.input_schema.clone(), }, }) - .collect(); + .collect::>(); + + // The API will return a Bad Request (with no error message) when tools + // were used previously in the conversation but no tools are provided as + // part of this request. Inserting a dummy tool seems to circumvent this + // error. + if tool_called && tools.is_empty() { + tools.push(Tool::Function { + function: copilot::copilot_chat::Function { + name: "noop".to_string(), + description: "No operation".to_string(), + parameters: serde_json::json!({}), + }, + }); + } Ok(CopilotChatRequest { intent: true,