Summary
app-server snapshots a configured model_catalog_json when it starts. Replacing
the referenced catalog file while the server is running does not affect later
model/list responses, even after a config/batchWrite request with
reloadUserConfig: true.
This prevents a long-running CLI or Desktop app from advertising a managed live
catalog whose models may be added or removed over time.
Reproduction
-
Configure a local catalog:
model_catalog_json = "/absolute/path/to/models.json"
-
Start app-server.
-
Call model/list; observe a visible model named custom-before.
-
Rewrite the same catalog path so it contains only custom-after.
-
Call model/list again in the same app-server process.
Current result: the second response still contains custom-before.
Expected result: the second response contains custom-after, so reopening a model
picker reflects additions and removals without restarting the host application.
I reproduced this against the Codex Desktop bundled app-server
0.146.0-alpha.3. The process loaded a 30-model custom catalog successfully at
startup, but neither rewriting the file nor requesting a user-config reload changed
membership in a later model/list response.
Root cause
model_catalog_json is parsed into Config.model_catalog, then the
ThreadManager's model manager retains that startup snapshot.
CatalogRequestProcessor::model_list delegates to
thread_manager.list_models(...) without loading the latest effective config, so
the custom catalog file is not revisited.
Proposed behavior
For each model/list request:
- load the latest effective config for the current cwd;
- when
model_catalog_json is configured, construct a temporary
StaticModelsManager from the newly loaded catalog;
- otherwise preserve the existing
ThreadManager online/remote catalog behavior.
This keeps the change limited to explicitly configured custom catalogs and avoids
altering ChatGPT remote-catalog refresh semantics.
Tested implementation
A focused implementation and regression test are available here:
https://github.com/Ajnunezg/codex/tree/agent/reload-custom-model-catalog
The regression test starts one app-server, calls model/list, rewrites the catalog
from custom-before to custom-after, and verifies the next model/list response
uses the new model.
Validation on current openai/codex:main:
cargo fmt --all --check
cargo test -p codex-app-server --test all suite::v2::model_list -- --nocapture
6 passed; 0 failed
Related but distinct issues
This report is only about refreshing an already supported local
model_catalog_json in a running app-server.
Would the maintainers accept this behavior and invite a PR for the tested branch?
Summary
app-serversnapshots a configuredmodel_catalog_jsonwhen it starts. Replacingthe referenced catalog file while the server is running does not affect later
model/listresponses, even after aconfig/batchWriterequest withreloadUserConfig: true.This prevents a long-running CLI or Desktop app from advertising a managed live
catalog whose models may be added or removed over time.
Reproduction
Configure a local catalog:
Start
app-server.Call
model/list; observe a visible model namedcustom-before.Rewrite the same catalog path so it contains only
custom-after.Call
model/listagain in the same app-server process.Current result: the second response still contains
custom-before.Expected result: the second response contains
custom-after, so reopening a modelpicker reflects additions and removals without restarting the host application.
I reproduced this against the Codex Desktop bundled app-server
0.146.0-alpha.3. The process loaded a 30-model custom catalog successfully atstartup, but neither rewriting the file nor requesting a user-config reload changed
membership in a later
model/listresponse.Root cause
model_catalog_jsonis parsed intoConfig.model_catalog, then theThreadManager's model manager retains that startup snapshot.CatalogRequestProcessor::model_listdelegates tothread_manager.list_models(...)without loading the latest effective config, sothe custom catalog file is not revisited.
Proposed behavior
For each
model/listrequest:model_catalog_jsonis configured, construct a temporaryStaticModelsManagerfrom the newly loaded catalog;ThreadManageronline/remote catalog behavior.This keeps the change limited to explicitly configured custom catalogs and avoids
altering ChatGPT remote-catalog refresh semantics.
Tested implementation
A focused implementation and regression test are available here:
https://github.com/Ajnunezg/codex/tree/agent/reload-custom-model-catalog
The regression test starts one app-server, calls
model/list, rewrites the catalogfrom
custom-beforetocustom-after, and verifies the nextmodel/listresponseuses the new model.
Validation on current
openai/codex:main:Related but distinct issues
model/list.This report is only about refreshing an already supported local
model_catalog_jsonin a running app-server.Would the maintainers accept this behavior and invite a PR for the tested branch?