Manage context
A tool-heavy run grows with every trip: each result stays in the history and is re-sent on every later call. Two agent options keep that in check. Both are off by default and both work with every provider.
contextEditing | compaction | |
|---|---|---|
| What it does | Replaces the content of old tool results with a short placeholder | Replaces an old slice of the conversation with a summary |
| Extra model call | No | Yes (your summarize callback) |
| Provider-native form | Anthropic clear_tool_uses | Anthropic server-side compaction (providerOptions) |
| Loses | Tool output (the call and its arguments stay visible) | Detail of everything in the slice |
When both are set, editing runs first and compaction summarizes what is still too large.
Clear old tool results
Section titled “Clear old tool results”const worker = ai.agent({ model, tools, contextEditing: { clearToolResults: { afterTokens: 60_000, // start once the history is estimated at this size; omit to clear every trip keep: 4, // newest tool results that stay intact (default 3) exclude: ["plan"], // tools whose results are never cleared clearAtLeast: 8_000, // skip a clear that would free fewer tokens than this placeholder: "[cleared]", // default: "[tool result cleared to save context]" }, },});clearToolResults: true uses the defaults (keep 3, no size threshold).
Token estimates (this rule’s, and compaction’s) count each image, PDF or audio part as a fixed 1,000 tokens, not by its base64 length.
clearAtLeast keeps a small clear from rewriting the prompt cache: when the
results to clear would free fewer tokens than that, nothing is cleared on that
trip. On the client the freed size is estimated from the cleared results; on
Anthropic the provider applies it.
Only the content of old tool messages changes. Every tool call still has its result, so the history stays valid for every provider, and the model still sees which tool ran with which arguments. Results are cleared in the agent’s history, so they stay cleared on later trips (this also keeps provider prompt caches stable after the first edit) and in report.messages and durable snapshots.
A clear rewrites history the provider may already have cached, so the next request pays a cache write for the changed prefix instead of a cheap cache read. With cache reads priced at a small fraction of normal input, clearing pays off mainly when it frees a large share of the window near the context limit; a small clear on a warm cache usually costs more than it saves (clearAtLeast guards against that). Defaults are unchanged.
Each client-side clear emits agent.context.edited with { tripIndex, clearedResults, tokensBefore, tokensAfter }, so a cache write that follows is explained. The trip’s prompt fingerprint is taken after clearing and compaction, so with diagnostics: { cacheFingerprint: true } that trip’s agent.trip.cache-miss-cause lists messages. A provider-side (native) edit does not emit the event.
agent.on("agent.context.edited", ({ tripIndex, clearedResults, tokensBefore, tokensAfter }) => { log.info( `trip ${tripIndex}: cleared ${clearedResults} results, ${tokensBefore} -> ${tokensAfter} tokens`, );});afterTokens is a number or a window-relative { share, reserve?, max? } (see Automatic compaction for the formula; an unknown window means no clearing). Leaving it out clears on every trip, which rewrites the prefix and defeats prompt caching on providers without native editing, so the agent logs a one-time warning. It is compared with an offline character estimate of messages and tool schemas. Pass countTokens(messages, options) for an exact count (model.countTokens when the model has one).
Native providers
Section titled “Native providers”A model that sets capabilities.nativeContextEditing (the Anthropic adapter does) handles the edit server-side: the agent sends the rule as ModelCallOptions.contextEditing and leaves the history alone. The Anthropic adapter turns it into a clear_tool_uses_20250919 edit (afterTokens is the input-token trigger, keep the number of tool uses kept, exclude becomes exclude_tools, clearAtLeast becomes clear_at_least) and adds the context-management beta. An explicit providerOptions.anthropic.contextManagement.clearToolUses still wins over the neutral rule.
Set contextEditing.native: false to edit on the client even on such a model. Other adapters ignore the hint, so the agent clears client-side for them.
The model needs to support context editing on Anthropic’s side (Claude 4 and later); pass native: false for a proxy or older model that does not.
Summarize
Section titled “Summarize”compaction is covered in Run an agent: afterTokens, keep and a summarize callback (ai.compaction.summarize({ model }) builds one). Reach for it when the conversation itself, not just tool output, outgrows the window.
Which one
Section titled “Which one”- Large tool outputs (file reads, search results, API payloads):
contextEditing. Cheap, no extra call. - Long chats with little tool use:
compaction. - Both for long autonomous runs.
- Anthropic only: its server-side compaction is available through
providerOptions.anthropic.serverCompactionas well.