Interrupting the agent: stop controls done right
Every long-running agent needs a way out — but a stop button that discards work is as bad as none. Here is how real products handle interruption: non-destructively, cleanly, and with the partial work kept.
An independent guide, grounded in official documentation from Anthropic, OpenAI and the Vercel AI SDK. Quotes are verbatim from the linked official pages and verified against them.
Stop is an off-ramp, not a kill-switch
- The interrupt control stops the current response or tool call mid-turn so the user can redirect — the work done so far is kept, not discarded.
- A stop that preserves partial work turns an escape hatch into a steering wheel: the user can read what arrived, keep it, and redirect.
- The distinction is the product: killing a run loses trust, keeping it invites iteration.
“Stop the current response or tool call mid-turn so you can redirect. Claude keeps the work done so far.”
Source: Claude Code docs — Interactive mode ↗
Cancellation cleans up — and keeps the partial work
- When a stream is aborted, the app is expected to persist partial results and clean up resources — cancelling is not the same as erasing.
- The abort path should be as deliberate as the run path: what to save, what to close, what to release.
- A cancel that silently drops the half-finished answer teaches users not to cancel.
“When streams are aborted, you may need to perform cleanup operations such as persisting partial results or cleaning up resources.”
Source: Vercel AI SDK — Advanced: Stopping Streams ↗
A stop button can be a lie
- Without explicit cancellation support, stop() only stops the client-side stream — the server-side generation may keep running in the background.
- A stop control that doesn’t actually stop is worse than none: the user thinks the work is dead while it keeps burning tokens.
- Wire the stop all the way through — client, transport, server — or don’t label it Stop.
“Without supportsCancellation, stop() still stops the client-side stream but the server-side generation may continue.”
Source: Vercel AI SDK — Advanced: Stopping Streams ↗
Define the stopping conditions
- Long-running agents should carry stopping conditions — a maximum number of iterations, a budget, a goal reached — so they know when to stop on their own.
- A stopping condition is control you don’t have to be present to exercise; it bounds runaway work.
- Show the condition in the status UI when you can — “Max 10 steps” tells the user the run is bounded, not endless.
“it’s also common to include stopping conditions (such as a maximum number of iterations) to maintain control.”
Source: Anthropic — Building effective agents ↗
- Parsing your question
- Planning the search
- Querying three sources
- Extracting citations
- Writing the answer
Interrupt without being asked
- Interruption can be automatic: the interface detects the user’s speech, cancels the in-flight response, and starts a new one without a visible control at all.
- Voice interruption is the purest form of steering — the user’s input itself is the stop signal, so the UI just has to not get in the way.
- The lesson generalizes: any strong new input can cancel the old task, as long as the partial work is kept.
“Realtime API handles interruptions when VAD is enabled, in that it detects user speech, cancels the ongoing response, and starts a new one.”
Source: OpenAI — Realtime API conversations ↗
Keep the played, drop the unplayed
- One concrete retention model: on interruption, keep what was already played and remove only the unplayed remainder of the response.
- Truncating the last response keeps the conversation coherent — the user sees what the agent got out, and the dead tail is pruned.
- Retention is a spectrum — some products keep everything, some trim to the played portion; pick the model that keeps the user’s context intact.
“We call this truncating the model’s last response, i.e. removing the unplayed portion of the model’s last response from the conversation.”
Source: OpenAI — Realtime API conversations ↗
A decision rule
- Give every long-running agent a stop control — and make the stop actually stop the work on the server, not just hide it.
- Make interruption non-destructive: keep the partial work, trim the unplayed tail, and let the user pick up from there.
- Prefer automatic interruption when the user’s next input can serve as the stop signal — the cleanest stop control is the one the user never has to find.
Design takeaways
- A stop control that discards work is worse than none — interruption should keep the partial work done so far.
- Make the stop real end-to-end: a button that only hides the stream while the server keeps generating is a lie.
- Bound long tasks with stopping conditions so they know when to stop without a human watching.
- Strong new user input can be its own stop signal — the cleanest interrupt is the one the user never has to find.
Sources
Build it with our components
Action row under a message — copy, regenerate, share and feedback.
Streaming MessageAssistant message that renders token-by-token with a cursor and stop control.
Reasoning StepsCollapsible multi-step reasoning trace with per-step status and an elapsed timer.
Voice InputA voice input control that expands into a recording panel with waveform and transcript.