Skip to content

feat: add agentic context management with model-driven compression tools#2754

Draft
notowen333 wants to merge 1 commit into
strands-agents:mainfrom
notowen333:agentic-context-standalone
Draft

feat: add agentic context management with model-driven compression tools#2754
notowen333 wants to merge 1 commit into
strands-agents:mainfrom
notowen333:agentic-context-standalone

Conversation

@notowen333

Copy link
Copy Markdown
Contributor

Summary

  • Adds contextManager: 'agentic' option that registers context tools (summarize_context, truncate_context, pin) and injects <context-status> XML via middleware so the model can autonomously manage its own context window
  • Refactors shared compression logic (summarization, pin handling, tool-pair safety) out of SlidingWindowConversationManager and SummarizingConversationManager into a reusable compression/ module
  • Adds InvokeModelStage.Input middleware stage for pre-model-call message transformation

Key design decisions

  • Model is guided via tool descriptions (e.g. "Often most useful with messageType 'messages'") rather than hard-coded logic — tested and confirmed working with Bedrock Sonnet
  • Context tools operate directly on agent.messages (in-place splice) so compression effects persist across invokes
  • messageType filter lets the model selectively target chat messages vs tool results for compression
  • Pinned messages are always protected from eviction

Test plan

  • 174 unit tests pass (agentic-context, context-compression, token-usage-middleware, pin, sliding-window, summarizing)
  • 11 integration tests pass (middleware injection, tool invocation, end-to-end coherence)
  • Build passes cleanly
  • Manually verified model autonomously chooses summarize_context with messageType: "messages" for chat and truncate_context with messageType: "tools" for bulky tool results

Introduces `contextManager: 'agentic'` which gives the model tools
(summarize_context, truncate_context, pin) and injects context-status
XML so it can autonomously manage its own context window. Refactors
shared compression logic into a reusable compression/ module.
@github-actions github-actions Bot added enhancement New feature or request typescript Pull requests that update typescript code area-context Session or context related area-agent Related to the agent class or general agent questions labels Jun 12, 2026
Comment thread strands-ts/src/agent/agent.ts
Comment thread strands-ts/src/conversation-manager/compression/index.ts
Comment thread strands-ts/src/agent/agent.ts
Comment thread strands-ts/src/agent/agent.ts
Comment thread strands-ts/src/agent/agent.ts
...retryStrategies,
...(config?.plugins ?? []),
...(config?.contextManager === 'auto' && !hasOffloader
...((config?.contextManager === 'auto' || config?.contextManager === 'agentic') && !hasOffloader

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we have larger offloading limits? or allow the agent to configure this at all?

i think it makes sense to have a higher token barrier to offload if we are also exposing a tool for this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

spoke offline that we'll skip tool based offloading setting for now.

Comment thread strands-ts/src/agent/agent.ts
Comment thread strands-ts/src/conversation-manager/agentic/agentic-context.ts
Comment thread strands-ts/src/conversation-manager/agentic/agentic-context.ts
.optional()
.describe(
'Filter which messages to target. "tools" targets only tool use/result messages, ' +
'"messages" targets only non-tool messages, "all" (default) targets everything.'

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we filter by user / assistant message as well?

message being non-tool is a bit of a catch all.... what other items live in the messages array? is there a way we could do inverse (ie. select all messages except user messages, i see that as a use case for future context for sure.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can add this later since this isn't exposed. but just a note

Comment thread strands-ts/src/conversation-manager/agentic/agentic-context.ts
Comment thread strands-ts/src/conversation-manager/agentic/agentic-context.ts
Comment thread strands-ts/src/conversation-manager/agentic/agentic-context.ts
}),
])
.describe(
'How to select messages. "current_turn" pins the last user+assistant exchange. ' +

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we pin only user/assistant exchanges?

can we pin only user or only assistant? can we pin tool results?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think its important that we can only pin user messages as an option.

fine to ship as is and we can follow up on these things after summit if they are not breaking

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I redesigned the tool interface which should cover these


let targetIndices: number[]

if (selector.type === 'current_turn') {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so a turn is defined as any batch of assistant messages followed up user messages, both can be any length?

i'd want to iterate on this definition after summit

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

its now just walking backwards until we hit a user text block

Comment thread strands-ts/src/conversation-manager/agentic/index.ts
Comment thread strands-ts/src/conversation-manager/compression/pin-message.ts
/**
* Partition a range of messages into pinned and unpinned groups.
*/
export function partitionPinned(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this be in pin-messages.ts?

@lizradway lizradway Jun 12, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually im pretty sure we already have this same function there and this is duplicate

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not pure pinning, so I didn't put it there

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i.e. it uses a DS in the input that's only for the agentic mode

@lizradway lizradway Jun 12, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry what is DS? can we consolidate by calling the existing partition pinned with start=0? i think two functions w the same name that are basically the same is pretty confusing

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a really simple functionality. I think this is actually simpler to have a 3 way partition separate instead of first re-using the 2 way

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DS=data structure which specifically I mean MessageTypeFilter

Comment thread strands-ts/src/conversation-manager/index.ts
Comment thread strands-ts/src/middleware/stages.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-agent Related to the agent class or general agent questions area-context Session or context related enhancement New feature or request size/xl typescript Pull requests that update typescript code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants