Context Management
Long-running sessions accumulate history - messages, tool results, screenshots, file reads. Once that history approaches the model's context window, the provider rejects the request and the session would otherwise fail. Two agent config knobs make the agent robust to this: maxToolOutputTokens caps how much any single tool result puts into context, and contextManagement automatically compacts older history as it fills up. Together they keep a long task, a long conversation, or one oversized tool output from ending the session.
Compaction and bounding transform only what the model sees on each request. The stored conversation is never changed - the complete history is always preserved.
Configuration
maxToolOutputTokens is a top-level agent field (a sibling of model and system), because bounding a single tool result is independent of history compaction. Workers set the same cap per thread on their start-thread block. contextManagement groups the compaction knobs:
| Field | Required | Description |
|---|---|---|
summarizerWorker | No | Slug of a worker (declared in workers:) that produces the running summary. Enables summarization-based compaction. |
thresholdPercent | No | Fraction of the model's context window at which compaction starts. No default; omit to disable proactive compaction. |
recentPercent | No | Fraction of the context window kept verbatim as the recent window. No default; omit to disable summarization. |
recentWindow | No | Deprecated and ignored. Superseded by recentPercent (a context-window fraction). |
How it works
- When
maxToolOutputTokensis set, every tool result is bounded before it enters the model's view: anything over the budget is replaced with a head-and-tail preview plus a note saying how much was omitted and how to fetch the rest. The full result is still preserved in the stored conversation, so nothing is lost - the model just sees a bounded copy and can narrow, page, or search for more. - When
thresholdPercentis set and the prompt crosses that fraction of the context window, the oldest turns are folded into a running summary while the original task and the most-recent turns (recentPercentof the context window, a token budget) are kept verbatim - so the agent keeps the goal and full fidelity on what it is doing now. Both are opt-in with no default: omit them and the agent does no proactive compaction, relying on the automatic recovery below. - Compaction is incremental: each cycle only summarizes the newly-expired turns and folds them into the existing summary, so cost stays bounded no matter how long the session runs.
- If the model rejects a request for being too long anyway, the agent recovers automatically (it reduces context and retries) rather than failing the session.
Bounded tool output
Some tool calls return very large output - a big file read, a full-page extract, a large MCP or skill result. Left unbounded, one such call can blow past the context window in a single step. Set maxToolOutputTokens on the agent (or, for a worker, on its start-thread block) to cap how much of any single result reaches the model, while the full result stays in the stored conversation and the trace.
There is no default: bounding only happens when you set maxToolOutputTokens, so the runtime never silently truncates output you did not ask it to. When a result is truncated, the model is always told what was omitted and how to retrieve it, so it can decide to narrow the request, paginate, or read a specific range.
Bounding is never hidden: each time a tool result first crosses the budget, a tool-output-bounded entry is recorded in the session's execution logs with the tool name, the original size, and the cap. The full, untruncated result stays in the corresponding tool-result entry, so you can always see both what the model saw and the complete output.
The summarizer worker
summarizerWorker points at a worker you define and ship like any other (see Workers). It takes two inputs - PREVIOUS_SUMMARY (the running summary so far) and CONVERSATION (the older turns to fold in) - and returns the updated summary.
Summarization is gated on its sizing knobs: a worker only runs if you also set recentPercent (the recent window it folds around), and it only runs proactively if you also set thresholdPercent. Set a worker without recentPercent and it never runs - validation warns you about this.
Declare it in the top-level workers: section so it can be resolved, but keep it out of agent.workers: that list is what the model can call as a tool, and the summarizer is invoked automatically, never chosen by the model.
Without a summarizerWorker, the agent still recovers from a context overflow by reducing older tool results, but it won't produce a summary of earlier turns.
What users see
Because the summarizer is a worker, it surfaces like any other worker, following its display mode (a subtle description indicator by default). Compaction is otherwise seamless - the conversation reads as one continuous thread and the complete history is preserved.