From 98e70a706e14c1a643aa9c9dafa0222acafecb79 Mon Sep 17 00:00:00 2001 From: Randi <55005611+rdself@users.noreply.github.com> Date: Mon, 27 Apr 2026 06:12:08 -0400 Subject: [PATCH] [urgent] fix gpt-5.5 websocket transport and model labels (#1656) Integrated into release/v3.7.2 --- open-sse/config/providerRegistry.ts | 3 +- open-sse/executors/codex.ts | 58 ++++++++++++++------------ src/i18n/messages/ar.json | 12 +++--- src/i18n/messages/bg.json | 12 +++--- src/i18n/messages/bn.json | 12 +++--- src/i18n/messages/cs.json | 12 +++--- src/i18n/messages/da.json | 12 +++--- src/i18n/messages/de.json | 12 +++--- src/i18n/messages/en.json | 12 +++--- src/i18n/messages/es.json | 12 +++--- src/i18n/messages/fa.json | 12 +++--- src/i18n/messages/fi.json | 12 +++--- src/i18n/messages/fr.json | 12 +++--- src/i18n/messages/gu.json | 12 +++--- src/i18n/messages/he.json | 12 +++--- src/i18n/messages/hi.json | 12 +++--- src/i18n/messages/hu.json | 12 +++--- src/i18n/messages/id.json | 12 +++--- src/i18n/messages/in.json | 12 +++--- src/i18n/messages/it.json | 12 +++--- src/i18n/messages/ja.json | 12 +++--- src/i18n/messages/ko.json | 12 +++--- src/i18n/messages/mr.json | 12 +++--- src/i18n/messages/ms.json | 12 +++--- src/i18n/messages/nl.json | 12 +++--- src/i18n/messages/no.json | 12 +++--- src/i18n/messages/phi.json | 12 +++--- src/i18n/messages/pl.json | 12 +++--- src/i18n/messages/pt.json | 12 +++--- src/i18n/messages/ro.json | 12 +++--- src/i18n/messages/ru.json | 12 +++--- src/i18n/messages/sk.json | 12 +++--- src/i18n/messages/sv.json | 12 +++--- src/i18n/messages/sw.json | 12 +++--- src/i18n/messages/ta.json | 12 +++--- src/i18n/messages/te.json | 12 +++--- src/i18n/messages/th.json | 12 +++--- src/i18n/messages/tr.json | 12 +++--- src/i18n/messages/uk-UA.json | 12 +++--- src/i18n/messages/ur.json | 12 +++--- src/i18n/messages/vi.json | 12 +++--- src/i18n/messages/zh-CN.json | 12 +++--- src/shared/constants/modelSpecs.ts | 1 - tests/unit/executor-codex.test.ts | 23 ++++++++++ tests/unit/plan3-p0.test.ts | 6 +++ tests/unit/t12-pricing-updates.test.ts | 4 ++ 46 files changed, 306 insertions(+), 269 deletions(-) diff --git a/open-sse/config/providerRegistry.ts b/open-sse/config/providerRegistry.ts index 0309f486a5..2cbfc1bd19 100644 --- a/open-sse/config/providerRegistry.ts +++ b/open-sse/config/providerRegistry.ts @@ -385,7 +385,8 @@ export const REGISTRY: Record = { { id: "codex-auto-review", name: "Codex Auto Review", targetFormat: "openai-responses" }, { id: "gpt-5.5-xhigh", name: "GPT 5.5 (xHigh)", ...GPT_5_5_CODEX_CAPABILITIES }, { id: "gpt-5.5-high", name: "GPT 5.5 (High)", ...GPT_5_5_CODEX_CAPABILITIES }, - { id: "gpt-5.5", name: "GPT 5.5 (Medium)", ...GPT_5_5_CODEX_CAPABILITIES }, + { id: "gpt-5.5-medium", name: "GPT 5.5 (Medium)", ...GPT_5_5_CODEX_CAPABILITIES }, + { id: "gpt-5.5", name: "GPT 5.5", ...GPT_5_5_CODEX_CAPABILITIES }, { id: "gpt-5.5-low", name: "GPT 5.5 (Low)", ...GPT_5_5_CODEX_CAPABILITIES }, { id: "gpt-5.5-mini", name: "GPT 5.5 Mini", targetFormat: "openai-responses" }, { id: "gpt-5.4", name: "GPT 5.4", targetFormat: "openai-responses" }, diff --git a/open-sse/executors/codex.ts b/open-sse/executors/codex.ts index 6d81606273..f934a392cc 100644 --- a/open-sse/executors/codex.ts +++ b/open-sse/executors/codex.ts @@ -10,6 +10,7 @@ import { PROVIDERS } from "../config/constants.ts"; import { getCodexClientVersion, getCodexUserAgent } from "../config/codexClient.ts"; import { getAccessToken } from "../services/tokenRefresh.ts"; import { getThinkingBudgetConfig, ThinkingMode } from "../services/thinkingBudget.ts"; +import { getCorsOrigin } from "../utils/cors.ts"; import { createRequire } from "module"; // ─── wreq-js lazy loader ─────────────────────────────────────────────────── @@ -30,8 +31,10 @@ type WebsocketFn = (url: string, opts?: Record) => Promise = { supportsThinking: true, supportsTools: true, supportsVision: true, - aliases: ["gpt-5.5-xhigh", "gpt-5.5-high", "gpt-5.5-medium", "gpt-5.5-low", "gpt-5.5-none"], }, // ── Gemini 3 Flash series ─────────────────────────────────────── diff --git a/tests/unit/executor-codex.test.ts b/tests/unit/executor-codex.test.ts index a1b6080b0f..f129b1b22f 100644 --- a/tests/unit/executor-codex.test.ts +++ b/tests/unit/executor-codex.test.ts @@ -3,6 +3,7 @@ import assert from "node:assert/strict"; import { CodexExecutor, + __setCodexWebSocketTransportForTesting, encodeResponseSseEvent, getCodexModelScope, getCodexRateLimitKey, @@ -19,6 +20,7 @@ import { test.afterEach(() => { setThinkingBudgetConfig(DEFAULT_THINKING_CONFIG); + __setCodexWebSocketTransportForTesting(undefined); }); async function withEnv(entries, fn) { @@ -62,7 +64,9 @@ test("Codex helper functions isolate rate-limit scopes and parse quota headers", assert.equal(getCodexModelScope("gpt-5.3-codex"), "codex"); assert.equal(getCodexModelScope("gpt-5.5-xhigh"), "codex"); assert.equal(getCodexUpstreamModel("gpt-5.5-xhigh"), "gpt-5.5"); + assert.equal(getCodexUpstreamModel("gpt-5.5-medium"), "gpt-5.5"); assert.equal(isCodexResponsesWebSocketRequired("gpt-5.5-xhigh", {}), true); + assert.equal(isCodexResponsesWebSocketRequired("gpt-5.5-medium", {}), true); assert.equal(isCodexResponsesWebSocketRequired("gpt-5.5-mini", {}), false); assert.equal(getCodexRateLimitKey("acct-1", "codex-spark-mini"), "acct-1:spark"); assert.equal(quota.usage5h, 100); @@ -294,6 +298,25 @@ test("CodexExecutor.transformRequest keeps gpt-5.5 as the model and applies xhig assert.equal(result.reasoning.effort, "xhigh"); }); +test("CodexExecutor.execute returns 503 when gpt-5.5 websocket transport is unavailable", async () => { + __setCodexWebSocketTransportForTesting(null); + const executor = new CodexExecutor(); + + const result = await executor.execute({ + model: "gpt-5.5-xhigh", + body: { model: "gpt-5.5-xhigh", input: [{ role: "user", content: "hello" }] }, + stream: true, + credentials: { accessToken: "codex-token" }, + }); + const body = await result.response.json(); + + assert.equal(result.response.status, 503); + assert.equal(result.response.headers.get("Access-Control-Allow-Origin"), "*"); + assert.equal(body.error.code, "wreq_unavailable"); + assert.match(body.error.message, /WebSocket transport unavailable/); + assert.equal(result.transformedBody.model, "gpt-5.5"); +}); + test("CodexExecutor maps Codex websocket error events to response.failed SSE", () => { const raw = JSON.stringify({ type: "error", diff --git a/tests/unit/plan3-p0.test.ts b/tests/unit/plan3-p0.test.ts index efc5fc819e..4e7fa7a390 100644 --- a/tests/unit/plan3-p0.test.ts +++ b/tests/unit/plan3-p0.test.ts @@ -40,6 +40,12 @@ test("getModelInfoCore resolves gpt-5.5 to codex", async () => { assert.equal(info.model, "gpt-5.5"); }); +test("getModelInfoCore keeps explicit gpt-5.5-medium separate from gpt-5.5", async () => { + const info = await getModelInfoCore("gpt-5.5-medium", {}); + assert.equal(info.provider, "codex"); + assert.equal(info.model, "gpt-5.5-medium"); +}); + test("getModelInfoCore resolves explicit gpt-5.5 Codex model", async () => { const info = await getModelInfoCore("cx/gpt-5.5", {}); assert.equal(info.provider, "codex"); diff --git a/tests/unit/t12-pricing-updates.test.ts b/tests/unit/t12-pricing-updates.test.ts index b47a399bc3..bf0f0cfe81 100644 --- a/tests/unit/t12-pricing-updates.test.ts +++ b/tests/unit/t12-pricing-updates.test.ts @@ -38,9 +38,13 @@ test("T12: pricing table includes MiniMax, GLM, Kimi and gpt-5.4 mini entries", test("T12: codex catalog includes GPT 5.5 entries", () => { const codexModels = new Map(REGISTRY.codex.models.map((m) => [m.id, m])); assert.ok(codexModels.has("gpt-5.5"), "missing codex/gpt-5.5"); + assert.ok(codexModels.has("gpt-5.5-medium"), "missing codex/gpt-5.5-medium"); assert.ok(codexModels.has("gpt-5.5-mini"), "missing codex/gpt-5.5-mini"); + assert.equal(codexModels.get("gpt-5.5")?.name, "GPT 5.5"); + assert.equal(codexModels.get("gpt-5.5-medium")?.name, "GPT 5.5 (Medium)"); assert.equal(codexModels.get("gpt-5.5")?.contextLength, 1050000); assert.equal(codexModels.get("gpt-5.5")?.supportsXHighEffort, true); + assert.equal(codexModels.get("gpt-5.5-medium")?.targetFormat, "openai-responses"); assert.equal(codexModels.get("gpt-5.5-xhigh")?.targetFormat, "openai-responses"); });