From 3664806f2f37951fedc1d5b8db6e99b74756fb8f Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Thu, 9 Jul 2026 23:13:58 +0200 Subject: [PATCH] fix(ai): add GPT-5.4 and GPT-5.5 long-context pricing --- packages/ai/CHANGELOG.md | 1 + packages/ai/scripts/generate-models.ts | 35 +++++++++++++------ .../ai/src/providers/openai-codex.models.ts | 2 ++ packages/ai/src/providers/openai.models.ts | 4 +++ 4 files changed, 31 insertions(+), 11 deletions(-) diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index 547cd642..124f0f53 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -10,6 +10,7 @@ ### Fixed - Fixed post-compaction output-token budgeting to ignore stale assistant usage from before the compaction boundary ([#6464](https://github.com/earendil-works/pi/issues/6464)). +- Fixed GPT-5.4 and GPT-5.5 long-context cost accounting while retaining the intentional 272K default context limit for models that require an explicit override. - Fixed GPT-5.6 metadata to keep direct OpenAI requests in the 272K short-context tier while exposing the Codex backend's 372K context window with long-context pricing. ## [0.80.5] - 2026-07-09 diff --git a/packages/ai/scripts/generate-models.ts b/packages/ai/scripts/generate-models.ts index 01297b51..64469182 100644 --- a/packages/ai/scripts/generate-models.ts +++ b/packages/ai/scripts/generate-models.ts @@ -195,7 +195,22 @@ const ANT_LING_RING_THINKING_LEVEL_MAP = { const MODELS_DEV_OPENAI_UNSUPPORTED_MODEL_IDS = new Set(["gpt-5.6"]); const OPENAI_LONG_CONTEXT_INPUT_THRESHOLD = 272000; -const OPENAI_GPT_56_MODEL_IDS = new Set(["gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna"]); +const OPENAI_SHORT_CONTEXT_CAPPED_MODEL_IDS = new Set([ + "gpt-5.4", + "gpt-5.5", + "gpt-5.6-sol", + "gpt-5.6-terra", + "gpt-5.6-luna", +]); +const OPENAI_LONG_CONTEXT_PRICING_MODEL_IDS = new Set([ + "gpt-5.4", + "gpt-5.4-pro", + "gpt-5.5", + "gpt-5.5-pro", + "gpt-5.6-sol", + "gpt-5.6-terra", + "gpt-5.6-luna", +]); function withOpenAiLongContextPricing(cost: Model["cost"]): Model["cost"] { return { @@ -1695,16 +1710,14 @@ async function generateModels() { candidate.contextWindow = 272000; candidate.maxTokens = 128000; } - // Keep direct OpenAI requests in the short-context pricing tier. - if ( - candidate.provider === "openai" && - (candidate.id === "gpt-5.4" || candidate.id === "gpt-5.5" || OPENAI_GPT_56_MODEL_IDS.has(candidate.id)) - ) { + // Keep direct OpenAI requests in the short-context pricing tier by default. Users can opt into the + // larger context through model overrides, so retain long-context cost metadata on the capped models. + if (candidate.provider === "openai" && OPENAI_SHORT_CONTEXT_CAPPED_MODEL_IDS.has(candidate.id)) { candidate.contextWindow = OPENAI_LONG_CONTEXT_INPUT_THRESHOLD; candidate.maxTokens = 128000; - if (OPENAI_GPT_56_MODEL_IDS.has(candidate.id)) { - candidate.cost = withOpenAiLongContextPricing(candidate.cost); - } + } + if (candidate.provider === "openai" && OPENAI_LONG_CONTEXT_PRICING_MODEL_IDS.has(candidate.id)) { + candidate.cost = withOpenAiLongContextPricing(candidate.cost); } // models.dev reports gpt-5-pro output as 272000 (a duplicate of the input sub-limit); // the actual max output is 128000. Also propagates to the derived Azure clone. @@ -1950,7 +1963,7 @@ async function generateModels() { baseUrl: CODEX_BASE_URL, reasoning: true, input: ["text", "image"], - cost: { input: 2.5, output: 15, cacheRead: 0.25, cacheWrite: 0 }, + cost: withOpenAiLongContextPricing({ input: 2.5, output: 15, cacheRead: 0.25, cacheWrite: 0 }), contextWindow: CODEX_CONTEXT, maxTokens: CODEX_MAX_TOKENS, }, @@ -1974,7 +1987,7 @@ async function generateModels() { baseUrl: CODEX_BASE_URL, reasoning: true, input: ["text", "image"], - cost: { input: 5, output: 30, cacheRead: 0.5, cacheWrite: 0 }, + cost: withOpenAiLongContextPricing({ input: 5, output: 30, cacheRead: 0.5, cacheWrite: 0 }), contextWindow: CODEX_CONTEXT, maxTokens: CODEX_MAX_TOKENS, }, diff --git a/packages/ai/src/providers/openai-codex.models.ts b/packages/ai/src/providers/openai-codex.models.ts index 0c8dcd40..1c0ae6fe 100644 --- a/packages/ai/src/providers/openai-codex.models.ts +++ b/packages/ai/src/providers/openai-codex.models.ts @@ -36,6 +36,7 @@ export const OPENAI_CODEX_MODELS = { output: 15, cacheRead: 0.25, cacheWrite: 0, + tiers: [{"inputTokensAbove":272000,"input":5,"output":22.5,"cacheRead":0.5,"cacheWrite":0}], }, contextWindow: 272000, maxTokens: 128000, @@ -72,6 +73,7 @@ export const OPENAI_CODEX_MODELS = { output: 30, cacheRead: 0.5, cacheWrite: 0, + tiers: [{"inputTokensAbove":272000,"input":10,"output":45,"cacheRead":1,"cacheWrite":0}], }, contextWindow: 272000, maxTokens: 128000, diff --git a/packages/ai/src/providers/openai.models.ts b/packages/ai/src/providers/openai.models.ts index b90c87e7..1ea1d15b 100644 --- a/packages/ai/src/providers/openai.models.ts +++ b/packages/ai/src/providers/openai.models.ts @@ -512,6 +512,7 @@ export const OPENAI_MODELS = { output: 15, cacheRead: 0.25, cacheWrite: 0, + tiers: [{"inputTokensAbove":272000,"input":5,"output":22.5,"cacheRead":0.5,"cacheWrite":0}], }, contextWindow: 272000, maxTokens: 128000, @@ -566,6 +567,7 @@ export const OPENAI_MODELS = { output: 180, cacheRead: 0, cacheWrite: 0, + tiers: [{"inputTokensAbove":272000,"input":60,"output":270,"cacheRead":0,"cacheWrite":0}], }, contextWindow: 1050000, maxTokens: 128000, @@ -584,6 +586,7 @@ export const OPENAI_MODELS = { output: 30, cacheRead: 0.5, cacheWrite: 0, + tiers: [{"inputTokensAbove":272000,"input":10,"output":45,"cacheRead":1,"cacheWrite":0}], }, contextWindow: 272000, maxTokens: 128000, @@ -602,6 +605,7 @@ export const OPENAI_MODELS = { output: 180, cacheRead: 0, cacheWrite: 0, + tiers: [{"inputTokensAbove":272000,"input":60,"output":270,"cacheRead":0,"cacheWrite":0}], }, contextWindow: 1050000, maxTokens: 128000,