diff --git a/packages/types/src/provider-settings.ts b/packages/types/src/provider-settings.ts index 95fbcf10c9..d040766a38 100644 --- a/packages/types/src/provider-settings.ts +++ b/packages/types/src/provider-settings.ts @@ -244,6 +244,7 @@ const openAiSchema = baseProviderSettingsSchema.extend({ openAiApiKey: z.string().optional(), openAiLegacyFormat: z.boolean().optional(), openAiR1FormatEnabled: z.boolean().optional(), + openAiDisableNativeTools: z.boolean().optional(), openAiModelId: z.string().optional(), openAiCustomModelInfo: modelInfoSchema.nullish(), openAiUseAzure: z.boolean().optional(), diff --git a/src/api/providers/openai.ts b/src/api/providers/openai.ts index 7ab2b00524..99a37026f4 100644 --- a/src/api/providers/openai.ts +++ b/src/api/providers/openai.ts @@ -292,12 +292,23 @@ export class OpenAiHandler extends BaseProvider implements SingleCompletionHandl override getModel() { const id = this.options.openAiModelId ?? "" + const enabledR1Format = this.options.openAiR1FormatEnabled ?? false + const disableNativeTools = this.options.openAiDisableNativeTools ?? false + + // Detect DeepSeek reasoner models that don't support native tool calling + const isDeepSeekReasoner = + id.includes("deepseek-reasoner") || id.includes("deepseek-r1") || enabledR1Format + // Ensure OpenAI-compatible models default to supporting native tool calling. // This is required for [`Task.attemptApiRequest()`](src/core/task/Task.ts:3817) to // include tool definitions in the request. + // However, disable native tools for DeepSeek reasoner models or when explicitly disabled + // by the user, as these models don't support function calling and will return 400 errors. const info: ModelInfo = { ...NATIVE_TOOL_DEFAULTS, ...(this.options.openAiCustomModelInfo ?? openAiModelInfoSaneDefaults), + // Override: Disable native tools if user setting is enabled or model is a DeepSeek reasoner + ...((disableNativeTools || isDeepSeekReasoner) && { supportsNativeTools: false }), } const params = getModelParams({ format: "openai", modelId: id, model: info, settings: this.options }) return { id, info, ...params } diff --git a/webview-ui/src/components/settings/providers/OpenAICompatible.tsx b/webview-ui/src/components/settings/providers/OpenAICompatible.tsx index ad338d342a..2f1519a2c6 100644 --- a/webview-ui/src/components/settings/providers/OpenAICompatible.tsx +++ b/webview-ui/src/components/settings/providers/OpenAICompatible.tsx @@ -155,6 +155,18 @@ export const OpenAICompatible = ({ onChange={handleInputChange("openAiR1FormatEnabled", noTransform)} openAiR1FormatEnabled={apiConfiguration?.openAiR1FormatEnabled ?? false} /> +
+
+ + {t("settings:modelInfo.disableNativeTools")} + +
+

+ {t("settings:modelInfo.disableNativeToolsTips")} +

+