Repository navigation
fix(anthropic): give each Claude model its real 128K output maximum - #6329
Conversation
Carries #6316 unchanged plus maintainer review fixes; the contributor gate re-drafted the original after the maintainer push. Co-authored-by: vadymhimself <11277453+vadymhimself@users.noreply.github.com>
|
✅ Deterministic PR hygiene checks passed. |
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. Note Currently processing new changes in this PR. This may take a few minutes, please wait... ⚙️ Run configurationConfiguration used: Repository: lidge-jun/opencodex/.coderabbit.yaml Review profile: ASSERTIVE Plan: Advanced Run ID: 📒 Files selected for processing (5)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
|
Maintainer integration into |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e21d966a8a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| export const ANTHROPIC_MODEL_MAX_OUTPUT_TOKENS: Record<string, number> = { | ||
| "claude-fable-5-1": 128_000, |
There was a problem hiding this comment.
Apply maxima to versioned Claude model IDs
When a request uses a concrete Anthropic ID such as claude-opus-4-8-20260201, these base-family keys are not selected: modelRecordValue only supports exact, case-folded, or colon-family matches. Consequently both the adapter and admission resolver fall back to the 64K provider default, so live-discovered/date-pinned models still truncate at the old limit. Resolve output maxima through the same numeric-family fallback already used by anthropicFamilyContextWindow, and add a dated-ID regression case.
Useful? React with 👍 / 👎.
| // Codex omits max_output_tokens; without a provider budget the Anthropic adapter | ||
| // falls back to 8192, which truncates long answers with stop_reason=max_tokens. | ||
| defaultMaxOutputTokens: ANTHROPIC_DEFAULT_MAX_OUTPUT_TOKENS, | ||
| modelMaxOutputTokens: { ...ANTHROPIC_MODEL_MAX_OUTPUT_TOKENS }, |
There was a problem hiding this comment.
Update the owned provider contract documentation
This registry field changes the effective Anthropic wire behavior for every omitted max_tokens request, but the commit does not update the mapped structure/ contract documentation, such as the provider registry/Anthropic adapter description in structure/providers-and-adapters.md. Record the new per-model output-budget contract in the same change as required for owned src/providers/ changes.
AGENTS.md reference: AGENTS.md:L38-L46
Useful? React with 👍 / 👎.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
…mum (#6355) * fix(anthropic): clamp budget thinking to the model's real output maximum The budget-thinking branch sized `max_tokens` with a flat REASONING_MAX_TOKENS_CEILING of 32000, so a caller asking for 128000 on Opus 4.6 or Sonnet 4.6 silently got 32000 — a quarter of what those models document. The adaptive branch directly above already honours an explicit caller limit above 32k; this one overrode it. The constant dates from Claude 4.x models that really stopped near 32k. Opus 4.6 and Sonnet 4.6 document 128K synchronous output and Haiku 4.5 documents 64K, so the flat value is no longer a safe ceiling for the families that take this path: `usesAdaptiveThinking` sends sonnet >= 5, opus >= 4.7 and fable down the adaptive branch, leaving exactly opus-4-6, sonnet-4-6 and haiku-4-5 here, and all three exceed 32000. It now clamps to `configuredMaxOut`, the per-model value already resolved a few lines above for the omitted-limit default (`modelMaxOutputTokens` falling back to `defaultMaxOutputTokens`), so this reuses that lookup rather than adding a second one. REASONING_MAX_TOKENS_CEILING stays the fallback for a target whose ceiling is unknown, which keeps today's behaviour for an unconfigured provider. Measured before and after, with the provider carrying the seeded maxima: opus-4-6 asked 128000 -> 32000 before, 128000 after sonnet-4-6 asked 128000 -> 32000 before, 128000 after haiku-4-5 asked 128000 -> 32000 before, 64000 after (its real maximum) opus-4-6 asked 10000 -> 24576 both (budget+headroom, unchanged) no maxima asked 128000 -> 32000 both (fallback preserved) Anthropic's invariant `max_tokens > thinking.budget_tokens` holds in every case above; the test asserts it alongside the figures. Follow-up to #6329, where the per-model maxima landed and the reviewer noted this clamp as still outstanding. Verification: `bun run typecheck` clean; 73/73 in tests/adapters/anthropic/anthropic-reasoning.test.ts. The new case fails with "Expected: 128000, Received: 32000" without the source change. tests/adapters/anthropic reports the same 654 pass / 30 fail with and without it — those are pre-existing account-pause/pacing failures on dev, unrelated to max_tokens. Co-Authored-By: Claude Code <noreply@anthropic.com> * fix(anthropic): let the stated ceiling only raise, never lower, the thinking clamp Addresses CodeRabbit's finding on #6355: the first revision treated `configuredMaxOut` as a capability ceiling, but that value is two different things depending on the provider. On the canonical Anthropic entries it is a documented Messages API maximum. On any other provider it is a plain fallback budget for requests that omit `max_output_tokens`. Reading the second as the first meant an operator's deliberately cheap `defaultMaxOutputTokens: 8192` was interpreted as "this model cannot emit more", so an explicit 128000 request was clamped to 8192 with the thinking budget squeezed to 4096 — below the 32000/16384 this path produced before the change. Reproduced before fixing: defaultMaxOutputTokens 8192, explicit 128000, high effort before this commit: max_tokens 8192, budget_tokens 4096 base (pre-PR): max_tokens 32000, budget_tokens 16384 The clamp now takes the LARGER of the configured value and REASONING_MAX_TOKENS_CEILING, so the historical ceiling acts as a floor: a stated maximum can lift it where the vendor documents more, and a low fallback budget can never drag it below what the flat constant already allowed. seeded maxima opus-4-6 explicit 128000 -> 128000 (its documented maximum) seeded maxima haiku-4-5 explicit 128000 -> 64000 (its documented maximum) cheap 8192 opus-4-6 explicit 128000 -> 32000 (floor held, budget 16384) no maxima opus-4-6 explicit 128000 -> 32000 (unchanged) The fallback budget still decides an omitted request, which is what it is for, and that is asserted too so the two roles stay distinguished. Verification: `bun run typecheck` clean; 74/74 in anthropic-reasoning.test.ts, the new case covering the low-budget regression with the explicit assertion that budget_tokens stays 16384. tests/adapters/anthropic unchanged at the same pre-existing 30 failures. Co-Authored-By: Claude Code <noreply@anthropic.com> --------- Co-authored-by: Claude Code <noreply@anthropic.com>
Summary
Carries #6316 by @vadymhimself. The contributor gate returned the original to draft after a maintainer commit, so the final state lands here with author credit.
Claude models without an explicit caller limit now get their real per-model output maximum (128K where Anthropic documents it) instead of a shared lower cap. Explicit caller limits are preserved. The maintainer commits bring the branch onto current
dev(the original Cross-platform run failed only on the stale release-version-line assertion) and register the new regression file inscripts/test-layout/layout.jsonandtests/fixtures/test-layout-expected.json.Closes #6316
Co-authored-by: vadymhimself 11277453+vadymhimself@users.noreply.github.com
Verification
release-version-line3 pass after the update;bun run typecheckpasses.dev:bun x tsc --noEmitpasses; the PRs' test files 124 pass / 0 fail.devtip after this landing batch.Checklist