549e49bc10cf27052b2ae608bd80632c026eb836
A message sent while an answer was streaming was recorded in the middle of that answer and above the tool call it ended with. The model had committed to that call in the same message it was already writing, so it had read none of it -- and on screen the tool result underneath read as something the steer had asked for. The answer also split into two bubbles around a message that was not part of it. The driver announced a steer at "the next assistant text or tool call", on the reasoning that anything the CLI says next is proof it has been round the model again. With --include-partial-messages that is not true: the deltas and the tool_use block of a message already in flight keep arriving afterwards, and none of them saw the steer. `message_start` is what actually proves it. The CLI sends the previous call's tool results back before it opens the next assistant message, so that line is the first moment anything written since can have been read -- and it carries no events of its own, which is what makes it a place to put one. Verified against 2.1.237: message_start, the blocks, the tool_result, then the next message_start. The end of the turn stays as the other half, and is the case that must not be lost: a message typed after the final model call has no later message_start, and one that is only recorded when announced would otherwise vanish while a phone drew it as still waiting. Checked live on haiku, before and after. Before: the steer landed at seq 37 among the essay's deltas, with the tool call at 45 and its result at 46. After: essay whole, tool call 42, result 43, steer 44. Also checked the case this had no reason to touch -- a steer sent during a 30-second Bash call, which was already correct -- and it still records after the result. The two tests fail on the old rule; the failure prints the old order, which is the bug.
Languages
Rust
54%
Kotlin
43.6%
Shell
2.4%