Skip to content

fix(codex): clamp reasoning.effort max/ultra to xhigh (HTTP 400) - #68365

Closed
joelbrilliant wants to merge 2 commits into
NousResearch:mainfrom
joelbrilliant:fix/reasoning-effort-clamp-fallback
Closed

fix(codex): clamp reasoning.effort max/ultra to xhigh (HTTP 400)#68365
joelbrilliant wants to merge 2 commits into
NousResearch:mainfrom
joelbrilliant:fix/reasoning-effort-clamp-fallback

Conversation

@joelbrilliant

Copy link
Copy Markdown
Contributor

Problem

Desktop dogfood (2026-07-21): fallback/switch onto openai-codex / gpt-5.5 with agent.reasoning_effort: max hard-failed:

HTTP 400: Invalid value: 'max'. Supported values are: 'none', 'minimal', 'low', 'medium', 'high', and 'xhigh'.
param: reasoning.effort

Hermes accepts max/ultra in config (generic ladder). Codex Responses wire vocabulary does not include max (observed). Older code even mapped gpt-5.6 ultra → wire max.

Fix

In agent/transports/codex.py, clamp max/ultraxhigh on the Codex Responses path. xAI Responses still caps stronger levels at high.

Tests

pytest tests/agent/transports/test_codex_transport.py -k 'effort or reasoning' -q
# 19 passed

Evidence

agent.log session 20260721_060132_be3b5e ~11:31 AEST.

Risk

Low. Wire values only. Config can still say max; transport sanitizes.

@alt-glitch alt-glitch added type/bug Something isn't working comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint provider/openai OpenAI / Codex Responses API P2 Medium — degraded but workaround exists labels Jul 21, 2026
@teknium1

Copy link
Copy Markdown
Contributor

Thanks for the focused transport-boundary fix. The premise remains valid on current main: agent/transports/codex.py:224-231 leaves generic max unchanged and maps gpt-5.6 ultra to max, while agent/transports/codex.py:361 emits that value on non-xAI Responses requests. Both levels are accepted by the generic configuration parser in hermes_constants.py:807-835 and reach this transport through agent/chat_completion_helpers.py:1170-1231.

The diff clamps both values to xhigh, preserves xAI's separate high ceiling, and covers both ResponsesApiTransport.build_kwargs() and the AIAgent._build_api_kwargs() integration path. No blocking code problems found.

Automated hermes-sweeper review.

@joelbrilliant
joelbrilliant force-pushed the fix/reasoning-effort-clamp-fallback branch from 229b1a0 to 251fb18 Compare July 30, 2026 03:17
@teknium1 teknium1 added sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 30, 2026
@joelbrilliant

Copy link
Copy Markdown
Contributor Author

Thanks for checking this against current main. I’ve rebased the branch and retained both the transport-level clamp and the AIAgent integration coverage.

The focused transport and Responses integration suites are 99 passed, with ruff clean. Current head is 251fb188b.

@joelbrilliant

joelbrilliant commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

The shared Vercel fixture fix has now landed on main via #74576 as 8eb06e75b, so I closed my duplicate #74586.

I rebased this PR onto the corrected main and pushed b4b50f2d6. CI run 30514213406 is fully green.

Codex/OpenAI Responses rejects reasoning.effort=max with HTTP 400
invalid_value (allowed: none|minimal|low|medium|high|xhigh). Hermes
config and generic effort ladder still use max/ultra; previously gpt-5.6
even mapped ultra to max on the wire.

Clamp max and ultra to xhigh for the Codex Responses path (xAI still
caps stronger levels at high). Covers fallback swaps onto openai-codex
with a global agent.reasoning_effort of max.

Evidence: desktop session 20260721_060132_be3b5e agent.log 11:31:52.
Signed-off-by: joelbrilliant <joelbrilliant1@gmail.com>
CI failed on test_build_api_kwargs_codex_preserves_supported_efforts,
which still treated max as a pass-through wire value. Align with the
transport clamp (max/ultra -> xhigh) that fixes the live HTTP 400.

Signed-off-by: joelbrilliant <joelbrilliant1@gmail.com>
@joelbrilliant
joelbrilliant force-pushed the fix/reasoning-effort-clamp-fallback branch from 251fb18 to b4b50f2 Compare July 30, 2026 04:33
teknium1 added a commit that referenced this pull request Aug 20, 2026
…longer 400s on 'max' (#68365 confirmed live)

Live probes against api.openai.com/v1/responses (Aug 2026):
- gpt-5.6: accepts none/low/medium/high/xhigh/max; rejects minimal, ultra
- gpt-5.5: accepts none/low/medium/high/xhigh; rejects max ('Unsupported
  value'), minimal, ultra

So #68365's premise was half right: 'max' does 400 — but only on pre-5.6
models; blanket-clamping max->xhigh on gpt-5.6 (its fix) would have capped
the one model that supports max. The declared-vocabulary design absorbs
this as data: codex_supported_efforts(model) picks CODEX_GPT56_EFFORTS or
CODEX_LEGACY_EFFORTS, and the shared clamp does the rest. Both the main
Codex transport and the auxiliary client's Responses path use it.

Wire outcomes: ultra -> max on gpt-5.6, ultra/max -> xhigh on gpt-5.5/o5,
minimal -> low everywhere.
@teknium1

Copy link
Copy Markdown
Contributor

Thanks for this report — your July observation that the Responses API rejects effort=max was real, and we live-verified it (Aug 2026): max 400s on gpt-5.5 ("Unsupported value ... Supported values are: 'none', 'low', 'medium', 'high', 'xhigh'") but IS accepted on gpt-5.6 — so the blanket max → xhigh clamp here would have capped the one model that supports it. PR #90441 lands the verified per-model split (codex_supported_efforts() picking gpt-5.6 vs legacy vocabularies over the shared clamp from #90350), with credit to you for the premise. ultra/max now resolve to xhigh on pre-5.6 models and max stays usable on 5.6. Closing in favor of #90441.

orgoj added a commit to orgoj/hermes-agent that referenced this pull request Aug 20, 2026
…-runtime

* upstream/main: (695 commits)
  fix(api-server): 'max' and 'ultra' reasoning efforts are no longer silently ignored on API/browser requests
  fix: K3 plan-variant slugs (k3-256k) now get K3's effort vocabulary
  fmt(js): `npm run fix` on merge (NousResearch#90552)
  feat(desktop): show unread count on the sessions sidebar toggle
  feat(desktop): count unread sessions from the shared status map
  fix(checkpoints): bare /rollback falls back to a labeled all-directories view (NousResearch#10505, reapply NousResearch#10633)
  fix(compression): /compress refusal no longer reports a successful rewrite
  fix(desktop): authenticate gated file downloads like REST
  fix(desktop): name the gated file-download auth decision
  fix: Codex Responses effort vocabulary is now per-model — gpt-5.5 no longer 400s on 'max' (NousResearch#68365 confirmed live)
  fix(desktop): give mermaid diagrams a pixel size in the overlay and on copy
  fix(desktop): mermaid zoom overlay body collapsed to zero height
  feat(relay): live-card ops — native draft streaming + task cards over the relay (gateway half) (NousResearch#85796)
  fmt(js): `npm run fix` on merge (NousResearch#90536)
  feat(desktop): unfocused session panes recede
  fix(desktop): scrollbars stop carrying the theme accent
  feat(desktop): one theme list in the palette, with a mode toggle inside it
  fix(a2a): expose schemas through tool describe
  fmt(js): `npm run fix` on merge (NousResearch#90523)
  refactor(desktop): replace every window.confirm with the shared dialog
  ...

# Conflicts:
#	gateway/run.py
lisajlau pushed a commit to lisajlau/hermes-agent that referenced this pull request Aug 20, 2026
…longer 400s on 'max' (NousResearch#68365 confirmed live)

Live probes against api.openai.com/v1/responses (Aug 2026):
- gpt-5.6: accepts none/low/medium/high/xhigh/max; rejects minimal, ultra
- gpt-5.5: accepts none/low/medium/high/xhigh; rejects max ('Unsupported
  value'), minimal, ultra

So NousResearch#68365's premise was half right: 'max' does 400 — but only on pre-5.6
models; blanket-clamping max->xhigh on gpt-5.6 (its fix) would have capped
the one model that supports max. The declared-vocabulary design absorbs
this as data: codex_supported_efforts(model) picks CODEX_GPT56_EFFORTS or
CODEX_LEGACY_EFFORTS, and the shared clamp does the rest. Both the main
Codex transport and the auxiliary client's Responses path use it.

Wire outcomes: ultra -> max on gpt-5.6, ultra/max -> xhigh on gpt-5.5/o5,
minimal -> low everywhere.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint P2 Medium — degraded but workaround exists provider/openai OpenAI / Codex Responses API sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants