diff --git a/packages/opencode/src/provider/provider.ts b/packages/opencode/src/provider/provider.ts index 220b0144e1..24c5119296 100644 --- a/packages/opencode/src/provider/provider.ts +++ b/packages/opencode/src/provider/provider.ts @@ -1439,6 +1439,7 @@ const layer = Layer.effect( } for (const [modelID, model] of Object.entries(provider.models ?? {})) { + const catalogModel = existing?.models[model.id ?? modelID] const existingModel = parsed.models[model.id ?? modelID] const apiID = model.id ?? existingModel?.api.id ?? modelID const apiNpm = @@ -1491,7 +1492,10 @@ const layer = Layer.effect( ? { field: "reasoning_content" } : false), }, - reasoning_options: existingModel?.reasoning_options, + // Config models don't define reasoning_options. Inherit them only + // when the config model is explicitly based on a catalog model; + // pure custom models keep undefined so legacy heuristics still run. + reasoning_options: catalogModel?.reasoning_options, cost: { input: model?.cost?.input ?? existingModel?.cost?.input ?? 0, output: model?.cost?.output ?? existingModel?.cost?.output ?? 0, diff --git a/packages/opencode/test/provider/provider.test.ts b/packages/opencode/test/provider/provider.test.ts index 5c8414b1ab..3222a836fe 100644 --- a/packages/opencode/test/provider/provider.test.ts +++ b/packages/opencode/test/provider/provider.test.ts @@ -1644,6 +1644,39 @@ it.instance( }, ) +it.instance( + "custom config reasoning model without variants uses fallback variants", + Effect.gen(function* () { + const providers = yield* list + const model = providers[ProviderV2.ID.make("custom-reasoning-fallback")].models["reasoning-model"] + expect(model.reasoning_options).toBeUndefined() + expect(model.variants).toEqual({ + low: { reasoningEffort: "low" }, + medium: { reasoningEffort: "medium" }, + high: { reasoningEffort: "high" }, + }) + }), + { + config: { + provider: { + "custom-reasoning-fallback": { + name: "Custom Reasoning Fallback", + npm: "@ai-sdk/openai-compatible", + env: [], + models: { + "reasoning-model": { + name: "Reasoning Model", + reasoning: true, + limit: { context: 128000, output: 16000 }, + }, + }, + options: { apiKey: "test-key" }, + }, + }, + }, + }, +) + it.instance( "custom model with variants enabled and disabled", Effect.gen(function* () {