Skip to content

[stack 2/8] feat: expand providers and make native model discovery account-aware - #305

Draft
OnlineChef (ChefGroep) wants to merge 39 commits into
stack/20261005-01-prompt-cachefrom
stack/20261005-02-providers
Draft

OnlineChef (ChefGroep) wants to merge 39 commits into
stack/20261005-01-prompt-cachefrom
stack/20261005-02-providers

Conversation

@ChefGroep

@ChefGroep OnlineChef (ChefGroep) commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

Stacked re-landing of #297 (feat/providers-account-cli-20261003). Position 2/8; base: stack/20261005-01-prompt-cache. Merge bottom-up; each layer is a real merge of the original PR head, so the diff shows only that PR plus any conflict resolution (noted in the merge commit message).

Stack

# Layer Original
1/8 #304 feat: make prompt cache behavior measurable #296
2/8 #305 feat: expand providers and make native model discovery account-aware #297
3/8 #306 feat(gui): start auth-inspired OpenCodex redesign #299
4/8 #307 feat(trace): opt-in trace store linked to usage.jsonl #298
5/8 #308 feat(trace): add safe local trace reader #300
6/8 #309 feat(trace): cover compact and response-cache hits #301
7/8 #310 feat(trace): cover Responses WebSocket turns #302
8/8 #311 feat(trace): cover live call-create HTTP #303

Original description:

Summary

  • Fetch the native Codex model catalog with the account OpenCodex can actually use, without rewriting ~/.codex/auth.json.
  • Prefer an explicitly selected pool account, fall back from a dead physical main login to healthy pool credentials, and preserve the existing snapshot when live discovery cannot complete.
  • Serve the same live native catalog through OCX's real GET /v1/models?client_version=... Codex client route, preserving authoritative context/reasoning metadata for newly rolled-out models.
  • Admit authoritative native slugs returned by the current Codex catalog so new OpenAI model rollouts do not require a static OpenCodex whitelist release.
  • Make native Codex + OpenCodex coexistence an enforced invariant: loopback keeps the built-in openai identity and normal ChatGPT/Codex login, while OCX owns the proxy transport plus one canonical merged $CODEX_HOME/opencodex-catalog.json.
  • Replace competing root model_catalog_json pointers while OCX owns routing, restore the pre-OCX value through the existing journal on stop/eject, and fail back to native Codex metadata when the managed catalog omits the selected native GPT/Codex model.
  • Preserve live native capability metadata including context window, reasoning ladder, search/deferred-tool support, tool mode, Responses-lite, modalities, and visibility.
  • Add first-class OpenAI-compatible presets for Cohere, FriendliAI, SambaNova, Nebius AI Studio, and Novita AI.
  • Align the free-provider directory with the promoted Cohere and Nebius endpoints.

Root cause

There were two coupled sources of native-model metadata drift.

First, activeCodexAccountId controls OpenCodex pool routing, but the physical Codex main credential remains ~/.codex/auth.json. Native catalog refresh could therefore stay pinned to a stale Desktop login even while another pool account was healthy. Current Codex model discovery only needs the account Bearer token plus ChatGPT-Account-ID for GET /backend-api/codex/models?client_version=...; this PR uses that request contract directly instead of copying pool credentials into Codex's native auth store.

Second, config injection previously preserved an arbitrary pre-existing root model_catalog_json while OCX simultaneously owned the active transport. That created split authority: a parallel or stale merged catalog could omit a newly rolled-out native model even though the normal ChatGPT/Codex account could serve it. Codex then synthesized generic fallback model metadata for the selected slug. Besides reporting the wrong context window, generic fallback can also lose native tool/search capability metadata and change direct-vs-deferred tool exposure.

The corrected ownership model is native-first and additive. On loopback, Codex keeps its built-in openai provider identity, normal ChatGPT/Codex authentication, and native thread identity. OCX owns only the managed proxy transport plus the canonical merged $CODEX_HOME/opencodex-catalog.json while routing is active. Bare native rows in that catalog come from authoritative account/client discovery; routed providers remain namespaced additions.

If the managed catalog does not contain the currently selected bare native GPT/Codex model, OCX deliberately leaves model_catalog_json unset so Codex can use its native model metadata instead of silently entering generic fallback. User-owned external providers and unmarked root openai_base_url values remain ownership boundaries and are left untouched.

Safety boundaries

  • No mutation or credential copying into ~/.codex/auth.json.
  • Live catalog JSON is bounded and validated at the external boundary before it enters catalog assembly.
  • Account fallbacks share one request deadline, so configured pool size cannot multiply an upstream stall.
  • codexAccountPools: false remains a hard standalone boundary: pool credentials are not consulted.
  • Upstream HTTP, body-read, invalid-shape, or auth failures degrade through the existing fallback path, but a selected native model missing from the managed catalog forces native Codex catalog ownership instead of generic model fallback.
  • Pre-OCX config, including an earlier catalog pointer, remains journaled for reversible stop/eject restore.
  • User-owned external model_provider and root openai_base_url values are atomic ownership boundaries; OCX does not half-manage only their catalog.
  • Existing catalog callers retain behavior through defaulted appended parameters.
  • Authoritative live native rows keep upstream context/tool/search/Responses-lite/reasoning metadata; OCX does not synthesize or downgrade those fields on newly rolled-out models.

Coverage

Regression coverage includes selected-pool preference, dead-main fallback, one shared fallback deadline, safe degradation on response-body failure, account-pool opt-out, authoritative new native slugs, live metadata preservation in the catalog builder, preservation of deferred/search-tool capability fields, replacement of competing root catalog pointers, native fallback when the selected native model is absent from the managed catalog, atomic user-owned routing boundaries, registry/free-tier parity, and a hermetic end-to-end server test that proves /v1/models?client_version=9.9.9 forwards the exact client version and account headers while returning the live native row.

Non-goals

This PR does not swap Codex Desktop/app-server login state, rewrite the native auth file, or fold the larger Codex/app-server lifecycle decoupling into the provider/catalog change.

The proxy already runs independently as its own service. Remaining Codex coupling is primarily lifecycle/integration: config/catalog injection and stale long-lived codex app-server consumers after disk catalog changes. Remote CLI endpoint/profile orchestration should be a separate PR built on the existing shared runtimeRequest(baseUrl) management client.

@coderabbitai

coderabbitai Bot commented Oct 4, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

This branch has not been deployed

No deployments
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.

1 participant