Skip to content

feat(effort): carry the client's effort level to Codex and Anthropic backends - #644

Merged
Destynova2 merged 2 commits into
mainfrom
feat/effort-passthrough
Oct 14, 2026
Merged

Destynova2 merged 2 commits into
mainfrom
feat/effort-passthrough

Conversation

@Destynova2

Copy link
Copy Markdown
Contributor

Why

Claude Code sends its /effort setting as output_config.effort on every request (captured on the wire: output_config, context_management and thinking.display are all present). CanonicalRequest has no slot for any of them, so serde silently dropped them at the parse and Anthropic never saw the effort level, the context editing config, or the thinking display mode. In the other direction, a Codex CLI reasoning.effort was never translated for an Anthropic backend.

What

  • Passthrough: RequestExtensions::anthropic_passthrough keeps every native /v1/messages top-level field the canonical request cannot hold (plus the raw thinking object for its display key). The Anthropic provider merges it back into the outbound body for api.anthropic.com only; other Anthropic-compatible backends keep the canonical shape since they 400 on unknown fields.
  • Shared effort: output_config.effort feeds extensions.reasoning_effort, so the Codex path uses the client's level instead of its flat xhigh default.
  • Translation (src/models/effort.rs): max/ultra clamp to xhigh on gpt-5 models (which reject them; gpt-6 takes them as-is); minimal → low and ultra → max on Anthropic; output_config is only sent to models that accept it (Opus/Sonnet 4.6+, Claude 5), so a request mapped onto claude-haiku-4-5 is unchanged.
  • effort-2025-11-24 added to the default Anthropic beta set.
  • Docs: api-compatibility.md and providers.md get the field table and the translation matrix.

Verified

Debug build on a spare port with the real config, outbound bodies read from the grob::wire log:

Client Backend Outbound
/v1/messages + output_config.effort: low + thinking.display: omitted claude-fable-5-1 both forwarded verbatim, 200
/v1/messages + output_config.effort: high gpt-6-astra 200 (effort wired through resolve_reasoning_effort, unit-tested)
/v1/responses + reasoning.effort: ultra claude-fable-5-1 output_config.effort: max, 200
/v1/messages + output_config.effort: high claude-haiku-4-5 no output_config, 200

1616 lib tests pass, clippy clean.

🤖 Generated with Claude Code

Destynova2 and others added 2 commits October 14, 2026 20:44
…backends

Claude Code sends its /effort setting as output_config.effort, and the
canonical request had no slot for it: serde dropped it at the parse,
along with context_management and thinking.display. The Codex path
likewise never translated a Responses reasoning.effort for an Anthropic
backend.

- Keep every native /v1/messages field the canonical request cannot
  hold in extensions.anthropic_passthrough and merge it back into the
  outbound body for api.anthropic.com only.
- Expose output_config.effort as the shared reasoning_effort so the
  Codex path honours it over its flat default.
- Translate between the two vocabularies in models::effort: max/ultra
  clamp to xhigh on gpt-5 models, minimal→low and ultra→max on Anthropic,
  and output_config is only sent to models that accept it (4.6+ and 5).
- Add the effort-2025-11-24 beta to the default Anthropic beta set.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@Destynova2
Destynova2 enabled auto-merge (squash) October 14, 2026 19:20
@Destynova2
Destynova2 merged commit f8be3b7 into main Oct 14, 2026
44 checks passed
@Destynova2
Destynova2 deleted the feat/effort-passthrough branch October 14, 2026 19:34
Destynova2 added a commit that referenced this pull request Oct 14, 2026
## 🤖 New release

* `grob`: 0.36.124 -> 0.36.125

<details><summary><i><b>Changelog</b></i></summary><p>

<blockquote>

##
[0.36.125](v0.36.124...v0.36.125)
- 2026-10-14

### Added

- *(effort)* carry the client's effort level to Codex and Anthropic
backends ([#644](#644))

### Other

- skip the no-commit-to-branch hook in the prek gate
([#641](#641))
</blockquote>


</p></details>

---
This PR was generated with
[release-plz](https://github.com/release-plz/release-plz/).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant