Description
Summary
normalizeReasoningEffort() rejects max and ultra before the CLI is ever invoked, so
the top two reasoning tiers of the current flagship model are unreachable from the plugin.
scripts/codex-companion.mjs:71 (v1.0.6):
const VALID_REASONING_EFFORTS = new Set(["none", "minimal", "low", "medium", "high", "xhigh"]);#485 notes the --effort hint omits these values and files it as cosmetic. The hint is
the smaller half: this Set is a hard gate, and it fails the request locally with no API
call, so raising it is a functional fix rather than a docs one.
Current levels
From codex debug models → supported_reasoning_levels, listed models only:
| model | supported reasoning levels |
|---|---|
gpt-6-astra |
low, medium, high, xhigh, max, ultra |
gpt-5.6-sol |
low, medium, high, xhigh, max, ultra |
gpt-5.6-terra |
low, medium, high, xhigh, max, ultra |
gpt-5.6-luna |
low, medium, high, xhigh, max |
gpt-5.5 |
low, medium, high, xhigh |
gpt-5.4-mini |
low, medium, high, xhigh |
ultra is described in the catalog as "Maximum reasoning with automatic task delegation"
— a distinct capability, and the flagship's headline mode, not just one more notch.
Repro
$ node scripts/codex-companion.mjs task --model gpt-6-astra --effort ultra "Reply with the single word: ok"
Unsupported reasoning effort "ultra". Use one of: none, minimal, low, medium, high, xhigh.
exit 1
Verified after widening the Set
Adding max and ultra to VALID_REASONING_EFFORTS (no other change), values read from
the session rollout JSONL rather than exit codes:
| invocation | recorded model |
recorded reasoning_effort |
result |
|---|---|---|---|
--model gpt-6-astra --effort ultra |
gpt-6-astra |
ultra |
exit 0, ~6 s, 17,210 tokens, no error lines |
--model gpt-5.6-luna --effort max |
gpt-5.6-luna |
max |
exit 0 |
--model gpt-5.6-luna --effort ultra |
gpt-5.6-luna |
ultra |
exit 0 |
The gate still discriminates after widening: --effort bogus is rejected locally, exit 1,
no API call.
Two things worth a maintainer's eye
1. Per-model effort validity is not enforced on this path. Row 3 is ultra on
gpt-5.6-luna, whose catalog entry stops at max. It was accepted and recorded rather
than rejected. If per-model validity is meant to hold, nothing on this path enforces it.
(The rollout shows the request carried ultra; it does not show whether the server
clamped it.)
2. none and minimal are accepted by the plugin but appear in no listed model's
supported_reasoning_levels. Same drift, opposite direction — possibly legacy values
worth pruning in the same pass.
Suggested fix
Immediate: add max and ultra to VALID_REASONING_EFFORTS, and update the three places
that spell the list out — the usage string (scripts/codex-companion.mjs:82), the error
text (:124), commands/rescue.md:3, and skills/codex-cli-runtime/SKILL.md:35.
Better: derive the set from codex debug models, cached with a static fallback. This Set
and MODEL_ALIASES (see #687) are both hardcoded copies of vocabularies the CLI already
resolves at runtime, and both have now drifted behind it. A plugin release currently pins
a model vocabulary that the API can invalidate at any time, and the user sees either a 400
or a local rejection naming values that are no longer the real set.
Environment
- Plugin
codexv1.0.6 (db52e28f4d9ded852ab3942cea316258ae4ef346) codex-cli0.153.4- macOS 25.6.0 (arm64), Node v24.15.0, ChatGPT sign-in
Related: #485 (hint omission, filed as cosmetic), #687 (the MODEL_ALIASES half of the
same drift), #476 / #651 (--effort task-vs-review asymmetry).
Activity
aleozlx commentedon Sep 12, 2026
Independent confirmation on Windows, plus a data point that complicates the suggested fix:
for one model there are three disagreeing vocabularies, and the catalog is not a superset
of the API's.
Hitting your point 2 from the other side —
--effort minimalpasses the plugin's local gateand is then rejected by the API:
Lining that server message up against the other two sources, all for
gpt-5.6-terra:VALID_REASONING_EFFORTS(plugin)codex debug models(catalog)No two agree, and every value is contested by something:
minimal— plugin only. Rejected by the API, as above.none— plugin and API, absent from the catalog.max— catalog and API, blocked by the plugin. This issue.ultra— catalog only. The API's error text does not list it for this model, yet yourtable shows
ultracompleting ongpt-6-astraandgpt-5.6-luna.The last two rows are the ones I would flag for the "derive it from
codex debug models"plan. Deriving strictly from the catalog would drop
none, which the API names as supported,and would offer
ultra, which the API's own enumeration for this model omits even though itdemonstrably runs. So the error text is not a reliable enumeration either — it is a third
approximation rather than the authority, and a derived Set would trade one drift for another.
That is an argument for the immediate half of your fix over the clever half: widening the Set
is a straightforward correctness win, whereas picking a single authoritative source needs one
that is actually authoritative, and none of these three is. The gate may be better as a
typo-catcher that rejects unknown shapes while letting the API arbitrate per-model validity,
since it already cannot enforce that (your point 1).
Environment
Windows 11 (26200), plugin
codexv1.0.5,codex-cli0.153.4, Node v24.19.0, ChatGPTsign-in,
model = "gpt-5.6-terra"pinned in~/.codex/config.tomlby the Codex desktop app.Tangential, since this was my trigger too: when that 400 comes back,
statusreports thewhole reason as
Summary: {. Filed separately as #757 — unrelated to the vocabulary, but itis why the rejection took a while to see.
wagneripjr commentedon Oct 21, 2026
The three open PRs for this (#616, #637, #761) each add
maxandultratoVALID_REASONING_EFFORTS. That fixes today's symptom but keeps the root cause: a hardcoded copy of a list that Codex already validates server-side, and that varies per model. It will go stale again with the next tier.Proposal: drop the allowlist and let Codex validate.
normalizeReasoningEffortbecomes trim + lowercase,--effortforwards whatever was asked.Unsupported values still fail fast with a clearer, model-aware message. With Codex CLI 0.163.0 on the default model:
Note
ultrais absent there: support genuinely is per-model, so any local list is wrong for some model either way.Implementation with tests (per-effort forwarding incl.
max/ultra/case-normalisation, unset when omitted,--resumeand--backgroundpaths) and help/skill/README updates: wagneripjr@0630113Happy to open it as a PR (minus the version bump) if maintainers prefer this approach over extending the list.
danielkassar commentedon Nov 3, 2026
I can confirm this issue still affects
openai/codex-plugin-ccas of November 3, 2026.Environment:
Reproduction:
Delegating to
gpt-6-lunawith--effort maxfails before Codex is invoked.The installed
codex-companion.mjsonly acceptsnone,minimal,low,medium,high, andxhigh.The Codex CLI configuration supports
max, but the plugin rejects it locally.Update — Local workaround confirmed
I manually extended
VALID_REASONING_EFFORTSin the installedcodex-companion.mjsto includemaxandultra.After applying the change:
gpt-6-lunawith--effort maxcompleted successfully.Hello from Codex. Delegation successful.gpt-6-lunawithreasoning_effort: max.This confirms that the plugin's local validation was the blocker in my environment, rather than Codex lacking support for
max.Note: I verified
max, but have not independently testedultra.The workaround modifies the installed plugin cache and may be overwritten by plugin updates.
It would be helpful to merge an upstream fix, ideally avoiding a hardcoded reasoning-effort allowlist that can become outdated as new models and effort levels are introduced.
Are there plans to merge one of the existing fixes (#616, #637, or #761)?