feat: add openAiOmitToolChoice setting for Azure/LiteLLM compatibility

Add a new boolean setting that allows users to omit the tool_choice
parameter from OpenAI API requests. This fixes compatibility issues
with Azure-hosted models and LiteLLM proxies that do not support
the tool_choice parameter.

Fixes #10701
This commit is contained in:
Roo Code 2026-01-13 22:19:19 +00:00
parent 83037104c6
commit 1b56f5ef84
4 changed files with 21 additions and 4 deletions

View file

@ -250,6 +250,7 @@ const openAiSchema = baseProviderSettingsSchema.extend({
openAiStreamingEnabled: z.boolean().optional(),
openAiHostHeader: z.string().optional(), // Keep temporarily for backward compatibility during migration.
openAiHeaders: z.record(z.string(), z.string()).optional(),
openAiOmitToolChoice: z.boolean().optional(), // Omit tool_choice parameter for Azure/LiteLLM compatibility.
})
const ollamaSchema = baseProviderSettingsSchema.extend({

View file

@ -161,7 +161,8 @@ export class OpenAiHandler extends BaseProvider implements SingleCompletionHandl
...(isGrokXAI ? {} : { stream_options: { include_usage: true } }),
...(reasoning && reasoning),
...(metadata?.tools && { tools: this.convertToolsForOpenAI(metadata.tools) }),
...(metadata?.tool_choice && { tool_choice: metadata.tool_choice }),
...(metadata?.tool_choice &&
!this.options.openAiOmitToolChoice && { tool_choice: metadata.tool_choice }),
...(metadata?.toolProtocol === "native" &&
metadata.parallelToolCalls === true && {
parallel_tool_calls: true,
@ -231,7 +232,8 @@ export class OpenAiHandler extends BaseProvider implements SingleCompletionHandl
? convertToR1Format([{ role: "user", content: systemPrompt }, ...messages])
: [systemMessage, ...convertToOpenAiMessages(messages)],
...(metadata?.tools && { tools: this.convertToolsForOpenAI(metadata.tools) }),
...(metadata?.tool_choice && { tool_choice: metadata.tool_choice }),
...(metadata?.tool_choice &&
!this.options.openAiOmitToolChoice && { tool_choice: metadata.tool_choice }),
...(metadata?.toolProtocol === "native" &&
metadata.parallelToolCalls === true && {
parallel_tool_calls: true,
@ -358,7 +360,8 @@ export class OpenAiHandler extends BaseProvider implements SingleCompletionHandl
reasoning_effort: modelInfo.reasoningEffort as "low" | "medium" | "high" | undefined,
temperature: undefined,
...(metadata?.tools && { tools: this.convertToolsForOpenAI(metadata.tools) }),
...(metadata?.tool_choice && { tool_choice: metadata.tool_choice }),
...(metadata?.tool_choice &&
!this.options.openAiOmitToolChoice && { tool_choice: metadata.tool_choice }),
...(metadata?.toolProtocol === "native" &&
metadata.parallelToolCalls === true && {
parallel_tool_calls: true,
@ -394,7 +397,8 @@ export class OpenAiHandler extends BaseProvider implements SingleCompletionHandl
reasoning_effort: modelInfo.reasoningEffort as "low" | "medium" | "high" | undefined,
temperature: undefined,
...(metadata?.tools && { tools: this.convertToolsForOpenAI(metadata.tools) }),
...(metadata?.tool_choice && { tool_choice: metadata.tool_choice }),
...(metadata?.tool_choice &&
!this.options.openAiOmitToolChoice && { tool_choice: metadata.tool_choice }),
...(metadata?.toolProtocol === "native" &&
metadata.parallelToolCalls === true && {
parallel_tool_calls: true,

View file

@ -173,6 +173,16 @@ export const OpenAICompatible = ({
onChange={handleInputChange("openAiUseAzure", noTransform)}>
{t("settings:modelInfo.useAzure")}
</Checkbox>
<div>
<Checkbox
checked={apiConfiguration?.openAiOmitToolChoice ?? false}
onChange={handleInputChange("openAiOmitToolChoice", noTransform)}>
{t("settings:modelInfo.omitToolChoice")}
</Checkbox>
<div className="text-sm text-vscode-descriptionForeground ml-6">
{t("settings:modelInfo.omitToolChoiceDescription")}
</div>
</div>
<div>
<Checkbox
checked={azureApiVersionSelected}

View file

@ -879,6 +879,8 @@
"enableR1FormatTips": "Must be enabled when using R1 models such as QWQ to prevent 400 errors",
"useAzure": "Use Azure",
"azureApiVersion": "Set Azure API version",
"omitToolChoice": "Omit tool_choice parameter",
"omitToolChoiceDescription": "Enable this if your Azure or LiteLLM proxy does not support the tool_choice parameter.",
"gemini": {
"freeRequests": "* Free up to {{count}} requests per minute. After that, billing depends on prompt size.",
"pricingDetails": "For more info, see pricing details.",