Repository navigation
Honor $/cancel_request for a prompt and a sign-in - #228
Conversation
There was a problem hiding this comment.
This change enables the agent to honor $/cancel_request notifications for both prompt and sign-in requests, which previously required explicit handler support and were ignored if sent by JSON-RPC id. The main.rs changes ensure that prompt and authenticate handlers now check for cancellation and terminate appropriately: prompts are stopped via cancel_turn (which also kills any running command), and sign-ins are dropped with an error. The select! in the prompt handler ensures that cancellation is registered after the first poll, avoiding a race where cancellation could be missed if it arrived before the handler registered. The test suite adds a case to verify that $/cancel_request for a prompt id cancels the turn, kills the terminal, and returns the correct stop reason, using a new helper to generalize mid-command cancellation. Previous findings about cancellation not being honored for $/cancel_request are addressed by these changes.
Automated review by siGit Code Review · commit 3c5f670 · see the review dashboard
The SDK records a $/cancel_request against the request it names, but a handler has to read responder.cancellation() for anything to happen, and none did. A client that cancels by JSON-RPC id instead of session/cancel was ignored. The prompt handler now watches the marker and stops the turn through cancel_turn, the path session/cancel already takes, so the running command is killed too. The prompt is still answered with a result and the cancelled stop reason, which keeps what was streamed. authenticate is dropped instead, which closes the loopback listener, and answers -32800. The other handlers still ignore the notification, as the spec allows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Co-Authored-By: siGit Code v1.6.7-acp <noreply@sigit.si>
3c5f670 to
0f3d1f0
Compare
The SDK records a
$/cancel_requestagainst the request it names, but a handler has to readresponder.cancellation()for anything to happen, and none did. A client that cancels by JSON-RPC id instead ofsession/cancelwas ignored.session/prompt: the handler watches the marker and stops the turn throughcancel_turn, the pathsession/cancelalready takes, so the running command is killed too. The prompt is still answered with a result and thecancelledstop reason, which keeps what was streamed.authenticate: the sign-in is dropped, which closes the loopback listener, and the request is answered-32800.The select polls the turn before the marker. A turn registers for cancellation on its first poll, and a cancel that arrived while the prompt was queued on the session lock would otherwise run before there was anything to cancel.
Test:
a_cancel_request_for_the_prompt_ends_the_turn_cancelledintests/acp_client_terminal.rsdrives the binary, sends$/cancel_requestwhile a command runs in the client's terminal, and checks forterminal/killand thecancelledstop reason.