|
| 1 | +--- |
| 2 | +title: "Changelog" |
| 3 | +sidebarTitle: "Changelog" |
| 4 | +description: "Pre-release updates for AI chat agents." |
| 5 | +--- |
| 6 | + |
| 7 | +<Update label="April 14, 2026" description="0.0.0-chat-prerelease-20260414181032" tags={["SDK"]}> |
| 8 | + |
| 9 | +## `chat.response` — persistent data parts |
| 10 | + |
| 11 | +Added `chat.response.write()` for writing data parts that both stream to the frontend AND persist in `onTurnComplete`'s `responseMessage` and `uiMessages`. |
| 12 | + |
| 13 | +```ts |
| 14 | +// Persists to responseMessage.parts — available in onTurnComplete |
| 15 | +chat.response.write({ type: "data-handover", data: { context: summary } }); |
| 16 | + |
| 17 | +// Transient — streams to frontend only, not in responseMessage |
| 18 | +writer.write({ type: "data-progress", data: { percent: 50 }, transient: true }); |
| 19 | +``` |
| 20 | + |
| 21 | +Non-transient `data-*` chunks written via lifecycle hook `writer.write()` now automatically persist to the response message, matching the AI SDK's default semantics. Add `transient: true` for ephemeral chunks (progress indicators, status updates). |
| 22 | + |
| 23 | +See [Custom data parts](/ai-chat/features#custom-data-parts). |
| 24 | + |
| 25 | +## Tool approvals |
| 26 | + |
| 27 | +Added support for AI SDK tool approvals (`needsApproval: true`). When the model calls a tool that needs approval, the turn completes and the frontend shows approve/deny buttons. After approval, the updated assistant message is sent back and matched by ID in the accumulator. |
| 28 | + |
| 29 | +```ts |
| 30 | +const sendEmail = tool({ |
| 31 | + description: "Send an email. Requires human approval.", |
| 32 | + inputSchema: z.object({ to: z.string(), subject: z.string(), body: z.string() }), |
| 33 | + needsApproval: true, |
| 34 | + execute: async ({ to, subject, body }) => { /* ... */ }, |
| 35 | +}); |
| 36 | +``` |
| 37 | + |
| 38 | +Frontend setup requires `sendAutomaticallyWhen` and `addToolApprovalResponse` from `useChat`. See [Tool approvals](/ai-chat/frontend#tool-approvals). |
| 39 | + |
| 40 | +## `transport.stopGeneration(chatId)` |
| 41 | + |
| 42 | +Added `stopGeneration` method to `TriggerChatTransport` for reliable stop after page refresh / stream reconnect. Works regardless of whether the AI SDK passes `abortSignal` through `reconnectToStream`. |
| 43 | + |
| 44 | +```tsx |
| 45 | +const stop = useCallback(() => { |
| 46 | + transport.stopGeneration(chatId); |
| 47 | + aiStop(); // also update useChat state |
| 48 | +}, [transport, chatId, aiStop]); |
| 49 | +``` |
| 50 | + |
| 51 | +See [Stop generation](/ai-chat/frontend#stop-generation). |
| 52 | + |
| 53 | +## `generateMessageId` support |
| 54 | + |
| 55 | +`generateMessageId` can now be passed via `uiMessageStreamOptions` to control response message ID generation (e.g. UUID-v7). The backend automatically passes `originalMessages` to `toUIMessageStream` so message IDs are consistent between frontend and backend. |
| 56 | + |
| 57 | +## Bug fixes |
| 58 | + |
| 59 | +- **`onTurnComplete` not called**: Fixed `turnCompleteResult?.lastEventId` TypeError that silently skipped `onTurnComplete` when `writeTurnCompleteChunk` returned undefined in dev. |
| 60 | +- **Stop during streaming**: Added 2s timeout on `onFinishPromise` so `onBeforeTurnComplete` and `onTurnComplete` fire even when the AI SDK's `onFinish` doesn't fire after abort. |
| 61 | +- **`toStreamTextOptions` without `chat.prompt.set()`**: `prepareStep` injection (compaction, steering, background context) now works even when the user passes `system` directly to `streamText` instead of using `chat.prompt.set()`. |
| 62 | +- **Background queue vs tool approvals**: Background context injection is now skipped when the last accumulated message is a `tool` message, preventing it from breaking `streamText`'s `collectToolApprovals`. |
| 63 | + |
| 64 | +</Update> |
0 commit comments