fix(codex-native): bridge provider config into the model-probe home - #6249
Conversation
The codex catalog probe built its CODEX_HOME by hand and materialized only auth.json, never config.toml. A launch shape resolved off the user's own ~/.codex/config.toml pins just the provider name (-c model_provider="X"), while the [model_providers.X] tables live in that config file, so codex was told to route through a provider the probe home could not see: Error: error loading default config after config error: Model provider `Databricks` not found It exits 1 before binding the listener, so every probe raised "Codex model discovery exited early (1)" and the pre-launch picker offered zero models (host/connect.py keeps no curated fallback). Call the same bridge a session launch uses, in its minimal shape, which copies only model_provider/model_providers/profiles and skips hooks, instructions and plugin dirs so no MCPs start for a probe. That also fixes the credential: the hand-rolled version linked only auth.json, while the bridge covers .credentials.json too, so a home using that spelling no longer probes as logged out. The copied config is unlinked first because the bridge skips existing files and the probe home is persistent. Closes omnigent-ai#6248 Signed-off-by: Dhruv Gupta <dhruv0811@gmail.com>
|
/review |
|
|
🏷️ Doc impact: Internal change to how the Codex model-probe home is materialized (provider tables plus credential) with added tests; no user-facing surface, integration, or documented default changed. Auto-classified on merge. Set the label manually before merging to override. · run |
|
/review |
|
Related issue
Closes #6248
Summary
The codex-native model catalog probe built its
CODEX_HOMEby hand andmaterialized only
auth.json, neverconfig.toml. When a host's codex routingcomes from the user's own
~/.codex/config.toml, ambient detection pins just theprovider name (
-c model_provider="Databricks") while the[model_providers.Databricks]tables live in that config file, which the probehome never received. Codex refuses to load a config naming a provider it cannot
see and exits 1 before binding its listener, so every probe raised
Codex model discovery exited early (1)and the pre-launch picker offered zeromodels (
host/connect.pydeliberately keeps no curated fallback)._probe_codex_homenow calls the same bridge a session launch uses(
_populate_codex_home_config(..., minimal_config=True)) instead ofre-implementing a subset of it.
minimal_configalready exists for this shape:it copies only
model_provider/model_providers/profilesand skipshooks,
AGENTS.mdand plugin dirs, so a probe still starts no MCPs. It isalready used by
runner/background_titles/codex_native.pyfor the same reason.auth.json, while_CODEX_HOME_SYMLINK_FILESalso covers.credentials.json. A home storing the credential under that spelling wasprobing as logged out, so login-gated entries and the account default were
wrong even when the probe did boot.
files that already exist and the probe home is deliberately persistent (codex's
models_cache.jsonETag reuse). Without that, the tables copied on first usewould be pinned forever and later edits to
~/.codex/config.tomlignored. Thesame applies to the credential: the home is keyed only by the overrides, so a
source home that moves under an unchanged override set would leave the symlink
naming the old path, and a removed source would leave it dangling. A dangling
link reads as present to the bridge's skip check, so such a home could never
self-heal and every later probe would answer for a logged-out account.
ELI5: the probe was handed the name of a door but not the door. Now it gets the
same keyring the real session launch gets, minus the noisy extras.
Test Plan
Unit, on the failing path:
3 passed. Both halves of the new test are confirmed to catch their regression by
reverting only
codex_native_app_server.py:FileNotFoundError: .../codex-model-probe/<key>/config.toml;config.tomlalone fails the credentialassertion, with the symlink still resolving into the old
.codexwhile theconfig came from
moved-codex.Live, against a real
~/.codex/config.tomlusing a Databricks gateway provider(the configuration that reproduced the bug), with the probe cache cleared first:
A second, warm-home probe returns the same 5 models, with the credential
correctly relinked. The same command before the fix raised
RuntimeError: Codex model discovery exited early (1). Inspected the materialized home to confirm theminimal shape held:
model_providerspresent (3 hits),mcp_serversabsent (0 hits), nohooks.json, credential symlinked to the real~/.codex/.credentials.json.Demo
Type of change
Test coverage
Coverage notes
The unit test drives
_probe_codex_homeagainst a fake source home and assertsthe three properties the bug turned on: the provider tables are present, the
credential is symlinked, and a persistent home re-reads an edited source config
rather than pinning the first copy. It also asserts the minimal shape (no
mcp_servers, nohooks.json) so a future widening to a full config copy doesnot silently make probes start the user's MCP servers.
Manual verification covers what a unit test cannot: that the real
codexbinary actually boots and returns a catalog under this materialization. The
failure mode was a subprocess exiting on its own config validation, so the fix
is only meaningful against a real CLI and a real provider config.
Changelog
The codex model picker now lists models when your codex routing comes from a custom provider in
~/.codex/config.toml, instead of coming up empty.