From 2039095f6902a0bfa42b0ea98ce31d8172fe4a17 Mon Sep 17 00:00:00 2001 From: Diego Rodrigues de Sa e Souza <8016841+diegosouzapw@users.noreply.github.com> Date: Wed, 24 Jun 2026 00:04:13 -0300 Subject: [PATCH] =?UTF-8?q?chore(claude,codex):=20bump=20pinned=20CLI=20id?= =?UTF-8?q?entity=20=E2=80=94=20Claude=202.1.158=E2=86=922.1.187,=20Codex?= =?UTF-8?q?=200.132.0=E2=86=920.142.0=20(#4883)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Integrated into release/v3.8.36 --- .env.example | 6 +-- docs/providers/AGENTROUTER.md | 2 +- docs/reference/ENVIRONMENT.md | 2 +- docs/security/STEALTH_GUIDE.md | 6 +-- open-sse/config/anthropicHeaders.ts | 2 +- open-sse/config/codexClient.ts | 2 +- open-sse/executors/claudeIdentity.ts | 2 +- open-sse/services/ccBridgeTransforms.ts | 2 +- open-sse/services/claudeCodeCompatible.ts | 4 +- tests/integration/chat-pipeline.test.ts | 2 +- ...claude-codex-identity-version-sync.test.ts | 47 +++++++++++++++++++ tests/unit/cli-tools.test.ts | 4 +- tests/unit/executor-codex.test.ts | 12 ++--- tests/unit/t20-t22-provider-headers.test.ts | 2 +- 14 files changed, 71 insertions(+), 24 deletions(-) create mode 100644 tests/unit/claude-codex-identity-version-sync.test.ts diff --git a/.env.example b/.env.example index 7a2cdc237e..c1a9d5ecce 100644 --- a/.env.example +++ b/.env.example @@ -797,7 +797,7 @@ GITHUB_OAUTH_CLIENT_ID=Iv1.b507a08c87ecfe98 # Used by: open-sse/executors/base.ts — buildHeaders() dynamic lookup. # Update these when providers release new CLI versions to avoid blocks. -CLAUDE_USER_AGENT="claude-cli/2.1.158 (external, cli)" +CLAUDE_USER_AGENT="claude-cli/2.1.187 (external, cli)" # Disable the deterministic tool-name cloak applied on both Anthropic-bound paths # (executors/base.ts native OAuth + executors/cliproxyapi.ts CLIProxyAPI) — @@ -806,7 +806,7 @@ CLAUDE_USER_AGENT="claude-cli/2.1.158 (external, cli)" # stream with a misleading 400 out-of-extra-usage placeholder. Set to true to # forward the original names verbatim (debugging only). # CLAUDE_DISABLE_TOOL_NAME_CLOAK=false -CODEX_USER_AGENT="codex-cli/0.132.0 (Windows 10.0.26200; x64)" +CODEX_USER_AGENT="codex-cli/0.142.0 (Windows 10.0.26200; x64)" GITHUB_USER_AGENT="GitHubCopilotChat/0.45.1" ANTIGRAVITY_USER_AGENT="antigravity/2.0.1 linux/arm64 google-api-nodejs-client/10.3.0" KIRO_USER_AGENT="AWS-SDK-JS/3.0.0 kiro-ide/1.0.0" @@ -828,7 +828,7 @@ GEMINI_CLI_USER_AGENT="google-api-nodejs-client/10.3.0" # Override Codex client version sent in headers independently of the # CODEX_USER_AGENT string. Used by: open-sse/config/codexClient.ts. -# CODEX_CLIENT_VERSION=0.132.0 +# CODEX_CLIENT_VERSION=0.142.0 # Kill-switch to strip non-standard `codex.*` SSE events (e.g. codex.rate_limits) # from the Codex Responses stream. These frames break the OpenAI SDK's diff --git a/docs/providers/AGENTROUTER.md b/docs/providers/AGENTROUTER.md index dcb9e18e7b..7130cc53d8 100644 --- a/docs/providers/AGENTROUTER.md +++ b/docs/providers/AGENTROUTER.md @@ -124,7 +124,7 @@ request (see `open-sse/services/claudeCodeCompatible.ts`): | Header | Value | | ------------------------------------------- | --------------------------------------------------------------------------------------------------- | | `Authorization` | `Bearer ` | -| `User-Agent` | `claude-cli/2.1.158 (external, sdk-cli)` | +| `User-Agent` | `claude-cli/2.1.187 (external, sdk-cli)` | | `anthropic-version` | `2023-06-01` | | `anthropic-beta` | `claude-code-20250219,interleaved-thinking-2025-05-14,effort-2025-11-24` | | Per-connection redact-thinking beta toggle | Adds `redact-thinking-2026-02-12` for upstreams that specifically require redacted thinking streams | diff --git a/docs/reference/ENVIRONMENT.md b/docs/reference/ENVIRONMENT.md index 266c7fe90a..d999288096 100644 --- a/docs/reference/ENVIRONMENT.md +++ b/docs/reference/ENVIRONMENT.md @@ -471,7 +471,7 @@ process.env[`${PROVIDER_ID}_USER_AGENT`] | -------------------------------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `CLAUDE_USER_AGENT` | `claude-cli/2.1.145 (external, cli)` | When Anthropic releases a new CLI version | | `CLAUDE_DISABLE_TOOL_NAME_CLOAK` | `false` | `executors/base.ts` + `executors/cliproxyapi.ts` | Set to `1`/`true` to forward third-party harness tool names verbatim to Anthropic on both Anthropic-bound paths (native OAuth and CLIProxyAPI). By default the executor deterministically aliases non-Claude-Code tool names (Claude Code canonical mapping where one exists, otherwise PascalCase) and reverses them on the response via `_toolNameMap`, so harnesses with snake_case tools are not refused as fingerprinted third-party clients. Debugging only. | -| `CODEX_USER_AGENT` | `codex-cli/0.132.0 (Windows 10.0.26200; x64)` | When OpenAI updates the Codex CLI | +| `CODEX_USER_AGENT` | `codex-cli/0.142.0 (Windows 10.0.26200; x64)` | When OpenAI updates the Codex CLI | | `CODEX_CLIENT_VERSION` | `0.131.0` | Override Codex client version independently of full UA string | | `GITHUB_USER_AGENT` | `GitHubCopilotChat/0.45.1` | When GitHub Copilot Chat updates | | `ANTIGRAVITY_USER_AGENT` | `antigravity/2.0.1 darwin/arm64` | When Antigravity IDE updates | diff --git a/docs/security/STEALTH_GUIDE.md b/docs/security/STEALTH_GUIDE.md index 0983a126bf..8250882c68 100644 --- a/docs/security/STEALTH_GUIDE.md +++ b/docs/security/STEALTH_GUIDE.md @@ -88,7 +88,7 @@ Applied to: `system` blocks, all `messages[].content`, and `tools[].description` For third-party Anthropic relays that only accept "real Claude Code" traffic: -- `CLAUDE_CODE_COMPATIBLE_USER_AGENT = "claude-cli/2.1.158 (external, sdk-cli)"` +- `CLAUDE_CODE_COMPATIBLE_USER_AGENT = "claude-cli/2.1.187 (external, sdk-cli)"` - `CLAUDE_CODE_COMPATIBLE_STAINLESS_PACKAGE_VERSION = "0.94.0"` - `CLAUDE_CODE_COMPATIBLE_STAINLESS_RUNTIME_VERSION = "v24.3.0"` - `anthropic-beta = "claude-code-20250219,interleaved-thinking-2025-05-14,effort-2025-11-24"` by default @@ -213,8 +213,8 @@ All MITM endpoints require management auth (`requireCliToolsAuth`). The sudo pas | Variable | Default | | ------------------------ | --------------------------------------------- | -| `CLAUDE_USER_AGENT` | `claude-cli/2.1.158 (external, cli)` | -| `CODEX_USER_AGENT` | `codex-cli/0.132.0 (Windows 10.0.26200; x64)` | +| `CLAUDE_USER_AGENT` | `claude-cli/2.1.187 (external, cli)` | +| `CODEX_USER_AGENT` | `codex-cli/0.142.0 (Windows 10.0.26200; x64)` | | `GITHUB_USER_AGENT` | `GitHubCopilotChat/0.45.1` | | `ANTIGRAVITY_USER_AGENT` | `antigravity/2.0.1 darwin/arm64` | | `KIRO_USER_AGENT` | `AWS-SDK-JS/3.0.0 kiro-ide/1.0.0` | diff --git a/open-sse/config/anthropicHeaders.ts b/open-sse/config/anthropicHeaders.ts index 0cad3c043c..3ddcadc550 100644 --- a/open-sse/config/anthropicHeaders.ts +++ b/open-sse/config/anthropicHeaders.ts @@ -64,7 +64,7 @@ export function mergeClientAnthropicBeta( return baseList.join(","); } -export const CLAUDE_CLI_VERSION = "2.1.158"; +export const CLAUDE_CLI_VERSION = "2.1.187"; export const CLAUDE_CLI_USER_AGENT = `claude-cli/${CLAUDE_CLI_VERSION} (external, cli)`; export const CLAUDE_CLI_STAINLESS_PACKAGE_VERSION = "0.94.0"; export const CLAUDE_CLI_STAINLESS_RUNTIME_VERSION = "v24.3.0"; diff --git a/open-sse/config/codexClient.ts b/open-sse/config/codexClient.ts index 746870df73..1b6afa395f 100644 --- a/open-sse/config/codexClient.ts +++ b/open-sse/config/codexClient.ts @@ -1,4 +1,4 @@ -const DEFAULT_CODEX_CLIENT_VERSION = "0.132.0"; +const DEFAULT_CODEX_CLIENT_VERSION = "0.142.0"; const DEFAULT_CODEX_USER_AGENT_PLATFORM = "Windows 10.0.26200"; const DEFAULT_CODEX_USER_AGENT_ARCH = "x64"; const CODEX_VERSION_OVERRIDE_ENV = "CODEX_CLIENT_VERSION"; diff --git a/open-sse/executors/claudeIdentity.ts b/open-sse/executors/claudeIdentity.ts index 470fd62313..41728f8d5d 100644 --- a/open-sse/executors/claudeIdentity.ts +++ b/open-sse/executors/claudeIdentity.ts @@ -12,7 +12,7 @@ import { createHash, randomBytes, randomUUID } from "node:crypto"; // ---------- Versions ------------------------------------------------------ -export const CLAUDE_CODE_VERSION = "2.1.158"; +export const CLAUDE_CODE_VERSION = "2.1.187"; /** Bundled @anthropic-ai/sdk version for the pinned CLI release. */ export const CLAUDE_CODE_STAINLESS_VERSION = "0.94.0"; diff --git a/open-sse/services/ccBridgeTransforms.ts b/open-sse/services/ccBridgeTransforms.ts index eb9a5f79a5..d45c980dd3 100644 --- a/open-sse/services/ccBridgeTransforms.ts +++ b/open-sse/services/ccBridgeTransforms.ts @@ -114,7 +114,7 @@ export const CCH_SALT = "59cf53e54c78"; /** Character positions sampled from the first user message text. */ export const CCH_POSITIONS = [4, 7, 20] as const; /** Default `cc_version=` value embedded in the billing header. */ -export const DEFAULT_CLAUDE_CODE_VERSION = "2.1.158"; +export const DEFAULT_CLAUDE_CODE_VERSION = "2.1.187"; /** Identity sentinel prepended for Claude Agent SDK callers. */ export const CLAUDE_AGENT_SDK_IDENTITY = "You are a Claude agent, built on Anthropic's Claude Agent SDK."; diff --git a/open-sse/services/claudeCodeCompatible.ts b/open-sse/services/claudeCodeCompatible.ts index 60b22d2188..c8f0788861 100644 --- a/open-sse/services/claudeCodeCompatible.ts +++ b/open-sse/services/claudeCodeCompatible.ts @@ -40,8 +40,8 @@ export { CLAUDE_CODE_COMPATIBLE_REDACT_THINKING_BETA, resolveClaudeCodeCompatibleAnthropicBeta, } from "./claudeCodeCompatibleBeta.ts"; -export const CLAUDE_CODE_COMPATIBLE_VERSION = "2.1.158"; -export const CLAUDE_CODE_COMPATIBLE_USER_AGENT = "claude-cli/2.1.158 (external, sdk-cli)"; +export const CLAUDE_CODE_COMPATIBLE_VERSION = "2.1.187"; +export const CLAUDE_CODE_COMPATIBLE_USER_AGENT = "claude-cli/2.1.187 (external, sdk-cli)"; export const CLAUDE_CODE_COMPATIBLE_STAINLESS_PACKAGE_VERSION = "0.94.0"; export const CLAUDE_CODE_COMPATIBLE_STAINLESS_RUNTIME_VERSION = "v24.3.0"; export const CONTEXT_1M_BETA_HEADER = "context-1m-2025-08-07"; diff --git a/tests/integration/chat-pipeline.test.ts b/tests/integration/chat-pipeline.test.ts index 7627108d30..001d03e8e6 100644 --- a/tests/integration/chat-pipeline.test.ts +++ b/tests/integration/chat-pipeline.test.ts @@ -700,7 +700,7 @@ test("chat pipeline applies Codex CLI fingerprint to OAuth responses requests", assert.equal(call.headers.Version, getCodexClientVersion()); assert.equal(call.headers["Openai-Beta"], "responses=experimental"); assert.equal(call.headers["X-Codex-Beta-Features"], "responses_websockets"); - assert.equal(call.headers["User-Agent"], "codex-cli/0.132.0 (Windows 10.0.26200; x64)"); + assert.equal(call.headers["User-Agent"], "codex-cli/0.142.0 (Windows 10.0.26200; x64)"); assert.equal(call.headers["x-codex-window-id"], "conv_codex_fingerprint:0"); assert.ok(call.headers["x-client-request-id"], "expected Codex request id header"); assert.ok(call.headers["x-codex-turn-metadata"], "expected Codex turn metadata header"); diff --git a/tests/unit/claude-codex-identity-version-sync.test.ts b/tests/unit/claude-codex-identity-version-sync.test.ts new file mode 100644 index 0000000000..695e45f8f3 --- /dev/null +++ b/tests/unit/claude-codex-identity-version-sync.test.ts @@ -0,0 +1,47 @@ +/** + * tests/unit/claude-codex-identity-version-sync.test.ts + * + * Guards the pinned CLI identity versions against drift. The Claude Code version + * lives in FOUR places (claudeIdentity, anthropicHeaders, claudeCodeCompatible, + * ccBridgeTransforms) and MUST stay in lockstep — a partial bump produces an + * inconsistent wire fingerprint. The Codex client version lives in codexClient. + * + * When you capture a newer claude-cli / codex release, bump ALL constants and + * update the pinned values below in the same change. + */ + +import test from "node:test"; +import assert from "node:assert/strict"; + +const id = await import("../../open-sse/executors/claudeIdentity.ts"); +const hdr = await import("../../open-sse/config/anthropicHeaders.ts"); +const compat = await import("../../open-sse/services/claudeCodeCompatible.ts"); +const bridge = await import("../../open-sse/services/ccBridgeTransforms.ts"); +const codexCfg = await import("../../open-sse/config/codexClient.ts"); + +test("Claude CLI version constants are in lockstep across all 4 sources", () => { + const V = id.CLAUDE_CODE_VERSION; + assert.equal(hdr.CLAUDE_CLI_VERSION, V, "anthropicHeaders.CLAUDE_CLI_VERSION drift"); + assert.equal(compat.CLAUDE_CODE_COMPATIBLE_VERSION, V, "claudeCodeCompatible version drift"); + assert.equal(bridge.DEFAULT_CLAUDE_CODE_VERSION, V, "ccBridgeTransforms version drift"); + assert.equal( + hdr.CLAUDE_CLI_USER_AGENT, + `claude-cli/${V} (external, cli)`, + "CLAUDE_CLI_USER_AGENT drift" + ); + assert.equal( + compat.CLAUDE_CODE_COMPATIBLE_USER_AGENT, + `claude-cli/${V} (external, sdk-cli)`, + "CLAUDE_CODE_COMPATIBLE_USER_AGENT drift" + ); +}); + +test("Claude CLI is pinned to the captured 2.1.187 release", () => { + assert.equal(id.CLAUDE_CODE_VERSION, "2.1.187"); +}); + +test("Codex client is pinned to the captured 0.142.0 release", () => { + assert.equal(codexCfg.getCodexClientVersion(), "0.142.0"); + assert.equal(codexCfg.getCodexUserAgent(), "codex-cli/0.142.0 (Windows 10.0.26200; x64)"); + assert.equal(codexCfg.getCodexDefaultHeaders().Version, "0.142.0"); +}); diff --git a/tests/unit/cli-tools.test.ts b/tests/unit/cli-tools.test.ts index dc5a4f2676..7886d51448 100644 --- a/tests/unit/cli-tools.test.ts +++ b/tests/unit/cli-tools.test.ts @@ -87,12 +87,12 @@ test("CLI fingerprint preserves Codex executor User-Agent and maps legacy Copilo "codex", { Authorization: "Bearer token", - "User-Agent": "codex-cli/0.132.0 (Windows 10.0.26200; x64)", + "User-Agent": "codex-cli/0.142.0 (Windows 10.0.26200; x64)", }, { model: "gpt-5.5", messages: [], stream: true } ); - assert.equal(codex.headers["User-Agent"], "codex-cli/0.132.0 (Windows 10.0.26200; x64)"); + assert.equal(codex.headers["User-Agent"], "codex-cli/0.142.0 (Windows 10.0.26200; x64)"); assert.deepEqual(Object.keys(JSON.parse(codex.bodyString)), ["model", "stream", "messages"]); const copilot = applyFingerprint( diff --git a/tests/unit/executor-codex.test.ts b/tests/unit/executor-codex.test.ts index 673b205271..3ece99efe3 100644 --- a/tests/unit/executor-codex.test.ts +++ b/tests/unit/executor-codex.test.ts @@ -188,10 +188,10 @@ test("CodexExecutor.buildHeaders binds workspace ids and disables SSE accept for assert.equal(standardHeaders.Authorization, "Bearer codex-token"); assert.equal(standardHeaders.Accept, "text/event-stream"); assert.equal(standardHeaders["chatgpt-account-id"], "workspace-1"); - assert.equal(standardHeaders.Version, "0.132.0"); + assert.equal(standardHeaders.Version, "0.142.0"); assert.equal(standardHeaders["Openai-Beta"], "responses=experimental"); assert.equal(standardHeaders["X-Codex-Beta-Features"], "responses_websockets"); - assert.equal(standardHeaders["User-Agent"], "codex-cli/0.132.0 (Windows 10.0.26200; x64)"); + assert.equal(standardHeaders["User-Agent"], "codex-cli/0.142.0 (Windows 10.0.26200; x64)"); assert.equal(compactHeaders.Accept, "application/json"); }); @@ -200,13 +200,13 @@ test("CodexExecutor.buildHeaders honors safe env overrides for Version and User- await withEnv( { - CODEX_CLIENT_VERSION: "0.132.0", + CODEX_CLIENT_VERSION: "0.142.0", CODEX_USER_AGENT: undefined, }, () => { const headers = executor.buildHeaders({ accessToken: "codex-token" }, true); - assert.equal(headers.Version, "0.132.0"); - assert.equal(headers["User-Agent"], "codex-cli/0.132.0 (Windows 10.0.26200; x64)"); + assert.equal(headers.Version, "0.142.0"); + assert.equal(headers["User-Agent"], "codex-cli/0.142.0 (Windows 10.0.26200; x64)"); } ); @@ -217,7 +217,7 @@ test("CodexExecutor.buildHeaders honors safe env overrides for Version and User- }, () => { const headers = executor.buildHeaders({ accessToken: "codex-token" }, true); - assert.equal(headers.Version, "0.132.0"); + assert.equal(headers.Version, "0.142.0"); assert.equal(headers["User-Agent"], "custom-codex/9.9.9"); } ); diff --git a/tests/unit/t20-t22-provider-headers.test.ts b/tests/unit/t20-t22-provider-headers.test.ts index 5c60915512..aa65bf17e6 100644 --- a/tests/unit/t20-t22-provider-headers.test.ts +++ b/tests/unit/t20-t22-provider-headers.test.ts @@ -66,7 +66,7 @@ test("T20: codex config advertises current client headers and supported models", assert.equal(codex.headers.Version, getCodexClientVersion()); assert.equal(codex.headers["Openai-Beta"], "responses=experimental"); assert.equal(codex.headers["X-Codex-Beta-Features"], "responses_websockets"); - assert.equal(codex.headers["User-Agent"], "codex-cli/0.132.0 (Windows 10.0.26200; x64)"); + assert.equal(codex.headers["User-Agent"], "codex-cli/0.142.0 (Windows 10.0.26200; x64)"); assert.ok(codex.models.some((model) => model.id === "gpt-5.5-medium")); assert.ok(!codex.models.some((model) => model.id === "codex-auto-review")); });