`VALID_REASONING_EFFORTS` rejects `max` and `ultra` locally, so the flagship model's top two reasoning tiers are unreachable from the plugin

Author: rjredelmCreated Sep 8, 2026Updated Sep 12, 2026

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):

javascript
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 modelssupported_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 codex v1.0.6 (db52e28f4d9ded852ab3942cea316258ae4ef346)
  • codex-cli 0.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).