Tool Result Pairing
Everytool_use (a tool call made by the model) must have a corresponding tool_result in the conversation history. When this pairing breaks — due to interruption, timeout, or silent error — the API rejects the history.
The EnsureToolResultPairing system automatically validates and repairs:
Synthetic Results
When a tool_use has no corresponding result, ChatCLI injects:3-Phase Validation
1
ID Collection
Traverses the entire history collecting
tool_use IDs (from assistant messages) and tool_result IDs (from tool messages).2
Misalignment Detection
Compares the two sets of IDs. Tool uses without a result are “missing”. Tool results without a use are “orphans”. Duplicate IDs are flagged for deduplication.
3
History Reconstruction
Rebuilds the history: removes orphans, deduplicates tool_use IDs, and injects synthetic results after assistant messages with unmatched tool_uses.
Result Budget Enforcement
Tool results such as large file reads or command output can quickly consume the context window. The budget system limits the aggregate size at three levels:Per-tool truncation (capability)
Plugins that implementplugins.TruncationAware declare their own cap — useful when the tool has non-default context needs:
Truncation preserves the historical head/tail shape (5000-char preview + 1000-char suffix +
[TRUNCATED N chars omitted, M kept] marker).
How Enforcement Works
The budget is applied in two passes:- Pass 1: Per Result
- Pass 2: Per Turn
Each individual result is checked against
DefaultPerResultMaxChars (20KB). If it exceeds the limit, the full content is saved to disk and replaced with a preview:Disk Persistence
Truncated results are saved as temporary files inside the Session Workspace, instead of the legacy global/tmp/chatcli-tool-results/:
- Isolation between sessions. Multiple
chatcliinstances running in parallel on the same host no longer share the overflow pool. - On-demand reads by the agent. The scratch dir is on the agent’s read allowlist, so when the model encounters the
[full output saved to ...]marker in the preview, it can open the file withread_file:
Preview: Head + Tail
The preview retains the beginning and end of the result to maximize usefulness:Progressive Microcompaction
Microcompaction progressively reduces the size of old tool results as the conversation advances, without losing critical information:
With the compression layer active, both levels are lossless: the original result is archived in the CCR store before the cut and the preview/summary carries a
<<ccr:KEY>> marker (preserved across levels) that the model expands with @recall.
Content Type Detection
The summary automatically identifies the content type for context:Microcompaction Configuration
Only results larger than 3,000 chars are compacted. Small results are always preserved. Results from write and execution tools are preserved as they contain critical error information.
Complete Flow
Tool result management is applied in this order during the agent loop:Complete Configuration
Next Steps
Session Workspace
Where overflow files live and how the agent reads them.
Subagent Delegation
Complementary strategy to avoid saturating context with raw data.
Context Recovery
What happens when even with budgeting the context overflows.
Cost Tracking
Monitor token consumption including tool results.