feat(codex): self-contained codex app-server transport (executor + provider + sign-in) (#11205)

Merged after conflict resolution: the 5 conflicting test files were the base-red drains that #11201 already landed on the tip — kept the tip versions; the feature content is untouched. Validated on the combined batch board + this branch: codex-app-server + codex-gpt56-catalog 25/25, typecheck:core clean, docs-counts green (351 providers), provider-consistency 268/351/0. The opt-in codex-app-server transport (JSON-RPC-over-WS, turn/completed-awaited close, Responses SSE bridge) leaves the default codex path untouched. Thank you @arminanton — a 3.4k-line transport with the docs wave and tests to match!
This commit is contained in:
Armin Anton” ∴
2026-08-23 06:20:06 -07:00
committed by GitHub
parent 968fa96105
commit 8f390efffd
153 changed files with 3358 additions and 182 deletions

View File

@@ -1,4 +1,9 @@
export const DEFAULT_CODEX_CLIENT_VERSION = "0.146.0";
// Kept in lockstep with the codex CLI actually installed in the OmniRoute image
// (bin/omniroute-fix.Containerfile installs `codex` latest; app-server runtime is
// 0.149.0 as of 2026-08-22). When the image's codex is bumped, refresh this so the
// fingerprint OpenAI sees from the OAuth/Responses face matches the real client
// version. Overridable per-deployment via the CODEX_CLIENT_VERSION env.
export const DEFAULT_CODEX_CLIENT_VERSION = "0.149.0";
export const CODEX_CLI_RS_ORIGINATOR = "codex_cli_rs";
export function getCodexCliRsHeaders(

View File

@@ -401,6 +401,18 @@ export const FEATURE_FLAG_DEFINITIONS: FeatureFlagDefinition[] = [
requiresRestart: false,
warningLevel: "info",
},
{
key: "OMNIROUTE_CODEX_APP_SERVER_ENABLED",
label: "Codex App-Server Transport",
description:
"Allow Codex to use the local app-server WebSocket JSON-RPC transport (codexTransport=app-server). When off, connections opted into app-server fall back to Codex's other transports.",
descriptionI18nKey: "featureFlagOmnirouteCodexAppServerEnabledDescription",
category: "runtime",
defaultValue: "true",
type: "boolean",
requiresRestart: false,
warningLevel: "info",
},
{
key: "OMNIROUTE_EMERGENCY_FALLBACK",
label: "Emergency Fallback",

View File

@@ -175,6 +175,30 @@ export const NOAUTH_PROVIDERS = {
text: "ZCode runs locally through its native app-server. OmniRoute never receives or stores the Z.ai credential.",
},
},
"codex-app-server": {
id: "codex-app-server",
alias: "cxa",
name: "OpenAI Codex (App-Server)",
icon: "code",
color: "#10A37F",
textIcon: "CA",
website: "https://developers.openai.com/codex/cli",
noAuth: true,
hasFree: false,
serviceKinds: ["llm"],
isLocalCli: true,
// No subscriptionRisk / riskNoticeVariant: unlike the `codex` provider (which
// replays your ChatGPT/OpenAI session token to the API), this transport drives
// the Codex CLI's own `codex app-server` over JSON-RPC/WebSocket. The CLI owns
// and self-refreshes its OAuth (~/.codex/auth.json) exactly like an interactive
// `codex` session — OmniRoute never replays a token to the API — so the
// "official session not authorized for proxy use" caveat does not apply.
authHint:
"No token stored by OmniRoute. The Codex CLI app-server manages its own ChatGPT sign-in (~/.codex/auth.json, auto-refreshed). Use \u201cSign in with ChatGPT\u201d if the CLI is not yet authenticated.",
notice: {
text: "OpenAI Codex (App-Server) drives the Codex CLI's local app-server (JSON-RPC over WebSocket). The CLI self-manages its OpenAI OAuth, so OmniRoute never sees or replays your token. Requires the codex CLI reachable at the configured app-server URL; sign in via the CLI or the dashboard \u201cSign in with ChatGPT\u201d action.",
},
},
uncloseai: {
id: "uncloseai",
alias: "unc",

View File

@@ -338,6 +338,7 @@ export const CLI_TOOL_ALIASES: Readonly<Record<string, string>> = {
"claude-code": "claude",
"openai-codex": "codex",
openai: "codex",
"codex-app-server": "codex",
cn: "continue",
qodercli: "qoder",
};