One Pipe: Every Tool Output Is a Conversation¶
Evidence Level: F (directly proven by source code)
Analysis Baseline:4f843556
TL;DR¶
All tool outputs in Clawith flow through a single pipe into messages[], with no distinction between "execution result" and "conversation context." execute_code stdout, read_file contents, web_search results—all injected as role="tool" messages and permanently embedded in the conversation.
1. The Full Path: Tool Output → messages[]¶
# agent_tools.py — all tool _outcome functions
result = await backend._format_result(result) # base.py:117-124
return _typed_success(result) # agent_tools.py
# base.py:117-124
def _format_result(self, result):
parts = []
if result.stdout:
parts.append(f"📤 Output:\n{result.stdout}")
if result.stderr:
parts.append(f"\n⚠️ Stderr:\n{result.stderr}")
return "\n".join(parts)
# caller.py:621-835
api_messages.append(LLMMessage(role="tool", content=output))
Output Size Limits¶
| Scenario | Backend | Limit |
|---|---|---|
| execute_code | subprocess | stdout 1MB / stderr 500KB |
| execute_code | Docker | stdout 10K chars / stderr 5K chars |
| execute_code | base._format_result | No truncation (subprocess path) |
| read_file | — | Default 2000 lines, no char limit |
| jina_read | — | Default 8K, max 20K chars |
| web_search | — | Max 10 results |
No Independent Logging¶
execute_code stdout/stderr is never persisted to any audit table. It lives only in messages[]. If the conversation is compressed or lost, the execution log is gone forever.
2. Consequences¶
- Noise pollution: pip progress bars, npm dependency trees, git clone logs, AWS s3 cp transfer progress—information worthless to the LLM—crowd the context window
- No audit trail: tool execution results have no independent log, no traceability
- Death loop: compression loses critical info → LLM re-reads files / re-executes code → expansion again
3. Relationship to AI Coding¶
- "Tool output = conversation" is AI's most natural implementation: no distinction between "result" and "context," because the API only requires returning a string
- No audit awareness: AI won't proactively say "this output should also be written to a log table"—that requires an architect's holistic judgment about traceability
- Zero processing:
_typed_success(full_output)is the simplest possible implementation—no truncation, no summarization, no structuring
Code References¶
| File | Lines | Key Content |
|---|---|---|
agent_tools.py |
throughout | All _*_outcome return _typed_success(full_output) |
caller.py |
621-835 | api_messages.append(role="tool", content=...) |
base.py |
117-127 | _format_result concatenates stdout/stderr |
subprocess_backend.py |
16-17 | MAX_STDOUT_CAPTURE_BYTES = 1_000_000 |
docker_backend.py |
176-177 | stdout[:10000], stderr[:5000] |