feat(config): make codex reasoning effort configurable per role#17
Conversation
Every codex ACP role currently runs with a hardcoded model_reasoning_effort="xhigh". Validators re-checking one assertion and terminal reviewers do not need frontier effort on every dispatch, and there was no way to dial any of it down. Add ZENITH_WORKER_REASONING_EFFORT, ZENITH_VALIDATOR_REASONING_EFFORT, and ZENITH_TERMINAL_REVIEWER_REASONING_EFFORT. Unset roles inherit down the same chain the provider/command config already uses (terminal_reviewer -> validator -> worker), and a fully unset config keeps the historical xhigh default, so behavior is unchanged unless opted in. Values are validated against an allowlist at discovery: the resolved value is spliced into a shell command line, and a typo'd downgrade silently ignored would keep spending xhigh. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Thanks for this thoughtful addition. The per-role inheritance and early allowlist validation are especially nice touches. One request before merge: preserve these settings through
|
…figs Review follow-up for Intelligent-Internet#17: the three ZENITH_*_REASONING_EFFORT values were read by HarnessConfig.discover() but never written into the generated server config, so an MCP server launched outside the original shell silently fell back to xhigh. - add the three variables to the runtime env forward allowlist - merge forwarded runtime env before the .mcp.json / .codex/config.toml branch so both formats persist it; .mcp.json output is byte-identical when the variables are unset - rename MCP_ENV_FORWARD_ALLOWLIST / _forwarded_mcp_env to RUNTIME_ENV_FORWARD_ALLOWLIST / _forwarded_runtime_env to match the broader use - add claude + codex init tests asserting the configured values land in the generated server env Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Thanks for the review — all four points addressed in 3374e30:
One deliberate side effect worth flagging: While verifying we hit two pre-existing issues in the workspace-scope codex writer — a second |
|
Great feature! Can I suggest you add the following as well:
|
Review follow-up for Intelligent-Internet#17 (suggested by @stephanbrez): codex's ReasoningEffort enum now includes "max" (protocol/src/openai_models.rs), so admit it to VALID_REASONING_EFFORTS. "ultra" is deliberately excluded: it is not a reasoning tier. Codex downgrades ultra requests to "max" on the wire (core/src/client.rs) and instead flips the session into proactive multi-agent mode (core/src/session/multi_agents.rs) — inside a Zenith lane that would nest an agent swarm in a harness that already orchestrates and validates per-lane work, with no reasoning gain over "max". The allowlist comment records this so the omission doesn't read as a stale list. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Review follow-up for Intelligent-Internet#17 (suggested by @stephanbrez): expose --worker-reasoning-effort / --validator-reasoning-effort / --terminal-reviewer-reasoning-effort on `zenith init`, completing surface parity with the existing per-role provider/command flags. Flags are sugar for the ZENITH_*_REASONING_EFFORT env vars: choice-validated against VALID_REASONING_EFFORTS at parse time, they win over valid inherited shell settings, and they merge into the generated server env above the format branch so both .mcp.json and .codex/config.toml persist them. An invalid value already present in the environment still fails fast at discover() rather than being masked by a flag — the same validation would raise at server launch, so masking at init only defers the failure. A test pins that behavior. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Both suggestions are in —
While verifying delivery end-to-end we found the codex |
|
Thanks for that! I was wondering if the adapter was applying the overrides, glad you found it 👍 |
|
Looks good to me—approved and ready to merge. Thanks @Quigleybits |
Why
Every codex ACP role — worker, validator, terminal reviewer — currently launches with a hardcoded
model_reasoning_effort="xhigh"(_augment_acp_command). Validators re-checking a single assertion and the terminal reviewer don't need frontier effort on every dispatch, and today there is no knob to dial any of it down. Effort tiering per role is the cheapest cost lever available: validation lanes typically run more often than work lanes, so that's where spend concentrates on long missions.What
Three new env vars, following the exact shape of the existing per-role provider/command config:
ZENITH_WORKER_REASONING_EFFORTZENITH_VALIDATOR_REASONING_EFFORTZENITH_TERMINAL_REVIEWER_REASONING_EFFORTSemantics:
xhigh; nothing changes unless opted in.terminal_reviewer → validator → worker, resolved infor_role()exactly likeworker_provider_name/worker_acp_command.minimal | low | medium | high | xhigh | max): the resolved value is spliced into a shell command line, and a typo'd downgrade silently ignored would keep spending xhigh — so an invalid value fails fast atHarnessConfig.discover()instead. Codex'sultrais deliberately excluded — it is not a reasoning tier (codex downgrades the request tomaxon the wire) but a switch into proactive multi-agent mode; the allowlist comment documents this.-coverride; other providers pass through unchanged).Example — full-effort workers, cheaper validation lanes:
Review round 1 (@TueVNguyen) — persistence through
zenith initAddressed in 3374e30: the three variables are forwarded through the (renamed)
RUNTIME_ENV_FORWARD_ALLOWLIST, merged once above the format branch so both.mcp.jsonand.codex/config.tomlpersist them;.mcp.jsonoutput is byte-identical when the variables are unset; claude + codex init tests assert the values land in the generated server env.Review round 2 (@stephanbrez) —
max+ init flagsAddressed in 698ace4 + e63462b:
maxadded to the allowlist (now protocol-complete against codex'sReasoningEffort,ultraexcluded as above). Note: supported tiers vary per model; the adapter clamps unsupported values to the model default.zenith initgains--worker-reasoning-effort/--validator-reasoning-effort/--terminal-reviewer-reasoning-effort— choice-validated, sugar for the env vars, a flag wins over a valid inherited shell setting, and an invalid value already in the environment still fails fast at discovery (pinned by test).Known limitation (pre-existing on main, applies equally to the hardcoded
xhigh): the npm codex-acp adapter ignores-cargv entirely, so effort values currently configure Zenith's intent without reaching the worker on that adapter — tracked in #27 with a proposedCODEX_CONFIG-based delivery fix that builds on this PR's per-role values.Tests
None(→ xhigh), per-role overrides (includingmax), invalid value rejected with the env var named in the error.for_role()cascade: single worker-level setting reaches all three roles; explicit validator setting wins and feeds the terminal reviewer fallback._augment_acp_command: override lands in the codex command line, bypass flags unaffected, claude command untouched with or without an effort.zenith init: claude + codex formats persist env-configured efforts; flags override valid inherited env; invalid inherited env fails fast despite a flag.ruff check .,mypy src, andpytest -qall pass (Linux/py3.12, rebased on current main).🤖 Generated with Claude Code