ai 7.0.69 → 7.0.71
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 -0
- package/dist/index.js +100 -17
- package/dist/index.js.map +1 -1
- package/dist/internal/index.js +1 -1
- package/docs/03-agents/07-workflow-agent.mdx +28 -10
- package/docs/03-ai-sdk-harnesses/02-harness-agent.mdx +58 -0
- package/docs/04-ai-sdk-ui/21-transport.mdx +6 -2
- package/docs/04-ai-sdk-ui/50-stream-protocol.mdx +16 -0
- package/docs/07-reference/04-ai-sdk-workflow/01-workflow-agent.mdx +15 -1
- package/docs/07-reference/04-ai-sdk-workflow/02-workflow-chat-transport.mdx +25 -11
- package/package.json +3 -3
- package/src/generate-object/stream-object.ts +67 -4
- package/src/generate-text/execute-tools-from-stream.ts +5 -0
- package/src/generate-text/generate-text.ts +12 -8
- package/src/generate-text/is-tool-execution-allowed-finish-reason.ts +7 -0
- package/src/generate-text/stream-text.ts +14 -9
- package/src/ui/convert-to-model-messages.ts +1 -1
- package/src/ui/process-ui-message-stream.ts +17 -0
- package/src/ui-message-stream/ui-message-chunks.ts +9 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# ai
|
|
2
2
|
|
|
3
|
+
## 7.0.71
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 9a37469: Prevent exceptions in streaming `onChunk` and `onError` callbacks from terminating the stream or masking provider errors.
|
|
8
|
+
- Updated dependencies [936719b]
|
|
9
|
+
- @ai-sdk/gateway@4.0.57
|
|
10
|
+
|
|
11
|
+
## 7.0.70
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- 9566914: Stop multi-step text generation for client tool approval even when a provider-executed tool has a deferred result.
|
|
16
|
+
- b181020: fix: reject `streamObject` result promises and report failed completion when the provider stream errors
|
|
17
|
+
- 7054073: Filter preliminary tool outputs when `ignoreIncompleteToolCalls` is enabled.
|
|
18
|
+
- a828527: Prevent automatic tool execution when a model call ends with an unsafe finish reason.
|
|
19
|
+
- d3cc3fe: Clear partial UI message parts when a WorkflowAgent model-call step is retried.
|
|
20
|
+
- Updated dependencies [e6087c9]
|
|
21
|
+
- @ai-sdk/provider-utils@5.0.28
|
|
22
|
+
- @ai-sdk/gateway@4.0.56
|
|
23
|
+
|
|
3
24
|
## 7.0.69
|
|
4
25
|
|
|
5
26
|
### Patch Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -2403,6 +2403,11 @@ type UIMessageChunk<METADATA = unknown, DATA_TYPES extends UIDataTypes = UIDataT
|
|
|
2403
2403
|
type: 'start-step';
|
|
2404
2404
|
} | {
|
|
2405
2405
|
type: 'finish-step';
|
|
2406
|
+
} | {
|
|
2407
|
+
/**
|
|
2408
|
+
* Removes all message parts added during the current step.
|
|
2409
|
+
*/
|
|
2410
|
+
type: 'reset-step';
|
|
2406
2411
|
} | {
|
|
2407
2412
|
type: 'start';
|
|
2408
2413
|
messageId?: string;
|
package/dist/index.js
CHANGED
|
@@ -1143,7 +1143,7 @@ import {
|
|
|
1143
1143
|
} from "@ai-sdk/provider-utils";
|
|
1144
1144
|
|
|
1145
1145
|
// src/version.ts
|
|
1146
|
-
var VERSION = true ? "7.0.
|
|
1146
|
+
var VERSION = true ? "7.0.71" : "0.0.0-test";
|
|
1147
1147
|
|
|
1148
1148
|
// src/util/download/download.ts
|
|
1149
1149
|
var download = async ({
|
|
@@ -3139,6 +3139,11 @@ var DefaultGeneratedFileWithType = class extends DefaultGeneratedFile {
|
|
|
3139
3139
|
}
|
|
3140
3140
|
};
|
|
3141
3141
|
|
|
3142
|
+
// src/generate-text/is-tool-execution-allowed-finish-reason.ts
|
|
3143
|
+
function isToolExecutionAllowedFinishReason(finishReason) {
|
|
3144
|
+
return finishReason === "stop" || finishReason === "tool-calls";
|
|
3145
|
+
}
|
|
3146
|
+
|
|
3142
3147
|
// src/generate-text/output.ts
|
|
3143
3148
|
var output_exports = {};
|
|
3144
3149
|
__export(output_exports, {
|
|
@@ -5838,7 +5843,9 @@ async function generateText({
|
|
|
5838
5843
|
(toolApprovalResponse) => toolApprovalResponse.approved === false
|
|
5839
5844
|
);
|
|
5840
5845
|
const toolExecutionMs = {};
|
|
5841
|
-
if (stepExecutionTools != null
|
|
5846
|
+
if (stepExecutionTools != null && isToolExecutionAllowedFinishReason(
|
|
5847
|
+
currentModelResponse.finishReason.unified
|
|
5848
|
+
)) {
|
|
5842
5849
|
const toolExecutionResults = await executeTools({
|
|
5843
5850
|
toolCalls: clientToolCalls.filter(
|
|
5844
5851
|
(toolCall) => !toolCall.invalid && !blockedToolCallIds.has(toolCall.toolCallId)
|
|
@@ -5974,10 +5981,9 @@ async function generateText({
|
|
|
5974
5981
|
}
|
|
5975
5982
|
}
|
|
5976
5983
|
} while (
|
|
5977
|
-
// Continue
|
|
5978
|
-
//
|
|
5979
|
-
|
|
5980
|
-
(clientToolCalls.length > 0 && clientToolOutputs.length + deniedToolApprovalResponses.length === clientToolCalls.length || pendingDeferredToolCalls.size > 0) && // continue until a stop condition is met:
|
|
5984
|
+
// Continue only after all client tool calls have been executed or denied,
|
|
5985
|
+
// and if there are client results or pending deferred provider results.
|
|
5986
|
+
clientToolOutputs.length + deniedToolApprovalResponses.length === clientToolCalls.length && (clientToolCalls.length > 0 || pendingDeferredToolCalls.size > 0) && // continue until a stop condition is met:
|
|
5981
5987
|
!await isStopConditionMet({ stopConditions, steps })
|
|
5982
5988
|
);
|
|
5983
5989
|
const lastStep = steps[steps.length - 1];
|
|
@@ -6711,6 +6717,9 @@ var uiMessageChunkSchema = lazySchema(
|
|
|
6711
6717
|
z.looseObject({
|
|
6712
6718
|
type: z.literal("finish-step")
|
|
6713
6719
|
}),
|
|
6720
|
+
z.looseObject({
|
|
6721
|
+
type: z.literal("reset-step")
|
|
6722
|
+
}),
|
|
6714
6723
|
z.looseObject({
|
|
6715
6724
|
type: z.literal("start"),
|
|
6716
6725
|
messageId: z.string().optional(),
|
|
@@ -7364,6 +7373,20 @@ function processUIMessageStream({
|
|
|
7364
7373
|
state.activeReasoningParts = createIdMap();
|
|
7365
7374
|
break;
|
|
7366
7375
|
}
|
|
7376
|
+
case "reset-step": {
|
|
7377
|
+
const currentStepParts = getCurrentStepParts();
|
|
7378
|
+
state.activeTextParts = createIdMap();
|
|
7379
|
+
state.activeReasoningParts = createIdMap();
|
|
7380
|
+
state.partialToolCalls = createIdMap();
|
|
7381
|
+
if (currentStepParts.length > 0) {
|
|
7382
|
+
state.message.parts.splice(
|
|
7383
|
+
state.message.parts.length - currentStepParts.length,
|
|
7384
|
+
currentStepParts.length
|
|
7385
|
+
);
|
|
7386
|
+
write();
|
|
7387
|
+
}
|
|
7388
|
+
break;
|
|
7389
|
+
}
|
|
7367
7390
|
case "start": {
|
|
7368
7391
|
if (chunk.messageId != null) {
|
|
7369
7392
|
state.message.id = chunk.messageId;
|
|
@@ -8169,6 +8192,9 @@ function executeToolsFromStream({
|
|
|
8169
8192
|
return;
|
|
8170
8193
|
}
|
|
8171
8194
|
case "model-call-end": {
|
|
8195
|
+
if (!isToolExecutionAllowedFinishReason(chunk.finishReason)) {
|
|
8196
|
+
return;
|
|
8197
|
+
}
|
|
8172
8198
|
await Promise.all(
|
|
8173
8199
|
toolCallsToExecute.map(async (toolCall) => {
|
|
8174
8200
|
try {
|
|
@@ -9112,13 +9138,19 @@ var DefaultStreamTextResult = class {
|
|
|
9112
9138
|
var _a23, _b, _c, _d;
|
|
9113
9139
|
controller.enqueue(chunk);
|
|
9114
9140
|
const { part } = chunk;
|
|
9115
|
-
await (
|
|
9141
|
+
await notify({
|
|
9142
|
+
event: { chunk: part },
|
|
9143
|
+
callbacks: onChunk
|
|
9144
|
+
});
|
|
9116
9145
|
if (part.type === "error") {
|
|
9117
9146
|
const error = wrapGatewayError(part.error);
|
|
9118
9147
|
if (NoOutputGeneratedError.isInstance(error)) {
|
|
9119
9148
|
recordedNoOutputError = error;
|
|
9120
9149
|
}
|
|
9121
|
-
await
|
|
9150
|
+
await notify({
|
|
9151
|
+
event: { error },
|
|
9152
|
+
callbacks: onError
|
|
9153
|
+
});
|
|
9122
9154
|
}
|
|
9123
9155
|
if (part.type === "custom" || part.type === "source" || part.type === "tool-call" || part.type === "tool-approval-request" || part.type === "tool-approval-response" || part.type === "tool-error") {
|
|
9124
9156
|
recordedContent.push(part);
|
|
@@ -10043,10 +10075,9 @@ var DefaultStreamTextResult = class {
|
|
|
10043
10075
|
}
|
|
10044
10076
|
cleanupStepTimeouts();
|
|
10045
10077
|
if (
|
|
10046
|
-
// Continue
|
|
10047
|
-
//
|
|
10048
|
-
|
|
10049
|
-
(clientToolCalls.length > 0 && clientToolCalls.length === clientToolOutputs.length + deniedToolApprovalResponses.length || pendingDeferredToolCalls.size > 0) && // continue until a stop condition is met:
|
|
10078
|
+
// Continue only after all client tool calls have been executed or denied,
|
|
10079
|
+
// and if there are client results or pending deferred provider results.
|
|
10080
|
+
clientToolCalls.length === clientToolOutputs.length + deniedToolApprovalResponses.length && (clientToolCalls.length > 0 || pendingDeferredToolCalls.size > 0) && // continue until a stop condition is met:
|
|
10050
10081
|
!await isStopConditionMet({
|
|
10051
10082
|
stopConditions,
|
|
10052
10083
|
steps: recordedSteps
|
|
@@ -10789,7 +10820,7 @@ async function convertToModelMessages(messages, options) {
|
|
|
10789
10820
|
messages = messages.map((message) => ({
|
|
10790
10821
|
...message,
|
|
10791
10822
|
parts: message.parts.filter(
|
|
10792
|
-
(part) => !isToolUIPart(part) || part.state === "approval-responded" || part.state === "output-available" || part.state === "output-error" || part.state === "output-denied"
|
|
10823
|
+
(part) => !isToolUIPart(part) || part.state === "approval-responded" || part.state === "output-available" && part.preliminary !== true || part.state === "output-error" || part.state === "output-denied"
|
|
10793
10824
|
)
|
|
10794
10825
|
}));
|
|
10795
10826
|
}
|
|
@@ -13366,6 +13397,12 @@ function simulateReadableStream({
|
|
|
13366
13397
|
|
|
13367
13398
|
// src/generate-object/stream-object.ts
|
|
13368
13399
|
var originalGenerateId5 = createIdGenerator7({ prefix: "aiobj", size: 24 });
|
|
13400
|
+
async function markPromiseAsHandled2(promise) {
|
|
13401
|
+
try {
|
|
13402
|
+
await promise;
|
|
13403
|
+
} catch (e) {
|
|
13404
|
+
}
|
|
13405
|
+
}
|
|
13369
13406
|
function streamObject(options) {
|
|
13370
13407
|
const {
|
|
13371
13408
|
model,
|
|
@@ -13497,7 +13534,10 @@ var DefaultStreamObjectResult = class {
|
|
|
13497
13534
|
transform(chunk, controller) {
|
|
13498
13535
|
controller.enqueue(chunk);
|
|
13499
13536
|
if (chunk.type === "error") {
|
|
13500
|
-
|
|
13537
|
+
void notify({
|
|
13538
|
+
event: { error: wrapGatewayError(chunk.error) },
|
|
13539
|
+
callbacks: onError
|
|
13540
|
+
});
|
|
13501
13541
|
}
|
|
13502
13542
|
}
|
|
13503
13543
|
});
|
|
@@ -13595,6 +13635,7 @@ var DefaultStreamObjectResult = class {
|
|
|
13595
13635
|
let providerMetadata;
|
|
13596
13636
|
let object3;
|
|
13597
13637
|
let error;
|
|
13638
|
+
let terminalError;
|
|
13598
13639
|
let msToFirstChunk = void 0;
|
|
13599
13640
|
let accumulatedText = "";
|
|
13600
13641
|
let textDelta = "";
|
|
@@ -13660,16 +13701,27 @@ var DefaultStreamObjectResult = class {
|
|
|
13660
13701
|
};
|
|
13661
13702
|
break;
|
|
13662
13703
|
}
|
|
13704
|
+
case "error": {
|
|
13705
|
+
if (terminalError === void 0) {
|
|
13706
|
+
const wrappedError = wrapGatewayError(chunk.error);
|
|
13707
|
+
terminalError = { error: wrappedError };
|
|
13708
|
+
error = wrappedError;
|
|
13709
|
+
finishReason = "error";
|
|
13710
|
+
self.rejectResultPromises(wrappedError);
|
|
13711
|
+
}
|
|
13712
|
+
controller.enqueue(chunk);
|
|
13713
|
+
break;
|
|
13714
|
+
}
|
|
13663
13715
|
case "finish": {
|
|
13664
13716
|
if (textDelta !== "") {
|
|
13665
13717
|
controller.enqueue({ type: "text-delta", textDelta });
|
|
13666
13718
|
}
|
|
13667
|
-
finishReason = chunk.finishReason.unified;
|
|
13719
|
+
finishReason = terminalError === void 0 ? chunk.finishReason.unified : "error";
|
|
13668
13720
|
usage = asLanguageModelUsage(chunk.usage);
|
|
13669
13721
|
providerMetadata = chunk.providerMetadata;
|
|
13670
13722
|
controller.enqueue({
|
|
13671
13723
|
...chunk,
|
|
13672
|
-
finishReason
|
|
13724
|
+
finishReason,
|
|
13673
13725
|
usage,
|
|
13674
13726
|
response: fullResponse
|
|
13675
13727
|
});
|
|
@@ -13678,6 +13730,9 @@ var DefaultStreamObjectResult = class {
|
|
|
13678
13730
|
provider: model.provider,
|
|
13679
13731
|
model: model.modelId
|
|
13680
13732
|
});
|
|
13733
|
+
if (terminalError !== void 0) {
|
|
13734
|
+
break;
|
|
13735
|
+
}
|
|
13681
13736
|
self._usage.resolve(usage);
|
|
13682
13737
|
self._providerMetadata.resolve(providerMetadata);
|
|
13683
13738
|
self._warnings.resolve(warnings);
|
|
@@ -13765,9 +13820,19 @@ var DefaultStreamObjectResult = class {
|
|
|
13765
13820
|
}
|
|
13766
13821
|
})
|
|
13767
13822
|
);
|
|
13768
|
-
stitchableStream.addStream(transformedStream
|
|
13823
|
+
stitchableStream.addStream(transformedStream, {
|
|
13824
|
+
onError(error2) {
|
|
13825
|
+
const wrappedError = wrapGatewayError(error2);
|
|
13826
|
+
self.rejectResultPromises(wrappedError);
|
|
13827
|
+
void notify({
|
|
13828
|
+
event: { error: wrappedError },
|
|
13829
|
+
callbacks: onError
|
|
13830
|
+
});
|
|
13831
|
+
}
|
|
13832
|
+
});
|
|
13769
13833
|
})().catch(async (error) => {
|
|
13770
13834
|
var _a23;
|
|
13835
|
+
self.rejectResultPromises(error);
|
|
13771
13836
|
await ((_a23 = telemetryDispatcher.onError) == null ? void 0 : _a23.call(telemetryDispatcher, { callId, error }));
|
|
13772
13837
|
stitchableStream.addStream(
|
|
13773
13838
|
new ReadableStream({
|
|
@@ -13782,6 +13847,24 @@ var DefaultStreamObjectResult = class {
|
|
|
13782
13847
|
});
|
|
13783
13848
|
this.outputStrategy = outputStrategy;
|
|
13784
13849
|
}
|
|
13850
|
+
rejectResultPromises(error) {
|
|
13851
|
+
this.rejectResultPromise({ delayedPromise: this._object, error });
|
|
13852
|
+
this.rejectResultPromise({ delayedPromise: this._usage, error });
|
|
13853
|
+
this.rejectResultPromise({ delayedPromise: this._providerMetadata, error });
|
|
13854
|
+
this.rejectResultPromise({ delayedPromise: this._warnings, error });
|
|
13855
|
+
this.rejectResultPromise({ delayedPromise: this._request, error });
|
|
13856
|
+
this.rejectResultPromise({ delayedPromise: this._response, error });
|
|
13857
|
+
this.rejectResultPromise({ delayedPromise: this._finishReason, error });
|
|
13858
|
+
}
|
|
13859
|
+
rejectResultPromise({
|
|
13860
|
+
delayedPromise,
|
|
13861
|
+
error
|
|
13862
|
+
}) {
|
|
13863
|
+
if (delayedPromise.isPending()) {
|
|
13864
|
+
delayedPromise.reject(error);
|
|
13865
|
+
markPromiseAsHandled2(delayedPromise.promise);
|
|
13866
|
+
}
|
|
13867
|
+
}
|
|
13785
13868
|
get object() {
|
|
13786
13869
|
return this._object.promise;
|
|
13787
13870
|
}
|