From a7047a07d475207a6685b1d288f1aa57c027f405 Mon Sep 17 00:00:00 2001 From: decolua Date: Thu, 10 Sep 2026 21:23:24 +0700 Subject: [PATCH] fix(codex): restore Version header and single-source the CLI version The image handler's `version` header was commented out, so Codex image requests reached chatgpt.com without the Version identity the backend expects. Restore it and route every Codex identity header through one constant. The CLI version now lives on registry codex.transport as `cliVersion` (the same pattern gemini-cli uses) and is re-exported as CODEX_CLI_VERSION, so the registry User-Agent, the image handler and the connection test can no longer drift apart. Bumped 0.136.0 -> 0.154.0 (current stable). Co-Authored-By: Claude Code --- open-sse/config/appConstants.js | 3 +++ open-sse/handlers/imageProviders/codex.js | 6 +++--- open-sse/providers/registry/codex.js | 7 ++++++- src/app/api/providers/[id]/test/testUtils.js | 3 ++- tests/__baseline__/providers-baseline.json | 3 ++- tests/unit/image-generation.test.js | 2 +- 6 files changed, 17 insertions(+), 7 deletions(-) diff --git a/open-sse/config/appConstants.js b/open-sse/config/appConstants.js index 3e18633e..4df1463e 100644 --- a/open-sse/config/appConstants.js +++ b/open-sse/config/appConstants.js @@ -7,6 +7,9 @@ import { createRequire } from "module"; export const GEMINI_CLI_VERSION = PROVIDERS["gemini-cli"]?.cliVersion; export const GEMINI_CLI_API_CLIENT = PROVIDERS["gemini-cli"]?.apiClient; +// === Codex CLI === derive từ registry codex.transport +export const CODEX_CLI_VERSION = PROVIDERS["codex"]?.cliVersion; + // Map Node arch to Gemini CLI arch string (x64/x86/arm64/...) function geminiCLIArch() { const a = arch(); diff --git a/open-sse/handlers/imageProviders/codex.js b/open-sse/handlers/imageProviders/codex.js index 218302ab..385ec5b6 100644 --- a/open-sse/handlers/imageProviders/codex.js +++ b/open-sse/handlers/imageProviders/codex.js @@ -2,10 +2,10 @@ import { randomUUID } from "node:crypto"; import { nowSec } from "./_base.js"; import { PROVIDERS } from "../../config/providers.js"; +import { CODEX_CLI_VERSION } from "../../config/appConstants.js"; const CODEX_RESPONSES_URL = PROVIDERS["codex"].baseUrl; -const CODEX_USER_AGENT = "codex_cli_rs/0.136.0"; -const CODEX_VERSION = "0.136.0"; +const CODEX_USER_AGENT = `codex_cli_rs/${CODEX_CLI_VERSION}`; const CODEX_ORIGINATOR = "codex_cli_rs"; const CODEX_MODEL_SUFFIX = "-image"; const CODEX_REF_DETAIL = "high"; @@ -157,7 +157,7 @@ export default { "originator": CODEX_ORIGINATOR, "session_id": randomUUID(), "user-agent": CODEX_USER_AGENT, - "version": CODEX_VERSION, + "version": CODEX_CLI_VERSION, "x-client-request-id": randomUUID(), }; }, diff --git a/open-sse/providers/registry/codex.js b/open-sse/providers/registry/codex.js index 1909fe97..bf436a10 100644 --- a/open-sse/providers/registry/codex.js +++ b/open-sse/providers/registry/codex.js @@ -1,5 +1,9 @@ import { withCodexReviewModels } from "../models/helpers.js"; +// Codex CLI version seen by OpenAI's backend — single source for the Version / +// User-Agent identity headers. Bump when the installed codex CLI is upgraded. +const CODEX_CLI_VERSION = "0.154.0"; + export default { id: "codex", priority: 30, @@ -34,9 +38,10 @@ export default { baseUrl: "https://chatgpt.com/backend-api/codex/responses", format: "openai-responses", forceStream: true, + cliVersion: CODEX_CLI_VERSION, headers: { originator: "codex_cli_rs", - "User-Agent": "codex_cli_rs/0.136.0", + "User-Agent": `codex_cli_rs/${CODEX_CLI_VERSION}`, }, usage: { url: "https://chatgpt.com/backend-api/wham/usage", diff --git a/src/app/api/providers/[id]/test/testUtils.js b/src/app/api/providers/[id]/test/testUtils.js index bd0c4782..9572e69e 100644 --- a/src/app/api/providers/[id]/test/testUtils.js +++ b/src/app/api/providers/[id]/test/testUtils.js @@ -4,6 +4,7 @@ import { testProxyUrl } from "@/lib/network/proxyTest"; import { isOpenAICompatibleProvider, isAnthropicCompatibleProvider } from "@/shared/constants/providers"; import { getDefaultModel } from "open-sse/config/providerModels.js"; import { resolveOllamaLocalHost, PROVIDERS } from "open-sse/config/providers.js"; +import { CODEX_CLI_VERSION } from "open-sse/config/appConstants.js"; import { refreshProviderCredentials, shouldRefreshCredentials, @@ -27,7 +28,7 @@ const OAUTH_TEST_CONFIG = { method: "POST", authHeader: "Authorization", authPrefix: "Bearer ", - extraHeaders: { "Content-Type": "application/json", "originator": "codex_cli_rs", "User-Agent": "codex_cli_rs/0.136.0" }, + extraHeaders: { "Content-Type": "application/json", "originator": "codex_cli_rs", "User-Agent": `codex_cli_rs/${CODEX_CLI_VERSION}` }, // Minimal invalid body — triggers fast 400 without consuming quota body: JSON.stringify({ model: "gpt-5.3-codex", input: [], stream: false, store: false }), // 400 (bad request) means auth succeeded; only 401/403 means token is bad diff --git a/tests/__baseline__/providers-baseline.json b/tests/__baseline__/providers-baseline.json index db0b8bad..2dd09f55 100644 --- a/tests/__baseline__/providers-baseline.json +++ b/tests/__baseline__/providers-baseline.json @@ -192,9 +192,10 @@ "baseUrl": "https://chatgpt.com/backend-api/codex/responses", "format": "openai-responses", "forceStream": true, + "cliVersion": "0.154.0", "headers": { "originator": "codex_cli_rs", - "User-Agent": "codex_cli_rs/0.136.0" + "User-Agent": "codex_cli_rs/0.154.0" }, "usage": { "url": "https://chatgpt.com/backend-api/wham/usage", diff --git a/tests/unit/image-generation.test.js b/tests/unit/image-generation.test.js index 12dce95d..4df94afc 100644 --- a/tests/unit/image-generation.test.js +++ b/tests/unit/image-generation.test.js @@ -351,7 +351,7 @@ describe("handleImageGenerationCore", () => { headers: expect.objectContaining({ authorization: "Bearer codex-token", "chatgpt-account-id": "account-123", - version: "0.136.0", + version: "0.154.0", }), }) );