/responses/{response_id}/cancel or /invocations/{invocation_id}/cancel - scoped to one specific in-flight turn. It’s different from steering, which redirects a turn by queuing a replacement, and different from stopping a session, which is a session-management API, not a per-turn one - see How stopping a session affects an in-flight turn for the side effect stopping a session has on any work in flight.
Long-running agents are in preview. APIs and package versions can change.
Cancel in the Responses protocol
The framework exposes a built-in cancel endpoint - you don’t implement it yourself:background=true; calling it on a synchronous response returns an error. It sets the same cooperative cancel signal your handler already observes as its third positional parameter, and stamps context.client_cancelled = True so the handler can tell a genuine cancel apart from steering pressure:
Cancel in the Invocations protocol
The Invocations protocol registers the/invocations/{invocation_id}/cancel route for you, but doesn’t wire it to anything automatically - the framework has no built-in disconnect monitoring or automatic cancellation for this protocol. Without a registered handler, calling it returns 404 not_found.
If you’re using the task primitives (@task / @multi_turn_task) directly, the way to actually end an in-flight or suspended multi-turn chain is delete(), called on the decorated function itself:
delete() always removes the chain’s persisted record, for a running turn or a suspended one waiting on its next turn. This behavior is a real difference from the Responses protocol’s /cancel: Responses cancels the current turn but keeps the conversation resumable; delete() ends the conversation - there’s no next turn to resume. There’s no built-in “cancel this turn only, keep the chain alive” primitive for direct task-primitive use; if you need that, build it as an app-level convention (for example, a flag in your own task state that the handler checks and reacts to by returning normally, leaving the chain in its usual suspended state).One-shot tasks (@task) have no equivalent method - they’re always deleted automatically on their own completion, failure, or cancellation, so there’s nothing separate to call.What happens at the task-store level
The outcome depends on which mechanism ends the turn. The two protocols don’t always produce the same result:How this process differs from stopping a session
Cancel is an agent-level route scoped to one turn. Stopping a session is a session-management API that tears down the whole container. It has noresponse_id or invocation_id and isn’t part of the cancellation contract described on this page. Because it ends the container rather than targeting a turn, it still affects any turn that happens to be running. To learn more, see How stopping a session affects an in-flight turn.