fix: preserve thinking block signatures and fix compaction headroom asymmetry#14393
fix: preserve thinking block signatures and fix compaction headroom asymmetry#14393gnadaban wants to merge 1 commit intoanomalyco:devfrom
Conversation
|
The following comment was made by an LLM, it may be inaccurate: Potential Related PRs Found:
These PRs address similar domains (thinking block signatures and compaction behavior), though they may be addressing different specific bugs or prior versions of the same issues. |
|
Re: related PRs flagged by bot Checked all three:
|
fd795c0 to
c045a8f
Compare
…rategy UI Root cause fix (from PR anomalyco#14393): - Always pass providerMetadata for reasoning parts (removed differentModel guard) - Always pass callProviderMetadata for tool parts - Fix asymmetric compaction buffer (use maxOutputTokens consistently) Configurable thinking strategy (none/strip/compact): - Settings > General: Thinking Strategy dropdown - Context tab: Always-visible strategy selector - Error card: Retry buttons for thinking block errors - Processor: Auto-compact on thinking error with compact strategy Default 'none' preserves original behavior.
c045a8f to
04021bb
Compare
04021bb to
b898bf0
Compare
…symmetry Two compounding bugs caused sessions to crash with 'thinking blocks cannot be modified' when compaction fired for models with extended thinking: 1. toModelMessages() stripped providerMetadata (including cryptographic signatures) from message parts when the current model differed from the original. Anthropic's API requires signatures to be byte-identical. Fix: always pass providerMetadata through — the API handles filtering. 2. isOverflow() used an asymmetric buffer when limit.input was set (capped at 20K via COMPACTION_BUFFER) vs the full maxOutputTokens on the non-input path. This caused compaction to trigger too late. Fix: use maxOutputTokens (capped at 32K) for both paths. Also fixed the non-input path to respect config.compaction.reserved.
b898bf0 to
cef2b52
Compare
Issue for this PR
Closes #13286
Related: #10634, #8089, #12621, #8185
Type of change
What does this PR do?
Two compounding bugs cause sessions to crash with
'thinking' or 'redacted_thinking' blocks in the latest assistant message cannot be modifiedwhen compaction fires for models with extended thinking enabled (e.g. Claude Opus on Bedrock).Bug 1 — Thinking block signature stripping (
message-v2.ts)toModelMessages()compares the current model against each historical message's original model via adifferentModelguard. When they differ — which always happens during compaction since it uses its own model — allproviderMetadatais stripped from message parts. This removes the cryptographicsignaturethat Anthropic requires on thinking blocks, causing the API to reject the messages.The fix removes the
differentModelguard entirely and always passesproviderMetadata/callProviderMetadatathrough. This is safe because:{ anthropic: { signature: "..." } }), so other providers ignore unknown keyspart.metadataisundefined, and the Vercel AI SDK'sconvertToModelMessagesalready null-checks before settingproviderOptions(except reasoning parts, where it's a no-op)Bug 2 — Compaction headroom asymmetry (
compaction.ts)isOverflow()had an asymmetric buffer calculation:limit.input:reserved = Math.min(20_000, maxOutputTokens)→ only 20K headroomlimit.input:reserved = maxOutputTokens→ full 32K headroomThis meant models with
limit.inputcould grow ~12K tokens larger before compaction triggered, making context overflow more likely.The fix removes the 20K cap and uses
maxOutputTokens()(itself capped at 32K viaOUTPUT_TOKEN_MAX) for both paths. Also fixed the non-input path to respectconfig.compaction.reserved— previously it hardcodedmaxOutputTokens(), ignoring the user's configured override from #12924.How did you verify your code works?
BUG:in the test file) now pass with correct expectationsScreenshots / recordings
N/A — not a UI change.
Checklist