You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
After resuming, `useChat`'s built-in `stop()` won't send the stop signal to the backend because
161
+
the AI SDK doesn't pass its abort signal through `reconnectToStream`. Use
162
+
`transport.stopGeneration(chatId)` for reliable stop behavior after resume — see
163
+
[Stop generation](#stop-generation) for the recommended pattern.
164
+
</Note>
165
+
159
166
<Warning>
160
167
In React strict mode (enabled by default in Next.js dev), you may see a `TypeError: Cannot read
161
168
properties of undefined (reading 'state')` in the console when using `resume`. This is a [known
@@ -235,10 +242,18 @@ Supports Zod, ArkType, Valibot, and other schema libraries supported by the SDK.
235
242
236
243
## Stop generation
237
244
238
-
Calling `stop()` from `useChat` sends a stop signal to the running task via input streams. The task aborts the current `streamText` call, but the run stays alive for the next message:
245
+
Use `transport.stopGeneration(chatId)` to stop the current generation. This sends a stop signal to the running task via input streams, aborting the current `streamText` call while keeping the run alive for the next message.
246
+
247
+
`stopGeneration` works in all scenarios — including after a page refresh when the stream was reconnected via `resume`. Call it alongside `useChat`'s `stop()` to also update the frontend state:
239
248
240
249
```tsx
241
-
const { messages, sendMessage, stop, status } =useChat({ transport });
250
+
const { messages, sendMessage, stop: aiStop, status } =useChat({ transport });
251
+
252
+
// Wrap both calls in a single stop handler
253
+
const stop =useCallback(() => {
254
+
transport.stopGeneration(chatId);
255
+
aiStop();
256
+
}, [transport, chatId, aiStop]);
242
257
243
258
{
244
259
status==="streaming"&& (
@@ -249,6 +264,20 @@ const { messages, sendMessage, stop, status } = useChat({ transport });
249
264
}
250
265
```
251
266
267
+
<Info>
268
+
`transport.stopGeneration(chatId)` handles the backend stop signal and closes
269
+
the SSE connection, while `aiStop()` (from `useChat`) updates the frontend
270
+
status to `"ready"` and fires the `onFinish` callback.
271
+
</Info>
272
+
273
+
<Tip>
274
+
A [PR to the AI SDK](https://github.com/vercel/ai/pull/14350) has been
275
+
submitted to pass `abortSignal` through `reconnectToStream`, which would make
276
+
`useChat`'s built-in `stop()` work after resume without needing
277
+
`stopGeneration`. Until that lands, use the pattern above for reliable stop
278
+
behavior after page refresh.
279
+
</Tip>
280
+
252
281
See [Stop generation](/ai-chat/backend#stop-generation) in the backend docs for how to handle stop signals in your task.
Returns `true` if the stop signal was sent, `false` if there's no active session. Works for both initial connections and reconnected streams (after page refresh with `resume: true`).
532
+
533
+
Use alongside `useChat`'s `stop()` for a complete stop experience:
534
+
535
+
```tsx
536
+
const { stop: aiStop } =useChat({ transport });
537
+
538
+
const stop =useCallback(() => {
539
+
transport.stopGeneration(chatId);
540
+
aiStop();
541
+
}, [transport, chatId, aiStop]);
542
+
```
543
+
544
+
See [Stop generation](/ai-chat/frontend#stop-generation) for full details.
0 commit comments