Skip to content

[FEATURE] Add an overridable Model.compact() and route summarization through it #5464

Description

@jimbrub

Human Overview

Summarization should go through the model, so each provider can decide how to compact. Model.compact() gets a working default that does today's client-side summary, and providers that support native compaction override it, the same way countTokens() works.

SDK Language

Both / Not language-specific

Problem Statement

SummarizeStrategy builds the summary itself, on the client. A provider that can compact server-side, keeping preserved thinking valid, has no way to take over. The strategy also has nothing to tell it where a safe cut point is (a user-prompt boundary, never between a toolUse and its toolResult).

Proposed Solution

Part 1 of design 0022:

  • Add a concrete Model.compact(), not an abstract one. The default is today's client-side summary, and it returns [summary, ...preserved] or undefined.
    • TS: compact(messages, options?: CompactOptions) with preservedMessages, systemPrompt, toolSpecs, instructions.
    • Python: compact(messages, *, preserved_messages=0, tool_specs=None, system_prompt=None, instructions=None).
  • Add a shared compactionSplitIndex helper. It moves the cut back to a user-prompt boundary, never splits a toolUse/toolResult pair, and never summarizes pinned messages.
  • The strategy decides when to compact and the model decides how. Message-level summaries in SummarizeStrategy always call model.compact() (through _compact()), passing the live system prompt and tool specs, and SummarizeConfig.systemPrompt as instructions.
  • BaseOffloadStrategy gains _isRetroactive (_isMessageLevel || _preserveRecent > 0). A retroactive per-block summary calls compact() only when the model reports serverCompaction === true. Otherwise it keeps today's behavior.

Done when:

  • Python and TypeScript have unit tests for the default compact(), compactionSplitIndex (tool pairs, pinned messages, user-prompt boundaries), and the strategy routing.
  • Summarization output and behavior are unchanged for models that don't override compact().

Use Case

A provider adds native compaction by overriding one method, and every summarize strategy (context_manager="auto", agentic, proactive_summarization) picks it up.

Additional Context

Metadata

Metadata

Assignees

Labels

Type

Fields

Language

None yet

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions