Model selector not available with custom LLM provider

Open 💬 7 comments Opened Mar 19, 2026 by ameent
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

What version of the Codex App are you using (From “About Codex” dialog)?

Version 26.317.21539 (1088)

What subscription do you have?

Pro, but I'm using this through 3rd party provider

What platform is your computer?

Darwin 25.3.0 arm64 arm

What issue are you seeing?

The model selector does not appear in the desktop app, even though it correctly appears in the CLI. Interestingly, the Automations tab of the desktop app, does correctly show the model and reasoning level selector, yet the main threads and conversations do not.

I've tried the following without any luck:

  • Not pinning any specific models in the configuration
  • Using a custom model_catalog.json which is a copy of what ships with codex out of the box, but switched to it refers to models from my own provider

What steps can reproduce the bug?

Use the attached config file:

personality = "pragmatic"
approval_policy = "never"
sandbox_mode = "danger-full-access"
model_provider = "oca"
web_search = "live"
preferred_auth_method = "apikey"
forced_login_methad = "api"
trust_level = "trusted"
# model = "gpt-5.4"
# model_reasoning_effort = "medium"
model_catalog_json = "/Users/core/.codex/model_catalog.json"
model = "oca/gpt-5.4"
model_reasoning_effort = "xhigh"
# model = "oca/gpt-5.4"
# model_reasoning_effort = "xhigh"

[model_providers.oca]
base_url = "https://code-internal.aiservice.us-chicago-1.oci.oraclecloud.com/20250206/app/litellm"
http_headers = { "client" = "codex-cli", "client-version" = "0" }
name = "Oracle Code Assist"
wire_api = "responses"

[projects."/Users/core"]
trust_level = "trusted"

[features]
multi_agent = true

[notice.model_migrations]
"gpt-5.3-codex" = "gpt-5.4"

You can remove the default models specified in the top of the config, and the outcome is the same. You can also remove the model_catalog_json as well, and still the model selector does not appear. I'll attach my model catalog_json as well.

What is the expected behavior?

I expect that I'll see the model selector in the GUI and that I'm able to switch between available models, and various reasoning efforts per given thread and conversation, exactly how I can do so in the CLI.

Additional information

_No response_

View original on GitHub ↗

7 Comments

ameent · 4 months ago

<img width="800" height="217" alt="Image" src="https://github.com/user-attachments/assets/5edff2ec-66b7-4ba3-b8d0-ecd50b002d12" />

Here's how the GUI looks (note no model selector is available)

github-actions[bot] contributor · 4 months ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #14008

Powered by Codex Action

rnett · 2 months ago

This applies to the CLI too.

ryoreonhz-dev · 1 month ago

also reproducible with Moon Bridge + DeepSeek

Astro-Han · 1 month ago

The most useful clue here is the asymmetry you already found: the Automations tab shows the picker but the main thread does not, in the same app build, with the same catalog. That rules out your catalog file and your provider auth as the cause. Both surfaces can see the models, so something gates the main-thread picker specifically.

Two things to check to narrow it down:

  • The Automations picker and the conversation picker are almost certainly fed by different model lists. The conversation one looks like it goes through a server-pushed allowlist (the desktop app pulls a Statsig dynamic config into Local Storage with an available_models array and a default_model; see #14008 for the same config blob). For a custom model_provider, that allowlist comes back empty, so the picker has nothing to render and hides itself. The Automations tab reads the catalog directly, which is why it still works. You can confirm by opening the app's Local Storage in DevTools and looking for that config.
  • Your model = "oca/gpt-5.4" is provider-prefixed. The CLI resolves provider/model fine, but the app's main-thread selector may match that string against the (empty) server list and fall back to nothing instead of to your catalog. Try a bare model = "gpt-5.4" with model_provider = "oca" and see if the picker behaves differently, even if it doesn't fix the disappearance.

So this points at the app filtering the conversation model list through an OpenAI-account-scoped source that custom providers never populate, rather than a config mistake on your end.

This is a recurring gap in BYOK desktop setups where the GUI assumes the first-party model list. We ran into the same thing on PawWork (an opencode fork, https://github.com/Astro-Han/pawwork) and ended up driving the in-conversation model/provider switcher straight off the provider config and catalog, with no separate server allowlist, so a custom provider's models land in the picker the same way the first-party ones do. Different codebase, but the fix is the same shape: the conversation picker should read from the same source the CLI and the Automations tab already use.

steveepreston · 1 month ago

Huge +1

Rafik-Belkadi-Reccap · 1 month ago

Same