Files
OmniRoute/docs/providers/CHATGPT_WEB.md
Diego Rodrigues de Sa e Souza a94fe23e89 fix(release): drain the twelve reds every PR against release/v3.8.51 was born with (#11940)
* fix(release): drain the twelve reds every PR against release/v3.8.51 was born with

Measured on the cycle tip: fifteen unit files were red on every PR. Two came
from the v3.8.50 sync-back (fixed in #11929); the other thirteen predate it and
are the branch's own drift. This sweep clears all of them but the ESLint debt
(#11924), each with the smallest change that keeps the guard honest:

- .env.example + ENVIRONMENT.md: NEXT_PUBLIC_SW_BUILD_ID / OMNIROUTE_SW_BUILD_ID /
  SOURCE_VERSION (#11779 service-worker cache busting) documented — the env/docs
  contract gate was failing on every PR.
- stryker.conf.json: the six tests the mutation gate found covering mutated modules
  (four retirement runtime-block suites, combo connection-aware expansion, tunnel
  error sanitization) registered in tap.testFiles.
- dependency-allowlist: eslint-plugin-react-hooks 7.0.1 approved; its findings are
  tracked in #11924.
- i18n: the six combo.sort.* strings (d5dfcfff58) translated for vi (strict parity)
  and pt-BR.
- docs/providers/CHATGPT_WEB.md: the retirement test is migration-168, not 163.
- g4f gateways: authHint now says member key, which the discontinued-providers
  guard asserts.
- tests realigned to the catalog the branch actually ships: qwen-web (#11713) and
  chatgpt-web (#11720) are retired, so web-session-contract and
  token-health-check-webcookie use perplexity-web, grok-web and chatgpt-web-codex.
- db-core-init: the two minimal legacy fixtures gained the columns migrations 164-168
  UPDATE (error_code, last_error*, test_status) — they exist on every real legacy DB
  (base CREATE TABLE); the fixtures simply never declared them.
- no-js-extension guard: a .js specifier whose target is a genuine JavaScript file
  (open-sse/lib/deepseek-pow-hash.js, shared with a worker) is not the #10674
  defect; the test now skips targets that exist as .js.

All twelve files pass locally; docs-sync, docs-counts, env-doc-sync, the tap
drift gate and the fabricated-docs gates are green on the tree.

* test(release): move the deferred-finish translator test into a collected path

tests/unit/translator/ is not one of the unit collectors (package.json test:unit,
merge-train.sh, build-test-impact-map, check-test-discovery), so the suite that
dd35750e5f added there never ran — check:test-discovery flagged it as a new orphan
on every PR. Relocated next to its sibling openai-to-claude-trailing-usage-11817
under tests/unit/, where the root glob collects it (5/5 pass).

* fix(dashboard): type the four sort-method sites #11812 left red on the dashboard typecheck ratchet

d5dfcfff58 added the combo model sort and raised combos/page.tsx from 23 to 27
scoped TypeScript errors (TS2339 +1, TS2345 +2, TS2322 +1), which fails
check:dashboard-typecheck on every PR against release/v3.8.51:

- initialSortMethod: sanitizeComboRuntimeConfig() is untyped, so config.modelSort is
  unknown; narrow it before reading .method (normalizeSortMethod takes unknown anyway).
- handleAddModels: the batch path passes ComboBuilderDraftModelStep[] to the ComboStep[]
  sort helpers without the cast handleSortChange already uses; mirror it.
- ComboSortSelect expects a translate-with-fallback (k, f) => string, but received
  next-intl's Translator whose second argument is a values object. Pass the page's
  getI18nOrFallback adapter instead of the raw translator — that is also what makes
  the `has()` check and the fallback text actually work at runtime.

Baseline untouched (no widening). Scoped tsc: 0 new/regressed errors.
2026-08-28 18:18:33 -03:00

5.6 KiB

title, version, lastUpdated
title version lastUpdated
Providers — ChatGPT Web (Codex) 3.8.50 2026-08-26

Providers — ChatGPT Web (Codex)

chatgpt-web-codex (alias cgpt-codex) bridges Codex Responses turns through an authenticated ChatGPT browser session. It is independent from the retired common chatgpt-web provider and uses the MIT-noticed implementation under open-sse/vendor/codex-chatgpt-web/.

Common provider retirement

The former common provider IDs chatgpt-web and cgpt-web no longer ship because the provenance of their pre-key/proof-of-work implementation could not be cleared. Explicit requests to either ID, including slash-prefixed model IDs and persisted aliases, fail closed with HTTP 410 and code PROVIDER_RETIRED before any upstream request.

Migration 163_retire_chatgpt_web.sql tombstones matching provider connections and invalidates their active session leases. It preserves connection history and API-key allowlists; it does not add replacement access to an allowlist. The Codex provider and its connections are not matched by this retirement.

Prerequisites

  • a full Cookie header from a signed-in ChatGPT session;
  • Chrome or Chromium for npm, systemd, and PM2 installs;
  • with the Docker web profile, the internal Chromium service from docker-compose.yml;
  • an OpenAI tunnel and a ChatGPT custom connector for local Codex tools.

The tunnel is only needed for tool turns. The pro model is read-only and does not need a local tool connector.

Dashboard setup

  1. Open the ChatGPT Web (Codex) provider and add a connection.
  2. Paste the full ChatGPT Cookie header, tunnel ID, runtime key, and custom connector name.
  3. Run the connection check. OmniRoute opens a headless Temporary Chat and detects whether pro is available for the account.
  4. Save the connection. OmniRoute replaces the pasted cookie with the verified Playwright storage state and stores it with the runtime key through the encrypted credential abstraction.

The raw cookie is not retained after a successful save. When the session expires, open the connection, paste a fresh full Cookie header, and rerun the check. The doctor status in the edit dialog reports browser, storage state, sign-in, Temporary Chat, tunnel, connector, and tool round-trip separately.

Never commit a real cookie, runtime key, storage state, or capability token. Test and documentation values must always be placeholders.

Models and combos

The fixed model routes are:

  • chatgpt-web-codex/instant
  • chatgpt-web-codex/medium
  • chatgpt-web-codex/high
  • chatgpt-web-codex/extra-high
  • chatgpt-web-codex/pro

Add one of them to a combo like any other model. The Codex app sends the combo name as model to the regular Responses endpoint, /v1/responses; there is no separate Codex endpoint or mode switch.

pro does not run local tools. A forced tool makes that combo target incompatible. With optional tools, the turn runs read-only and reports the limitation as commentary.

Security model

  • The native path requires a Responses request, a recognized Codex client, and matching thread and turn identities.
  • Workspace, sandbox, approval policy, and tool catalog come from the native Codex shell; free-form prompt text is not authority for them.
  • ChatGPT receives only a short-lived capability per turn. The MCP broker accepts only tools Codex offered in that exact turn.
  • Auto-confirming Allow once only returns the tool request to Codex. Codex alone decides on approval and execution.
  • Before the first output, a combo may fall back to another compatible target. After output begins, provider, model, connection, and browser turn remain pinned until the turn completes.
  • Cookies, runtime keys, storage state, and capability tokens do not appear in provider responses or request logs.

Headless VPS and Docker

For npm, systemd, and PM2 installs, OmniRoute detects common Chrome and Chromium paths. Alternatively, set CHATGPT_WEB_CODEX_CHROME_PATH.

The Docker web profile starts chatgpt-web-codex-browser on the internal Compose network. Its CDP port is not published on the host. The protected browser profile volume is separate from the OmniRoute data volume, and the browser receives enough shared memory. The internal CDP proxy listens only on port 9223 inside the Compose network; Chrome remains bound to loopback in the sidecar.

A supervisor lease under DATA_DIR prevents multiple OmniRoute processes from owning the same tunnel and broker state. A conflict is reported by the doctor.

Interactive recovery

The normal path is headless. When ChatGPT requires an interactive sign-in or challenge, the existing VNC browser infrastructure can be used for recovery. Browser UI and CDP must remain reachable only over loopback, an authenticated management connection, or an SSH tunnel; noVNC stays disabled during normal operation.

WebSocket fallback

When a combo contains ChatGPT Web (Codex), the Responses WebSocket bridge requests the HTTP/SSE fallback before connecting upstream. The transfer then goes through /v1/responses.

Verification

Run the provider controls without invoking the retired provider:

node --import tsx/esm --test \\
  tests/unit/chatgpt-web-codex.test.ts \\
  tests/unit/chatgpt-web-codex-turn-pin.test.ts \\
  tests/unit/chatgpt-web-environment-double-unescape.test.ts

Retirement regression guards live in:

  • tests/unit/chatgpt-web-retirement.test.ts
  • tests/unit/chatgpt-web-runtime-block.test.ts
  • tests/unit/chatgpt-web-image-handler-retirement.test.ts
  • tests/unit/chatgpt-web-source-retirement.test.ts
  • tests/unit/migration-168-retire-chatgpt-web.test.ts