Problem
The first sentence makes it obvious the model misread the question. The remaining four hundred words are going to be a careful, well-formatted answer to something nobody asked, and they’ll take another twenty seconds to arrive.
Solution
Streaming created this problem. It also has to solve it. Before responses streamed there was no middle of a response to stand in, so there was nothing to interrupt. Now there’s a twenty-second window in which the viewer knows more than the model does.
The dominant convention puts stop in the send button’s position and swaps the two by state. One control slot, two mutually exclusive states, and the pointer is already there because that’s where the viewer just clicked. It costs nothing in layout and preserves the muscle memory.
Stopping has to do four things, and products routinely ship two of them:
- Abort the request. The client cancels the stream. Separately, the server has to cancel the generation, or the model keeps producing tokens nobody will read and the viewer keeps paying for them.
- Keep the partial output. Discarding it is hostile. The first two paragraphs were often exactly right, and the interruption was about the third. Truncating on stop throws away the part that worked.
- Mark it stopped. A partial answer that looks complete is worse than no answer, because a later reader has no way to tell the model stopped mid-sentence rather than concluding there. Label the turn, and keep the label when the conversation is exported or shared.
- Say what it cost. If the product meters usage, a stopped response still consumed tokens. Silence here produces support tickets.
This is HAX guideline 8 and guideline 9 in the same control. Efficient dismissal means getting out of an unwanted service quickly. Efficient correction means making it easy to steer the system when it’s wrong. Stop is the moment both become available at once, and the reason it earns such a prominent slot.
The keyboard binding is the part most often missed. Escape is the obvious key, it’s unclaimed in a chat surface, and binding it costs one line.
Use when
Anything that streams for longer than a couple of seconds. If a response can be interrupted usefully, the control has to exist.
Don’t use when
Generation is short enough that the button would appear and vanish before it could be hit. Below roughly a second the swap is visual noise, and a viewer who lands on a flickering control learns to distrust it.
Trade-offs
Swapping send and stop in the same position means a fast typist who hits enter twice stops their own generation on the second press. Guarding with a short disabled window fixes it and introduces a moment where neither action is available. Keeping partial output leaves incomplete text in the transcript that later turns may reference, and the model will read its own truncated sentence as context on the next turn unless the stop is recorded. A stop that only cancels the client stream is the quiet failure here—the interface goes calm, the meter keeps running, and nothing on screen says so.
Checklist
- Does stop cancel the generation server-side, or only the client’s stream?
- Does the partial response stay on screen?
- Is the turn marked as stopped, and does the mark survive export and sharing?
- Does the model see that the previous turn was interrupted when it reads the history?
- Is Escape bound to it?
- Does a double-press of enter stop the generation the first press started?
- If usage is metered, does the viewer learn what the stopped response cost?
- Can the viewer edit and resend immediately, or do they have to clear something first?
- What happens to a tool call or a document already in flight when stop is pressed?
- Does the control return to send cleanly, with no intermediate state that accepts neither?
Compare
ChatGPT puts stop in the composer where send was and leaves the partial answer in place, so the next move is a follow-up rather than a recovery. Claude uses the same slot and keeps a document already opened alongside the stopped turn, so interrupting the prose does not discard the artifact it was building. Perplexity has less need for the control, because an answer short enough to read in one pass finishes before the intent to stop it forms. GitHub Copilot Chat inherits the editor’s conventions instead of the composer’s, where Escape already means dismiss, and the in-editor suggestion disappears entirely rather than being kept as partial output.
Related
Streaming response is the pattern that makes this control necessary. Regenerate is the other half of the correction: stop kills the answer, regenerate asks for another one. Composer owns the slot the button lives in. Generation error looks almost identical on screen and means something completely different. Usage meter is where the cost of a stopped response has to show up.