model_reasoning_effort not forwarded to third-party providers
What version of Codex is running?
codex-cli 0.64.0
What subscription do you have?
gpt-5.1-codex via ZenMux API
Which model were you using?
gpt-5.1-codex
What platform is your computer?
Microsoft Windows NT 10.0.19045.0 x64
What issue are you seeing?
Configured model_reasoning_effort = "high" (and model_reasoning_summary = "auto"). When routing via a custom provider (base_url points to a relay that adds an openai/ prefix to model names), Codex does not forward reasoning controls:
1) Chat wire (POST /v1/chat/completions): Body never contains a top‑level "reasoning_effort" key.
2) Responses wire (POST /v1/responses): "reasoning" becomes null unless the model slug matches specific patterns (appears tied to CONTEXT_WINDOW_272K‑related checks). With the relay’s openai/ prefix, the slug check never matches, so "reasoning" stays null.
Representative (redacted) downstream log (Chat wire):
POST /chat/completions
Headers: { "authorization": "Bearer ****(masked)", "accept": "text/event-stream", ... }
JSON Body:
{
"model": "openai/gpt-5.1-codex",
"messages": [
{"role":"system","content":"..."},
{"role":"user","content":"test"}
]
// No "reasoning_effort" present
}
Code pointer found while investigating:
pub(crate) fn get_model_info(model_family: &ModelFamily) -> Option<ModelInfo> {
let slug = model_family.slug.as_str();
match slug {
// ...
_ if slug.starts_with("gpt-5-codex")
|| slug.starts_with("gpt-5.1-codex")
|| slug.starts_with("gpt-5.1-codex-max") => {
Some(ModelInfo::new(CONTEXT_WINDOW_272K))
}
_ if slug.starts_with("gpt-5") => Some(ModelInfo::new(CONTEXT_WINDOW_272K)),
_ if slug.starts_with("codex-") => Some(ModelInfo::new(CONTEXT_WINDOW_272K)),
_ if slug.starts_with("exp-") => Some(ModelInfo::new(CONTEXT_WINDOW_272K)),
_ => None,
}
}
Observation (correlation, not proof): In our testing, models whose names match the above prefixes tend to produce a non-null "reasoning" in responses mode, while names that do not match (relay prefixes them with openai/…) result in "reasoning": null.
What steps can reproduce the bug?
1) Start a local transparent proxy to print requests and forward to the real third‑party relay (any simple HTTP proxy that dumps JSON is fine).
2) Configure Codex to use a custom provider with that proxy’s base_url.
config.toml (redacted)
model = "openai/gpt-5.1-codex"
model_provider = "my3p"
model_reasoning_effort = "high"
model_reasoning_summary = "auto"
[model_providers.my3p]
name = "ThirdParty"
base_url = "http://127.0.0.1:8787/v1" # points to local proxy
env_key = "THIRDPARTY_API_KEY"
wire_api = "chat" # also test "responses"
3) Run Codex once (any trivial prompt, e.g., “test”).
4) Inspect the proxy logs.
Observed:
- With
wire_api="chat"→ body lacks"reasoning_effort". - With
wire_api="responses"→"reasoning"isnullunless the model slug matches internal patterns; when the relay prefixes model withopenai/…, it never matches, so"reasoning"staysnull.
Note: The relay consistently rewrites the model name to include openai/ (e.g., openai/gpt-5.1-codex).
What is the expected behavior?
- When
model_reasoning_effortis set in config: - Chat wire should include a top‑level
"reasoning_effort": "<low|medium|high|minimal>"in the request body. - Responses wire should include
"reasoning": { "effort": "<…>", "summary": "<auto|…>" }". - Emission of these fields should not depend on model‑name heuristics or context‑window families. Providers that don’t support the field can reject it server‑side.
Additional information
_No response_
4 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
+1 on this issue.
Another use case is when the model name on the deployment doesn't match at all. So maybe we want abstract deployments called
defaultandthink-harderthat happen to map behind the scenes togpt-5.1-codexandgpt-5.1-codex-max, respectively. Ideally, Codex CLI wouldn't need to interrogate my model names to try to guess whether I'm allowed to change things likemodel_reasoning_effortand should instead trust that I know what I'm doing. Furthermore, whengpt-5.2-codexmodels come out, I shouldn't necessarily have to update Codex CLI in order for it to work.I do realize that Codex is interrogating names for good reasons, like deciding which prompts to use. Perhaps there should be a more explicit setting like
model_familythat can be set inconfig.tomlto allow this?This bug report hasn't received any upvotes or additional posts in four months. Closing.
Is there a way to verify if the configured model_reasoning_effort is correctly passed to openrouter. I have configured for example this
In https://openrouter.ai/logs, I see reasoning tokens are being used, but I cannot verify if the model_reasoning_effort is coming in correctly.