Skip to content

Custom Strategies

When the built-in modes don’t fit, build a custom strategy pipeline. Define which content to reduce, how to reduce it, and when each strategy fires.

Strategies run as an ordered pipeline. Each strategy sees the output of the previous one, so order determines priority. If two strategies target the same content, the first one to shrink it below the next strategy’s threshold wins.

The SDK always appends an emergency truncation strategy as the final step. It only fires when the context window is still overflowing after all user strategies have run.

from strands import Agent
from strands.experimental.context_manager import Offload
agent = Agent(
context_manager={
"strategies": [
Offload.truncate("tool_results").when(
threshold=2000,
),
Offload.summarize("*").when(
utilization=0.8,
preserve_recent=4,
),
],
},
)

The Offload namespace exposes three methods. Each returns a strategy builder that can be chained with .when().when() to add conditions.

Replaces oversized content with a head/tail preview. The original content is stored in the stash for later retrieval.

from strands.experimental.context_manager import Offload
Offload.truncate(
"tool_results",
{"preview_tokens": 750},
).when(threshold=1500)

Truncate configuration:

ParameterPythonTypeScriptDefault
Preview sizepreview_tokenspreviewTokens1,000
Preview modepreviewpreview"head_tail" / "headTail"

Preview modes: "head", "tail", "head_tail""headTail".

Replaces content with an LLM-generated summary. Uses the agent’s model by default.

from strands.experimental.context_manager import Offload
Offload.summarize("*").when(
utilization=0.85,
preserve_recent=4,
)

Summarize configuration:

ParameterPythonTypeScriptDefault
ModelmodelmodelAgent’s model
System promptsystem_promptsystemPromptBuilt-in

Removes matching content entirely. No preview, no stash entry.

from strands.experimental.context_manager import Offload
Offload.drop("tool_results").when(preserve_recent=5)

Chain .when().when() to control when a strategy fires. Conditions determine the granularity of the strategy, not the method.

ConditionGranularityBehavior
thresholdthreshold onlyPer-block, eagerActs on each block above this token size on message arrival
utilizationutilization onlyMessage-level, batchRemoves/summarizes oldest messages when utilization exceeded
BothMessage-levelTargets messages with blocks over the threshold, fires at utilization
preserve_recentpreserveRecentNumber of most recent matching messages to skip
preserve_recentpreserveRecent

accepts an integer (absolute count) or a float between 0 and 1 (ratio of matching messages, e.g., 0.7 keeps 70%).

Fire eagerly on individual blocks over 2,000 tokens:

from strands.experimental.context_manager import Offload
Offload.truncate("tool_results").when(threshold=2000)

Summarize oldest messages when the window reaches 85%:

from strands.experimental.context_manager import Offload
Offload.summarize("*").when(
utilization=0.85,
preserve_recent=4,
)

Target tool results over 1,500 tokens, but only fire when the window reaches 90%:

from strands.experimental.context_manager import Offload
Offload.truncate("tool_results").when(
threshold=1500,
utilization=0.9,
)

Targets specify which content a strategy applies to.

TargetPythonTypeScript
All content"*""*"
Tool results"tool_results""toolResults"
Failed tool results"tool_result_errors""toolResultErrors"
Assistant text"assistant_text""assistantText"
User text"user_text""userText"
Specific tools["tool::bash", "tool::read_file"]["tool::bash", "tool::read_file"]
Exclude tools["!tool::bash"]["!tool::bash"]

Tool name lists use the tool:: prefix. Prefix a name with ! to exclude it (apply to all tools except the listed ones).

The stash stores all message content on arrival as JSON, before any strategy runs. Truncated or summarized content can be retrieved on demand through the retrieve_contextretrieve_context tool, which the SDK registers by default.

Stash uses in-memory storage by default. Configure it through the stashstash key:

  • Omit or pass true for defaults (in-memory storage)
  • Pass a config with a custom storage backend
  • Pass false to disable stash entirely
from strands import Agent
# Disable stash and retrieval tool
agent = Agent(
context_manager={
"stash": False,
},
)

Every strategy pipeline ends with an emergency truncation strategy, appended automatically. It fires only when the context window is still overflowing after all user strategies have run. When it fires, it drops the oldest 20% of non-head messages.

Emergency truncation intentionally ignores pinned messages so an all-pinned overflow is still recoverable. Regular strategies respect pins.