Bound what the model sees
One size limit per tool result: keep the head and the tail, save the rest to a file.
- Problem
One noisy command can dump megabytes of output into the conversation, filling the context window and burying the part that mattered.
- Idea
Cap every tool result with one limit, keep its beginning and end, and save the full output to a file the model can open if it needs more.
An agent runs npm test, a build, or a grep over a big repo, and one tool result is suddenly megabytes of text. If it all goes into the conversation, it fills the context window, costs a fortune on every later turn, and buries the one line that mattered.
This repo's rewrite puts every tool result through one choke point with one limit.
Try it: 2,000 lines or 50 KB
change the output size and line width; see what the model gets
Output under both limits passes through unchanged. Over either one, the model gets the beginning and the end with a marker in between, and the full text is saved to a file whose path is in the marker.
... output truncated; full content saved to <data>/tool-output/tool_01J… ...
The rules
- One aggregate limit per tool resultThe configured maximum lines or UTF-8 bytes, whichever is reached first: 2,000 lines or 50 KB by default. It's provider-independent; token pressure is handled later, by context assembly and compaction.
- Tools shape, the registry enforcesA tool may first turn its output into something more useful for the model. The tool registry applies the final limit to every tool, so no tool can forget.
- Keep both endsGeneric truncation keeps the first half and the last half of the allowed lines. For build and test output, the end is usually where the error is.
- Lose nothingThe complete text is written to a managed tool-output file, and its path appears in the visible marker and as a typed field, so the model (or a later tool call) can open it.
The careful parts
Byte-safe cuts
Head and tail are cut by UTF-8 byte size one character at a time, so a multi-byte character is never split in half.
The marker fits too
Room for the marker is reserved inside the limit, so the bounded result itself never exceeds it.
Files are never overwritten
Each file gets a new ascending ID and is created with an exclusive flag. Old ones are cleaned up after a 7-day retention.
Structure untouched
Only the text the model sees is bounded. The tool's validated structured result is never modified.
Steal this
Put every tool result through one choke point with one limit. Keep the beginning and the end, save the rest to a file whose path the model can see, cut on character boundaries, and never let a tool opt out.
Use it in your code
A prompt for your coding agent
Run it from the root of your repo. It checks whether the idea fits before it changes anything.
Put a hard, central limit on how much tool or command output this app sends to an LLM.
The idea: every tool result goes through one choke point that enforces a single limit (lines or bytes, whichever comes first). Oversized output keeps its beginning and end with a clear marker in between, and the complete output is saved to a file whose path the model can open later. Tools may summarize their own output first, but the central limit always has the final say.
1. Find every place where tool, command, API or file output is added to a model request. Tell me whether there's one central place that limits size, or none.
2. Measure or estimate the worst cases: the largest outputs these tools can produce today.
3. Propose one choke point with a configurable limit (start with 2,000 lines or 50 KB). It keeps the first and last halves, inserts a marker like "... output truncated; full content saved to <path> ...", and writes the full text to a file that is never overwritten and is cleaned up after a few days. Count bytes in UTF-8 and never cut a character in half.
4. Implement it, with tests for: output under the limit (unchanged), over the line limit, over the byte limit with multi-byte characters, and a saved file containing the full output.
Keep structured results unchanged. Only the text the model sees is bounded.Read the source
Where this comes from
OpenCode (anomalyco/opencode), the open-source coding agent (these lessons are from its upcoming v2). The files behind this lesson: