What changed: ended() kept a turn's id (turnUUID, backKey) only until the
reply that called a tool. From then on, a client that went away while the
run answered the turn's tool results (a cut connection, or the user
interrupting to send a message queued during the tool call) could not be
rewound: letGo ended the run. The client's next request, its results sent
again or the next turn, logged "tool results no run waiting", and a new
Claude Code was told the whole conversation in one message, with every
image in it, which the model in #1365 took for new. Now the turn's id lasts
across its tool rounds, until a reply ends without calling a tool. letGo
rewinds the run to the turn's user message, its tool rounds with it, and
the run waits at the conversation before the turn. The next request is
resumed there (nextTurn's key is backKey) and told the turn since its user
message. resume logs "a turn taken back goes on in its run" after the
"no run waiting" line. A run started anew for the turn, or one with a call
still in the client's hands, is ended as before. Nothing else sent to
Anthropic changes.
Why: the issue's log showed "no run waiting" four times, then a whole-
conversation replay. On current main a queued message with an image is
sent beside the tool_result (checked with Claude Code 2.1.295 against a
local mock) and match keeps it with the result, so it does not break
matching by itself. The MCP call reaches magpie ~3ms after the tool
reply's message_stop, well inside match's 500ms grace. What drops the run
is a client going away during a tool-result continuation. The exact client
trigger in the report is not confirmed.
What was run:
- New TestClaudeToolResultsGivenUpOnAreTakenBack (fake Claude Code that
makes its call through magpie's MCP callback and answers
rewind_conversation): the turn's results are given up on mid-reply, the
run is rewound to the turn's message, and the resend goes on in the same
process, told the turn and not turn 1's words. With ended() clearing the
id as before, it fails: no rewind is asked.
- Real Claude Code 2.1.295 against a local mock of Anthropic:
rewind_conversation to a user message, sent while the reply to that
turn's tool result is streaming, answers rewound:true, and the next
request's messages drop the turn and its tool round.
- go test -tags nogui ./internal/gateway/ (full package) under a temp HOME;
-race -count=20 on the new test and the TestClaudeTurnGivenUpOn* /
TestClaudeFirstTurnGivenUpOnEnds tests; gofmt -l; go vet for darwin,
linux and windows (-tags nogui); GOOS=linux/windows go build.
Not tried with a real Claude account or Claude Desktop.