fix(core): derive reasoning variants from models.dev

This commit is contained in:
Dax Raad
2026-06-30 22:50:20 -04:00
parent 8dd993d25a
commit 6ca6566bd3
3 changed files with 90 additions and 35 deletions
+28 -7
View File
@@ -38,12 +38,33 @@ function cost(input: ModelsDev.Model["cost"]) {
] ]
} }
function variants(model: ModelsDev.Model) { function variants(model: ModelsDev.Model, packageName: string | undefined): ModelV2Info["variants"] {
return Object.entries(model.experimental?.modes ?? {}).map(([id, item]) => ({ const result = new Map<ModelV2.VariantID, ModelV2Info["variants"][number]>()
id: ModelV2.VariantID.make(id), if (packageName === "@ai-sdk/openai" || packageName === "@ai-sdk/openai-compatible") {
headers: { ...(item.provider?.headers ?? {}) }, const option = model.reasoning_options?.find((option) => option.type === "effort")
body: { ...(item.provider?.body ?? {}) }, for (const value of option?.values ?? []) {
})) const id = value === null ? "none" : value
if (typeof id !== "string") continue
const variantID = ModelV2.VariantID.make(id)
result.set(variantID, {
id: variantID,
headers: {},
body:
packageName === "@ai-sdk/openai"
? { include: ["reasoning.encrypted_content"], reasoning: { effort: id, summary: "auto" } }
: { reasoning_effort: id },
})
}
}
for (const [id, item] of Object.entries(model.experimental?.modes ?? {})) {
const variantID = ModelV2.VariantID.make(id)
result.set(variantID, {
id: variantID,
headers: { ...(item.provider?.headers ?? {}) },
body: { ...(item.provider?.body ?? {}) },
})
}
return [...result.values()]
} }
function mergeVariants(model: ModelV2Info, next: ModelV2Info["variants"]) { function mergeVariants(model: ModelV2Info, next: ModelV2Info["variants"]) {
@@ -121,7 +142,7 @@ export const ModelsDevPlugin = define({
input: [...(model.modalities?.input ?? [])], input: [...(model.modalities?.input ?? [])],
output: [...(model.modalities?.output ?? [])], output: [...(model.modalities?.output ?? [])],
} }
mergeVariants(draft, variants(model)) mergeVariants(draft, variants(model, model.provider?.npm ?? item.npm))
draft.time.released = released(model.release_date) draft.time.released = released(model.release_date)
draft.cost = cost(model.cost) draft.cost = cost(model.cost)
draft.status = model.status ?? "active" draft.status = model.status ?? "active"
@@ -9,26 +9,25 @@
"id": "local", "id": "local",
"name": "Local", "name": "Local",
"env": [], "env": [],
"models": {}
},
"opencode": {
"id": "opencode",
"name": "OpenCode",
"env": [],
"npm": "@ai-sdk/openai-compatible",
"models": { "models": {
"model": { "gpt-5.5": {
"id": "model", "id": "gpt-5.5",
"name": "Local Model", "name": "GPT-5.5",
"release_date": "2026-01-01", "release_date": "2026-04-23",
"attachment": false, "attachment": true,
"reasoning": true, "reasoning": true,
"temperature": true, "reasoning_options": [{ "type": "effort", "values": [null, "none", "low", "medium", "high", "xhigh"] }],
"temperature": false,
"tool_call": true, "tool_call": true,
"limit": { "context": 1000, "output": 100 }, "limit": { "context": 400000, "output": 128000 },
"experimental": { "provider": { "npm": "@ai-sdk/openai", "api": "https://console.opencode.ai/inference/openai/v1" }
"modes": {
"high": {
"provider": { "body": { "reasoning_effort": "high" } }
},
"max": {
"provider": { "headers": { "x-variant": "max" }, "body": { "reasoning_effort": "max" } }
}
}
}
} }
} }
} }
+46 -11
View File
@@ -76,7 +76,7 @@ describe("ModelsDevPlugin", () => {
), ),
) )
it.effect("loads models.dev variants without replacing existing variants", () => it.effect("derives OpenAI reasoning variants from models.dev reasoning options", () =>
Effect.acquireUseRelease( Effect.acquireUseRelease(
Effect.sync(() => { Effect.sync(() => {
const previous = { const previous = {
@@ -89,27 +89,61 @@ describe("ModelsDevPlugin", () => {
}), }),
() => () =>
Effect.gen(function* () { Effect.gen(function* () {
const service = yield* Catalog.Service const catalog = yield* Catalog.Service
const integrations = yield* Integration.Service const integrations = yield* Integration.Service
yield* service.transform((catalog) => { yield* catalog.transform((catalog) => {
catalog.model.update(ProviderV2.ID.make("local"), ModelV2.ID.make("model"), (model) => { catalog.model.update(ProviderV2.ID.opencode, ModelV2.ID.make("gpt-5.5"), (model) => {
model.variants = [ model.variants = [
{ id: ModelV2.VariantID.make("high"), headers: { custom: "true" }, body: {} }, {
{ id: ModelV2.VariantID.make("custom"), headers: {}, body: { custom: true } }, id: ModelV2.VariantID.make("high"),
headers: { custom: "true" },
body: { custom: true },
},
] ]
}) })
}) })
yield* ModelsDevPlugin.effect( yield* ModelsDevPlugin.effect(
host({ host({
catalog: catalogHost(service), catalog: catalogHost(catalog),
integration: integrationHost(integrations), integration: integrationHost(integrations),
}), }),
) )
expect((yield* service.model.get(ProviderV2.ID.make("local"), ModelV2.ID.make("model")))?.variants).toEqual([ expect((yield* catalog.model.get(ProviderV2.ID.opencode, ModelV2.ID.make("gpt-5.5")))?.variants).toEqual([
expect.objectContaining({ id: "high", headers: { custom: "true" } }), {
expect.objectContaining({ id: "max", headers: { "x-variant": "max" }, body: { reasoning_effort: "max" } }), id: ModelV2.VariantID.make("none"),
expect.objectContaining({ id: "custom", body: { custom: true } }), headers: {},
body: {
include: ["reasoning.encrypted_content"],
reasoning: { effort: "none", summary: "auto" },
},
},
expect.objectContaining({
id: "low",
body: {
include: ["reasoning.encrypted_content"],
reasoning: { effort: "low", summary: "auto" },
},
}),
expect.objectContaining({
id: "medium",
body: {
include: ["reasoning.encrypted_content"],
reasoning: { effort: "medium", summary: "auto" },
},
}),
expect.objectContaining({
id: "high",
headers: { custom: "true" },
body: { custom: true },
}),
expect.objectContaining({
id: "xhigh",
body: {
include: ["reasoning.encrypted_content"],
reasoning: { effort: "xhigh", summary: "auto" },
},
}),
]) ])
}).pipe(Effect.provide(ModelsDev.defaultLayer)), }).pipe(Effect.provide(ModelsDev.defaultLayer)),
(previous) => (previous) =>
@@ -119,4 +153,5 @@ describe("ModelsDevPlugin", () => {
}), }),
), ),
) )
}) })