Skip to content

Commit c031301

Browse files
committed
fix(provider): support Kimi K3 reasoning effort
Kimi K3 models using Anthropic-compatible endpoint derive adaptive low/high/max variants from models.dev, preventing budget-token fallback. Includes unit and provider regression coverage.
1 parent efb6cc2 commit c031301

3 files changed

Lines changed: 31 additions & 2 deletions

File tree

packages/opencode/src/provider/transform.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1704,6 +1704,8 @@ function reasoningEffort(model: Provider.Model, effort: string) {
17041704
}
17051705

17061706
function anthropicEffort(model: Provider.Model, effort: string) {
1707+
// K3's Anthropic-compatible endpoint exposes adaptive thinking through output_config.effort.
1708+
if (model.family === "kimi-k3") return { thinking: { type: "adaptive" }, effort }
17071709
if (["opus-4-5", "opus-4.5"].some((value) => model.api.id.includes(value))) return { effort }
17081710
if (!anthropicAdaptiveEfforts(model.api.id)) return
17091711
return {

packages/opencode/test/provider/provider.test.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1514,6 +1514,15 @@ test("models.dev reasoning options replace generated variants and unsupported op
15141514
limit: { context: 128_000, output: 64_000 },
15151515
experimental: { modes: { fast: {} } },
15161516
},
1517+
k3: {
1518+
id: "k3",
1519+
name: "Kimi K3",
1520+
family: "kimi-k3",
1521+
reasoning: true,
1522+
reasoning_options: [{ type: "effort", values: ["low", "high", "max"] }],
1523+
provider: { npm: "@ai-sdk/anthropic" },
1524+
limit: { context: 1_048_576, output: 131_072 },
1525+
},
15171526
},
15181527
} as unknown as ModelsDev.Provider
15191528

@@ -1531,6 +1540,11 @@ test("models.dev reasoning options replace generated variants and unsupported op
15311540
high: { thinkingConfig: { includeThoughts: true, thinkingLevel: "high" } },
15321541
})
15331542
expect(models["gemini-3-pro-fast"].variants).toEqual(models.override.variants)
1543+
expect(models.k3.variants).toEqual({
1544+
low: { thinking: { type: "adaptive" }, effort: "low" },
1545+
high: { thinking: { type: "adaptive" }, effort: "high" },
1546+
max: { thinking: { type: "adaptive" }, effort: "max" },
1547+
})
15341548
})
15351549

15361550
test("public provider info omits invalid models", () => {

packages/opencode/test/provider/transform.test.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3028,8 +3028,8 @@ describe("ProviderTransform.temperature - Cohere North", () => {
30283028

30293029
describe("ProviderTransform.reasoningVariants", () => {
30303030
const model = (reasoning_options: ModelsDev.Model["reasoning_options"]) => ({ reasoning_options }) as ModelsDev.Model
3031-
const target = (npm: string, id = "test-model") =>
3032-
({ id, api: { id, npm, url: "" }, capabilities: { reasoning: true }, limit: { output: 64_000 } }) as any
3031+
const target = (npm: string, id = "test-model", family?: string) =>
3032+
({ id, family, api: { id, npm, url: "" }, capabilities: { reasoning: true }, limit: { output: 64_000 } }) as any
30333033

30343034
test("respects explicitly empty reasoning options", () => {
30353035
expect(ProviderTransform.reasoningVariants(model([]), target("@ai-sdk/openai"))).toEqual({})
@@ -3103,6 +3103,19 @@ describe("ProviderTransform.reasoningVariants", () => {
31033103
).toEqual({ high: { effort: "high" } })
31043104
})
31053105

3106+
test("uses adaptive effort for Kimi K3", () => {
3107+
expect(
3108+
ProviderTransform.reasoningVariants(
3109+
model([{ type: "effort", values: ["low", "high", "max"] }]),
3110+
target("@ai-sdk/anthropic", "k3", "kimi-k3"),
3111+
),
3112+
).toEqual({
3113+
low: { thinking: { type: "adaptive" }, effort: "low" },
3114+
high: { thinking: { type: "adaptive" }, effort: "high" },
3115+
max: { thinking: { type: "adaptive" }, effort: "max" },
3116+
})
3117+
})
3118+
31063119
test("leaves legacy Anthropic effort options to budget fallback", () => {
31073120
expect(
31083121
ProviderTransform.reasoningVariants(

0 commit comments

Comments
 (0)