When a tool call (most visibly `write` with >~1000 lines of content) is
truncated by `stop_reason: length` — e.g. OpenCode Zen's claude-3-5-haiku
with its 8192 `max_tokens` cap — the agent loop correctly refuses to
execute the call (its streamed arguments are mid-string) but used to
attach the same generic placeholder result it uses for non-runnable
non-tool turns: "Tool call was not executed because the assistant ended
its turn." The auto-continue loop re-prompted, the model re-emitted the
same oversized payload, and the user saw the file write fail again and
again — perceived as a "write tool crash" with the target file lost.
`createAbortedToolResult` now takes a `length` reason that names
`stop_reason: length` and tells the model to split the work into multiple
smaller tool calls (write the first chunk, append the rest with `edit`
insert ops, or break the file into multiple `write` targets). The skip
path in agentLoop forwards the real stop reason so the hint reaches the
model on the very next continuation. Tool execution is still guarded —
the truncated args never run.
Regression test in packages/agent/test/agent-loop.test.ts verifies the
synthetic `write` call is skipped AND the resulting tool-result message
carries the length-specific guidance.
Fixes#1785