fix(provider): loosen models.dev reasoning options

This commit is contained in:
Aiden Cline
2026-06-30 23:22:41 -05:00
parent 6e3c76e86e
commit 6413d66aa2
4 changed files with 101 additions and 8 deletions
@@ -58,4 +58,23 @@ describe("provider model status schemas", () => {
}).status,
).toBe("active")
})
test("keeps models.dev reasoning options opaque for forward compatibility", () => {
expect(() =>
Schema.decodeUnknownSync(ModelsDev.Model)({
id: "test-model",
name: "Test Model",
release_date: "2026-01-01",
attachment: false,
reasoning: true,
reasoning_options: {
future: "shape",
values: [{ type: "new_control", values: ["turbo"] }],
},
temperature: true,
tool_call: true,
limit: { context: 128000, output: 8192 },
}),
).not.toThrow()
})
})
@@ -1450,6 +1450,55 @@ test("models.dev normalization preserves reasoning options for variant generatio
expect(model.variants!.xhigh).toEqual({ reasoningEffort: "xhigh" })
})
test("models.dev normalization ignores unknown reasoning options and passes new effort strings", () => {
const provider = {
id: "custom",
name: "Custom",
env: [],
npm: "@ai-sdk/openai-compatible",
models: {
reasoner: {
id: "reasoner",
name: "Reasoner",
reasoning: true,
reasoning_options: [
{ type: "future_control", values: ["turbo"] },
{ type: "effort", values: ["turbo", 123, null] },
{ type: "budget_tokens", min: "1024", max: 16_000 },
"invalid",
],
cost: { input: 1, output: 2 },
limit: { context: 128_000, output: 32_000 },
},
changed: {
id: "changed",
name: "Changed",
reasoning: true,
reasoning_options: { type: "effort", values: ["turbo"] },
cost: { input: 1, output: 2 },
limit: { context: 128_000, output: 32_000 },
},
future: {
id: "future",
name: "Future",
reasoning: true,
reasoning_options: [{ type: "future_control", values: ["turbo"] }],
cost: { input: 1, output: 2 },
limit: { context: 128_000, output: 32_000 },
},
},
} as unknown as ModelsDev.Provider
const models = Provider.fromModelsDevProvider(provider).models
expect(models.reasoner.reasoning_options).toEqual([
{ type: "effort", values: ["turbo", null] },
{ type: "budget_tokens", max: 16_000 },
])
expect(models.reasoner.variants).toEqual({ turbo: { reasoningEffort: "turbo" } })
expect(models.changed.reasoning_options).toBeUndefined()
expect(models.future.reasoning_options).toBeUndefined()
})
it.instance("model variants are generated for reasoning models", () =>
Effect.gen(function* () {
yield* set("ANTHROPIC_API_KEY", "test-api-key")