feat: accept max and ultra reasoning efforts - #616
Open
t-sato wants to merge 1 commit into
Open
Conversation
`--effort max` and `--effort ultra` were rejected by the companion even
though Codex supports both. GPT-5.6 models advertise them as reasoning
levels, so the plugin was the only thing blocking them:
$ codex debug models
gpt-5.6-sol efforts=[low,medium,high,xhigh,max,ultra]
gpt-5.6-terra efforts=[low,medium,high,xhigh,max,ultra]
gpt-5.6-luna efforts=[low,medium,high,xhigh,max]
gpt-5.5 efforts=[low,medium,high,xhigh]
Codex's own docs string agrees: "GPT-5.6 supports none, low, medium,
high, xhigh, and max."
The app-server protocol does not model effort as a closed enum. In the
generated types, `TurnStartParams.effort` is a `ReasoningEffort`, and
`ReasoningEffort` is `string` — Codex validates the value against the
reasoning levels the selected model advertises. Because the companion
kept its own hardcoded list, it fell behind: it still accepts `none`
and `minimal`, which no model in the current catalog advertises, while
rejecting `max` and `ultra`, which the current models do.
Verified end to end against a real Codex run:
$ node codex-companion.mjs task --model gpt-5.6-luna --effort max \
"Reply with exactly: OK"
[codex] Turn completed.
OK
Per-model validation stays with Codex, which is where the model catalog
lives; the companion only rejects values Codex has no variant for.
This was referenced Aug 11, 2026
|
@dkundel-openai duplicate PRs has been getting closed. When do we expect current PR to be reviewed, merged, and release created? |
t-sato
added a commit
to t-sato/codex-plugin-cc
that referenced
this pull request
Aug 14, 2026
Fork-only release marker so Claude Code picks up the max/ultra reasoning effort change. The upstream PR (openai#616) deliberately omits this bump, since upstream bumps versions in its own commits.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
--effort maxand--effort ultraare rejected by the companion even though Codex supports both:VALID_REASONING_EFFORTSinplugins/codex/scripts/codex-companion.mjshas been a hardcoded list since the initial commit and has drifted from Codex. This PR addsmaxandultrato it, and updates the usage string, error message,argument-hint, runtime skill, README, and tests to match.Why these values are valid
1. The models advertise them. From
codex debug models(codex-cli 0.146.1):gpt-5.6-solgpt-5.6-terragpt-5.6-lunagpt-5.5gpt-5.4,gpt-5.4-minigpt-5.3-codex-sparkCodex's own instructions agree: "GPT-5.6 supports
none,low,medium,high,xhigh, andmax. If omitted, GPT-5.6 defaults tomedium."2. The app-server protocol does not model effort as a closed enum. From
codex app-server generate-ts:Effort is an open string, and Codex validates it against the reasoning levels the selected model advertises. A hardcoded allowlist in the plugin is therefore guaranteed to fall behind — and it already has, in both directions: it still accepts
noneandminimal, which no model in the current catalog advertises, while rejectingmaxandultra, which the current models do.3. Verified end to end against a real Codex run through the app-server path this plugin uses:
Note on #99
#99 (closing #77) changed the README example from
model_reasoning_effort = "xhigh"to"high"on the grounds thatxhighwas unsupported.xhighis in fact advertised by every model in the catalog above, including thegpt-5.4generation current at the time. That change is unrelated to this PR's diff, but it's the same root cause: the effort list has never tracked upstream. Happy to send a follow-up restoring that example if you'd like.Design choice
Per-model validation stays with Codex, which is where the model catalog lives. The companion's list only rejects values Codex has no variant for at all, so
--effort ultraon a model that does not advertiseultrais Codex's error to raise, not the plugin's.If you'd prefer the stricter version, I can narrow this to
maxonly and dropultra. If you'd prefer the looser one, dropping the allowlist entirely and forwarding any non-empty string is the option that matches the protocol's own design most closely — say the word and I'll rework it.Tests
Added to
tests/runtime.test.mjs:maxandultraare forwarded to app-serverturn/start(table-driven over both values)Updated the
--effortassertions intests/commands.test.mjs.npm testfrom a clean state: 90 pass, 4 fail. The 4 failures (resolveStateDir uses a temp-backed per-workspace directory,status shows phases, hints, and the latest finished job,status preserves adversarial review kind labels,result returns the stored output for the latest finished job by default) reproduce identically onmainwith this branch stashed, so they are pre-existing on my machine and not introduced here. Two contributing factors I found while bisecting, in case they're useful:setup/status/resulttests run withcwd: ROOTand leave plugin state (broker.json,jobs/) in the repository's own state directory. A secondnpm testrun in the same checkout then sees a registered shared runtime, and fivesetuptests flip toready: true. Deleting the state directory restores them.resolveStateDir uses a temp-backed per-workspace directoryfails wheneverCLAUDE_PLUGIN_DATAis set in the environment, which it is when the suite is run from inside Claude Code with this plugin installed. It passes underenv -u CLAUDE_PLUGIN_DATA.Both are out of scope here; I can open separate issues.