Skip to content

feat(provider): list the models each ChatGPT account serves - #1579

Open
bwachman wants to merge 3 commits into
cl-11727-prepare-bounded-catalogs-for-the-live-chatgpt-catalogfrom
cl-11727-restore-the-live-codex-model-catalog-fetch-for-chatgpt
Open

bwachman wants to merge 3 commits into
cl-11727-prepare-bounded-catalogs-for-the-live-chatgpt-catalogfrom
cl-11727-restore-the-live-codex-model-catalog-fetch-for-chatgpt

Conversation

@bwachman

@bwachman bwachman commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • A ChatGPT (Codex OAuth) profile lists the models its account serves: the TUI fetches GET /codex/models after startup and after /connect, keeps the listed entries in the backend's priority order, and makes the first one the profile's default. Requests send client_version 0.165.0, the current Codex CLI release; the backend returns no models to the previous 0.50.0.
  • Connecting a ChatGPT account shows that account's live models in the model step and preselects the first one, unless the operator has moved to another model or the type-a-model row.
  • When a fetch fails, the profile keeps its last live list or the built-in list.

Verification

  • bun run check and bun run test pass.
  • Against a live ChatGPT Plus account, a profile lists gpt-6.1-sol, gpt-6-astra, gpt-6.1-terra, gpt-6-sol, gpt-6-luna, gpt-5.6-sol, gpt-5.6-terra and gpt-5.6-luna, with gpt-6.1-sol as the default.
  • A headless turn on codex/plus with gpt-6.1-sol completes.

Fixes CL-11727

@linear-code

linear-code Bot commented Oct 29, 2026

Copy link
Copy Markdown

CL-11727

@bwachman

Copy link
Copy Markdown
Contributor Author

Self-Review (code-review skill)

The branch carries the following intentional exceptions:

  • src/tui/runner/settings.ts (post-connect picker): after a ChatGPT connect, the reopened picker focuses the picked model only when that model is in the built-in list. A model only the account's live list offers appears once the post-connect refresh lands, without moving focus, and stays out of the picker until restart if that refresh fails; the choice is persisted, so the next start recovers. Today the live list matches the built-in list. Authorized by Greybeard on grounds of cost against impact: the fix is seeding the stored profile's catalog from the connect-time fetch, which needs a new write path on the shared bounded catalog for a transient double-fault case.
  • src/tui/provider/discovery.ts (connect model step): the sign-in result type does not let the compiler prove its tokens are ChatGPT tokens; the call type-checks structurally, as the existing sign-in scope check does. Accepted by the operator.
  • src/provider/codex-model-catalog.ts (discoverStagedCodexModels): if staged sign-in tokens expire during a long idle and the operator re-enters the model step and submits at once, the catalog fetch and the submit-time scope check can both refresh the same staged token. Accepted by the operator.

The ChatGPT picker offered a built-in list that went stale as OpenAI
added models and retired others for ChatGPT sign-in, so a fresh login
could default to a model its account no longer serves. The backend
returns no models to client_version 0.50.0, so requests now send the
current Codex CLI version, including the sign-in scope check.
@bwachman
bwachman force-pushed the cl-11727-restore-the-live-codex-model-catalog-fetch-for-chatgpt branch from 9ca662d to a5f74c3 Compare October 29, 2026 18:49
@bwachman
bwachman changed the base branch from main to cl-11727-prepare-bounded-catalogs-for-the-live-chatgpt-catalog October 29, 2026 18:49
@bwachman

Copy link
Copy Markdown
Contributor Author

Stack merge order: #1580 → #1581 → #1579. This repo keeps merged branches, so GitHub does not retarget the next PR on its own:

  1. After fix(auth): offer only the models ChatGPT sign-in still serves #1580 merges: gh pr edit 1581 --base main
  2. After refactor(provider): prepare live model catalogs for per-account lists #1581 merges: gh pr edit 1579 --base main

TheGreatAxios

This comment was marked as duplicate.

@TheGreatAxios TheGreatAxios left a comment •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review · Request changes

A ChatGPT profile fetches the models that account can use and shows those in the picker. The first one is the default. A failed fetch is supposed to keep the last good list, or the built-in list if there has never been one.

  • The fetched list is saved under the account id from the first token read (src/provider/codex-model-catalog.ts:119). If that read fails, the list is saved under "no account." The fetch then reads the token again, succeeds, and learns the real account id. The picker looks the list up under that new id, finds nothing, and shows the built-in models instead of the ones just fetched. The comment on that function says the second read fails the same way. It does not. A temporary test of this sequence failed and was removed. Save the list under the account id the successful fetch used. Startup only fetches once, so the picker stays on the built-in list until something fetches again.

  • Two logins that have no account id share one saved list. Switch accounts and have the new fetch fail or come back empty, and the picker still shows the previous account's models, while the request uses the new account's token. Logins that both have account ids do not share a list.

  • The models shown while connecting are not saved. That fetch builds a throwaway list (src/provider/codex-model-catalog.ts:140). If the fetch after connect then fails, the fallback is the built-in list, not the models just shown.

@corbits-triage

corbits-triage Bot commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

Triage: Fail

Asking a maintainer about:

  • changes sensitive paths: auth: src/auth/codex/constants.ts, auth: src/auth/oauth-scope-check.ts

Notes:

  • added code matches a code pattern: src/provider/codex-model-catalog.ts:119 Promise chain; use async/await with try/catch., src/tui/provider/discovery.ts:228 Promise chain; use async/await with try/catch., src/tui/runner/settings.ts:389 Immediately invoked function; name the function., src/tui/runner/settings.ts:389 Promise chain; use async/await with try/catch.

Triage will label.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants