ai 7.0.112 → 7.0.113
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 +26 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +315 -213
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts +2 -1
- package/dist/internal/index.js +105 -28
- package/dist/internal/index.js.map +1 -1
- package/docs/03-agents/06-tool-approvals.mdx +16 -0
- package/docs/03-ai-sdk-core/37-speech.mdx +2 -0
- package/docs/07-reference/01-ai-sdk-core/12-generate-speech.mdx +1 -1
- package/docs/07-reference/01-ai-sdk-core/32-validate-ui-messages.mdx +18 -0
- package/package.json +11 -11
- package/src/embed/embed-many.ts +18 -2
- package/src/generate-speech/generate-speech.ts +15 -4
- package/src/generate-speech/generated-audio-file.ts +0 -8
- package/src/generate-text/execute-tools-from-stream.ts +0 -2
- package/src/generate-text/generate-text.ts +1 -0
- package/src/generate-text/generated-file.ts +0 -8
- package/src/generate-text/invoke-tool-callbacks-from-stream.ts +9 -8
- package/src/generate-text/output.ts +0 -2
- package/src/generate-text/parse-tool-call.ts +38 -25
- package/src/generate-text/stream-text.ts +1 -0
- 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 +39 -3
- package/src/generate-video/generate-video.ts +0 -2
- package/src/middleware/extract-reasoning-middleware.ts +1 -1
- package/src/middleware/wrap-embedding-model.ts +9 -1
- package/src/model/get-embedding-model-provider-options-transformer.ts +17 -0
- package/src/prompt/content-part.ts +3 -0
- package/src/registry/custom-provider.ts +12 -5
- package/src/ui/chat.ts +108 -17
- package/src/ui/convert-to-model-messages.ts +8 -0
- package/src/ui/direct-chat-transport.ts +2 -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 +98 -132
- package/src/ui-message-stream/to-ui-message-chunk.ts +7 -0
- package/src/ui-message-stream/ui-message-chunks.ts +2 -0
- package/src/util/write-to-server-response.ts +0 -2
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
type Experimental_EvaluationModelV4 as EvaluationModelV4,
|
|
3
3
|
type EmbeddingModelV4,
|
|
4
|
+
type Experimental_VideoModelV3,
|
|
4
5
|
type Experimental_VideoModelV4,
|
|
5
6
|
type FilesV4,
|
|
6
7
|
type ImageModelV4,
|
|
@@ -35,6 +36,12 @@ import type { SpeechModel } from '../types/speech-model';
|
|
|
35
36
|
import type { TranscriptionModel } from '../types/transcription-model';
|
|
36
37
|
import type { VideoModel } from '../types/video-model';
|
|
37
38
|
|
|
39
|
+
type ProviderWithOptionalVideoModel = {
|
|
40
|
+
videoModel?: (
|
|
41
|
+
modelId: string,
|
|
42
|
+
) => Experimental_VideoModelV3 | Experimental_VideoModelV4;
|
|
43
|
+
};
|
|
44
|
+
|
|
38
45
|
/**
|
|
39
46
|
* Creates a custom provider with specified language models, text embedding models, image models, transcription models, speech models, file APIs, skill APIs, and an optional fallback provider.
|
|
40
47
|
*
|
|
@@ -247,11 +254,11 @@ export function customProvider<
|
|
|
247
254
|
return resolveVideoModel(videoModels[modelId]);
|
|
248
255
|
}
|
|
249
256
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
if (videoModel) {
|
|
254
|
-
return videoModel(modelId);
|
|
257
|
+
const provider = fallbackProviderArg as
|
|
258
|
+
| ProviderWithOptionalVideoModel
|
|
259
|
+
| undefined;
|
|
260
|
+
if (provider?.videoModel) {
|
|
261
|
+
return resolveVideoModel(provider.videoModel(modelId));
|
|
255
262
|
}
|
|
256
263
|
|
|
257
264
|
throw new NoSuchModelError({ modelId, modelType: 'videoModel' });
|
package/src/ui/chat.ts
CHANGED
|
@@ -260,6 +260,7 @@ export abstract class AbstractChat<UI_MESSAGE extends UIMessage> {
|
|
|
260
260
|
private sendAutomaticallyWhen?: ChatInit<UI_MESSAGE>['sendAutomaticallyWhen'];
|
|
261
261
|
|
|
262
262
|
private pendingMessagePreparations = new Set<AbortController>();
|
|
263
|
+
private pendingApprovalMessageId: string | undefined;
|
|
263
264
|
private activeResponse: ActiveResponse<UI_MESSAGE> | undefined = undefined;
|
|
264
265
|
private activeResumeRequest: ActiveResumeRequest | undefined = undefined;
|
|
265
266
|
private jobExecutor = new SerialJobExecutor();
|
|
@@ -362,9 +363,37 @@ export abstract class AbstractChat<UI_MESSAGE extends UIMessage> {
|
|
|
362
363
|
options?: ChatRequestOptions,
|
|
363
364
|
): Promise<void> => {
|
|
364
365
|
if (message == null) {
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
366
|
+
let messageId = this.pendingApprovalMessageId;
|
|
367
|
+
|
|
368
|
+
if (messageId == null) {
|
|
369
|
+
messageId = this.lastMessage?.id;
|
|
370
|
+
|
|
371
|
+
// When hydrating a chat with an already-responded approval, continue
|
|
372
|
+
// the most recent matching assistant message so result chunks can
|
|
373
|
+
// resolve its tool invocation.
|
|
374
|
+
for (let i = this.state.messages.length - 1; i >= 0; i--) {
|
|
375
|
+
const candidate = this.state.messages[i];
|
|
376
|
+
if (
|
|
377
|
+
candidate.role === 'assistant' &&
|
|
378
|
+
candidate.parts.some(
|
|
379
|
+
part => isToolUIPart(part) && part.state === 'approval-responded',
|
|
380
|
+
)
|
|
381
|
+
) {
|
|
382
|
+
messageId = candidate.id;
|
|
383
|
+
break;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
const consumesPendingApproval =
|
|
389
|
+
messageId != null && messageId === this.pendingApprovalMessageId;
|
|
390
|
+
const pendingApprovalMessageIndex = consumesPendingApproval
|
|
391
|
+
? this.state.messages.findIndex(message => message.id === messageId)
|
|
392
|
+
: -1;
|
|
393
|
+
|
|
394
|
+
await this.makeRequestForToolApproval({
|
|
395
|
+
messageId,
|
|
396
|
+
messageIndex: pendingApprovalMessageIndex,
|
|
368
397
|
...options,
|
|
369
398
|
});
|
|
370
399
|
return;
|
|
@@ -512,7 +541,6 @@ export abstract class AbstractChat<UI_MESSAGE extends UIMessage> {
|
|
|
512
541
|
}) =>
|
|
513
542
|
this.jobExecutor.run(async () => {
|
|
514
543
|
const messages = this.state.messages;
|
|
515
|
-
const lastMessage = messages[messages.length - 1];
|
|
516
544
|
|
|
517
545
|
const updatePart = (
|
|
518
546
|
part: UIMessagePart<UIDataTypes, UITools>,
|
|
@@ -527,11 +555,25 @@ export abstract class AbstractChat<UI_MESSAGE extends UIMessage> {
|
|
|
527
555
|
}
|
|
528
556
|
: part;
|
|
529
557
|
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
558
|
+
const messageIndex = messages.findIndex(message =>
|
|
559
|
+
message.parts.some(
|
|
560
|
+
part =>
|
|
561
|
+
isToolUIPart(part) &&
|
|
562
|
+
part.state === 'approval-requested' &&
|
|
563
|
+
part.approval.id === id,
|
|
564
|
+
),
|
|
565
|
+
);
|
|
566
|
+
|
|
567
|
+
if (messageIndex !== -1) {
|
|
568
|
+
const message = messages[messageIndex];
|
|
569
|
+
|
|
570
|
+
// update the message to trigger an immediate UI update
|
|
571
|
+
this.state.replaceMessage(messageIndex, {
|
|
572
|
+
...message,
|
|
573
|
+
parts: message.parts.map(updatePart),
|
|
574
|
+
});
|
|
575
|
+
this.pendingApprovalMessageId = message.id;
|
|
576
|
+
}
|
|
535
577
|
|
|
536
578
|
// update the active response if it exists
|
|
537
579
|
if (this.activeResponse) {
|
|
@@ -548,9 +590,14 @@ export abstract class AbstractChat<UI_MESSAGE extends UIMessage> {
|
|
|
548
590
|
this.shouldSendAutomatically().then(shouldSend => {
|
|
549
591
|
if (shouldSend) {
|
|
550
592
|
// no await to avoid deadlocking
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
593
|
+
const messageId =
|
|
594
|
+
messageIndex === -1
|
|
595
|
+
? this.lastMessage?.id
|
|
596
|
+
: messages[messageIndex].id;
|
|
597
|
+
|
|
598
|
+
this.makeRequestForToolApproval({
|
|
599
|
+
messageId,
|
|
600
|
+
messageIndex,
|
|
554
601
|
...options,
|
|
555
602
|
});
|
|
556
603
|
}
|
|
@@ -636,6 +683,36 @@ export abstract class AbstractChat<UI_MESSAGE extends UIMessage> {
|
|
|
636
683
|
return result as boolean;
|
|
637
684
|
}
|
|
638
685
|
|
|
686
|
+
private async makeRequestForToolApproval({
|
|
687
|
+
messageId,
|
|
688
|
+
messageIndex,
|
|
689
|
+
...options
|
|
690
|
+
}: {
|
|
691
|
+
messageId?: string;
|
|
692
|
+
messageIndex: number;
|
|
693
|
+
} & ChatRequestOptions) {
|
|
694
|
+
const consumesPendingApproval =
|
|
695
|
+
messageId != null && messageId === this.pendingApprovalMessageId;
|
|
696
|
+
if (consumesPendingApproval) {
|
|
697
|
+
this.pendingApprovalMessageId = undefined;
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
await this.makeRequest({
|
|
701
|
+
trigger: 'submit-message',
|
|
702
|
+
messageId,
|
|
703
|
+
...options,
|
|
704
|
+
});
|
|
705
|
+
|
|
706
|
+
if (
|
|
707
|
+
consumesPendingApproval &&
|
|
708
|
+
this.status === 'error' &&
|
|
709
|
+
this.pendingApprovalMessageId == null
|
|
710
|
+
) {
|
|
711
|
+
this.pendingApprovalMessageId =
|
|
712
|
+
this.state.messages[messageIndex]?.id ?? messageId;
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
|
|
639
716
|
private async makeRequest({
|
|
640
717
|
trigger,
|
|
641
718
|
metadata,
|
|
@@ -723,6 +800,18 @@ export abstract class AbstractChat<UI_MESSAGE extends UIMessage> {
|
|
|
723
800
|
this.setStatus({ status: 'submitted', error: undefined });
|
|
724
801
|
|
|
725
802
|
const lastMessage = this.lastMessage;
|
|
803
|
+
const responseMessageIndex =
|
|
804
|
+
trigger === 'submit-message' && messageId != null
|
|
805
|
+
? this.state.messages.findIndex(message => message.id === messageId)
|
|
806
|
+
: this.state.messages.length - 1;
|
|
807
|
+
const responseMessage =
|
|
808
|
+
responseMessageIndex === -1
|
|
809
|
+
? lastMessage
|
|
810
|
+
: this.state.messages[responseMessageIndex];
|
|
811
|
+
const usesEarlierAssistantMessage =
|
|
812
|
+
responseMessageIndex !== -1 &&
|
|
813
|
+
responseMessageIndex < this.state.messages.length - 1 &&
|
|
814
|
+
responseMessage?.role === 'assistant';
|
|
726
815
|
|
|
727
816
|
let isAbort = false;
|
|
728
817
|
let isDisconnect = false;
|
|
@@ -735,7 +824,7 @@ export abstract class AbstractChat<UI_MESSAGE extends UIMessage> {
|
|
|
735
824
|
lastMessage:
|
|
736
825
|
trigger === 'resume-stream' || trigger === 'regenerate-message'
|
|
737
826
|
? undefined
|
|
738
|
-
: this.state.snapshot(
|
|
827
|
+
: this.state.snapshot(responseMessage),
|
|
739
828
|
messageId: this.generateId(),
|
|
740
829
|
}),
|
|
741
830
|
abortController,
|
|
@@ -789,10 +878,12 @@ export abstract class AbstractChat<UI_MESSAGE extends UIMessage> {
|
|
|
789
878
|
this.setStatus({ status: 'streaming' });
|
|
790
879
|
}
|
|
791
880
|
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
881
|
+
if (usesEarlierAssistantMessage) {
|
|
882
|
+
this.state.replaceMessage(
|
|
883
|
+
responseMessageIndex,
|
|
884
|
+
response.state.message,
|
|
885
|
+
);
|
|
886
|
+
} else if (response.state.message.id === this.lastMessage?.id) {
|
|
796
887
|
this.state.replaceMessage(
|
|
797
888
|
this.state.messages.length - 1,
|
|
798
889
|
response.state.message,
|
|
@@ -245,6 +245,14 @@ export async function convertToModelMessages<UI_MESSAGE extends UIMessage>(
|
|
|
245
245
|
...(part.approval.requestReason != null
|
|
246
246
|
? { reason: part.approval.requestReason }
|
|
247
247
|
: {}),
|
|
248
|
+
...(Object.prototype.hasOwnProperty.call(
|
|
249
|
+
part.approval,
|
|
250
|
+
'inputSchemaInput',
|
|
251
|
+
)
|
|
252
|
+
? {
|
|
253
|
+
inputSchemaInput: part.approval.inputSchemaInput,
|
|
254
|
+
}
|
|
255
|
+
: {}),
|
|
248
256
|
...(part.approval.signature != null
|
|
249
257
|
? { signature: part.approval.signature }
|
|
250
258
|
: {}),
|
|
@@ -124,6 +124,8 @@ export class DirectChatTransport<
|
|
|
124
124
|
// Return the UI message stream
|
|
125
125
|
return toUIMessageStream({
|
|
126
126
|
...this.uiMessageStreamOptions,
|
|
127
|
+
originalMessages:
|
|
128
|
+
this.uiMessageStreamOptions.originalMessages ?? validatedMessages,
|
|
127
129
|
stream: result.stream,
|
|
128
130
|
tools: this.agent.tools,
|
|
129
131
|
});
|
|
@@ -755,6 +755,12 @@ export function processUIMessageStream<UI_MESSAGE extends UIMessage>({
|
|
|
755
755
|
...(chunk.approvalDescriptor != null
|
|
756
756
|
? { descriptor: chunk.approvalDescriptor }
|
|
757
757
|
: {}),
|
|
758
|
+
...(Object.prototype.hasOwnProperty.call(
|
|
759
|
+
chunk,
|
|
760
|
+
'inputSchemaInput',
|
|
761
|
+
)
|
|
762
|
+
? { inputSchemaInput: chunk.inputSchemaInput }
|
|
763
|
+
: {}),
|
|
758
764
|
...(chunk.reason != null
|
|
759
765
|
? { requestReason: chunk.reason }
|
|
760
766
|
: {}),
|
package/src/ui/ui-messages.ts
CHANGED
|
@@ -324,6 +324,7 @@ export type UIToolInvocation<TOOL extends UITool | Tool> = {
|
|
|
324
324
|
reason?: never;
|
|
325
325
|
isAutomatic?: boolean;
|
|
326
326
|
signature?: string;
|
|
327
|
+
inputSchemaInput?: unknown;
|
|
327
328
|
};
|
|
328
329
|
}
|
|
329
330
|
| {
|
|
@@ -340,6 +341,7 @@ export type UIToolInvocation<TOOL extends UITool | Tool> = {
|
|
|
340
341
|
reason?: string;
|
|
341
342
|
isAutomatic?: boolean;
|
|
342
343
|
signature?: string;
|
|
344
|
+
inputSchemaInput?: unknown;
|
|
343
345
|
};
|
|
344
346
|
}
|
|
345
347
|
| {
|
|
@@ -358,6 +360,7 @@ export type UIToolInvocation<TOOL extends UITool | Tool> = {
|
|
|
358
360
|
reason?: string;
|
|
359
361
|
isAutomatic?: boolean;
|
|
360
362
|
signature?: string;
|
|
363
|
+
inputSchemaInput?: unknown;
|
|
361
364
|
};
|
|
362
365
|
}
|
|
363
366
|
| {
|
|
@@ -380,6 +383,7 @@ export type UIToolInvocation<TOOL extends UITool | Tool> = {
|
|
|
380
383
|
reason?: string;
|
|
381
384
|
isAutomatic?: boolean;
|
|
382
385
|
signature?: string;
|
|
386
|
+
inputSchemaInput?: unknown;
|
|
383
387
|
};
|
|
384
388
|
}
|
|
385
389
|
| {
|
|
@@ -396,6 +400,7 @@ export type UIToolInvocation<TOOL extends UITool | Tool> = {
|
|
|
396
400
|
reason?: string;
|
|
397
401
|
isAutomatic?: boolean;
|
|
398
402
|
signature?: string;
|
|
403
|
+
inputSchemaInput?: unknown;
|
|
399
404
|
};
|
|
400
405
|
}
|
|
401
406
|
);
|
|
@@ -456,6 +461,7 @@ export type DynamicToolUIPart = {
|
|
|
456
461
|
reason?: never;
|
|
457
462
|
isAutomatic?: boolean;
|
|
458
463
|
signature?: string;
|
|
464
|
+
inputSchemaInput?: unknown;
|
|
459
465
|
};
|
|
460
466
|
}
|
|
461
467
|
| {
|
|
@@ -472,6 +478,7 @@ export type DynamicToolUIPart = {
|
|
|
472
478
|
reason?: string;
|
|
473
479
|
isAutomatic?: boolean;
|
|
474
480
|
signature?: string;
|
|
481
|
+
inputSchemaInput?: unknown;
|
|
475
482
|
};
|
|
476
483
|
}
|
|
477
484
|
| {
|
|
@@ -490,6 +497,7 @@ export type DynamicToolUIPart = {
|
|
|
490
497
|
reason?: string;
|
|
491
498
|
isAutomatic?: boolean;
|
|
492
499
|
signature?: string;
|
|
500
|
+
inputSchemaInput?: unknown;
|
|
493
501
|
};
|
|
494
502
|
}
|
|
495
503
|
| {
|
|
@@ -507,6 +515,7 @@ export type DynamicToolUIPart = {
|
|
|
507
515
|
reason?: string;
|
|
508
516
|
isAutomatic?: boolean;
|
|
509
517
|
signature?: string;
|
|
518
|
+
inputSchemaInput?: unknown;
|
|
510
519
|
};
|
|
511
520
|
}
|
|
512
521
|
| {
|
|
@@ -523,6 +532,7 @@ export type DynamicToolUIPart = {
|
|
|
523
532
|
reason?: string;
|
|
524
533
|
isAutomatic?: boolean;
|
|
525
534
|
signature?: string;
|
|
535
|
+
inputSchemaInput?: unknown;
|
|
526
536
|
};
|
|
527
537
|
}
|
|
528
538
|
);
|