ai 7.0.148 → 7.0.149
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 +21 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +47 -32
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts +2 -1
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +4 -1
- package/dist/internal/index.js.map +1 -1
- package/docs/03-ai-sdk-core/15-tools-and-tool-calling.mdx +7 -0
- package/docs/03-ai-sdk-core/18-code-mode.mdx +3 -1
- package/docs/03-ai-sdk-core/36-transcription.mdx +40 -39
- package/docs/03-ai-sdk-core/37-speech.mdx +1 -0
- package/docs/03-ai-sdk-core/60-telemetry.mdx +25 -2
- package/docs/03-ai-sdk-harnesses/05-harness-adapters.mdx +1 -1
- package/docs/07-reference/01-ai-sdk-core/01-generate-text.mdx +4 -4
- package/docs/07-reference/01-ai-sdk-core/02-stream-text.mdx +7 -7
- package/docs/07-reference/02-ai-sdk-ui/01-use-chat.mdx +1 -1
- package/docs/07-reference/02-ai-sdk-ui/40-create-ui-message-stream.mdx +1 -1
- package/docs/07-reference/03-ai-sdk-rsc/01-stream-ui.mdx +1 -1
- package/docs/07-reference/05-ai-sdk-errors/ai-tool-choice-violation-error.mdx +12 -7
- package/package.json +12 -12
- package/src/error/tool-choice-violation-error.ts +6 -4
- package/src/generate-text/collect-tool-approvals.ts +10 -0
- package/src/generate-text/generate-text.ts +24 -12
- package/src/generate-text/stream-language-model-call.ts +37 -12
- package/src/generate-text/stream-text.ts +4 -1
- package/src/types/language-model.ts +2 -0
- package/src/ui/chat.ts +40 -12
- package/src/ui-message-stream/ui-message-chunks.ts +1 -0
|
@@ -2465,7 +2465,7 @@ class DefaultStreamTextResult<
|
|
|
2465
2465
|
activeTools: prepareStepResult?.activeTools ?? activeTools,
|
|
2466
2466
|
});
|
|
2467
2467
|
const {
|
|
2468
|
-
executionTools
|
|
2468
|
+
executionTools,
|
|
2469
2469
|
modelTools: stepModelTools,
|
|
2470
2470
|
toolCallerMessages,
|
|
2471
2471
|
} = prepareToolsForToolCallers({
|
|
@@ -2495,6 +2495,8 @@ class DefaultStreamTextResult<
|
|
|
2495
2495
|
const stepToolChoice = prepareToolChoice({
|
|
2496
2496
|
toolChoice: prepareStepResult?.toolChoice ?? toolChoice,
|
|
2497
2497
|
});
|
|
2498
|
+
const stepExecutionTools =
|
|
2499
|
+
stepToolChoice.type === 'none' ? undefined : executionTools;
|
|
2498
2500
|
|
|
2499
2501
|
const stepMessages = appendToolCallerMessages({
|
|
2500
2502
|
messages: prepareStepResult?.messages ?? stepInputMessages,
|
|
@@ -3215,6 +3217,7 @@ class DefaultStreamTextResult<
|
|
|
3215
3217
|
cleanupStepTimeouts();
|
|
3216
3218
|
|
|
3217
3219
|
if (
|
|
3220
|
+
stepFinishReason !== 'interrupted' &&
|
|
3218
3221
|
// Continue only after all client tool calls have been executed or denied,
|
|
3219
3222
|
// and if there are client results or pending deferred provider results.
|
|
3220
3223
|
clientToolCalls.length ===
|
|
@@ -70,6 +70,7 @@ export type LanguageModel =
|
|
|
70
70
|
* - `content-filter`: content filter violation stopped the model
|
|
71
71
|
* - `tool-calls`: model triggered tool calls
|
|
72
72
|
* - `error`: model stopped because of an error
|
|
73
|
+
* - `interrupted`: provider stream ended without a completion signal; output may be incomplete
|
|
73
74
|
* - `other`: model stopped for other reasons
|
|
74
75
|
*/
|
|
75
76
|
export type FinishReason =
|
|
@@ -78,6 +79,7 @@ export type FinishReason =
|
|
|
78
79
|
| 'content-filter'
|
|
79
80
|
| 'tool-calls'
|
|
80
81
|
| 'error'
|
|
82
|
+
| 'interrupted'
|
|
81
83
|
| 'other';
|
|
82
84
|
|
|
83
85
|
/**
|
package/src/ui/chat.ts
CHANGED
|
@@ -274,6 +274,9 @@ export abstract class AbstractChat<UI_MESSAGE extends UIMessage> {
|
|
|
274
274
|
|
|
275
275
|
private pendingMessagePreparations = new Set<AbortController>();
|
|
276
276
|
private pendingApprovalMessageId: string | undefined;
|
|
277
|
+
// Keep interruption state after activeResponse is cleared so late tool updates
|
|
278
|
+
// cannot automatically continue an interrupted message.
|
|
279
|
+
private interruptedMessageIds = new Set<string>();
|
|
277
280
|
private activeResponse: ActiveResponse<UI_MESSAGE> | undefined = undefined;
|
|
278
281
|
private activeResumeRequest: ActiveResumeRequest | undefined = undefined;
|
|
279
282
|
private resumableStreamState:
|
|
@@ -638,7 +641,9 @@ export abstract class AbstractChat<UI_MESSAGE extends UIMessage> {
|
|
|
638
641
|
this.status !== 'submitted' &&
|
|
639
642
|
this.sendAutomaticallyWhen
|
|
640
643
|
) {
|
|
641
|
-
const shouldSend = await this.shouldSendAutomatically(
|
|
644
|
+
const shouldSend = await this.shouldSendAutomatically(
|
|
645
|
+
messages[messageIndex].id,
|
|
646
|
+
);
|
|
642
647
|
|
|
643
648
|
if (shouldSend) {
|
|
644
649
|
// no await to avoid deadlocking
|
|
@@ -735,7 +740,9 @@ export abstract class AbstractChat<UI_MESSAGE extends UIMessage> {
|
|
|
735
740
|
this.status !== 'submitted' &&
|
|
736
741
|
this.sendAutomaticallyWhen
|
|
737
742
|
) {
|
|
738
|
-
const shouldSend = await this.shouldSendAutomatically(
|
|
743
|
+
const shouldSend = await this.shouldSendAutomatically(
|
|
744
|
+
messages[messageIndex].id,
|
|
745
|
+
);
|
|
739
746
|
|
|
740
747
|
if (shouldSend) {
|
|
741
748
|
// no await to avoid deadlocking
|
|
@@ -794,19 +801,29 @@ export abstract class AbstractChat<UI_MESSAGE extends UIMessage> {
|
|
|
794
801
|
this.transport.close?.();
|
|
795
802
|
};
|
|
796
803
|
|
|
797
|
-
private async shouldSendAutomatically(
|
|
798
|
-
|
|
804
|
+
private async shouldSendAutomatically(
|
|
805
|
+
messageId = this.lastMessage?.id,
|
|
806
|
+
): Promise<boolean> {
|
|
807
|
+
const isInterrupted = (id: string | undefined) =>
|
|
808
|
+
id != null && this.interruptedMessageIds.has(id);
|
|
799
809
|
|
|
800
|
-
|
|
810
|
+
if (
|
|
811
|
+
!this.sendAutomaticallyWhen ||
|
|
812
|
+
isInterrupted(messageId) ||
|
|
813
|
+
isInterrupted(this.lastMessage?.id)
|
|
814
|
+
) {
|
|
815
|
+
return false;
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
const result = await this.sendAutomaticallyWhen({
|
|
801
819
|
messages: this.state.messages,
|
|
802
820
|
});
|
|
803
821
|
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
return result as boolean;
|
|
822
|
+
return (
|
|
823
|
+
result &&
|
|
824
|
+
!isInterrupted(messageId) &&
|
|
825
|
+
!isInterrupted(this.lastMessage?.id)
|
|
826
|
+
);
|
|
810
827
|
}
|
|
811
828
|
|
|
812
829
|
private async runAutomaticRequest(
|
|
@@ -1182,6 +1199,13 @@ export abstract class AbstractChat<UI_MESSAGE extends UIMessage> {
|
|
|
1182
1199
|
} finally {
|
|
1183
1200
|
try {
|
|
1184
1201
|
if (activeResponse) {
|
|
1202
|
+
const { message, finishReason } = activeResponse.state;
|
|
1203
|
+
if (finishReason === 'interrupted') {
|
|
1204
|
+
this.interruptedMessageIds.add(message.id);
|
|
1205
|
+
} else if (!isAbort && !isError) {
|
|
1206
|
+
this.interruptedMessageIds.delete(message.id);
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1185
1209
|
this.onFinish?.({
|
|
1186
1210
|
message: activeResponse.state.message,
|
|
1187
1211
|
messages: this.state.messages,
|
|
@@ -1201,7 +1225,11 @@ export abstract class AbstractChat<UI_MESSAGE extends UIMessage> {
|
|
|
1201
1225
|
}
|
|
1202
1226
|
|
|
1203
1227
|
// automatically send the message if the sendAutomaticallyWhen function returns true
|
|
1204
|
-
if (
|
|
1228
|
+
if (
|
|
1229
|
+
!isAbort &&
|
|
1230
|
+
!isError &&
|
|
1231
|
+
activeResponse?.state.finishReason !== 'interrupted'
|
|
1232
|
+
) {
|
|
1205
1233
|
await this.runAutomaticRequest(() =>
|
|
1206
1234
|
this.makeRequest({
|
|
1207
1235
|
trigger: 'submit-message',
|