Support model providers in the app-server model/list API

Open 💬 1 comment Opened Aug 18, 2026 by marmeladema

What variant of Codex are you using?

app-server API through my Giskard web frontend

What feature would you like to see?

Problem

The app-server model/list API currently lists models only for the configured
default provider. Unlike thread/start, clients cannot select a model provider.

This makes it difficult for clients to present models for another configured
provider before starting a thread.

Proposed behavior

Add an optional modelProvider parameter to model/list:

{
  "modelProvider": "amazon-bedrock",
  "limit": 100,
  "cursor": null,
  "includeHidden": false
}

When omitted, model/list should continue using the configured default provider.

The response should also identify the provider associated with the returned
catalog. Two possible shapes are:

  1. Add modelProvider to every model, allowing future mixed-provider responses.
  2. Add modelProvider to ModelListResponse, establishing that one response

always contains models from exactly one provider.

The response-level field may be preferable because the request resolves exactly
one provider and avoids repeating identical metadata:

{
  "modelProvider": "amazon-bedrock",
  "data": [
    {
      "id": "openai.gpt-5.6-sol",
      "model": "openai.gpt-5.6-sol"
    }
  ],
  "nextCursor": null
}

Listing models from all providers could be considered separately. That design
would need explicit rules for ordering, pagination, per-provider defaults,
latency, and partial failures.

Implementation considerations

  • Unknown provider IDs should return an invalid-request error.
  • Provider resolution should use the latest effective configuration.
  • Pagination cursors should remain scoped to the selected provider.
  • Provider-specific model managers should be reused in memory.
  • Alternate providers should not share the current file-backed model cache,

because that cache is not partitioned by provider.

Reference implementation

I explored an implementation on my fork:

https://github.com/marmeladema/codex/tree/model-list-provider-support

The reference implementation uses the per-model modelProvider shape. It also
includes generated API schemas, documentation, and integration coverage for
explicit provider selection, default-provider fallback, and unknown providers.

I understand that external pull requests are not accepted; the fork is provided
only as technical exploration and a concrete reference for the design.

Additional information

_No response_

View original on GitHub ↗

1 Comment

marmeladema · 8 days ago

Three things worth folding in.

1. It's a correctness bug, not just listing. Turn metadata resolves from the
single ThreadManagerState.models_manager:

  • core/src/thread_manager.rs:1858Session::spawn is handed

Arc::clone(&self.models_manager), even though the config in that same
struct literal already carries the thread's resolved model_provider.

  • core/src/session/mod.rs:645 and core/src/session/turn_context.rs:338 both

call get_model_info on it.

So a thread started with a non-default modelProvider looks its model up in the
root provider's catalog, misses, and degrades silently:
Model metadata for <slug> not found. Defaulting to fallback metadata
conservative context window, generic effort ladder. Resolving that manager from
the registry this issue already proposes, keyed on the session's provider, fixes
it. Same registry, one more caller.

2. A shared remote_models is a collision, not just a limitation. In
apply_remote_models, should_use_remote_models_only is true whenever the auth
mode has a ChatGPT account and the fetched list has a visible model — and it
replaces remote_models outright rather than merging. With one shared list the
last provider to refresh wins and the other provider's models disappear.
Per-provider managers make that impossible rather than merely unlikely.

3. The cache point is already acknowledged in-tree
models-manager/src/manager.rs:

// TODO(celia-oai): Include provider identity in cache eligibility so switching
// providers does not reuse a fresh models_cache.json entry from another provider.