Once text has been shown, there is a user-visible commitment even if no final completion event arrived. A new model request is a new generation. It does not know the hidden generation state of the first model and may produce a different continuation, including a changed citation or conclusion. Splicing bytes together and labeling the result complete hides the failure. OpenAI's streaming documentation distinguishes incremental text events from a completed response and error events. That lifecycle is the important part here, not a promise that every provider can resume a lost generation.

Give each answer attempt an ID and an explicit state: generating, complete, failed after partial output, or cancelled. Persist the displayed events and their order if the product offers reconnect replay. On transport loss, first ask whether the same provider response is still running and whether that provider's chosen mode supports retrieving or resuming it. If it does, resume that response with its supported cursor and dedupe displayed events. That is different from issuing a second completion request. If it does not, mark the visible answer interrupted and offer to regenerate from the original request or from a reviewed summary of what was shown. Present a fresh answer as a new attempt or replace the partial answer visibly. Never silently append it as if it were one coherent output.

Tool calls make the boundary stricter. Partial streamed arguments are not an authorized tool action. Assemble and validate the complete call, then authorize and execute through the action broker. If a tool effect was already sent before the stream failed, a regeneration must not send it again under a new operation ID. The runtime reconciles that operation first. If the partial text claimed the action succeeded before verification, the UI must correct that status, not let the prose become state. For a read-only tool, a fresh call may be safe, but evidence and citations may have changed and should be revalidated.

What about seamless UX? You can minimize disruption with a visible “connection interrupted, resuming” state if same-response resume is supported. If recovery is a new model attempt, label it as such and keep the old fragment only as history. Test failure after the first token, mid-sentence, after a complete-looking paragraph, during a tool-argument stream, and after an external effect but before its result is shown. Count completed coherent answers, interrupted attempts, repeated effects, and user-visible corrections. A fast retry is not a success if it changes the meaning of text the user already read.