fix: minimal being incorrectly assigned for some models

This commit is contained in:
Aiden Cline 2026-05-07 22:08:26 -05:00
parent e8ce5df414
commit c5e9538c63
2 changed files with 74 additions and 15 deletions

View file

@ -509,23 +509,23 @@ const OPENAI_NONE_EFFORT_RELEASE_DATE = "2025-11-13"
// OpenAI rolled out the `xhigh` reasoning_effort tier on this date. Same reasoning.
const OPENAI_XHIGH_EFFORT_RELEASE_DATE = "2025-12-04"
// Matches members of the gpt-5 family across the id formats we encounter:
// "gpt-5", "gpt-5-nano", "gpt-5.4", "openai/gpt-5.4-codex".
// Anchored to start-of-string or "/" so it doesn't false-match "gpt-50" or "gpt-5o".
const GPT5_FAMILY_RE = /(?:^|\/)gpt-5(?:[.-]|$)/
// Matches the first generation GPT-5 ids that still accept `minimal`.
const GPT5_INITIAL_RE = /(?:^|\/)gpt-5(?:-(?:mini|nano))?$/
// Computes the reasoning_effort tiers an OpenAI (or OpenAI-compatible upstream
// routed through it, e.g. cf-ai-gateway) model exposes. Returns null for models
// with no tunable effort knob (gpt-5-pro). Effort order: weakest to strongest.
function openaiReasoningEfforts(apiId: string, releaseDate: string): string[] | null {
const id = apiId.toLowerCase()
if (id === "gpt-5-pro" || id === "openai/gpt-5-pro") return null
if (id.endsWith("chat-latest")) return ["medium"]
if (id.endsWith("-pro")) return id.includes("5.1") ? null : ["medium", "high", "xhigh"]
if (id.includes("codex")) {
if (id.includes("5.2") || id.includes("5.3")) return [...WIDELY_SUPPORTED_EFFORTS, "xhigh"]
return [...WIDELY_SUPPORTED_EFFORTS]
const efforts = ["minimal", ...WIDELY_SUPPORTED_EFFORTS]
if (!["5-codex", "5.1-codex", "5.1-codex-mini"].some((v) => id.endsWith(v))) efforts.push("xhigh")
return efforts
}
const efforts = [...WIDELY_SUPPORTED_EFFORTS]
if (GPT5_FAMILY_RE.test(id)) efforts.unshift("minimal")
if (GPT5_INITIAL_RE.test(id)) efforts.unshift("minimal")
if (releaseDate >= OPENAI_NONE_EFFORT_RELEASE_DATE) efforts.unshift("none")
if (releaseDate >= OPENAI_XHIGH_EFFORT_RELEASE_DATE) efforts.push("xhigh")
return efforts

View file

@ -310,6 +310,65 @@ describe("ProviderTransform.options - gpt-5 textVerbosity", () => {
})
})
describe("ProviderTransform.variants - openai gpt-5 reasoning efforts", () => {
const createModel = (apiId: string, releaseDate = "2025-12-04") =>
({
id: `openai/${apiId}`,
providerID: "openai",
api: {
id: apiId,
url: "https://api.openai.com",
npm: "@ai-sdk/openai",
},
name: apiId,
release_date: releaseDate,
capabilities: {
temperature: true,
reasoning: true,
attachment: true,
toolcall: true,
input: { text: true, audio: false, image: true, video: false, pdf: false },
output: { text: true, audio: false, image: false, video: false, pdf: false },
interleaved: false,
},
cost: { input: 0.03, output: 0.06, cache: { read: 0.001, write: 0.002 } },
limit: { context: 128000, output: 4096 },
status: "active",
options: {},
headers: {},
}) as any
test.each([
["gpt-5", ["none", "minimal", "low", "medium", "high", "xhigh"]],
["gpt-5-mini", ["none", "minimal", "low", "medium", "high", "xhigh"]],
["gpt-5-nano", ["none", "minimal", "low", "medium", "high", "xhigh"]],
["gpt-5.1", ["none", "low", "medium", "high", "xhigh"]],
["gpt-5.2", ["none", "low", "medium", "high", "xhigh"]],
["gpt-5.4", ["none", "low", "medium", "high", "xhigh"]],
["gpt-5.4-fast", ["none", "low", "medium", "high", "xhigh"]],
["gpt-5.4-mini", ["none", "low", "medium", "high", "xhigh"]],
["gpt-5.4-mini-fast", ["none", "low", "medium", "high", "xhigh"]],
["gpt-5.4-nano", ["none", "low", "medium", "high", "xhigh"]],
["gpt-5.5", ["none", "low", "medium", "high", "xhigh"]],
["gpt-5.5-fast", ["none", "low", "medium", "high", "xhigh"]],
["gpt-5.1-chat-latest", ["medium"]],
["gpt-5.2-chat-latest", ["medium"]],
["gpt-5.3-chat-latest", ["medium"]],
["gpt-5.2-pro", ["medium", "high", "xhigh"]],
["gpt-5.4-pro", ["medium", "high", "xhigh"]],
["gpt-5.5-pro", ["medium", "high", "xhigh"]],
["gpt-5-codex", ["minimal", "low", "medium", "high"]],
["gpt-5.1-codex", ["minimal", "low", "medium", "high"]],
["gpt-5.1-codex-mini", ["minimal", "low", "medium", "high"]],
["gpt-5.1-codex-max", ["minimal", "low", "medium", "high", "xhigh"]],
["gpt-5.2-codex", ["minimal", "low", "medium", "high", "xhigh"]],
["gpt-5.3-codex", ["minimal", "low", "medium", "high", "xhigh"]],
["gpt-5.3-codex-spark", ["minimal", "low", "medium", "high", "xhigh"]],
])("%s exposes the expected effort variants", (apiId, efforts) => {
expect(Object.keys(ProviderTransform.variants(createModel(apiId)))).toEqual(efforts)
})
})
describe("ProviderTransform.options - gateway", () => {
const sessionID = "test-session-123"
@ -2932,7 +2991,7 @@ describe("ProviderTransform.variants", () => {
})
describe("@ai-sdk/openai", () => {
test("gpt-5-pro returns empty object", () => {
test("gpt-5-pro returns pro efforts", () => {
const model = createMockModel({
id: "gpt-5-pro",
providerID: "openai",
@ -2943,7 +3002,7 @@ describe("ProviderTransform.variants", () => {
},
})
const result = ProviderTransform.variants(model)
expect(result).toEqual({})
expect(Object.keys(result)).toEqual(["medium", "high", "xhigh"])
})
test("standard openai models return custom efforts with reasoningSummary", () => {
@ -2993,10 +3052,10 @@ describe("ProviderTransform.variants", () => {
release_date: "2025-12-05",
})
const result = ProviderTransform.variants(model)
expect(Object.keys(result)).toEqual(["none", "minimal", "low", "medium", "high", "xhigh"])
expect(Object.keys(result)).toEqual(["none", "low", "medium", "high", "xhigh"])
})
test("dotted gpt-5.x ids include 'minimal' (regression: matcher used to miss gpt-5.4)", () => {
test("dotted gpt-5.x ids include 'xhigh' without minimal", () => {
const model = createMockModel({
id: "gpt-5.4",
providerID: "openai",
@ -3008,7 +3067,7 @@ describe("ProviderTransform.variants", () => {
release_date: "2026-03-05",
})
const result = ProviderTransform.variants(model)
expect(Object.keys(result)).toEqual(["none", "minimal", "low", "medium", "high", "xhigh"])
expect(Object.keys(result)).toEqual(["none", "low", "medium", "high", "xhigh"])
})
test("gpt-50 (lookalike) does not get gpt-5 family treatment", () => {
@ -3490,13 +3549,13 @@ describe("ProviderTransform.variants", () => {
const result = ProviderTransform.variants(cfModel("openai/gpt-5.4", "2026-03-05"))
expect(result.xhigh).toEqual({ reasoningEffort: "xhigh" })
expect(result.high).toEqual({ reasoningEffort: "high" })
expect(Object.keys(result)).toContain("minimal")
expect(Object.keys(result)).not.toContain("minimal")
})
test("openai gpt-5.2-codex includes xhigh", () => {
const result = ProviderTransform.variants(cfModel("openai/gpt-5.2-codex", "2025-12-11"))
expect(result.xhigh).toEqual({ reasoningEffort: "xhigh" })
expect(Object.keys(result)).toEqual(["low", "medium", "high", "xhigh"])
expect(Object.keys(result)).toEqual(["minimal", "low", "medium", "high", "xhigh"])
})
test("openai gpt-4o (no reasoning) returns empty", () => {