Skip to content

fix(anthropic): give each Claude model its real 128K output maximum - #6329

Merged
lidge-jun merged 1 commit into
devfrom
codex/carry-6316-claude-output-maxima
Sep 30, 2026
Merged

lidge-jun merged 1 commit into
devfrom
codex/carry-6316-claude-output-maxima

Conversation

@lidge-jun

Copy link
Copy Markdown
Owner

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 in scripts/test-layout/layout.json and tests/fixtures/test-layout-expected.json.

Closes #6316

Co-authored-by: vadymhimself 11277453+vadymhimself@users.noreply.github.com

Verification

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed.
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults.

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>
@lidge-jun
lidge-jun requested a review from Ingwannu as a code owner September 30, 2026 14:59
@github-actions github-actions Bot added the bug Something isn't working label Sep 30, 2026
@github-actions

Copy link
Copy Markdown
Contributor

✅ Deterministic PR hygiene checks passed.

@coderabbitai

coderabbitai Bot commented Sep 30, 2026

Copy link
Copy Markdown
Contributor

Review in Change Stack →

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 configuration

Configuration used: Repository: lidge-jun/opencodex/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 258f3367-a64f-4312-9881-f0e80d155a70

📥 Commits

Reviewing files that changed from the base of the PR and between b0d275d and e21d966.

📒 Files selected for processing (5)
  • scripts/test-layout/layout.json
  • src/providers/registry/entries-core.ts
  • src/providers/registry/model-seeds.ts
  • tests/adapters/anthropic/anthropic-output-maxima.test.ts
  • tests/fixtures/test-layout-expected.json
 ___________________________________________________________________
< That's not technical debt - that's technical *predatory lending*. >
 -------------------------------------------------------------------
  \
   \   \
        \ /\
        ( )
      .( o ).
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


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.

@lidge-jun

Copy link
Copy Markdown
Owner Author

Maintainer integration into dev (MAINTAINERS.md, dev-only exception) by @lidge-jun. Carries #6316 with a Co-authored-by trailer; review and local integration evidence are in the description. Cross-platform CI for this head was cancelled per the maintainer's single-final-run instruction and runs once on the final dev tip. scripts/ci/assert-mergeable-review.sh --maintainer-integration OK at this head.

@lidge-jun
lidge-jun merged commit 6c32c4d into dev Sep 30, 2026
16 of 28 checks passed
@lidge-jun
lidge-jun deleted the codex/carry-6316-claude-output-maxima branch September 30, 2026 15:01

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 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".

Comment on lines +42 to +43
export const ANTHROPIC_MODEL_MAX_OUTPUT_TOKENS: Record<string, number> = {
"claude-fable-5-1": 128_000,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge 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 },

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge 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 👍 / 👎.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-30T15:06:37.204508Z e21d966 PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

lidge-jun pushed a commit that referenced this pull request Oct 1, 2026
…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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant