From 5fb884f079411ed35139921c71a0b5167621e2ba Mon Sep 17 00:00:00 2001 From: Artem Mikhalev Date: Thu, 23 Jul 2026 15:05:16 +0400 Subject: [PATCH 1/2] feat: support max reasoning effort --- README.md | 2 ++ plugins/codex/commands/rescue.md | 2 +- plugins/codex/scripts/codex-companion.mjs | 6 ++--- .../codex/skills/codex-cli-runtime/SKILL.md | 2 +- tests/commands.test.mjs | 4 +-- tests/runtime.test.mjs | 25 +++++++++++++++++++ 6 files changed, 34 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 937a3037b..32c711984 100644 --- a/README.md +++ b/README.md @@ -146,6 +146,7 @@ Examples: /codex:rescue fix the failing test with the smallest safe patch /codex:rescue --resume apply the top fix from the last run /codex:rescue --model gpt-5.4-mini --effort medium investigate the flaky integration test +/codex:rescue --model gpt-5.6-luna --effort max investigate a complex failure /codex:rescue --model spark fix the issue quickly /codex:rescue --background investigate the regression ``` @@ -159,6 +160,7 @@ Ask Codex to redesign the database connection to be more resilient. **Notes:** - if you do not pass `--model` or `--effort`, Codex chooses its own defaults. +- `max` is accepted for models that advertise support for maximum reasoning effort. - if you say `spark`, the plugin maps that to `gpt-5.3-codex-spark` - follow-up rescue requests can continue the latest Codex task in the repo diff --git a/plugins/codex/commands/rescue.md b/plugins/codex/commands/rescue.md index 56de9555d..c1ea8a7b1 100644 --- a/plugins/codex/commands/rescue.md +++ b/plugins/codex/commands/rescue.md @@ -1,6 +1,6 @@ --- description: Delegate investigation, an explicit fix request, or follow-up rescue work to the Codex rescue subagent -argument-hint: "[--background|--wait] [--resume|--fresh] [--model ] [--effort ] [what Codex should investigate, solve, or continue]" +argument-hint: "[--background|--wait] [--resume|--fresh] [--model ] [--effort ] [what Codex should investigate, solve, or continue]" allowed-tools: Bash(node:*), AskUserQuestion, Agent --- diff --git a/plugins/codex/scripts/codex-companion.mjs b/plugins/codex/scripts/codex-companion.mjs index 83df468ad..d620f11ce 100644 --- a/plugins/codex/scripts/codex-companion.mjs +++ b/plugins/codex/scripts/codex-companion.mjs @@ -68,7 +68,7 @@ const ROOT_DIR = path.resolve(fileURLToPath(new URL("..", import.meta.url))); const REVIEW_SCHEMA = path.join(ROOT_DIR, "schemas", "review-output.schema.json"); const DEFAULT_STATUS_WAIT_TIMEOUT_MS = 240000; const DEFAULT_STATUS_POLL_INTERVAL_MS = 2000; -const VALID_REASONING_EFFORTS = new Set(["none", "minimal", "low", "medium", "high", "xhigh"]); +const VALID_REASONING_EFFORTS = new Set(["none", "minimal", "low", "medium", "high", "xhigh", "max"]); const MODEL_ALIASES = new Map([["spark", "gpt-5.3-codex-spark"]]); const STOP_REVIEW_TASK_MARKER = "Run a stop-gate review of the previous Claude turn."; @@ -79,7 +79,7 @@ function printUsage() { " node scripts/codex-companion.mjs setup [--enable-review-gate|--disable-review-gate] [--json]", " node scripts/codex-companion.mjs review [--wait|--background] [--base ] [--scope ]", " node scripts/codex-companion.mjs adversarial-review [--wait|--background] [--base ] [--scope ] [focus text]", - " node scripts/codex-companion.mjs task [--background] [--write] [--resume-last|--resume|--fresh] [--model ] [--effort ] [prompt]", + " node scripts/codex-companion.mjs task [--background] [--write] [--resume-last|--resume|--fresh] [--model ] [--effort ] [prompt]", " node scripts/codex-companion.mjs transfer [--source ] [--json]", " node scripts/codex-companion.mjs status [job-id] [--all] [--json]", " node scripts/codex-companion.mjs result [job-id] [--json]", @@ -121,7 +121,7 @@ function normalizeReasoningEffort(effort) { } if (!VALID_REASONING_EFFORTS.has(normalized)) { throw new Error( - `Unsupported reasoning effort "${effort}". Use one of: none, minimal, low, medium, high, xhigh.` + `Unsupported reasoning effort "${effort}". Use one of: none, minimal, low, medium, high, xhigh, max.` ); } return normalized; diff --git a/plugins/codex/skills/codex-cli-runtime/SKILL.md b/plugins/codex/skills/codex-cli-runtime/SKILL.md index 0e91bfb50..82dd61069 100644 --- a/plugins/codex/skills/codex-cli-runtime/SKILL.md +++ b/plugins/codex/skills/codex-cli-runtime/SKILL.md @@ -32,7 +32,7 @@ Command selection: - If the forwarded request includes `--fresh`, strip that token from the task text and do not add `--resume-last`. - `--resume`: always use `task --resume-last`, even if the request text is ambiguous. - `--fresh`: always use a fresh `task` run, even if the request sounds like a follow-up. -- `--effort`: accepted values are `none`, `minimal`, `low`, `medium`, `high`, `xhigh`. +- `--effort`: accepted values are `none`, `minimal`, `low`, `medium`, `high`, `xhigh`, `max`. - `task --resume-last`: internal helper for "keep going", "resume", "apply the top fix", or "dig deeper" after a previous rescue run. Safety rules: diff --git a/tests/commands.test.mjs b/tests/commands.test.mjs index c34b06059..7b25d2e1f 100644 --- a/tests/commands.test.mjs +++ b/tests/commands.test.mjs @@ -104,7 +104,7 @@ test("rescue command absorbs continue semantics", () => { assert.match(rescue, /--background\|--wait/); assert.match(rescue, /--resume\|--fresh/); assert.match(rescue, /--model /); - assert.match(rescue, /--effort /); + assert.match(rescue, /--effort /); assert.match(rescue, /task-resume-candidate --json/); assert.match(rescue, /AskUserQuestion/); assert.match(rescue, /Continue current Codex thread/); @@ -150,7 +150,7 @@ test("rescue command absorbs continue semantics", () => { assert.match(runtimeSkill, /Map `spark` to `--model gpt-5\.3-codex-spark`/i); assert.match(runtimeSkill, /If the forwarded request includes `--background` or `--wait`, treat that as Claude-side execution control only/i); assert.match(runtimeSkill, /Strip it before calling `task`/i); - assert.match(runtimeSkill, /`--effort`: accepted values are `none`, `minimal`, `low`, `medium`, `high`, `xhigh`/i); + assert.match(runtimeSkill, /`--effort`: accepted values are `none`, `minimal`, `low`, `medium`, `high`, `xhigh`, `max`/i); assert.match(runtimeSkill, /Do not inspect the repository, read files, grep, monitor progress, poll status, fetch results, cancel jobs, summarize output, or do any follow-up work of your own/i); assert.match(runtimeSkill, /If the Bash call fails or Codex cannot be invoked, return nothing/i); assert.match(readme, /`codex:codex-rescue` subagent/i); diff --git a/tests/runtime.test.mjs b/tests/runtime.test.mjs index 8f276835b..61c5be6c1 100644 --- a/tests/runtime.test.mjs +++ b/tests/runtime.test.mjs @@ -784,6 +784,31 @@ test("task forwards model selection and reasoning effort to app-server turn/star assert.equal(fakeState.lastTurnStart.effort, "low"); }); +test("task forwards max reasoning effort to app-server turn/start", () => { + const repo = makeTempDir(); + const binDir = makeTempDir(); + const statePath = path.join(binDir, "fake-codex-state.json"); + installFakeCodex(binDir); + initGitRepo(repo); + fs.writeFileSync(path.join(repo, "README.md"), "hello\n"); + run("git", ["add", "README.md"], { cwd: repo }); + run("git", ["commit", "-m", "init"], { cwd: repo }); + + const result = run( + "node", + [SCRIPT, "task", "--model", "gpt-5.6-luna", "--effort", "max", "diagnose the failing test"], + { + cwd: repo, + env: buildEnv(binDir) + } + ); + + assert.equal(result.status, 0, result.stderr); + const fakeState = JSON.parse(fs.readFileSync(statePath, "utf8")); + assert.equal(fakeState.lastTurnStart.model, "gpt-5.6-luna"); + assert.equal(fakeState.lastTurnStart.effort, "max"); +}); + test("task logs reasoning summaries and assistant messages to the job log", () => { const repo = makeTempDir(); const binDir = makeTempDir(); From 98e8abae894461056809eb7c92b0e8f5ee17dc01 Mon Sep 17 00:00:00 2001 From: Artem Mikhalev Date: Fri, 24 Jul 2026 11:04:49 +0400 Subject: [PATCH 2/2] address review feedback --- README.md | 2 +- tests/runtime.test.mjs | 25 ------------------------- 2 files changed, 1 insertion(+), 26 deletions(-) diff --git a/README.md b/README.md index 32c711984..41a639723 100644 --- a/README.md +++ b/README.md @@ -160,7 +160,7 @@ Ask Codex to redesign the database connection to be more resilient. **Notes:** - if you do not pass `--model` or `--effort`, Codex chooses its own defaults. -- `max` is accepted for models that advertise support for maximum reasoning effort. +- `max` is only available for the newest models, starting with the GPT-5.6 family. - if you say `spark`, the plugin maps that to `gpt-5.3-codex-spark` - follow-up rescue requests can continue the latest Codex task in the repo diff --git a/tests/runtime.test.mjs b/tests/runtime.test.mjs index 61c5be6c1..8f276835b 100644 --- a/tests/runtime.test.mjs +++ b/tests/runtime.test.mjs @@ -784,31 +784,6 @@ test("task forwards model selection and reasoning effort to app-server turn/star assert.equal(fakeState.lastTurnStart.effort, "low"); }); -test("task forwards max reasoning effort to app-server turn/start", () => { - const repo = makeTempDir(); - const binDir = makeTempDir(); - const statePath = path.join(binDir, "fake-codex-state.json"); - installFakeCodex(binDir); - initGitRepo(repo); - fs.writeFileSync(path.join(repo, "README.md"), "hello\n"); - run("git", ["add", "README.md"], { cwd: repo }); - run("git", ["commit", "-m", "init"], { cwd: repo }); - - const result = run( - "node", - [SCRIPT, "task", "--model", "gpt-5.6-luna", "--effort", "max", "diagnose the failing test"], - { - cwd: repo, - env: buildEnv(binDir) - } - ); - - assert.equal(result.status, 0, result.stderr); - const fakeState = JSON.parse(fs.readFileSync(statePath, "utf8")); - assert.equal(fakeState.lastTurnStart.model, "gpt-5.6-luna"); - assert.equal(fakeState.lastTurnStart.effort, "max"); -}); - test("task logs reasoning summaries and assistant messages to the job log", () => { const repo = makeTempDir(); const binDir = makeTempDir();