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
Copy file name to clipboardExpand all lines: docs/ai-chat/backend.mdx
+32Lines changed: 32 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -516,6 +516,38 @@ This removes tool invocation parts stuck in `partial-call` state and marks any `
516
516
This is expected and does not require special handling.
517
517
</Note>
518
518
519
+
### Tool approvals
520
+
521
+
Tools with `needsApproval: true` pause execution until the user approves or denies via the frontend. Define the tool as normal and pass it to `streamText` — `chat.agent` handles the rest:
522
+
523
+
```ts
524
+
const sendEmail =tool({
525
+
description: "Send an email. Requires human approval.",
526
+
inputSchema: z.object({ to: z.string(), subject: z.string(), body: z.string() }),
527
+
needsApproval: true,
528
+
execute: async ({ to, subject, body }) => {
529
+
awaitemailService.send({ to, subject, body });
530
+
return { sent: true };
531
+
},
532
+
});
533
+
534
+
exportconst myChat =chat.agent({
535
+
id: "my-chat",
536
+
run: async ({ messages, signal }) => {
537
+
returnstreamText({
538
+
model: openai("gpt-4o"),
539
+
messages,
540
+
tools: { sendEmail },
541
+
abortSignal: signal,
542
+
});
543
+
},
544
+
});
545
+
```
546
+
547
+
When the model calls an approval-required tool, the turn completes with the tool in `approval-requested` state. After the user approves on the frontend, the updated message is sent back and `chat.agent` replaces it in the conversation accumulator by matching the message ID. `streamText` then executes the approved tool and continues.
548
+
549
+
See [Tool approvals](/ai-chat/frontend#tool-approvals) in the frontend docs for the UI setup.
See [Stop generation](/ai-chat/backend#stop-generation) in the backend docs for how to handle stop signals in your task.
282
282
283
+
## Tool approvals
284
+
285
+
The AI SDK supports tools that require human approval before execution. To use this with `chat.agent`, define a tool with `needsApproval: true` on the backend, then handle the approval UI and configure `sendAutomaticallyWhen` on the frontend.
286
+
287
+
### Backend: define an approval-required tool
288
+
289
+
```ts
290
+
import { tool } from"ai";
291
+
import { z } from"zod";
292
+
293
+
const sendEmail =tool({
294
+
description: "Send an email. Requires human approval before sending.",
295
+
inputSchema: z.object({
296
+
to: z.string(),
297
+
subject: z.string(),
298
+
body: z.string(),
299
+
}),
300
+
needsApproval: true,
301
+
execute: async ({ to, subject, body }) => {
302
+
awaitemailService.send({ to, subject, body });
303
+
return { sent: true, to, subject };
304
+
},
305
+
});
306
+
```
307
+
308
+
Pass the tool to `streamText` in your `run` function as usual. When the model calls the tool, `chat.agent` streams a `tool-approval-request` chunk. The turn completes and the run waits for the next message.
0 commit comments