Skip to content

fix: cap thinking.budget_tokens when >= max_tokens#143

Open
flwrenn wants to merge 1 commit intogriffinmartin:mainfrom
flwrenn:fix/cap-thinking-budget-tokens
Open

fix: cap thinking.budget_tokens when >= max_tokens#143
flwrenn wants to merge 1 commit intogriffinmartin:mainfrom
flwrenn:fix/cap-thinking-budget-tokens

Conversation

@flwrenn
Copy link
Copy Markdown

@flwrenn flwrenn commented Apr 7, 2026

Summary

  • Cap thinking.budget_tokens to 80% of max_tokens when OpenCode sends budget_tokens >= max_tokens, which the Anthropic API rejects with a 400 error
  • Affects custom models (e.g. claude-opus-4-6) not in OpenCode's built-in registry, where max_tokens and budget_tokens may be set to the same value
  • Follows the same defensive-fix pattern as the existing haiku effort stripping in transformBody

Problem

When using claude-opus-4-6 (or other custom model IDs) through OpenCode, the Go binary may set thinking.budget_tokens equal to max_tokens. The Anthropic API requires strict inequality (max_tokens > thinking.budget_tokens) and rejects these requests:

opencode-claude-auth: API 400 for claude-opus-4-6: `max_tokens` must be greater than
`thinking.budget_tokens`. Please consult our documentation at
https://docs.claude.com/en/docs/build-with-claude/extended-thinking#max-tokens-and-context-window-size

Fix

In transformBody, after the existing model override logic, check if budget_tokens >= max_tokens and cap it to Math.floor(max_tokens * 0.8). The 0.8 ratio matches what OpenCode's own Anthropic provider uses when it correctly configures thinking for built-in models.

Tests

Three new test cases covering:

  • budget_tokens == max_tokens (the observed failure case)
  • budget_tokens > max_tokens
  • budget_tokens < max_tokens (no-op, left unchanged)

OpenCode may set thinking.budget_tokens equal to (or greater than)
max_tokens for custom models that aren't in its built-in registry.
The Anthropic API requires max_tokens > thinking.budget_tokens and
rejects such requests with a 400 error.

Cap budget_tokens to 80% of max_tokens when the constraint is
violated, matching the ratio used by OpenCode's own Anthropic
provider when it correctly configures thinking.
Copilot AI review requested due to automatic review settings April 7, 2026 08:02
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a defensive transformation to avoid Anthropic API 400s when thinking.budget_tokens is configured to be greater than or equal to max_tokens (a situation observed with custom model IDs outside OpenCode’s built-in model registry).

Changes:

  • Parse and surface max_tokens in transformBody’s request-body shape.
  • Cap thinking.budget_tokens to Math.floor(max_tokens * 0.8) when budget_tokens >= max_tokens to satisfy the API’s strict inequality requirement.
  • Add three unit tests covering equal/greater-than/no-op scenarios for the cap logic.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/transforms.ts Adds runtime guard to ensure max_tokens > thinking.budget_tokens by capping the budget when invalid.
src/transforms.test.ts Adds targeted regression tests for the new capping behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@griffinmartin
Copy link
Copy Markdown
Owner

Thanks, will try to take a look at this tonight.

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