Skip to content

feat(context): add context manager class#2547

Draft
lizradway wants to merge 1 commit into
strands-agents:mainfrom
lizradway:context-manager
Draft

feat(context): add context manager class#2547
lizradway wants to merge 1 commit into
strands-agents:mainfrom
lizradway:context-manager

Conversation

@lizradway
Copy link
Copy Markdown
Member

@lizradway lizradway commented Jun 1, 2026

Description

Implements the v1 contextManager facade as designed in strands-agents/docs#831.

Adds a contextManager parameter to AgentConfig that pre-composes the SDK's context management primitives into a single configuration surface. An internal ContextManager plugin composes sub-plugins (ContextCompression, ContextOffloader) that handle the actual behavior.

Architecture

ContextManager (internal plugin)
├── ContextCompression (sub-plugin)
│   ├── Proactive compression (BeforeModelCallEvent)
│   ├── Reactive overflow recovery (AfterModelCallEvent)
│   └── Sliding window enforcement (AfterInvocationEvent)
└── ContextOffloader (sub-plugin)
    ├── Tool result caching (AfterToolCallEvent)
    └── retrieve_offloaded_content tool

Sub-plugins work independently when used standalone. User-provided plugins with matching names take precedence over managed sub-plugins. When contextManager is set, ContextCompression takes priority — NullConversationManager is used (same pattern as other dedicated-param plugins like retryStrategy, sessionManager).

What ships

  • contextManager parameter on AgentConfig — accepts "auto" or a config object
  • ContextCompression plugin — proactive/reactive compression with own reduction logic (truncate or summarize)
  • ContextOffloader — stays in vended-plugins/context-offloader/, composed internally by ContextManager
  • Message pinning (context-manager/compression/pin-message) — pinMessageTool for agent-controlled pinning at runtime. Internal utilities (pinMessage, unpinMessage, isPinned) are not exported; programmatic pinning API (e.g., Message.pin()) deferred.
  • estimateInputTokens() utility — shared token estimation in src/context-manager/token-estimation.ts
  • protectedMessageRange — positive protects first N, negative protects last N messages from eviction
  • conversationManager marked as pending deprecation — still works, JSDoc-tagged

Public API Surface

New on AgentConfig:

  • contextManager?: ContextManagerParam

New exports:

  • pinMessageTool (agent-invokable tool)
  • Types: ContextManagerParam, ContextManagerConfig, ContextStrategyValue, OffloaderConfig, CompressionConfig, CompressionOptions, TruncateCompressionConfig, SummarizeCompressionConfig, CompressionMethod

All classes (ContextManager, ContextCompression, ContextOffloader) are internal. ContextOffloader remains accessible via the vended-plugins/context-offloader sub-path for backward compat.

Configuration model

Two semantics depending on whether strategy: 'auto' is present:

Override (strategy: 'auto') — starts with everything enabled, you override specific settings:

contextManager: "auto"                                              // everything with defaults
contextManager: { strategy: 'auto', compression: { windowSize: 60 } }  // auto, tweak compression
contextManager: { strategy: 'auto', offloader: { threshold: 5000 } }   // auto, tweak offloader

Additive (no strategy) — starts with nothing, you enable what you want:

contextManager: { compression: true }                               // only compression
contextManager: { compression: 'summarize' }                        // only summarize compression
contextManager: { offloader: true }                                 // only offloading
contextManager: { compression: true, offloader: true }              // both (same as "auto")
contextManager: {}                                                  // nothing enabled

Plugin registration

contextManager must be passed via the dedicated parameter — same pattern as conversationManager, retryStrategy, and sessionManager. No guards for misuse in plugins[] (consistent with other special-cased plugins).

Deprecation Plan

The following are marked as pending deprecation in v1 and will be removed in v2:

  • AgentConfig.conversationManagercontextManager: { compression: ... }
  • Agent._estimateInputTokens() → shared estimateInputTokens() utility
  • BeforeModelCallEvent.projectedInputTokens → future contextManager budget API
  • ConversationManager, SlidingWindowConversationManager, SummarizingConversationManager, NullConversationManagerContextCompression plugin
  • vended-plugins/context-offloader/ sub-path → import from @strands-agents/sdk directly

Breaking Changes

None. All changes are additive. Existing behavior is unchanged when contextManager is not set.

Related Issues

Documentation PR

strands-agents/docs#831

Type of Change

New feature

Testing

How have you tested the change?

  • I ran npm run check
  • All 2532 existing unit tests pass (no regressions)
  • Type check passes (npm run type-check)
  • Lint passes (npm run lint)

Checklist

  • I have read the CONTRIBUTING document
  • I have added any necessary tests that prove my fix is effective or my feature works
  • I have updated the documentation accordingly
  • I have added an appropriate example to the documentation to outline the feature, or no new docs are needed
  • My changes generate no new warnings
  • Any dependent changes have been merged and published

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant