Repository navigation
Description
Important
Problem — Compaction fails with an API error on Bedrock Claude models that use extended thinking. The Anthropic API enforces that thinking/redacted_thinking blocks in the latest assistant message cannot be modified, but the compaction path preserves these blocks when the compaction model matches the conversation model. The API rejects the compaction request, and the failure path incorrectly advances the compaction epoch boundary — clearing the user's entire context window without producing a summary.
Approach — Two independent, small fixes (belt and suspenders): (A) Always strip reasoning/thinking blocks from messages sent to the compaction agent, enforcing the spec-documented invariant that reasoning does not survive compaction boundaries. (B) Guard the compaction boundary so it is only recognized as valid when a successful summary exists alongside the marker — preventing context loss on any compaction failure.
Scope — in: V1 message conversion (toModelMessagesEffect), V2 serialization (toLLMMessages), compaction boundary validation (filterCompacted, history loader) · out: compaction agent selection, summarization prompt content, streaming UX, upstream contribution
Assumptions — The existing spec (specs/v2/session.md) correctly states that reasoning blocks do not survive compaction; this fix enforces that invariant at runtime. The compaction agent does not need reasoning content to produce a useful summary.
Acceptance Criteria
- Compaction succeeds without API error when the conversation contains thinking/reasoning blocks (Bedrock Claude Opus 4.6, same-model compaction)
- Reasoning blocks are unconditionally stripped (downgraded to plain text or dropped) from all messages sent to the compaction agent, regardless of model match
- A failed or incomplete compaction (orphaned marker with no valid summary) does not truncate visible conversation history — the user retains their full pre-compaction context
- Existing test suite passes; new test cases cover both the stripping behavior and the orphaned-marker guard
Testing Decisions
- Extend
packages/opencode/test/session/message-v2.test.ts(already has a"thinking-bedrock"fixture) with a case verifying reasoning blocks are stripped when building compaction messages - Add a compaction test that creates an orphaned compaction marker (user-compaction message without a valid summary-assistant) and verifies
filterCompacted/ history loading does not treat it as a boundary
Key Decisions
- Strip, not preserve: reasoning blocks are dropped from compaction input unconditionally (not just for cross-model). The summarizer benefits from the reasoning content only as labeled plaintext (
[Reasoning]: ...), never as provider-native thinking blocks - Guard is passive, not rollback: orphaned compaction markers are left in the DB but ignored by the boundary detector, rather than actively deleted. This avoids a delete path in the message store and handles any future failure mode (timeout, network, provider quirk) without additional code
- Option-based signaling: the V1 path signals compaction context via a
forCompaction: trueoption in the existing options bag passed totoModelMessagesEffect, consistent with the existingstripMediaandtoolOutputMaxCharsoptions
Constraints & Invariants
specs/v2/session.mdinvariant: reasoning blocks do not survive compaction boundaries — this fix is enforcement, not a policy change- The Anthropic API constraint: thinking/redacted_thinking blocks in the latest assistant message of a request cannot be modified from their original form
- Compaction must remain idempotent: a second compaction attempt after a failed one must work correctly (no stacked orphaned markers blocking progress)
Prior Art
specs/v2/session.md— compaction spec, reasoning survival rulesCONTEXT.md(root) — "Native Continuation Metadata" definition, model-switch lowering ruleAMICODE-PATCHES.md— Patch Uniform, slightly taller default tile widgets #26 (thinking block restructure), adaptive-thinking version-regex fixpackages/opencode/test/session/message-v2.test.ts— existing"thinking-bedrock"fixture and "substitutes space for empty text between signed reasoning blocks" test
Notes
- Reproducible on Amazon Bedrock with Claude Opus 4.6 (model ID:
anthropic.claude-opus-4-6-v1) when extended thinking is enabled - The error message is:
messages.7.content.8: 'thinking' or 'redacted_thinking' blocks in the latest assistant message cannot be modified. These blocks must remain as they were in the original response. - The "context cleared" symptom suggests the compaction epoch advances (new context baseline) despite no summary being produced — the guard prevents this
Activity