Skip to content

fix: ensure MaxTokens >= budget when extended thinking is enabled#48

Merged
SantiagoDePolonia merged 3 commits intomainfrom
claude/fix-thinking-max-tokens-vdp8g
Jan 26, 2026
Merged

fix: ensure MaxTokens >= budget when extended thinking is enabled#48
SantiagoDePolonia merged 3 commits intomainfrom
claude/fix-thinking-max-tokens-vdp8g

Conversation

@SantiagoDePolonia
Copy link
Copy Markdown
Contributor

@SantiagoDePolonia SantiagoDePolonia commented Jan 26, 2026

When extended thinking is enabled via the reasoning parameter, Anthropic requires max_tokens to be at least the thinking budget_tokens. This fix ensures MaxTokens is bumped to the budget value when it's lower, in both ChatRequest and ResponsesRequest conversion paths.

Summary by CodeRabbit

  • Chores
    • Optimized internal reasoning effort computation to reduce redundant calculations.
    • Added validation to ensure token limits meet minimum requirements for Anthropic API requests.

✏️ Tip: You can customize this high-level summary in your review settings.

When extended thinking is enabled via the reasoning parameter, Anthropic
requires max_tokens to be at least the thinking budget_tokens. This fix
ensures MaxTokens is bumped to the budget value when it's lower, in both
ChatRequest and ResponsesRequest conversion paths.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jan 26, 2026

Warning

Rate limit exceeded

@SantiagoDePolonia has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 10 minutes and 11 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📝 Walkthrough

Walkthrough

Optimization and validation improvements made to the Anthropic provider's request conversion functions. A computed budget value is reused instead of being recalculated, and guards are added to ensure MaxTokens meets the computed budget requirement. No changes to public interfaces.

Changes

Cohort / File(s) Summary
Anthropic provider optimization
internal/providers/anthropic/anthropic.go
Eliminates duplicate calls to reasoningEffortToBudgetTokens by reusing computed budget value; adds MaxTokens validation guards in both convertToAnthropicRequest and convertResponsesRequestToAnthropic

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

🐰 A budget once counted, now counted just right,
We cache what we've found, no duplicate flight.
Guards check our tokens with careful refrain—
One little hop saves us time and maintains.
Small changes, much cleaner, efficiency's gain! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: ensuring MaxTokens is at least the budget value when extended thinking is enabled, which aligns with the PR's objectives and code modifications.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@internal/providers/anthropic/anthropic.go`:
- Around line 193-196: Add a debug/info log when you bump anthropicReq.MaxTokens
to the budget so users can see the change: capture the original
anthropicReq.MaxTokens, then when you set anthropicReq.MaxTokens = budget emit a
log using the same logger and message style as the temperature-override warning
(the same logger used near the temperature override) showing the original value
and the new budget value; apply the identical change in
convertResponsesRequestToAnthropic around the MaxTokens adjustment (lines
~522-525) so both conversion functions log adjustments consistently.

@@ -185,9 +185,14 @@ func convertToAnthropicRequest(req *core.ChatRequest) *anthropicRequest {

// Map reasoning effort to Anthropic extended thinking
if req.Reasoning != nil && req.Reasoning.Effort != "" {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@copilot, @coderabbitai Do we need a checking against - req.Reasoning.Effort not set / nil ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@SantiagoDePolonia The current checking is already sufficient. Here's why:

The condition if req.Reasoning != nil && req.Reasoning.Effort != "" properly handles all cases:

  1. req.Reasoning != nil - This prevents a nil pointer dereference by checking if the Reasoning object exists first
  2. req.Reasoning.Effort != "" - This checks if Effort is set (non-empty)

Since Go uses short-circuit evaluation with &&, if req.Reasoning is nil, the second condition won't be evaluated, preventing any panic.

Regarding Effort specifically: Based on the usage pattern (comparing with ""), Effort appears to be a string type, not a *string. In Go:

  • String fields cannot be nil—they default to "" (empty string) when not set
  • The check != "" already handles the "not set" case

Conclusion: No additional nil checking is needed. The current implementation correctly handles:

  • req.Reasoning being nil
  • req.Reasoning.Effort being empty/not set
  • ✅ Prevents nil pointer dereference with short-circuit evaluation

Copy link
Copy Markdown
Contributor

Copilot AI commented Jan 26, 2026

@SantiagoDePolonia I've opened a new pull request, #49, to work on those changes. Once the pull request is ready, I'll request review from you.

}
// Ensure MaxTokens is at least the budget tokens
if anthropicReq.MaxTokens < budget {
anthropicReq.MaxTokens = budget
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@copilot Add some logs here - that MaxTokens has been increased because ... Anthropic require etc...

Copy link
Copy Markdown
Contributor

Copilot AI commented Jan 26, 2026

@SantiagoDePolonia I've opened a new pull request, #50, to work on those changes. Once the pull request is ready, I'll request review from you.

Copilot AI and others added 2 commits January 26, 2026 16:32
)

* Initial plan

* feat: add logging for MaxTokens adjustment in Anthropic provider

Add informative log statements when MaxTokens is adjusted to meet
Anthropic extended thinking requirements. Logs include original value,
adjusted value, and the reason for adjustment.

Co-authored-by: SantiagoDePolonia <16936376+SantiagoDePolonia@users.noreply.github.com>

* refactor: extract MaxTokens logging into helper function

Extract duplicate logging statements into a dedicated helper function
to improve code maintainability and ensure consistency across both
ChatCompletion and StreamChatCompletion flows.

Co-authored-by: SantiagoDePolonia <16936376+SantiagoDePolonia@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: SantiagoDePolonia <16936376+SantiagoDePolonia@users.noreply.github.com>
* Initial plan

* test: add comprehensive tests for reasoning effort edge cases

Co-authored-by: SantiagoDePolonia <16936376+SantiagoDePolonia@users.noreply.github.com>

* fix: improve test code quality based on review feedback

Co-authored-by: SantiagoDePolonia <16936376+SantiagoDePolonia@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: SantiagoDePolonia <16936376+SantiagoDePolonia@users.noreply.github.com>
@SantiagoDePolonia SantiagoDePolonia merged commit c9ba680 into main Jan 26, 2026
7 checks passed
@SantiagoDePolonia SantiagoDePolonia deleted the claude/fix-thinking-max-tokens-vdp8g branch March 22, 2026 14:24
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.

3 participants