diff --git a/packages/opencode/src/kilocode/provider/provider.ts b/packages/opencode/src/kilocode/provider/provider.ts index 13ec8bdddd..21345881ee 100644 --- a/packages/opencode/src/kilocode/provider/provider.ts +++ b/packages/opencode/src/kilocode/provider/provider.ts @@ -103,8 +103,10 @@ type Variants = NonNullable type Generate = (model: Provider.Model) => Variants export function customProviderVariants(model: Provider.Model, npm: unknown, generate: Generate): Variants { + if (model.variants && Object.keys(model.variants).length > 0) return model.variants + const supported = typeof npm === "string" && CUSTOM_PROVIDER_PACKAGES.has(npm) && model.api.npm === npm - const variants = generate(supported ? { ...model, variants: {} } : model) + const variants = generate(model) if (Object.keys(variants).length > 0) return variants if (!model.capabilities.reasoning || !supported) return variants diff --git a/packages/opencode/src/provider/provider.ts b/packages/opencode/src/provider/provider.ts index e8f134f287..c830ad8bb7 100644 --- a/packages/opencode/src/provider/provider.ts +++ b/packages/opencode/src/provider/provider.ts @@ -1528,11 +1528,9 @@ const layer = Layer.effect( ...patchKiloConfigModel(model, existingModel), // kilocode_change } // kilocode_change start - const generated = customProviderVariants( - parsedModel, - model.provider?.npm ?? provider.npm, - ProviderTransform.variants, - ) + const generated = Object.keys(model.variants ?? {}).length + ? {} + : customProviderVariants(parsedModel, model.provider?.npm ?? provider.npm, ProviderTransform.variants) const merged = mergeDeep(generated, model.variants ?? {}) // kilocode_change end parsedModel.variants = mapValues( diff --git a/packages/opencode/test/kilocode/custom-provider-variants.test.ts b/packages/opencode/test/kilocode/custom-provider-variants.test.ts index e3a6e6be17..7de3036fd7 100644 --- a/packages/opencode/test/kilocode/custom-provider-variants.test.ts +++ b/packages/opencode/test/kilocode/custom-provider-variants.test.ts @@ -10,14 +10,13 @@ import { testEffect } from "../lib/effect" const it = testEffect(LayerNode.compile(LayerNode.group([Provider.node, Env.node, Plugin.node]))) it.instance( - "adds fallback efforts to configured reasoning models and merges explicit variants", + "uses configured variants instead of inferred reasoning efforts", () => Effect.gen(function* () { const providers = yield* Provider.use.list() const model = providers[ProviderV2.ID.make("custom")]?.models["qwen-custom"] - expect(Object.keys(model?.variants ?? {})).toEqual(["none", "low", "medium", "xhigh", "max", "custom"]) - expect(model?.variants?.none).toEqual({ reasoningEffort: "none" }) + expect(Object.keys(model?.variants ?? {})).toEqual(["custom"]) expect(model?.variants?.high).toBeUndefined() expect(model?.variants?.custom).toEqual({ reasoningEffort: "custom" }) }), diff --git a/packages/opencode/test/kilocode/provider-reasoning-options.test.ts b/packages/opencode/test/kilocode/provider-reasoning-options.test.ts index 268d27f439..5987819421 100644 --- a/packages/opencode/test/kilocode/provider-reasoning-options.test.ts +++ b/packages/opencode/test/kilocode/provider-reasoning-options.test.ts @@ -168,6 +168,18 @@ describe("custom provider fallback reasoning efforts", () => { expect(customProviderVariants(model, model.api.npm, () => generated)).toBe(generated) }) + test("prefers configured variants to inference", () => { + const variants = { custom: { reasoningEffort: "custom" } } + for (const npm of ["@ai-sdk/openai-compatible", "@ai-sdk/openai", "@ai-sdk/anthropic"]) { + const model = mockModel({ api: { id: "custom", url: "https://api.test.com", npm }, variants }) + expect( + customProviderVariants(model, npm, () => { + throw new Error("inference should not run") + }), + ).toBe(variants) + } + }) + test("requires a reasoning model with an explicitly configured supported package", () => { const npm = "@ai-sdk/openai-compatible" const plain = mockModel({