From 7b1923b09941131d145ffc46c2a91a644180e3ae Mon Sep 17 00:00:00 2001 From: roboomp Date: Mon, 3 Aug 2026 15:23:35 +0000 Subject: [PATCH] fix(ai): stop forwarding auto service tier to codex MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit shouldSendServiceTier/applyOpenAIServiceTier began forwarding every tier — including `auto` — for openai/openai-codex after PR #7376. Legacy/default sessions resolve to {openai:"auto"}, so Codex (ChatGPT OAuth) requests now carry service_tier:"auto", which that endpoint rejects with a 400, breaking every turn at default settings. Never send `auto`: it is OpenAI's implicit default, so omitting service_tier is identical where accepted and required where the tier is rejected. Explicit default/flex/scale/priority are unchanged. Fixes #7517 --- packages/ai/CHANGELOG.md | 4 ++++ packages/ai/src/types.ts | 13 ++++++++----- .../ai/test/service-tier-premium-requests.test.ts | 7 +++++-- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index abfe680ff..73ad730be 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Fixed + +- Fixed OpenAI-Codex (ChatGPT OAuth) requests failing with `Unsupported service_tier: auto` on default/legacy sessions. `shouldSendServiceTier` no longer forwards `auto` on the wire — it is OpenAI's implicit default, so omitting `service_tier` is equivalent, and the Codex endpoint rejects an explicit `auto`. Explicit `default`/`flex`/`scale`/`priority` are unaffected ([#7517](https://github.com/can1357/oh-my-pi/issues/7517)). + ## [17.2.6] - 2026-08-03 ### Added diff --git a/packages/ai/src/types.ts b/packages/ai/src/types.ts index 8a7cb8b18..e850eb004 100644 --- a/packages/ai/src/types.ts +++ b/packages/ai/src/types.ts @@ -214,16 +214,19 @@ export function resolveModelServiceTier( /** * True when the tier should be sent on the wire as the provider's service-tier - * request field. OpenAI / OpenAI-Codex accept every {@link ServiceTier}; - * Google (Gemini API + Vertex) and OpenRouter accept `flex`/`priority`; - * Fireworks Serverless realizes only its Priority serving path. Anthropic is - * absent because it realizes `priority` via `speed: "fast"`. + * request field. `auto` is never forwarded — it is OpenAI's implicit default, so + * omitting `service_tier` is identical to requesting `auto`, and the Codex + * (ChatGPT OAuth) endpoint rejects an explicit `auto` outright. OpenAI / + * OpenAI-Codex accept every other {@link ServiceTier}; Google (Gemini API + + * Vertex) and OpenRouter accept `flex`/`priority`; Fireworks Serverless + * realizes only its Priority serving path. Anthropic is absent because it + * realizes `priority` via `speed: "fast"`. */ export function shouldSendServiceTier( serviceTier: ServiceTier | null | undefined, target: Provider | ServiceTierModel | undefined, ): boolean { - if (!serviceTier) return false; + if (!serviceTier || serviceTier === "auto") return false; const provider = typeof target === "string" ? target : target?.provider; if (provider === "openai" || provider === "openai-codex") return true; if (provider === "openrouter") { diff --git a/packages/ai/test/service-tier-premium-requests.test.ts b/packages/ai/test/service-tier-premium-requests.test.ts index c0d0119cf..96fe0a3f8 100644 --- a/packages/ai/test/service-tier-premium-requests.test.ts +++ b/packages/ai/test/service-tier-premium-requests.test.ts @@ -78,14 +78,17 @@ describe("resolveModelServiceTier", () => { }); describe("shouldSendServiceTier", () => { - it("sends every tier on the OpenAI family and supported tiers elsewhere", () => { + it("sends every explicit tier on the OpenAI family, omits auto, supported tiers elsewhere", () => { for (const p of ["openai", "openai-codex"] as const) { expect(shouldSendServiceTier("flex", p)).toBe(true); expect(shouldSendServiceTier("scale", p)).toBe(true); expect(shouldSendServiceTier("priority", p)).toBe(true); expect(shouldSendServiceTier("default", p)).toBe(true); - expect(shouldSendServiceTier("auto", p)).toBe(true); + // `auto` is OpenAI's implicit default and the Codex endpoint rejects it — never sent. + expect(shouldSendServiceTier("auto", p)).toBe(false); } + expect(shouldSendServiceTier("auto", codex)).toBe(false); + expect(shouldSendServiceTier("auto", customOpenAI)).toBe(false); expect(shouldSendServiceTier("flex", "openrouter")).toBe(true); expect(shouldSendServiceTier("default", "openrouter")).toBe(false); expect(shouldSendServiceTier("priority", customCodex)).toBe(true);