mirror of
https://github.com/anomalyco/opencode.git
synced 2026-07-21 10:16:03 +00:00
fix(provider): honor reasoning option semantics (#37519)
This commit is contained in:
@@ -1586,7 +1586,7 @@ export function reasoningVariants(model: ModelsDev.Model, target: Provider.Model
|
|||||||
if (options.length === 0) return {}
|
if (options.length === 0) return {}
|
||||||
|
|
||||||
const effort = options.find((option) => option.type === "effort")
|
const effort = options.find((option) => option.type === "effort")
|
||||||
if (effort) return nonEmptyVariants(effortVariants(target, effort.values))
|
if (effort) return effortVariants(target, effort.values)
|
||||||
|
|
||||||
const toggle = options.some((option) => option.type === "toggle")
|
const toggle = options.some((option) => option.type === "toggle")
|
||||||
const budget = options.find((option) => option.type === "budget_tokens")
|
const budget = options.find((option) => option.type === "budget_tokens")
|
||||||
@@ -1651,7 +1651,7 @@ function reasoningEffort(model: Provider.Model, effort: string) {
|
|||||||
return { reasoning: { effort } }
|
return { reasoning: { effort } }
|
||||||
case "@ai-sdk/anthropic":
|
case "@ai-sdk/anthropic":
|
||||||
case "@ai-sdk/google-vertex/anthropic":
|
case "@ai-sdk/google-vertex/anthropic":
|
||||||
return anthropicEffort(model, effort)
|
return anthropicEffort(model, effort) ?? { effort }
|
||||||
case "@ai-sdk/google":
|
case "@ai-sdk/google":
|
||||||
case "@ai-sdk/google-vertex":
|
case "@ai-sdk/google-vertex":
|
||||||
return { thinkingConfig: { includeThoughts: true, thinkingLevel: effort } }
|
return { thinkingConfig: { includeThoughts: true, thinkingLevel: effort } }
|
||||||
|
|||||||
@@ -1477,7 +1477,7 @@ test("models.dev normalization fills required response fields", () => {
|
|||||||
expect(model.release_date).toBe("")
|
expect(model.release_date).toBe("")
|
||||||
})
|
})
|
||||||
|
|
||||||
test("models.dev reasoning options replace generated variants and unsupported options fall back", () => {
|
test("models.dev reasoning options replace generated variants and unsupported toggles fall back", () => {
|
||||||
const provider = {
|
const provider = {
|
||||||
id: "reasoning",
|
id: "reasoning",
|
||||||
name: "Reasoning",
|
name: "Reasoning",
|
||||||
@@ -1514,6 +1514,14 @@ test("models.dev reasoning options replace generated variants and unsupported op
|
|||||||
limit: { context: 128_000, output: 64_000 },
|
limit: { context: 128_000, output: 64_000 },
|
||||||
experimental: { modes: { fast: {} } },
|
experimental: { modes: { fast: {} } },
|
||||||
},
|
},
|
||||||
|
anthropicCompatible: {
|
||||||
|
id: "k3",
|
||||||
|
name: "Anthropic Compatible",
|
||||||
|
reasoning: true,
|
||||||
|
reasoning_options: [{ type: "effort", values: ["max"] }],
|
||||||
|
provider: { npm: "@ai-sdk/anthropic" },
|
||||||
|
limit: { context: 1_048_576, output: 131_072 },
|
||||||
|
},
|
||||||
},
|
},
|
||||||
} as unknown as ModelsDev.Provider
|
} as unknown as ModelsDev.Provider
|
||||||
|
|
||||||
@@ -1530,6 +1538,7 @@ test("models.dev reasoning options replace generated variants and unsupported op
|
|||||||
expect(models.override.variants).toEqual({
|
expect(models.override.variants).toEqual({
|
||||||
high: { thinkingConfig: { includeThoughts: true, thinkingLevel: "high" } },
|
high: { thinkingConfig: { includeThoughts: true, thinkingLevel: "high" } },
|
||||||
})
|
})
|
||||||
|
expect(models.anthropicCompatible.variants).toEqual({ max: { effort: "max" } })
|
||||||
expect(models["gemini-3-pro-fast"].variants).toEqual(models.override.variants)
|
expect(models["gemini-3-pro-fast"].variants).toEqual(models.override.variants)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -3103,13 +3103,20 @@ describe("ProviderTransform.reasoningVariants", () => {
|
|||||||
).toEqual({ high: { effort: "high" } })
|
).toEqual({ high: { effort: "high" } })
|
||||||
})
|
})
|
||||||
|
|
||||||
test("leaves legacy Anthropic effort options to budget fallback", () => {
|
test("uses explicit effort metadata for Anthropic-compatible models", () => {
|
||||||
expect(
|
expect(
|
||||||
ProviderTransform.reasoningVariants(
|
ProviderTransform.reasoningVariants(
|
||||||
model([{ type: "effort", values: ["high"] }]),
|
model([{ type: "effort", values: ["high"] }]),
|
||||||
target("@ai-sdk/anthropic", "claude-sonnet-4"),
|
target("@ai-sdk/anthropic", "claude-sonnet-4"),
|
||||||
),
|
),
|
||||||
).toBeUndefined()
|
).toEqual({ high: { effort: "high" } })
|
||||||
|
|
||||||
|
expect(
|
||||||
|
ProviderTransform.reasoningVariants(
|
||||||
|
model([{ type: "effort", values: ["max"] }]),
|
||||||
|
target("@ai-sdk/anthropic", "k3"),
|
||||||
|
),
|
||||||
|
).toEqual({ max: { effort: "max" } })
|
||||||
})
|
})
|
||||||
|
|
||||||
test("uses adaptive reasoning config for Anthropic models on Bedrock", () => {
|
test("uses adaptive reasoning config for Anthropic models on Bedrock", () => {
|
||||||
@@ -3129,13 +3136,13 @@ describe("ProviderTransform.reasoningVariants", () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test("leaves legacy Anthropic Bedrock effort options to budget fallback", () => {
|
test("does not replace unsupported Anthropic Bedrock effort options with token budgets", () => {
|
||||||
expect(
|
expect(
|
||||||
ProviderTransform.reasoningVariants(
|
ProviderTransform.reasoningVariants(
|
||||||
model([{ type: "effort", values: ["high"] }]),
|
model([{ type: "effort", values: ["high"] }]),
|
||||||
target("@ai-sdk/amazon-bedrock", "anthropic.claude-sonnet-4-v1:0"),
|
target("@ai-sdk/amazon-bedrock", "anthropic.claude-sonnet-4-v1:0"),
|
||||||
),
|
),
|
||||||
).toBeUndefined()
|
).toEqual({})
|
||||||
})
|
})
|
||||||
|
|
||||||
test.each([
|
test.each([
|
||||||
@@ -3256,10 +3263,13 @@ describe("ProviderTransform.reasoningVariants", () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test("leaves unsupported options for heuristic fallback", () => {
|
test("does not replace unsupported effort options with heuristic variants", () => {
|
||||||
expect(
|
expect(
|
||||||
ProviderTransform.reasoningVariants(model([{ type: "effort", values: ["high"] }]), target("@ai-sdk/perplexity")),
|
ProviderTransform.reasoningVariants(model([{ type: "effort", values: ["high"] }]), target("@ai-sdk/perplexity")),
|
||||||
).toBeUndefined()
|
).toEqual({})
|
||||||
|
})
|
||||||
|
|
||||||
|
test("leaves unsupported toggle options for heuristic fallback", () => {
|
||||||
expect(ProviderTransform.reasoningVariants(model([{ type: "toggle" }]), target("@ai-sdk/openai"))).toBeUndefined()
|
expect(ProviderTransform.reasoningVariants(model([{ type: "toggle" }]), target("@ai-sdk/openai"))).toBeUndefined()
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -3275,7 +3285,7 @@ describe("ProviderTransform.reasoningVariants", () => {
|
|||||||
})
|
})
|
||||||
expect(
|
expect(
|
||||||
ProviderTransform.reasoningVariants(effort, target("@ai-sdk/github-copilot", "gemini-3-pro")),
|
ProviderTransform.reasoningVariants(effort, target("@ai-sdk/github-copilot", "gemini-3-pro")),
|
||||||
).toBeUndefined()
|
).toEqual({})
|
||||||
})
|
})
|
||||||
|
|
||||||
test.each(["@ai-sdk/cohere", "@ai-sdk/perplexity", "@ai-sdk/vercel", "@ai-sdk/alibaba", "gitlab-ai-provider"])(
|
test.each(["@ai-sdk/cohere", "@ai-sdk/perplexity", "@ai-sdk/vercel", "@ai-sdk/alibaba", "gitlab-ai-provider"])(
|
||||||
@@ -3283,7 +3293,7 @@ describe("ProviderTransform.reasoningVariants", () => {
|
|||||||
(npm) => {
|
(npm) => {
|
||||||
expect(
|
expect(
|
||||||
ProviderTransform.reasoningVariants(model([{ type: "effort", values: ["high"] }]), target(npm)),
|
ProviderTransform.reasoningVariants(model([{ type: "effort", values: ["high"] }]), target(npm)),
|
||||||
).toBeUndefined()
|
).toEqual({})
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user