Skip to content

feat(anthropic): accept an effort level in ChatBedrockAnthropic(reasoning=) - #448

Merged
cpsievert merged 2 commits into
posit-dev:mainfrom
pcbeingused333:bedrock-anthropic-reasoning-effort
Oct 12, 2026
Merged

cpsievert merged 2 commits into
posit-dev:mainfrom
pcbeingused333:bedrock-anthropic-reasoning-effort

Conversation

@pcbeingused333

Copy link
Copy Markdown
Contributor

ChatBedrockAnthropic(reasoning=) only accepted an int, which became a manual {"type": "enabled", "budget_tokens": ...} thinking config. Its default model, us.anthropic.claude-sonnet-5, rejects manual budgets with a 400, as do Claude Opus 4.7 and later, so there was no way to turn on thinking with the default model.

ChatAnthropic(reasoning=) already handles this. A string effort level enables adaptive thinking ({"type": "adaptive"} plus output_config.effort), and an int stays a fixed budget. This PR moves that translation into a small reasoning_kwargs() helper that both functions call, so ChatBedrockAnthropic accepts the same forms:

ChatBedrockAnthropic(reasoning="high")  # adaptive thinking, effort "high"
ChatBedrockAnthropic(reasoning=4000)    # fixed budget, unchanged

The two docstrings also say that fixed budgets only work on models before Claude Opus 4.6 / Sonnet 4.6. That way someone on a current model reaches for an effort level instead of hitting the 400. This matches what ellmer does in chat_claude() with reasoning_effort.

Tests

  • TestReasoning in tests/test_provider_anthropic_bedrock.py checks that an effort string gives adaptive thinking and that an int still gives a fixed budget. With the change reverted, the effort test fails.
  • tests/test_provider_anthropic.py, tests/test_provider_anthropic_bedrock.py, tests/test_provider_bedrock.py: 73 passed, 9 skipped (live Bedrock).
  • ruff check, ruff format --check, and pyright chatlas/_provider_anthropic.py are clean.

I didn't run a live Bedrock request, so the new path is covered by the unit test and by ChatAnthropic already sending the same request shape.

🤖 Generated with Claude Code

https://claude.ai/code/session_01BeNHkjF4spsH9d18UiYPiU

…ning=)

`ChatBedrockAnthropic(reasoning=)` only took an int, which became a manual
`budget_tokens` thinking config. Its default model, Claude Sonnet 5, rejects
manual budgets, so there was no way to turn on thinking with that model.

The translation `ChatAnthropic()` already does (effort string -> adaptive
thinking plus `output_config.effort`, int -> fixed budget) moves into a shared
`reasoning_kwargs()` helper that both functions call. The docstrings now say
that fixed budgets only work on models before Claude Opus 4.6 / Sonnet 4.6.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BeNHkjF4spsH9d18UiYPiU

@cpsievert cpsievert left a comment •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

Comment thread chatlas/_provider_anthropic.py Outdated
Comment thread chatlas/_provider_anthropic.py Outdated
Co-authored-by: Carson Sievert <cpsievert1@gmail.com>
@cpsievert
cpsievert merged commit 1636be7 into posit-dev:main Oct 12, 2026
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.

2 participants