ai 7.0.69 → 7.0.70
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 +13 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +88 -14
- package/dist/index.js.map +1 -1
- package/dist/internal/index.js +1 -1
- package/docs/03-agents/07-workflow-agent.mdx +8 -3
- package/docs/04-ai-sdk-ui/50-stream-protocol.mdx +16 -0
- package/package.json +3 -3
- package/src/generate-object/stream-object.ts +63 -3
- 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 +6 -7
- 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,18 @@
|
|
|
1
1
|
# ai
|
|
2
2
|
|
|
3
|
+
## 7.0.70
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 9566914: Stop multi-step text generation for client tool approval even when a provider-executed tool has a deferred result.
|
|
8
|
+
- b181020: fix: reject `streamObject` result promises and report failed completion when the provider stream errors
|
|
9
|
+
- 7054073: Filter preliminary tool outputs when `ignoreIncompleteToolCalls` is enabled.
|
|
10
|
+
- a828527: Prevent automatic tool execution when a model call ends with an unsafe finish reason.
|
|
11
|
+
- d3cc3fe: Clear partial UI message parts when a WorkflowAgent model-call step is retried.
|
|
12
|
+
- Updated dependencies [e6087c9]
|
|
13
|
+
- @ai-sdk/provider-utils@5.0.28
|
|
14
|
+
- @ai-sdk/gateway@4.0.56
|
|
15
|
+
|
|
3
16
|
## 7.0.69
|
|
4
17
|
|
|
5
18
|
### 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.70" : "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 {
|
|
@@ -10043,10 +10069,9 @@ var DefaultStreamTextResult = class {
|
|
|
10043
10069
|
}
|
|
10044
10070
|
cleanupStepTimeouts();
|
|
10045
10071
|
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:
|
|
10072
|
+
// Continue only after all client tool calls have been executed or denied,
|
|
10073
|
+
// and if there are client results or pending deferred provider results.
|
|
10074
|
+
clientToolCalls.length === clientToolOutputs.length + deniedToolApprovalResponses.length && (clientToolCalls.length > 0 || pendingDeferredToolCalls.size > 0) && // continue until a stop condition is met:
|
|
10050
10075
|
!await isStopConditionMet({
|
|
10051
10076
|
stopConditions,
|
|
10052
10077
|
steps: recordedSteps
|
|
@@ -10789,7 +10814,7 @@ async function convertToModelMessages(messages, options) {
|
|
|
10789
10814
|
messages = messages.map((message) => ({
|
|
10790
10815
|
...message,
|
|
10791
10816
|
parts: message.parts.filter(
|
|
10792
|
-
(part) => !isToolUIPart(part) || part.state === "approval-responded" || part.state === "output-available" || part.state === "output-error" || part.state === "output-denied"
|
|
10817
|
+
(part) => !isToolUIPart(part) || part.state === "approval-responded" || part.state === "output-available" && part.preliminary !== true || part.state === "output-error" || part.state === "output-denied"
|
|
10793
10818
|
)
|
|
10794
10819
|
}));
|
|
10795
10820
|
}
|
|
@@ -13366,6 +13391,12 @@ function simulateReadableStream({
|
|
|
13366
13391
|
|
|
13367
13392
|
// src/generate-object/stream-object.ts
|
|
13368
13393
|
var originalGenerateId5 = createIdGenerator7({ prefix: "aiobj", size: 24 });
|
|
13394
|
+
async function markPromiseAsHandled2(promise) {
|
|
13395
|
+
try {
|
|
13396
|
+
await promise;
|
|
13397
|
+
} catch (e) {
|
|
13398
|
+
}
|
|
13399
|
+
}
|
|
13369
13400
|
function streamObject(options) {
|
|
13370
13401
|
const {
|
|
13371
13402
|
model,
|
|
@@ -13595,6 +13626,7 @@ var DefaultStreamObjectResult = class {
|
|
|
13595
13626
|
let providerMetadata;
|
|
13596
13627
|
let object3;
|
|
13597
13628
|
let error;
|
|
13629
|
+
let terminalError;
|
|
13598
13630
|
let msToFirstChunk = void 0;
|
|
13599
13631
|
let accumulatedText = "";
|
|
13600
13632
|
let textDelta = "";
|
|
@@ -13660,16 +13692,27 @@ var DefaultStreamObjectResult = class {
|
|
|
13660
13692
|
};
|
|
13661
13693
|
break;
|
|
13662
13694
|
}
|
|
13695
|
+
case "error": {
|
|
13696
|
+
if (terminalError === void 0) {
|
|
13697
|
+
const wrappedError = wrapGatewayError(chunk.error);
|
|
13698
|
+
terminalError = { error: wrappedError };
|
|
13699
|
+
error = wrappedError;
|
|
13700
|
+
finishReason = "error";
|
|
13701
|
+
self.rejectResultPromises(wrappedError);
|
|
13702
|
+
}
|
|
13703
|
+
controller.enqueue(chunk);
|
|
13704
|
+
break;
|
|
13705
|
+
}
|
|
13663
13706
|
case "finish": {
|
|
13664
13707
|
if (textDelta !== "") {
|
|
13665
13708
|
controller.enqueue({ type: "text-delta", textDelta });
|
|
13666
13709
|
}
|
|
13667
|
-
finishReason = chunk.finishReason.unified;
|
|
13710
|
+
finishReason = terminalError === void 0 ? chunk.finishReason.unified : "error";
|
|
13668
13711
|
usage = asLanguageModelUsage(chunk.usage);
|
|
13669
13712
|
providerMetadata = chunk.providerMetadata;
|
|
13670
13713
|
controller.enqueue({
|
|
13671
13714
|
...chunk,
|
|
13672
|
-
finishReason
|
|
13715
|
+
finishReason,
|
|
13673
13716
|
usage,
|
|
13674
13717
|
response: fullResponse
|
|
13675
13718
|
});
|
|
@@ -13678,6 +13721,9 @@ var DefaultStreamObjectResult = class {
|
|
|
13678
13721
|
provider: model.provider,
|
|
13679
13722
|
model: model.modelId
|
|
13680
13723
|
});
|
|
13724
|
+
if (terminalError !== void 0) {
|
|
13725
|
+
break;
|
|
13726
|
+
}
|
|
13681
13727
|
self._usage.resolve(usage);
|
|
13682
13728
|
self._providerMetadata.resolve(providerMetadata);
|
|
13683
13729
|
self._warnings.resolve(warnings);
|
|
@@ -13765,9 +13811,19 @@ var DefaultStreamObjectResult = class {
|
|
|
13765
13811
|
}
|
|
13766
13812
|
})
|
|
13767
13813
|
);
|
|
13768
|
-
stitchableStream.addStream(transformedStream
|
|
13814
|
+
stitchableStream.addStream(transformedStream, {
|
|
13815
|
+
onError(error2) {
|
|
13816
|
+
const wrappedError = wrapGatewayError(error2);
|
|
13817
|
+
self.rejectResultPromises(wrappedError);
|
|
13818
|
+
void notify({
|
|
13819
|
+
event: { error: wrappedError },
|
|
13820
|
+
callbacks: onError
|
|
13821
|
+
});
|
|
13822
|
+
}
|
|
13823
|
+
});
|
|
13769
13824
|
})().catch(async (error) => {
|
|
13770
13825
|
var _a23;
|
|
13826
|
+
self.rejectResultPromises(error);
|
|
13771
13827
|
await ((_a23 = telemetryDispatcher.onError) == null ? void 0 : _a23.call(telemetryDispatcher, { callId, error }));
|
|
13772
13828
|
stitchableStream.addStream(
|
|
13773
13829
|
new ReadableStream({
|
|
@@ -13782,6 +13838,24 @@ var DefaultStreamObjectResult = class {
|
|
|
13782
13838
|
});
|
|
13783
13839
|
this.outputStrategy = outputStrategy;
|
|
13784
13840
|
}
|
|
13841
|
+
rejectResultPromises(error) {
|
|
13842
|
+
this.rejectResultPromise({ delayedPromise: this._object, error });
|
|
13843
|
+
this.rejectResultPromise({ delayedPromise: this._usage, error });
|
|
13844
|
+
this.rejectResultPromise({ delayedPromise: this._providerMetadata, error });
|
|
13845
|
+
this.rejectResultPromise({ delayedPromise: this._warnings, error });
|
|
13846
|
+
this.rejectResultPromise({ delayedPromise: this._request, error });
|
|
13847
|
+
this.rejectResultPromise({ delayedPromise: this._response, error });
|
|
13848
|
+
this.rejectResultPromise({ delayedPromise: this._finishReason, error });
|
|
13849
|
+
}
|
|
13850
|
+
rejectResultPromise({
|
|
13851
|
+
delayedPromise,
|
|
13852
|
+
error
|
|
13853
|
+
}) {
|
|
13854
|
+
if (delayedPromise.isPending()) {
|
|
13855
|
+
delayedPromise.reject(error);
|
|
13856
|
+
markPromiseAsHandled2(delayedPromise.promise);
|
|
13857
|
+
}
|
|
13858
|
+
}
|
|
13785
13859
|
get object() {
|
|
13786
13860
|
return this._object.promise;
|
|
13787
13861
|
}
|