Repository navigation
[FEATURE] Summarize through Anthropic native compaction #5401
Description
Human Overview
Anthropic's preserved thinking models will return a 400 error when the prefix of a thinking block is changed. In order to keep thinking as a part of the conversation and not dropping thinking, summarization needs to happen through Claude's Native compact API. AnthropicModel overrides Model.compact() so that sessions with these models summarize through native compaction.
SDK Language
Both / Not language-specific
Problem Statement
Offload.summarize replaces older messages with a client-side summary. On preserved-thinking Claude models, that changes the history the kept turns' thinking is bound to, so the next request fails with 400 Invalid signature in thinking block, or drop_block discards the reasoning. This affects context_manager="auto", agentic, and proactive_summarization.
Proposed Solution
Part 1 of design 0022. Override AnthropicModel.compact() with on-demand compaction (compact-2026-09-04):
- Request settings:
compaction.instructionscomes frominstructions(SummarizeConfig.systemPrompt), capped at 16,384 characters.- Use the model's
max_tokens. Astop_reason: "max_tokens"result leaves history unchanged. - Don't send
stop_sequences,output_config.format, or a forcedtool_choice(the API rejects them). - Don't use threshold compaction (
compact_20260112).
- Gating on
serverCompaction:true: native compaction.undefined: try native, and record a capability rejection asfalse.false: fall back tosuper.compact(). IfhistoryBoundis true, warn and returnundefinedinstead, since a client-side summary would break the thinking.- Timeouts, throttles and 5xx errors are never recorded. Warn and return
undefined.
- Until the metadata work lands, the capability comes from a private list of preserved-thinking model IDs (Fable 5.1, Opus 5.5, Sonnet 5.5, Haiku 5.5) plus a temporary
AnthropicModelConfig.serverCompactionoverride, mirroringuse_native_token_count. - Once a compaction block is in history,
stream()andcountTokens()usebeta.messageswith the compaction beta. - The result is stored as a summary
TextBlockwithproviderData([FEATURE] Core:providerDataonTextBlockfor session restore and model switches #5402), with no[Summarized: …]header.
Done when:
- Python and TypeScript have unit tests for the gating table, the request settings, and the
max_tokensstop case. - An integ test with
prefix_mismatch_behavior: "error"compacts repeatedly with no 400, including when the fix(models): retry with drop_block when a history edit invalidates replayed thinking #5171 retry fires (both betas sent).
Use Case
A long-running agent on Opus 5.5 with Offload.summarize("*").when(utilization=0.8, preserve_recent=4) summarizes and keeps the reasoning in its recent turns, instead of failing or losing it.
Additional Context
- Depends on: [FEATURE] Add an overridable
Model.compact()and route summarization through it #5464, [FEATURE] Core:providerDataonTextBlockfor session restore and model switches #5402 - Design:
team/designs/0022-server-side-compaction-support.md(docs(designs): server-side compaction support #5242) - Reference (earlier prototype, not the spec): feat(context-manager): route retroactive summarization through Anthropic native compaction #5287
Metadata
Metadata
Assignees
Labels
Type
Fields
Language
Activity