Quick Start
1
@tool decorator — the simplest surface
Pass
to_model_output to shrink what the LLM sees.2
BaseTool subclass — override the hook
Override
to_model_output on the class.3
Return a ToolResult carrying its own compact view
Set
model_output on the ToolResult directly.How It Works
The executor snapshots the full result for tracing and hooks, then swaps in the compact view for the LLM.Configuration Options
No compact view declared → behaviour is exactly as before. Fully opt-in.
Resolution order
The executor picks the first hit, then falls back to the full string.Behavioural guarantees
- Backward compatible. No compact view →
str(result)/json.dumps(...)reaches the LLM exactly as before. - Full result survives. The compact view swaps in after tracing, the
AFTER_TOOLhook, result-aware loop detection, and the loop-guard have all seen the full payload. - Annotations preserved.
AFTER_TOOLadditional_contextand loop-guard messages are mirrored onto the compact view so notices always reach the model. - Prompt-injection fence still applies. For external tools,
wrap_if_external()wraps the compact override too — it never bypasses security markers. - Multimodal untouched. If the result has
content, the compact view is not resolved — image/file parts flow through unchanged. - Overflow spill untouched.
_output_overflow(see Tool Output Spill) still works;model_outputcomposes with it. - Failure is soft. A raising compact-view builder degrades to the full output — never crashes the tool call.
Common Patterns
Turn a heavy result into a headline the model can plan on.- Big JSON → 3-line status
- Web-scrape → head + tail
- ToolResult + multimodal
User-Interaction Flow
- A user asks the agent to summarise a large API response.
- Without
to_model_output: the whole 20 KB JSON enters the LLM context on every turn → token cost and slow re-planning. - With
to_model_output: the LLM sees"142 records, 3 anomalies"; the full JSON stays available for the display panel and any downstream tool the agent chains next. - Same answer, a fraction of the tokens, unchanged code elsewhere.
Best Practices
Summarise, don't truncate blindly
Summarise, don't truncate blindly
Return the headline the model needs to decide the next step — counts, status, top items — not a raw byte-slice that hides the signal.
Keep the full payload for downstream tools
Keep the full payload for downstream tools
The full
output still reaches display, hooks, and the next tool. Never fold data the agent chains on into the compact view only.Make the builder total and cheap
Make the builder total and cheap
The hook runs on every call. Keep it fast and side-effect free — a raise falls back to the full output, but that silently loses the token savings.
Prefer ToolResult(model_output=) when you already emit a ToolResult
Prefer ToolResult(model_output=) when you already emit a ToolResult
It has the highest precedence and keeps the compact view next to the data that produced it. Reach for
@tool(to_model_output=fn) for plain-return functions.Related
Tool Output Spill
Persist large execute_command output to disk artifacts
Multimodal Tool Output
Rich image/file parts alongside the text output
Runtime Tool Result Middleware
Cross-cutting transforms on tool results
Tool Output Store
Recover full outputs for arbitrary tool return values

