Skip to content

app-server model/list caches model_catalog_json until restart #35129

Description

@Ajnunezg

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

  1. Configure a local catalog:

    model_catalog_json = "/absolute/path/to/models.json"
  2. Start app-server.

  3. Call model/list; observe a visible model named custom-before.

  4. Rewrite the same catalog path so it contains only custom-after.

  5. 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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    app-serverIssues involving app server protocol or interfacesbugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions