Skip to content

fix(codex): current client_version + refresh-aware model sync - #2714

Closed
doedja wants to merge 1 commit into
decolua:masterfrom
doedja:fix/codex-models-client-version
Closed

doedja wants to merge 1 commit into
decolua:masterfrom
doedja:fix/codex-models-client-version

Conversation

@doedja

@doedja doedja commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Problem

Codex model sync calls https://chatgpt.com/backend-api/codex/models?client_version=1.0.0. That endpoint filters the returned catalog by minimal_client_version against whatever client_version the caller sends, and codex CLI's own manifest (openai/codex codex-rs/models-manager/models.json) already requires 0.144.0 for its newest models. 1.0.0 predates that by a wide margin, so the request can come back a clean 200 with the gated entries just missing, no error to react to.

We hit this in our own implementation of the same call: a real ChatGPT Plus account got a 200 with an empty model list at client_version=0.21.0, and the list populated once we bumped to a current release.

There's also no fallback in the generic sync branch this entry runs through (route.js ~519-547): a 200 with zero models is returned to the client as-is, with no warning field, nothing to signal that something's off.

Fix

  • Bump client_version to 0.144.6 (current stable, comfortably above the 0.144.0 gate) via a named constant with a comment explaining the gating, so it doesn't quietly go stale again.
  • Add the originator: codex_cli_rs header. Every other codex call site in this codebase already sends it (open-sse/providers/registry/codex.js, open-sse/handlers/imageProviders/codex.js, open-sse/services/usage/codex.js), just not this one.
  • Move the codex entry onto the existing buildOAuthResolver helper, the same pattern gemini-cli and grok-cli already use. refreshCodexToken was already implemented and used elsewhere (the general provider refresh table in open-sse/services/tokenRefresh.js), just never wired into model sync, so codex model listing never retried on an expired token the way the other OAuth providers do. This also means a genuinely empty response now comes back with a warning field instead of a silent empty array.

Scope

Kept this to the codex entry only. I looked at also wiring a static-catalog fallback for a fully-empty result (like kimchi/grok-cli do), but there's no static codex catalog in open-sse/config/providerModels.js to fall back to, and I didn't want to guess at a model list. Happy to follow up separately if that's wanted.

Checks

  • bunx eslint "src/app/api/providers/[id]/models/route.js" clean.
  • Skipped the test suite: vitest isn't a declared dependency and there's no test script in package.json, even though tests/unit/*.test.js exists, so I couldn't run it against a fresh clone.

Reference: https://raw.githubusercontent.com/openai/codex/refs/heads/main/codex-rs/models-manager/models.json

The codex models config sent client_version=1.0.0 to /codex/models.
That endpoint gates each catalog entry by minimal_client_version, and
codex CLI's own manifest already requires 0.144.0 for its newest
models, so an old client_version comes back 200 with those entries
silently missing instead of erroring.

Bump the version, add the originator header codex requests already
send everywhere else in this codebase (registry, image provider,
usage tracking), and move the codex entry onto the same
buildOAuthResolver pattern gemini-cli and grok-cli already use. That
gives model sync the same refresh-on-401 retry those providers get
(codex had none before) and surfaces a warning in the response
instead of a silent empty list when the upstream call still comes
back with zero models.
@decolua

decolua commented Jul 20, 2026

Copy link
Copy Markdown
Owner

Thanks @doedja for the contribution! Reviewed and merged into master. 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants