ai 7.0.85 → 7.0.87
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +15 -5
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts +17 -1
- package/dist/internal/index.js +99 -84
- package/dist/internal/index.js.map +1 -1
- package/docs/03-agents/06-tool-approvals.mdx +6 -3
- package/docs/03-agents/07-workflow-agent.mdx +43 -0
- package/docs/03-ai-sdk-harnesses/02-harness-agent.mdx +4 -0
- package/docs/04-ai-sdk-ui/03-chatbot-tool-usage.mdx +7 -0
- package/docs/04-ai-sdk-ui/50-stream-protocol.mdx +6 -2
- package/docs/07-reference/01-ai-sdk-core/31-ui-message.mdx +35 -0
- package/docs/07-reference/04-ai-sdk-workflow/01-workflow-agent.mdx +25 -0
- package/package.json +5 -5
- package/src/ui/process-ui-message-stream.ts +4 -7
- package/src/ui/ui-messages.ts +10 -0
- package/src/ui/validate-ui-messages.ts +10 -0
- package/src/ui-message-stream/ui-message-chunks.ts +2 -0
|
@@ -319,9 +319,12 @@ Every serverless instance that might handle a request needs the same secret, sin
|
|
|
319
319
|
- The secret is never sent to the client or included in the stream
|
|
320
320
|
|
|
321
321
|
<Note>
|
|
322
|
-
`
|
|
323
|
-
|
|
324
|
-
|
|
322
|
+
`WorkflowAgent` also supports `experimental_toolApprovalSecret`. It signs in
|
|
323
|
+
a workflow step before writing the durable approval request. Pass an
|
|
324
|
+
environment variable reference, such as
|
|
325
|
+
`{ environmentVariable: 'TOOL_APPROVAL_SECRET' }`, so the raw secret is read
|
|
326
|
+
only inside signing and verification steps. Only the signature is persisted
|
|
327
|
+
and sent to the client.
|
|
325
328
|
</Note>
|
|
326
329
|
|
|
327
330
|
## Related APIs
|
|
@@ -354,6 +354,49 @@ const agent = new WorkflowAgent({
|
|
|
354
354
|
|
|
355
355
|
Because the workflow is durable, the approval request survives process restarts — the user can approve hours later and the agent will resume.
|
|
356
356
|
|
|
357
|
+
### Signed Tool Approvals
|
|
358
|
+
|
|
359
|
+
Client-supplied message history can be modified before it is replayed to the
|
|
360
|
+
workflow. For tools that perform sensitive operations, configure
|
|
361
|
+
`experimental_toolApprovalSecret` to authenticate approval requests:
|
|
362
|
+
|
|
363
|
+
```ts highlight="4"
|
|
364
|
+
const agent = new WorkflowAgent({
|
|
365
|
+
model: 'anthropic/claude-sonnet-4-6',
|
|
366
|
+
experimental_toolApprovalSecret: {
|
|
367
|
+
environmentVariable: 'TOOL_APPROVAL_SECRET',
|
|
368
|
+
},
|
|
369
|
+
tools: {
|
|
370
|
+
bookFlight: tool({
|
|
371
|
+
description: 'Book a flight',
|
|
372
|
+
inputSchema: z.object({ flightId: z.string() }),
|
|
373
|
+
needsApproval: true,
|
|
374
|
+
execute: bookFlightStep,
|
|
375
|
+
}),
|
|
376
|
+
},
|
|
377
|
+
});
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
The agent HMAC-signs the approval ID, tool call ID, tool name, and validated
|
|
381
|
+
input. When approved message history is replayed, a missing or invalid
|
|
382
|
+
signature prevents the tool from executing. The signature is preserved through
|
|
383
|
+
the durable model-call stream, `createModelCallToUIChunkTransform()`,
|
|
384
|
+
`addToolApprovalResponse()`, and `convertToModelMessages()`.
|
|
385
|
+
|
|
386
|
+
Use a high-entropy secret of at least 32 bytes and make the same secret
|
|
387
|
+
available to every worker that can issue or resume an approval. Keep old keys
|
|
388
|
+
available while approvals signed with them are pending; changing the secret
|
|
389
|
+
invalidates those pending approvals.
|
|
390
|
+
|
|
391
|
+
`WorkflowAgent` passes only the environment variable name into signing and
|
|
392
|
+
verification steps. Each step reads the secret from its local environment, and
|
|
393
|
+
the raw value is never included in step arguments, durable stream parts,
|
|
394
|
+
callbacks, or telemetry events. Configure the environment variable on every
|
|
395
|
+
worker, and do not put the secret value in `runtimeContext` or `toolsContext`.
|
|
396
|
+
|
|
397
|
+
You can also provide `experimental_toolApprovalSecret` to `agent.stream()`.
|
|
398
|
+
The stream-level value overrides the constructor default.
|
|
399
|
+
|
|
357
400
|
## Loop Control
|
|
358
401
|
|
|
359
402
|
Control how many steps the agent can take:
|
|
@@ -526,6 +526,10 @@ console.log(preparation.identity);
|
|
|
526
526
|
- `sandboxConfig`: sandbox working-directory and lifecycle hook configuration.
|
|
527
527
|
- `telemetry`, `debug`, and `onLog`: observability and diagnostics.
|
|
528
528
|
|
|
529
|
+
Telemetry reports each turn's resolved model, instructions, and active
|
|
530
|
+
host-defined tools. Skills are adapter context and do not have a corresponding
|
|
531
|
+
AI SDK telemetry field, so they are not included in standard telemetry events.
|
|
532
|
+
|
|
529
533
|
Adapter-specific settings belong on the adapter factory, for example
|
|
530
534
|
`createCodex({ reasoningEffort: 'high' })`.
|
|
531
535
|
|
|
@@ -543,6 +543,13 @@ For manual approval requests, the reason for requiring approval is available as
|
|
|
543
543
|
`part.approval.requestReason`. It remains separate from an optional response
|
|
544
544
|
reason supplied to `addToolApprovalResponse`.
|
|
545
545
|
|
|
546
|
+
Approval request chunks can also include an `approvalDescriptor` with opaque
|
|
547
|
+
application-specific metadata. UI message processing exposes it as
|
|
548
|
+
`part.approval.descriptor` in the `approval-requested` state and preserves it in
|
|
549
|
+
subsequent approval-bearing states, including `approval-responded`. This lets
|
|
550
|
+
clients render or persist server-computed approval metadata without using it to
|
|
551
|
+
determine whether the tool was approved.
|
|
552
|
+
|
|
546
553
|
### Securing Approvals for Sensitive Tools
|
|
547
554
|
|
|
548
555
|
In the `useChat` pattern, the client sends the full message history to the server each turn. Without additional protection, a modified client could fabricate an approval response. For tools that perform sensitive operations, add `experimental_toolApprovalSecret` to your `streamText` call so the server cryptographically verifies that it issued the approval:
|
|
@@ -367,11 +367,15 @@ Format: Server-Sent Event with JSON object
|
|
|
367
367
|
Example:
|
|
368
368
|
|
|
369
369
|
```
|
|
370
|
-
data: {"type":"tool-approval-request","toolCallId":"call_fJdQDqnXeGxTmr4E3YPSR7Ar","approvalId":"approval_123","reason":"Requires operator review"}
|
|
370
|
+
data: {"type":"tool-approval-request","toolCallId":"call_fJdQDqnXeGxTmr4E3YPSR7Ar","approvalId":"approval_123","approvalDescriptor":{"scope":"account:delete"},"reason":"Requires operator review"}
|
|
371
371
|
|
|
372
372
|
```
|
|
373
373
|
|
|
374
|
-
When `isAutomatic` is omitted, the request expects an explicit approval response
|
|
374
|
+
When `isAutomatic` is omitted, the request expects an explicit approval response
|
|
375
|
+
from the client. `reason` is optional and explains why the tool call requires
|
|
376
|
+
approval. `approvalDescriptor` is optional opaque metadata for the approval.
|
|
377
|
+
When the stream is processed into UI messages, it is available as
|
|
378
|
+
`part.approval.descriptor` and is retained through subsequent approval states.
|
|
375
379
|
|
|
376
380
|
### Tool Approval Response Part
|
|
377
381
|
|
|
@@ -150,6 +150,36 @@ type ToolUIPart<TOOLS extends UITools = UITools> = ValueOf<{
|
|
|
150
150
|
output?: never;
|
|
151
151
|
errorText?: never;
|
|
152
152
|
}
|
|
153
|
+
| {
|
|
154
|
+
state: 'approval-requested';
|
|
155
|
+
input: TOOLS[NAME]['input'];
|
|
156
|
+
output?: never;
|
|
157
|
+
errorText?: never;
|
|
158
|
+
approval: {
|
|
159
|
+
id: string;
|
|
160
|
+
approved?: never;
|
|
161
|
+
descriptor?: unknown;
|
|
162
|
+
requestReason?: string;
|
|
163
|
+
reason?: never;
|
|
164
|
+
isAutomatic?: boolean;
|
|
165
|
+
signature?: string;
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
| {
|
|
169
|
+
state: 'approval-responded';
|
|
170
|
+
input: TOOLS[NAME]['input'];
|
|
171
|
+
output?: never;
|
|
172
|
+
errorText?: never;
|
|
173
|
+
approval: {
|
|
174
|
+
id: string;
|
|
175
|
+
approved: boolean;
|
|
176
|
+
descriptor?: unknown;
|
|
177
|
+
requestReason?: string;
|
|
178
|
+
reason?: string;
|
|
179
|
+
isAutomatic?: boolean;
|
|
180
|
+
signature?: string;
|
|
181
|
+
};
|
|
182
|
+
}
|
|
153
183
|
| {
|
|
154
184
|
state: 'output-available';
|
|
155
185
|
input: TOOLS[NAME]['input'];
|
|
@@ -168,6 +198,11 @@ type ToolUIPart<TOOLS extends UITools = UITools> = ValueOf<{
|
|
|
168
198
|
}>;
|
|
169
199
|
```
|
|
170
200
|
|
|
201
|
+
`approval.descriptor` contains optional opaque metadata supplied as
|
|
202
|
+
`approvalDescriptor` on the approval request stream chunk. It is preserved when
|
|
203
|
+
the tool part transitions from `approval-requested` to `approval-responded` and
|
|
204
|
+
in later approval-bearing output states.
|
|
205
|
+
|
|
171
206
|
### `CustomContentUIPart`
|
|
172
207
|
|
|
173
208
|
A provider-specific custom content part of a message.
|
|
@@ -136,6 +136,13 @@ To see `WorkflowAgent` in action, check out [these examples](#examples).
|
|
|
136
136
|
description:
|
|
137
137
|
'Default sandbox session passed to tool descriptions and execution as `experimental_sandbox`, and exposed to `prepareStep`. Per-stream values override this default.',
|
|
138
138
|
},
|
|
139
|
+
{
|
|
140
|
+
name: 'experimental_toolApprovalSecret',
|
|
141
|
+
type: 'WorkflowToolApprovalSecret',
|
|
142
|
+
isOptional: true,
|
|
143
|
+
description:
|
|
144
|
+
'Workflow-safe reference to the environment variable containing the secret used to HMAC-sign tool approval requests and verify approved message history before tool execution. Only the environment variable name crosses workflow boundaries; the secret is read inside signing and verification steps. Per-stream values override this default.',
|
|
145
|
+
},
|
|
139
146
|
{
|
|
140
147
|
name: 'prepareStep',
|
|
141
148
|
type: 'PrepareStepCallback',
|
|
@@ -559,6 +566,13 @@ const result = await agent.stream({
|
|
|
559
566
|
description:
|
|
560
567
|
'Sandbox session passed to tool descriptions and execution as `experimental_sandbox`, and exposed to `prepareStep`. Overrides the constructor default.',
|
|
561
568
|
},
|
|
569
|
+
{
|
|
570
|
+
name: 'experimental_toolApprovalSecret',
|
|
571
|
+
type: 'WorkflowToolApprovalSecret',
|
|
572
|
+
isOptional: true,
|
|
573
|
+
description:
|
|
574
|
+
'Workflow-safe reference to the environment variable containing the secret used to HMAC-sign tool approval requests and verify approved message history before tool execution. Only the environment variable name crosses workflow boundaries; the secret is read inside signing and verification steps. Overrides the constructor default.',
|
|
575
|
+
},
|
|
562
576
|
{
|
|
563
577
|
name: 'telemetry',
|
|
564
578
|
type: 'TelemetryOptions',
|
|
@@ -922,6 +936,9 @@ import { z } from 'zod';
|
|
|
922
936
|
|
|
923
937
|
const agent = new WorkflowAgent({
|
|
924
938
|
model: 'anthropic/claude-sonnet-4-6',
|
|
939
|
+
experimental_toolApprovalSecret: {
|
|
940
|
+
environmentVariable: 'TOOL_APPROVAL_SECRET',
|
|
941
|
+
},
|
|
925
942
|
tools: {
|
|
926
943
|
bookFlight: tool({
|
|
927
944
|
description: 'Book a flight',
|
|
@@ -936,6 +953,14 @@ const agent = new WorkflowAgent({
|
|
|
936
953
|
});
|
|
937
954
|
```
|
|
938
955
|
|
|
956
|
+
When `experimental_toolApprovalSecret` is configured, each approval request is
|
|
957
|
+
signed over its approval ID, tool call ID, tool name, and validated input.
|
|
958
|
+
Replayed approvals with a missing or invalid signature do not execute the tool.
|
|
959
|
+
The signature is preserved in the durable stream and UI message history, while
|
|
960
|
+
only the environment variable name crosses workflow boundaries. Signing and
|
|
961
|
+
verification steps read the raw secret from their local environment and do not
|
|
962
|
+
serialize it. A stream-level reference overrides the constructor value.
|
|
963
|
+
|
|
939
964
|
### Agent with Lifecycle Callbacks
|
|
940
965
|
|
|
941
966
|
```ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.87",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "AI SDK by Vercel - build apps like ChatGPT, Claude, Gemini, and more with a single interface for any model using the Vercel AI Gateway or go direct to OpenAI, Anthropic, Google, or any other model provider.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -42,18 +42,18 @@
|
|
|
42
42
|
}
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@ai-sdk/gateway": "4.0.
|
|
45
|
+
"@ai-sdk/gateway": "4.0.70",
|
|
46
46
|
"@ai-sdk/provider": "4.0.9",
|
|
47
47
|
"@ai-sdk/provider-utils": "5.0.34"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
|
-
"@ai-sdk/amazon-bedrock": "5.0.
|
|
50
|
+
"@ai-sdk/amazon-bedrock": "5.0.69",
|
|
51
51
|
"@ai-sdk/deepseek": "3.0.37",
|
|
52
|
-
"@ai-sdk/google": "4.0.
|
|
52
|
+
"@ai-sdk/google": "4.0.59",
|
|
53
53
|
"@ai-sdk/groq": "4.0.35",
|
|
54
54
|
"@ai-sdk/huggingface": "2.0.41",
|
|
55
55
|
"@ai-sdk/moonshotai": "3.0.43",
|
|
56
|
-
"@ai-sdk/openai": "4.0.
|
|
56
|
+
"@ai-sdk/openai": "4.0.53",
|
|
57
57
|
"@ai-sdk/test-server": "2.0.1",
|
|
58
58
|
"@ai-sdk/xai": "4.0.50",
|
|
59
59
|
"@edge-runtime/vm": "^5.0.0",
|
|
@@ -748,6 +748,9 @@ export function processUIMessageStream<UI_MESSAGE extends UIMessage>({
|
|
|
748
748
|
toolInvocation.state = 'approval-requested';
|
|
749
749
|
toolInvocation.approval = {
|
|
750
750
|
id: chunk.approvalId,
|
|
751
|
+
...(chunk.approvalDescriptor != null
|
|
752
|
+
? { descriptor: chunk.approvalDescriptor }
|
|
753
|
+
: {}),
|
|
751
754
|
...(chunk.reason != null
|
|
752
755
|
? { requestReason: chunk.reason }
|
|
753
756
|
: {}),
|
|
@@ -771,16 +774,10 @@ export function processUIMessageStream<UI_MESSAGE extends UIMessage>({
|
|
|
771
774
|
|
|
772
775
|
toolInvocation.state = 'approval-responded';
|
|
773
776
|
toolInvocation.approval = {
|
|
777
|
+
...approval,
|
|
774
778
|
id: chunk.approvalId,
|
|
775
779
|
approved: chunk.approved,
|
|
776
|
-
...(approval.requestReason != null
|
|
777
|
-
? { requestReason: approval.requestReason }
|
|
778
|
-
: {}),
|
|
779
780
|
...(chunk.reason != null ? { reason: chunk.reason } : {}),
|
|
780
|
-
...(approval.isAutomatic === true ? { isAutomatic: true } : {}),
|
|
781
|
-
...(approval.signature != null
|
|
782
|
-
? { signature: approval.signature }
|
|
783
|
-
: {}),
|
|
784
781
|
};
|
|
785
782
|
if (chunk.providerExecuted != null) {
|
|
786
783
|
toolInvocation.providerExecuted = chunk.providerExecuted;
|
package/src/ui/ui-messages.ts
CHANGED
|
@@ -319,6 +319,7 @@ export type UIToolInvocation<TOOL extends UITool | Tool> = {
|
|
|
319
319
|
approval: {
|
|
320
320
|
id: string;
|
|
321
321
|
approved?: never;
|
|
322
|
+
descriptor?: unknown;
|
|
322
323
|
requestReason?: string;
|
|
323
324
|
reason?: never;
|
|
324
325
|
isAutomatic?: boolean;
|
|
@@ -334,6 +335,7 @@ export type UIToolInvocation<TOOL extends UITool | Tool> = {
|
|
|
334
335
|
approval: {
|
|
335
336
|
id: string;
|
|
336
337
|
approved: boolean;
|
|
338
|
+
descriptor?: unknown;
|
|
337
339
|
requestReason?: string;
|
|
338
340
|
reason?: string;
|
|
339
341
|
isAutomatic?: boolean;
|
|
@@ -351,6 +353,7 @@ export type UIToolInvocation<TOOL extends UITool | Tool> = {
|
|
|
351
353
|
approval?: {
|
|
352
354
|
id: string;
|
|
353
355
|
approved: true;
|
|
356
|
+
descriptor?: unknown;
|
|
354
357
|
requestReason?: string;
|
|
355
358
|
reason?: string;
|
|
356
359
|
isAutomatic?: boolean;
|
|
@@ -368,6 +371,7 @@ export type UIToolInvocation<TOOL extends UITool | Tool> = {
|
|
|
368
371
|
approval?: {
|
|
369
372
|
id: string;
|
|
370
373
|
approved: true;
|
|
374
|
+
descriptor?: unknown;
|
|
371
375
|
requestReason?: string;
|
|
372
376
|
reason?: string;
|
|
373
377
|
isAutomatic?: boolean;
|
|
@@ -383,6 +387,7 @@ export type UIToolInvocation<TOOL extends UITool | Tool> = {
|
|
|
383
387
|
approval: {
|
|
384
388
|
id: string;
|
|
385
389
|
approved: false;
|
|
390
|
+
descriptor?: unknown;
|
|
386
391
|
requestReason?: string;
|
|
387
392
|
reason?: string;
|
|
388
393
|
isAutomatic?: boolean;
|
|
@@ -442,6 +447,7 @@ export type DynamicToolUIPart = {
|
|
|
442
447
|
approval: {
|
|
443
448
|
id: string;
|
|
444
449
|
approved?: never;
|
|
450
|
+
descriptor?: unknown;
|
|
445
451
|
requestReason?: string;
|
|
446
452
|
reason?: never;
|
|
447
453
|
isAutomatic?: boolean;
|
|
@@ -457,6 +463,7 @@ export type DynamicToolUIPart = {
|
|
|
457
463
|
approval: {
|
|
458
464
|
id: string;
|
|
459
465
|
approved: boolean;
|
|
466
|
+
descriptor?: unknown;
|
|
460
467
|
requestReason?: string;
|
|
461
468
|
reason?: string;
|
|
462
469
|
isAutomatic?: boolean;
|
|
@@ -474,6 +481,7 @@ export type DynamicToolUIPart = {
|
|
|
474
481
|
approval?: {
|
|
475
482
|
id: string;
|
|
476
483
|
approved: true;
|
|
484
|
+
descriptor?: unknown;
|
|
477
485
|
requestReason?: string;
|
|
478
486
|
reason?: string;
|
|
479
487
|
isAutomatic?: boolean;
|
|
@@ -490,6 +498,7 @@ export type DynamicToolUIPart = {
|
|
|
490
498
|
approval?: {
|
|
491
499
|
id: string;
|
|
492
500
|
approved: true;
|
|
501
|
+
descriptor?: unknown;
|
|
493
502
|
requestReason?: string;
|
|
494
503
|
reason?: string;
|
|
495
504
|
isAutomatic?: boolean;
|
|
@@ -505,6 +514,7 @@ export type DynamicToolUIPart = {
|
|
|
505
514
|
approval: {
|
|
506
515
|
id: string;
|
|
507
516
|
approved: false;
|
|
517
|
+
descriptor?: unknown;
|
|
508
518
|
requestReason?: string;
|
|
509
519
|
reason?: string;
|
|
510
520
|
isAutomatic?: boolean;
|
|
@@ -153,6 +153,7 @@ const uiMessagesSchema = lazySchema(() =>
|
|
|
153
153
|
approval: z.object({
|
|
154
154
|
id: z.string(),
|
|
155
155
|
approved: z.never().optional(),
|
|
156
|
+
descriptor: z.unknown().optional(),
|
|
156
157
|
requestReason: z.string().optional(),
|
|
157
158
|
reason: z.never().optional(),
|
|
158
159
|
isAutomatic: z.boolean().optional(),
|
|
@@ -173,6 +174,7 @@ const uiMessagesSchema = lazySchema(() =>
|
|
|
173
174
|
approval: z.object({
|
|
174
175
|
id: z.string(),
|
|
175
176
|
approved: z.boolean(),
|
|
177
|
+
descriptor: z.unknown().optional(),
|
|
176
178
|
requestReason: z.string().optional(),
|
|
177
179
|
reason: z.string().optional(),
|
|
178
180
|
isAutomatic: z.boolean().optional(),
|
|
@@ -196,6 +198,7 @@ const uiMessagesSchema = lazySchema(() =>
|
|
|
196
198
|
.object({
|
|
197
199
|
id: z.string(),
|
|
198
200
|
approved: z.literal(true),
|
|
201
|
+
descriptor: z.unknown().optional(),
|
|
199
202
|
requestReason: z.string().optional(),
|
|
200
203
|
reason: z.string().optional(),
|
|
201
204
|
isAutomatic: z.boolean().optional(),
|
|
@@ -220,6 +223,7 @@ const uiMessagesSchema = lazySchema(() =>
|
|
|
220
223
|
.object({
|
|
221
224
|
id: z.string(),
|
|
222
225
|
approved: z.literal(true),
|
|
226
|
+
descriptor: z.unknown().optional(),
|
|
223
227
|
requestReason: z.string().optional(),
|
|
224
228
|
reason: z.string().optional(),
|
|
225
229
|
isAutomatic: z.boolean().optional(),
|
|
@@ -241,6 +245,7 @@ const uiMessagesSchema = lazySchema(() =>
|
|
|
241
245
|
approval: z.object({
|
|
242
246
|
id: z.string(),
|
|
243
247
|
approved: z.literal(false),
|
|
248
|
+
descriptor: z.unknown().optional(),
|
|
244
249
|
requestReason: z.string().optional(),
|
|
245
250
|
reason: z.string().optional(),
|
|
246
251
|
isAutomatic: z.boolean().optional(),
|
|
@@ -284,6 +289,7 @@ const uiMessagesSchema = lazySchema(() =>
|
|
|
284
289
|
approval: z.object({
|
|
285
290
|
id: z.string(),
|
|
286
291
|
approved: z.never().optional(),
|
|
292
|
+
descriptor: z.unknown().optional(),
|
|
287
293
|
requestReason: z.string().optional(),
|
|
288
294
|
reason: z.never().optional(),
|
|
289
295
|
isAutomatic: z.boolean().optional(),
|
|
@@ -303,6 +309,7 @@ const uiMessagesSchema = lazySchema(() =>
|
|
|
303
309
|
approval: z.object({
|
|
304
310
|
id: z.string(),
|
|
305
311
|
approved: z.boolean(),
|
|
312
|
+
descriptor: z.unknown().optional(),
|
|
306
313
|
requestReason: z.string().optional(),
|
|
307
314
|
reason: z.string().optional(),
|
|
308
315
|
isAutomatic: z.boolean().optional(),
|
|
@@ -325,6 +332,7 @@ const uiMessagesSchema = lazySchema(() =>
|
|
|
325
332
|
.object({
|
|
326
333
|
id: z.string(),
|
|
327
334
|
approved: z.literal(true),
|
|
335
|
+
descriptor: z.unknown().optional(),
|
|
328
336
|
requestReason: z.string().optional(),
|
|
329
337
|
reason: z.string().optional(),
|
|
330
338
|
isAutomatic: z.boolean().optional(),
|
|
@@ -348,6 +356,7 @@ const uiMessagesSchema = lazySchema(() =>
|
|
|
348
356
|
.object({
|
|
349
357
|
id: z.string(),
|
|
350
358
|
approved: z.literal(true),
|
|
359
|
+
descriptor: z.unknown().optional(),
|
|
351
360
|
requestReason: z.string().optional(),
|
|
352
361
|
reason: z.string().optional(),
|
|
353
362
|
isAutomatic: z.boolean().optional(),
|
|
@@ -368,6 +377,7 @@ const uiMessagesSchema = lazySchema(() =>
|
|
|
368
377
|
approval: z.object({
|
|
369
378
|
id: z.string(),
|
|
370
379
|
approved: z.literal(false),
|
|
380
|
+
descriptor: z.unknown().optional(),
|
|
371
381
|
requestReason: z.string().optional(),
|
|
372
382
|
reason: z.string().optional(),
|
|
373
383
|
isAutomatic: z.boolean().optional(),
|
|
@@ -85,6 +85,7 @@ export const uiMessageChunkSchema = lazySchema(() =>
|
|
|
85
85
|
type: z.literal('tool-approval-request'),
|
|
86
86
|
approvalId: z.string(),
|
|
87
87
|
toolCallId: z.string(),
|
|
88
|
+
approvalDescriptor: z.unknown().optional(),
|
|
88
89
|
reason: z.string().optional(),
|
|
89
90
|
isAutomatic: z.boolean().optional(),
|
|
90
91
|
signature: z.string().optional(),
|
|
@@ -299,6 +300,7 @@ export type UIMessageChunk<
|
|
|
299
300
|
type: 'tool-approval-request';
|
|
300
301
|
approvalId: string;
|
|
301
302
|
toolCallId: string;
|
|
303
|
+
approvalDescriptor?: unknown;
|
|
302
304
|
reason?: string;
|
|
303
305
|
isAutomatic?: boolean;
|
|
304
306
|
signature?: string;
|