ai 6.0.289 → 6.0.291
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 +28 -0
- package/dist/index.d.mts +13 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +326 -250
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +263 -182
- package/dist/index.mjs.map +1 -1
- package/dist/internal/index.js +4 -2
- package/dist/internal/index.js.map +1 -1
- package/dist/internal/index.mjs +4 -2
- package/dist/internal/index.mjs.map +1 -1
- package/docs/03-ai-sdk-core/16-mcp-tools.mdx +57 -0
- package/docs/04-ai-sdk-ui/03-chatbot-tool-usage.mdx +7 -0
- package/package.json +4 -3
- package/src/embed/embed-many.ts +19 -3
- package/src/generate-speech/generated-audio-file.ts +0 -8
- package/src/generate-text/generated-file.ts +0 -4
- package/src/generate-text/parse-tool-call.ts +30 -23
- package/src/generate-text/stream-text.ts +9 -1
- package/src/generate-text/to-response-messages.ts +7 -0
- package/src/generate-text/tool-call.ts +26 -0
- package/src/generate-text/validate-tool-approvals.ts +20 -2
- package/src/middleware/extract-reasoning-middleware.ts +1 -1
- package/src/middleware/wrap-embedding-model.ts +12 -2
- package/src/model/get-embedding-model-provider-options-transformer.ts +17 -0
- package/src/prompt/content-part.ts +2 -0
- package/src/ui/chat.ts +108 -17
- package/src/ui/convert-to-model-messages.ts +8 -0
- package/src/ui/process-ui-message-stream.ts +6 -0
- package/src/ui/ui-messages.ts +10 -0
- package/src/ui/validate-ui-messages.ts +79 -114
- package/src/ui-message-stream/ui-message-chunks.ts +2 -0
- package/src/util/write-to-server-response.ts +0 -2
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
import { z } from 'zod/v4';
|
|
16
16
|
import { InvalidArgumentError } from '../error';
|
|
17
17
|
import { jsonValueSchema } from '../types/json-value';
|
|
18
|
+
import { isDeepEqualData } from '../util/is-deep-equal-data';
|
|
18
19
|
import { providerMetadataSchema } from '../types/provider-metadata';
|
|
19
20
|
import type {
|
|
20
21
|
DataUIPart,
|
|
@@ -49,8 +50,36 @@ function asDynamicToolPart(toolPart: ToolUIPart): DynamicToolUIPart {
|
|
|
49
50
|
} as DynamicToolUIPart;
|
|
50
51
|
}
|
|
51
52
|
|
|
52
|
-
|
|
53
|
-
|
|
53
|
+
function getToolPartInputSchemaInput(
|
|
54
|
+
toolPart: ToolUIPart,
|
|
55
|
+
): { value: unknown } | undefined {
|
|
56
|
+
return toolPart.approval != null &&
|
|
57
|
+
Object.prototype.hasOwnProperty.call(toolPart.approval, 'inputSchemaInput')
|
|
58
|
+
? { value: toolPart.approval.inputSchemaInput }
|
|
59
|
+
: undefined;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const uiMessagesSchema = lazySchema(() => {
|
|
63
|
+
const approvalRequestedSchema = z.object({
|
|
64
|
+
id: z.string(),
|
|
65
|
+
approved: z.never().optional(),
|
|
66
|
+
descriptor: z.unknown().optional(),
|
|
67
|
+
reason: z.never().optional(),
|
|
68
|
+
signature: z.string().optional(),
|
|
69
|
+
inputSchemaInput: z.unknown().optional(),
|
|
70
|
+
});
|
|
71
|
+
const approvalRespondedSchema = approvalRequestedSchema.extend({
|
|
72
|
+
approved: z.boolean(),
|
|
73
|
+
reason: z.string().optional(),
|
|
74
|
+
});
|
|
75
|
+
const approvalGrantedSchema = approvalRespondedSchema.extend({
|
|
76
|
+
approved: z.literal(true),
|
|
77
|
+
});
|
|
78
|
+
const approvalDeniedSchema = approvalRespondedSchema.extend({
|
|
79
|
+
approved: z.literal(false),
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
return zodSchema(
|
|
54
83
|
z
|
|
55
84
|
.array(
|
|
56
85
|
z
|
|
@@ -140,13 +169,7 @@ const uiMessagesSchema = lazySchema(() =>
|
|
|
140
169
|
output: z.never().optional(),
|
|
141
170
|
errorText: z.never().optional(),
|
|
142
171
|
callProviderMetadata: providerMetadataSchema.optional(),
|
|
143
|
-
approval:
|
|
144
|
-
id: z.string(),
|
|
145
|
-
approved: z.never().optional(),
|
|
146
|
-
descriptor: z.unknown().optional(),
|
|
147
|
-
reason: z.never().optional(),
|
|
148
|
-
signature: z.string().optional(),
|
|
149
|
-
}),
|
|
172
|
+
approval: approvalRequestedSchema,
|
|
150
173
|
}),
|
|
151
174
|
z.object({
|
|
152
175
|
type: z.literal('dynamic-tool'),
|
|
@@ -159,13 +182,7 @@ const uiMessagesSchema = lazySchema(() =>
|
|
|
159
182
|
output: z.never().optional(),
|
|
160
183
|
errorText: z.never().optional(),
|
|
161
184
|
callProviderMetadata: providerMetadataSchema.optional(),
|
|
162
|
-
approval:
|
|
163
|
-
id: z.string(),
|
|
164
|
-
approved: z.boolean(),
|
|
165
|
-
descriptor: z.unknown().optional(),
|
|
166
|
-
reason: z.string().optional(),
|
|
167
|
-
signature: z.string().optional(),
|
|
168
|
-
}),
|
|
185
|
+
approval: approvalRespondedSchema,
|
|
169
186
|
}),
|
|
170
187
|
z.object({
|
|
171
188
|
type: z.literal('dynamic-tool'),
|
|
@@ -180,15 +197,7 @@ const uiMessagesSchema = lazySchema(() =>
|
|
|
180
197
|
callProviderMetadata: providerMetadataSchema.optional(),
|
|
181
198
|
resultProviderMetadata: providerMetadataSchema.optional(),
|
|
182
199
|
preliminary: z.boolean().optional(),
|
|
183
|
-
approval:
|
|
184
|
-
.object({
|
|
185
|
-
id: z.string(),
|
|
186
|
-
approved: z.literal(true),
|
|
187
|
-
descriptor: z.unknown().optional(),
|
|
188
|
-
reason: z.string().optional(),
|
|
189
|
-
signature: z.string().optional(),
|
|
190
|
-
})
|
|
191
|
-
.optional(),
|
|
200
|
+
approval: approvalGrantedSchema.optional(),
|
|
192
201
|
}),
|
|
193
202
|
z.object({
|
|
194
203
|
type: z.literal('dynamic-tool'),
|
|
@@ -203,15 +212,7 @@ const uiMessagesSchema = lazySchema(() =>
|
|
|
203
212
|
errorText: z.string(),
|
|
204
213
|
callProviderMetadata: providerMetadataSchema.optional(),
|
|
205
214
|
resultProviderMetadata: providerMetadataSchema.optional(),
|
|
206
|
-
approval:
|
|
207
|
-
.object({
|
|
208
|
-
id: z.string(),
|
|
209
|
-
approved: z.literal(true),
|
|
210
|
-
descriptor: z.unknown().optional(),
|
|
211
|
-
reason: z.string().optional(),
|
|
212
|
-
signature: z.string().optional(),
|
|
213
|
-
})
|
|
214
|
-
.optional(),
|
|
215
|
+
approval: approvalGrantedSchema.optional(),
|
|
215
216
|
}),
|
|
216
217
|
z.object({
|
|
217
218
|
type: z.literal('dynamic-tool'),
|
|
@@ -224,13 +225,7 @@ const uiMessagesSchema = lazySchema(() =>
|
|
|
224
225
|
output: z.never().optional(),
|
|
225
226
|
errorText: z.never().optional(),
|
|
226
227
|
callProviderMetadata: providerMetadataSchema.optional(),
|
|
227
|
-
approval:
|
|
228
|
-
id: z.string(),
|
|
229
|
-
approved: z.literal(false),
|
|
230
|
-
descriptor: z.unknown().optional(),
|
|
231
|
-
reason: z.string().optional(),
|
|
232
|
-
signature: z.string().optional(),
|
|
233
|
-
}),
|
|
228
|
+
approval: approvalDeniedSchema,
|
|
234
229
|
}),
|
|
235
230
|
z.object({
|
|
236
231
|
type: z.string().startsWith('tool-'),
|
|
@@ -266,13 +261,7 @@ const uiMessagesSchema = lazySchema(() =>
|
|
|
266
261
|
output: z.never().optional(),
|
|
267
262
|
errorText: z.never().optional(),
|
|
268
263
|
callProviderMetadata: providerMetadataSchema.optional(),
|
|
269
|
-
approval:
|
|
270
|
-
id: z.string(),
|
|
271
|
-
approved: z.never().optional(),
|
|
272
|
-
descriptor: z.unknown().optional(),
|
|
273
|
-
reason: z.never().optional(),
|
|
274
|
-
signature: z.string().optional(),
|
|
275
|
-
}),
|
|
264
|
+
approval: approvalRequestedSchema,
|
|
276
265
|
}),
|
|
277
266
|
z.object({
|
|
278
267
|
type: z.string().startsWith('tool-'),
|
|
@@ -284,13 +273,7 @@ const uiMessagesSchema = lazySchema(() =>
|
|
|
284
273
|
output: z.never().optional(),
|
|
285
274
|
errorText: z.never().optional(),
|
|
286
275
|
callProviderMetadata: providerMetadataSchema.optional(),
|
|
287
|
-
approval:
|
|
288
|
-
id: z.string(),
|
|
289
|
-
approved: z.boolean(),
|
|
290
|
-
descriptor: z.unknown().optional(),
|
|
291
|
-
reason: z.string().optional(),
|
|
292
|
-
signature: z.string().optional(),
|
|
293
|
-
}),
|
|
276
|
+
approval: approvalRespondedSchema,
|
|
294
277
|
}),
|
|
295
278
|
z.object({
|
|
296
279
|
type: z.string().startsWith('tool-'),
|
|
@@ -304,15 +287,7 @@ const uiMessagesSchema = lazySchema(() =>
|
|
|
304
287
|
callProviderMetadata: providerMetadataSchema.optional(),
|
|
305
288
|
resultProviderMetadata: providerMetadataSchema.optional(),
|
|
306
289
|
preliminary: z.boolean().optional(),
|
|
307
|
-
approval:
|
|
308
|
-
.object({
|
|
309
|
-
id: z.string(),
|
|
310
|
-
approved: z.literal(true),
|
|
311
|
-
descriptor: z.unknown().optional(),
|
|
312
|
-
reason: z.string().optional(),
|
|
313
|
-
signature: z.string().optional(),
|
|
314
|
-
})
|
|
315
|
-
.optional(),
|
|
290
|
+
approval: approvalGrantedSchema.optional(),
|
|
316
291
|
}),
|
|
317
292
|
z.object({
|
|
318
293
|
type: z.string().startsWith('tool-'),
|
|
@@ -326,15 +301,7 @@ const uiMessagesSchema = lazySchema(() =>
|
|
|
326
301
|
errorText: z.string(),
|
|
327
302
|
callProviderMetadata: providerMetadataSchema.optional(),
|
|
328
303
|
resultProviderMetadata: providerMetadataSchema.optional(),
|
|
329
|
-
approval:
|
|
330
|
-
.object({
|
|
331
|
-
id: z.string(),
|
|
332
|
-
approved: z.literal(true),
|
|
333
|
-
descriptor: z.unknown().optional(),
|
|
334
|
-
reason: z.string().optional(),
|
|
335
|
-
signature: z.string().optional(),
|
|
336
|
-
})
|
|
337
|
-
.optional(),
|
|
304
|
+
approval: approvalGrantedSchema.optional(),
|
|
338
305
|
}),
|
|
339
306
|
z.object({
|
|
340
307
|
type: z.string().startsWith('tool-'),
|
|
@@ -346,13 +313,7 @@ const uiMessagesSchema = lazySchema(() =>
|
|
|
346
313
|
output: z.never().optional(),
|
|
347
314
|
errorText: z.never().optional(),
|
|
348
315
|
callProviderMetadata: providerMetadataSchema.optional(),
|
|
349
|
-
approval:
|
|
350
|
-
id: z.string(),
|
|
351
|
-
approved: z.literal(false),
|
|
352
|
-
descriptor: z.unknown().optional(),
|
|
353
|
-
reason: z.string().optional(),
|
|
354
|
-
signature: z.string().optional(),
|
|
355
|
-
}),
|
|
316
|
+
approval: approvalDeniedSchema,
|
|
356
317
|
}),
|
|
357
318
|
]),
|
|
358
319
|
),
|
|
@@ -372,8 +333,8 @@ const uiMessagesSchema = lazySchema(() =>
|
|
|
372
333
|
}),
|
|
373
334
|
)
|
|
374
335
|
.nonempty('Messages array must not be empty'),
|
|
375
|
-
)
|
|
376
|
-
);
|
|
336
|
+
);
|
|
337
|
+
});
|
|
377
338
|
|
|
378
339
|
export type SafeValidateUIMessagesResult<UI_MESSAGE extends UIMessage> =
|
|
379
340
|
| {
|
|
@@ -433,7 +394,7 @@ async function safeValidateUIMessagesInternal<UI_MESSAGE extends UIMessage>(
|
|
|
433
394
|
|
|
434
395
|
if (metadataSchema) {
|
|
435
396
|
for (const [msgIdx, message] of validatedMessages.entries()) {
|
|
436
|
-
await validateTypes({
|
|
397
|
+
message.metadata = await validateTypes({
|
|
437
398
|
value: message.metadata,
|
|
438
399
|
schema: metadataSchema,
|
|
439
400
|
context: {
|
|
@@ -471,7 +432,7 @@ async function safeValidateUIMessagesInternal<UI_MESSAGE extends UIMessage>(
|
|
|
471
432
|
};
|
|
472
433
|
}
|
|
473
434
|
|
|
474
|
-
await validateTypes({
|
|
435
|
+
dataPart.data = await validateTypes({
|
|
475
436
|
value: dataPart.data,
|
|
476
437
|
schema: dataSchema,
|
|
477
438
|
context: {
|
|
@@ -527,49 +488,53 @@ async function safeValidateUIMessagesInternal<UI_MESSAGE extends UIMessage>(
|
|
|
527
488
|
entityName: toolName,
|
|
528
489
|
entityId: toolPart.toolCallId,
|
|
529
490
|
};
|
|
491
|
+
const inputSchemaInput = getToolPartInputSchemaInput(toolPart);
|
|
492
|
+
const inputToValidate =
|
|
493
|
+
inputSchemaInput == null
|
|
494
|
+
? toolPart.input
|
|
495
|
+
: inputSchemaInput.value;
|
|
530
496
|
let convertToDynamic = false;
|
|
531
497
|
|
|
532
498
|
// Tool input validation
|
|
533
|
-
if (
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
value: toolPart.input,
|
|
540
|
-
schema: tool.inputSchema,
|
|
541
|
-
context: inputValidationContext,
|
|
542
|
-
});
|
|
543
|
-
convertToDynamic = !result.success;
|
|
544
|
-
}
|
|
545
|
-
} else if (toolPart.state === 'output-available') {
|
|
499
|
+
if (
|
|
500
|
+
toolPart.state !== 'input-streaming' &&
|
|
501
|
+
(toolPart.state !== 'output-error' ||
|
|
502
|
+
inputSchemaInput != null ||
|
|
503
|
+
toolPart.input !== undefined)
|
|
504
|
+
) {
|
|
546
505
|
const result = await safeValidateTypes({
|
|
547
|
-
value:
|
|
506
|
+
value: inputToValidate,
|
|
548
507
|
schema: tool.inputSchema,
|
|
549
508
|
context: inputValidationContext,
|
|
550
509
|
});
|
|
551
510
|
|
|
511
|
+
let inputError: TypeValidationError | undefined;
|
|
552
512
|
if (!result.success) {
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
513
|
+
inputError = result.error;
|
|
514
|
+
} else if (inputSchemaInput != null) {
|
|
515
|
+
if (!isDeepEqualData(result.value, toolPart.input)) {
|
|
516
|
+
inputError = new TypeValidationError({
|
|
517
|
+
value: toolPart.input,
|
|
518
|
+
cause:
|
|
519
|
+
'Tool input does not match the output reconstructed from inputSchemaInput.',
|
|
520
|
+
context: inputValidationContext,
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
if (inputError != null) {
|
|
526
|
+
// Failed calls and empty terminal inputs must remain loadable,
|
|
527
|
+
// but must not claim to match the current static input type.
|
|
528
|
+
if (
|
|
529
|
+
toolPart.state === 'output-error' ||
|
|
530
|
+
(toolPart.state === 'output-available' &&
|
|
531
|
+
isEmptyObject(toolPart.input))
|
|
532
|
+
) {
|
|
557
533
|
convertToDynamic = true;
|
|
558
534
|
} else {
|
|
559
|
-
throw
|
|
535
|
+
throw inputError;
|
|
560
536
|
}
|
|
561
537
|
}
|
|
562
|
-
} else if (
|
|
563
|
-
toolPart.state === 'input-available' ||
|
|
564
|
-
toolPart.state === 'approval-requested' ||
|
|
565
|
-
toolPart.state === 'approval-responded' ||
|
|
566
|
-
toolPart.state === 'output-denied'
|
|
567
|
-
) {
|
|
568
|
-
await validateTypes({
|
|
569
|
-
value: toolPart.input,
|
|
570
|
-
schema: tool.inputSchema,
|
|
571
|
-
context: inputValidationContext,
|
|
572
|
-
});
|
|
573
538
|
}
|
|
574
539
|
|
|
575
540
|
// Tool output validation
|
|
@@ -86,6 +86,7 @@ export const uiMessageChunkSchema = lazySchema(() =>
|
|
|
86
86
|
approvalId: z.string(),
|
|
87
87
|
toolCallId: z.string(),
|
|
88
88
|
approvalDescriptor: z.unknown().optional(),
|
|
89
|
+
inputSchemaInput: z.unknown().optional(),
|
|
89
90
|
signature: z.string().optional(),
|
|
90
91
|
}),
|
|
91
92
|
z.looseObject({
|
|
@@ -272,6 +273,7 @@ export type UIMessageChunk<
|
|
|
272
273
|
approvalId: string;
|
|
273
274
|
toolCallId: string;
|
|
274
275
|
approvalDescriptor?: unknown;
|
|
276
|
+
inputSchemaInput?: unknown;
|
|
275
277
|
signature?: string;
|
|
276
278
|
}
|
|
277
279
|
| {
|