feat: orchestrator model ladder + --sandbox workspace-write (v0.3.0) - #4
feat: orchestrator model ladder + --sandbox workspace-write (v0.3.0)#4KingGyuSuh wants to merge 4 commits into
Conversation
…e (v0.3.0) Image generation now runs on the strongest orchestrator model the account can access: the wrapper probes `codex debug models` and picks the first available rung of gpt-5.6-luna high -> gpt-5.6-terra medium -> gpt-5.6-sol high -> gpt-5.6-sol low, passing -m / -c model_reasoning_effort. A failed probe or no matching rung adds no flags (codex config default), so accounts without those models (e.g. ChatGPT Free) never regress. CODEX_IMAGE_MODEL + CODEX_IMAGE_EFFORT (both required) force a pair and skip the probe; /codex-image:status reports the resolved orchestrator. Also replaces deprecated `--full-auto` with `--sandbox workspace-write` (Codex 0.144.5 deprecation; same approval:never + workspace-write sandbox, verified live). status --json renames fullAuto -> headlessExec. Versions aligned to 0.3.0 across plugin.json, marketplace.json, and package.json (the latter two had been left at 0.1.0 by the 0.2.0 release). Verified end-to-end on codex-cli 0.144.5: ladder generate, --ref generate, edit, and env-override generate all produce images under the expected model/effort with no deprecation warning. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 35e3ddf06e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
An image turn is a full Codex agent turn (typically 1-3 minutes); the default 2-minute Bash timeout can kill it mid-generation. Observed live via `claude --plugin-dir`: the edit turn was cut off, the skill reported "in progress", and no file was produced. Retrying with a longer timeout succeeded, so the SKILL.md prose now tells the invoking model to allow 600000 ms. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c1386d5ea7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const result = runSync(CODEX.command, [...CODEX.prefix, "debug", "models"], { | ||
| cwd, | ||
| maxBuffer: 32 * 1024 * 1024 | ||
| }); |
There was a problem hiding this comment.
Bound the model-catalog probe before dispatch
When codex debug models stalls during catalog refresh or on a bad network/proxy, this synchronous probe runs before both generate and edit and has no timeout, so the promised best-effort fallback never triggers and the slash command never reaches the actual codex exec image turn. Please add a short timeout here and treat timeout/kill the same as an unavailable catalog so generation can continue with the Codex default.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in 75f239e: the probe now runs with a 15s spawnSync timeout, and a timed-out/killed probe reports a null status which the existing status !== 0 check already treats as an unavailable catalog — generation proceeds on the Codex config default.
Codex review on the PR flagged that bare `--sandbox workspace-write` does not match the old `--full-auto` approval contract when the user's config sets `approvals_reviewer = "auto_review"`: codex-rs build_exec_config rebuilds with approval_policy: None in that case unless the legacy --full-auto/bypass flag set preserve_headless_approval_policy, routing imagegen's mkdir/cp/sips through the reviewer. Verified on 0.144.5 with --ignore-user-config isolation: - --full-auto + auto_review -> approval: never - bare sandbox + auto_review -> approval: on-request (regression) - + -c approval_policy="never" -> approval: never (this fix) - bare sandbox, no auto_review -> approval: never (no-op elsewhere) Base exec args are now a shared CODEX_EXEC_BASE_ARGS constant used by generate and edit, with a unit test pinning the contract. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: deec3fcb76
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const efforts = catalog.get(rung.model); | ||
| if (efforts && efforts.has(rung.effort)) { | ||
| return { model: rung.model, effort: rung.effort }; |
There was a problem hiding this comment.
Avoid forcing ladder models onto custom providers
When a user routes Codex through a custom/API-key model_provider but leaves the default bundled catalog visible, this check can still pick gpt-5.6-luna just because the slug is in codex debug models; the later codex exec -m gpt-5.6-luna keeps the configured provider and sends that official slug to a provider that may not serve it. In that configuration, image generation used to rely on the user's working configured model, but now fails before reaching the image turn instead of falling back to the Codex default.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Addressed in 75f239e with a different mechanism than suggested: instead of detecting custom providers up front (fragile, and permanently loses the ladder benefit for those users), the ladder pick is now best-effort at spawn time. A backend rejection of the -m slug kills the turn at startup — verified live on 0.144.5: HTTP 400 "The 'X' model is not supported…" on stderr with empty stdout, i.e. before any image tokens are spent — so the wrapper matches that signature (isOrchestratorRejection, only on non-zero exit) and retries once without -m/-c, landing on the configured default that worked pre-ladder. Unrelated failures (quota/auth/transport) don't match and are never retried, so no double-billing. Env-forced pairs (CODEX_IMAGE_MODEL/CODEX_IMAGE_EFFORT) deliberately never fall back — an explicit assertion should surface its error. Live-verified: bogus ladder model → rejection → retry → config default → success.
… rejection Two Codex-review findings on the PR: 1. The `codex debug models` probe ran synchronously before every generate/edit with no timeout, so a stalled probe (bad network/proxy, hung catalog refresh) blocked the command before the image turn. The probe now has a 15s timeout; timeout == unavailable catalog == codex config default. 2. The catalog can list a model the actual backend refuses (custom model_provider not serving official slugs). Rather than skipping the ladder for such configs (fragile provider detection, permanent loss of the ladder benefit), the wrapper now treats a ladder pick as best-effort at spawn time: a rejection kills the turn at startup (verified live: HTTP 400 on stderr, empty stdout, no image tokens), is matched by isOrchestratorRejection, and triggers ONE retry without -m/-c — the pre-ladder default. Unrelated failures never match, so a real image-turn failure is not double-billed. An env-forced pair (CODEX_IMAGE_MODEL/EFFORT) never falls back; its error surfaces. Verified live on 0.144.5: bogus ladder model -> 400 rejection -> retry note -> config default (gpt-5.6-sol) -> DONE, exit 0; env-forced bogus model -> error surfaced, no retry; normal generate unaffected (luna high, no retry, SAVED). Also fixes the entry-point guard crashing when the module is imported from `node -e` (argv[1] undefined). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 75f239e1ff
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const CODEX_IMAGE_ORCHESTRATOR_LADDER = [ | ||
| { model: "gpt-5.6-luna", effort: "high" }, | ||
| { model: "gpt-5.6-terra", effort: "medium" }, | ||
| { model: "gpt-5.6-sol", effort: "high" }, | ||
| { model: "gpt-5.6-sol", effort: "low" } |
There was a problem hiding this comment.
Prefer Sol before lower-tier GPT-5.6 models
For accounts where all three ladder models are listed, selectOrchestratorFromLadder returns the first match, so this order always forces Luna. The current Codex model catalog describes gpt-5.6-sol as the latest frontier model, gpt-5.6-terra as balanced, and gpt-5.6-luna as fast/affordable (see the official catalog: https://github.com/openai/codex/blob/main/codex-rs/models-manager/models.json), so the new ladder downgrades fully entitled users to the weakest 5.6 rung instead of the stated stronger orchestrator. Please order Sol/Terra/Luna, or otherwise make the preference explicit, so generation quality does not regress for users with full access.
Useful? React with 👍 / 👎.
Summary
Two improvements to the codex spawn contract, released together as v0.3.0:
1. Image orchestrator model ladder
Image generation is a codex agent turn (the "orchestrator") that calls the built-in image tool — a stronger orchestrator model/effort interprets prompts, conditions references, and holds the requested aspect more reliably. Instead of hardcoding a model (which would break accounts that can't access it, e.g. ChatGPT Free), the wrapper now:
codex debug models(keepsvisibility: "list"models + theirsupported_reasoning_levels),gpt-5.6-lunahigh →gpt-5.6-terramedium →gpt-5.6-solhigh →gpt-5.6-sollow,-m <model> -c model_reasoning_effort="<effort>".A failed probe or no matching rung adds no flags — codex falls back to its config default, so generation never regresses.
CODEX_IMAGE_MODEL+CODEX_IMAGE_EFFORT(both required, else a hard error) force a specific pair and skip the probe./codex-image:statusreports the resolved orchestrator and only fails readiness on an inconsistent override.2.
--full-auto→--sandbox workspace-writeCodex CLI 0.144.5 deprecates
--full-auto(warning: --full-auto is deprecated; use --sandbox workspace-write instead) and has dropped it fromcodex exec --help. Both spellings resolve to the sameapproval: never+ workspace-write sandbox, verified live. The status--jsonfieldfullAutois renamed toheadlessExecaccordingly.Version alignment
plugin.json0.2.0 → 0.3.0;package.jsonandmarketplace.jsonhad been left at 0.1.0 by the 0.2.0 release and are now aligned to 0.3.0.Verification
On codex-cli 0.144.5, all live end-to-end runs succeeded with the expected session header (
model,reasoning effort,sandbox: workspace-write,approval: never), aSAVED:line, exit 0, and no deprecation warning:gpt-5.6-luna/high--refgenerate--imagearg ordergpt-5.6-luna/highgpt-5.6-luna/highgpt-5.6-terra/mediumworkspace-write, write landedclaude plugin validate .: pass/codex-image:status:Ready: yes, reportsgpt-5.6-luna (effort high) [ladder]Docs updated in the same change per the maintenance discipline:
docs/ARCHITECTURE.md(new "Image orchestrator model ladder" + rewritten "Sandbox mode, not--full-auto" load-bearing sections),README.md,CONTRIBUTING.md,CHANGELOG.md.🤖 Generated with Claude Code