From 738b3065dc2bf643daa40507061a928299f67d30 Mon Sep 17 00:00:00 2001 From: Aiden Cline <63023139+rekram1-node@users.noreply.github.com> Date: Mon, 27 Apr 2026 10:17:38 -0500 Subject: [PATCH] tweak: make interleaved reasoning_content default to true for openai compat deepseek setups (#24630) --- packages/opencode/src/provider/provider.ts | 23 ++++--- .../opencode/test/provider/provider.test.ts | 61 +++++++++++++++++++ 2 files changed, 76 insertions(+), 8 deletions(-) diff --git a/packages/opencode/src/provider/provider.ts b/packages/opencode/src/provider/provider.ts index 9aa1b6304c..04d53a685c 100644 --- a/packages/opencode/src/provider/provider.ts +++ b/packages/opencode/src/provider/provider.ts @@ -1135,6 +1135,13 @@ const layer: Layer.Layer< for (const [modelID, model] of Object.entries(provider.models ?? {})) { const existingModel = parsed.models[model.id ?? modelID] + const apiID = model.id ?? existingModel?.api.id ?? modelID + const apiNpm = + model.provider?.npm ?? + provider.npm ?? + existingModel?.api.npm ?? + modelsDev[providerID]?.npm ?? + "@ai-sdk/openai-compatible" const name = iife(() => { if (model.name) return model.name if (model.id && model.id !== modelID) return modelID @@ -1143,13 +1150,8 @@ const layer: Layer.Layer< const parsedModel: Model = { id: ModelID.make(modelID), api: { - id: model.id ?? existingModel?.api.id ?? modelID, - npm: - model.provider?.npm ?? - provider.npm ?? - existingModel?.api.npm ?? - modelsDev[providerID]?.npm ?? - "@ai-sdk/openai-compatible", + id: apiID, + npm: apiNpm, url: model.provider?.api ?? provider?.api ?? existingModel?.api.url ?? modelsDev[providerID]?.api ?? "", }, status: model.status ?? existingModel?.status ?? "active", @@ -1177,7 +1179,12 @@ const layer: Layer.Layer< model.modalities?.output?.includes("video") ?? existingModel?.capabilities.output.video ?? false, pdf: model.modalities?.output?.includes("pdf") ?? existingModel?.capabilities.output.pdf ?? false, }, - interleaved: model.interleaved ?? existingModel?.capabilities.interleaved ?? false, + interleaved: + model.interleaved ?? + existingModel?.capabilities.interleaved ?? + (!existingModel && apiNpm === "@ai-sdk/openai-compatible" && apiID.includes("deepseek") + ? { field: "reasoning_content" } + : false), }, cost: { input: model?.cost?.input ?? existingModel?.cost?.input ?? 0, diff --git a/packages/opencode/test/provider/provider.test.ts b/packages/opencode/test/provider/provider.test.ts index da98496c30..1480b2314d 100644 --- a/packages/opencode/test/provider/provider.test.ts +++ b/packages/opencode/test/provider/provider.test.ts @@ -312,6 +312,67 @@ test("custom provider with npm package", async () => { }) }) +test("custom DeepSeek openai-compatible model defaults interleaved reasoning field", async () => { + await using tmp = await tmpdir({ + init: async (dir) => { + await Bun.write( + path.join(dir, "opencode.json"), + JSON.stringify({ + $schema: "https://opencode.ai/config.json", + provider: { + "custom-provider": { + name: "Custom Provider", + npm: "@ai-sdk/openai-compatible", + api: "https://api.custom.com/v1", + models: { + "deepseek-r1": { + name: "DeepSeek R1", + }, + "deepseek-details": { + name: "DeepSeek Details", + interleaved: { field: "reasoning_details" }, + }, + "custom-model": { + name: "Custom Model", + }, + }, + options: { + apiKey: "custom-key", + }, + }, + "custom-anthropic-provider": { + name: "Custom Anthropic Provider", + npm: "@ai-sdk/anthropic", + api: "https://api.custom.com/v1", + models: { + "deepseek-r1": { + name: "DeepSeek R1", + }, + }, + options: { + apiKey: "custom-key", + }, + }, + }, + }), + ) + }, + }) + await Instance.provide({ + directory: tmp.path, + fn: async () => { + const providers = await list() + const provider = providers[ProviderID.make("custom-provider")] + expect(provider.models["deepseek-r1"].capabilities.interleaved).toEqual({ field: "reasoning_content" }) + expect(provider.models["deepseek-details"].capabilities.interleaved).toEqual({ field: "reasoning_details" }) + expect(provider.models["custom-model"].capabilities.interleaved).toBe(false) + expect( + providers[ProviderID.make("custom-anthropic-provider")].models["deepseek-r1"].capabilities.interleaved, + ).toBe(false) + }, + }) +}) + test("env variable takes precedence, config merges options", async () => { await using tmp = await tmpdir({ init: async (dir) => {