ai 7.0.82 → 7.0.83
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 +12 -0
- package/dist/index.d.ts +45 -19
- package/dist/index.js +272 -79
- package/dist/index.js.map +1 -1
- package/dist/internal/index.js +1 -1
- package/docs/07-reference/01-ai-sdk-core/02-stream-text.mdx +3 -3
- package/docs/07-reference/02-ai-sdk-ui/40-create-ui-message-stream.mdx +35 -6
- package/package.json +5 -5
- package/src/agent/create-agent-ui-stream.ts +2 -2
- package/src/ui/direct-chat-transport.ts +2 -2
- package/src/ui/last-assistant-message-is-complete-with-approval-responses.ts +1 -0
- package/src/ui/validate-ui-messages.ts +136 -55
- package/src/ui-message-stream/create-ui-message-stream.ts +47 -17
- package/src/ui-message-stream/handle-ui-message-stream-finish.ts +51 -14
- package/src/ui-message-stream/index.ts +5 -1
- package/src/ui-message-stream/to-ui-message-stream.ts +108 -26
- package/src/ui-message-stream/ui-message-stream-on-end-callback.ts +7 -0
- package/src/ui-message-stream/ui-message-stream-outcome.ts +12 -0
- package/src/ui-message-stream/ui-message-stream-writer.ts +15 -0
- package/src/util/create-stitchable-stream.ts +31 -1
package/dist/index.js
CHANGED
|
@@ -1179,7 +1179,7 @@ import {
|
|
|
1179
1179
|
} from "@ai-sdk/provider-utils";
|
|
1180
1180
|
|
|
1181
1181
|
// src/version.ts
|
|
1182
|
-
var VERSION = true ? "7.0.
|
|
1182
|
+
var VERSION = true ? "7.0.83" : "0.0.0-test";
|
|
1183
1183
|
|
|
1184
1184
|
// src/util/download/download.ts
|
|
1185
1185
|
var download = async ({
|
|
@@ -7533,7 +7533,8 @@ function handleUIMessageStreamFinish({
|
|
|
7533
7533
|
onEnd,
|
|
7534
7534
|
onFinish,
|
|
7535
7535
|
onError,
|
|
7536
|
-
stream
|
|
7536
|
+
stream,
|
|
7537
|
+
getOutcome
|
|
7537
7538
|
}) {
|
|
7538
7539
|
let lastMessage = originalMessages == null ? void 0 : originalMessages[originalMessages.length - 1];
|
|
7539
7540
|
if ((lastMessage == null ? void 0 : lastMessage.role) !== "assistant") {
|
|
@@ -7542,19 +7543,34 @@ function handleUIMessageStreamFinish({
|
|
|
7542
7543
|
messageId = lastMessage.id;
|
|
7543
7544
|
}
|
|
7544
7545
|
let isAborted = false;
|
|
7546
|
+
let hasProcessingFailure = false;
|
|
7547
|
+
let processingError;
|
|
7548
|
+
const recordProcessingFailure = (error) => {
|
|
7549
|
+
hasProcessingFailure = true;
|
|
7550
|
+
processingError = error;
|
|
7551
|
+
};
|
|
7545
7552
|
const idInjectedStream = stream.pipeThrough(
|
|
7546
7553
|
new TransformStream({
|
|
7547
7554
|
transform(chunk, controller) {
|
|
7548
|
-
|
|
7549
|
-
|
|
7550
|
-
if (
|
|
7551
|
-
startChunk
|
|
7555
|
+
try {
|
|
7556
|
+
let outputChunk = chunk;
|
|
7557
|
+
if (chunk.type === "start") {
|
|
7558
|
+
const startChunk = chunk;
|
|
7559
|
+
if (startChunk.messageId == null && messageId != null) {
|
|
7560
|
+
outputChunk = {
|
|
7561
|
+
...startChunk,
|
|
7562
|
+
messageId
|
|
7563
|
+
};
|
|
7564
|
+
}
|
|
7552
7565
|
}
|
|
7566
|
+
if (chunk.type === "abort") {
|
|
7567
|
+
isAborted = true;
|
|
7568
|
+
}
|
|
7569
|
+
controller.enqueue(outputChunk);
|
|
7570
|
+
} catch (error) {
|
|
7571
|
+
recordProcessingFailure(error);
|
|
7572
|
+
throw error;
|
|
7553
7573
|
}
|
|
7554
|
-
if (chunk.type === "abort") {
|
|
7555
|
-
isAborted = true;
|
|
7556
|
-
}
|
|
7557
|
-
controller.enqueue(chunk);
|
|
7558
7574
|
}
|
|
7559
7575
|
})
|
|
7560
7576
|
);
|
|
@@ -7569,19 +7585,28 @@ function handleUIMessageStreamFinish({
|
|
|
7569
7585
|
// will be overridden by the stream
|
|
7570
7586
|
});
|
|
7571
7587
|
const runUpdateMessageJob = async (job) => {
|
|
7572
|
-
|
|
7573
|
-
|
|
7588
|
+
try {
|
|
7589
|
+
await job({ state, write: () => {
|
|
7590
|
+
} });
|
|
7591
|
+
} catch (error) {
|
|
7592
|
+
recordProcessingFailure(error);
|
|
7593
|
+
throw error;
|
|
7594
|
+
}
|
|
7574
7595
|
};
|
|
7575
7596
|
let finishCalled = false;
|
|
7576
7597
|
const callOnEnd = async () => {
|
|
7598
|
+
var _a24;
|
|
7577
7599
|
if (finishCalled || !resolvedOnEnd) {
|
|
7578
7600
|
return;
|
|
7579
7601
|
}
|
|
7580
7602
|
finishCalled = true;
|
|
7581
7603
|
const isContinuation = state.message.id === (lastMessage == null ? void 0 : lastMessage.id);
|
|
7604
|
+
const declaredOutcome = (_a24 = getOutcome == null ? void 0 : getOutcome()) != null ? _a24 : { status: "unknown" };
|
|
7605
|
+
const outcome = hasProcessingFailure ? { status: "failed", error: processingError } : declaredOutcome.status === "unknown" && isAborted ? { status: "aborted" } : declaredOutcome;
|
|
7582
7606
|
await resolvedOnEnd({
|
|
7583
|
-
isAborted,
|
|
7607
|
+
isAborted: isAborted || outcome.status === "aborted",
|
|
7584
7608
|
isContinuation,
|
|
7609
|
+
outcome,
|
|
7585
7610
|
responseMessage: state.message,
|
|
7586
7611
|
messages: [
|
|
7587
7612
|
...isContinuation ? originalMessages.slice(0, -1) : originalMessages,
|
|
@@ -7902,32 +7927,96 @@ function toUIMessageStream({
|
|
|
7902
7927
|
onEnd,
|
|
7903
7928
|
onFinish
|
|
7904
7929
|
}) {
|
|
7930
|
+
let outcome = { status: "unknown" };
|
|
7931
|
+
let hasFatalFailure = false;
|
|
7932
|
+
const setSourceOutcome = (newOutcome) => {
|
|
7933
|
+
if (!hasFatalFailure && outcome.status !== "completed" && outcome.status !== "aborted" && newOutcome.status !== "unknown" && (outcome.status === "unknown" || newOutcome.status !== "failed")) {
|
|
7934
|
+
outcome = newOutcome;
|
|
7935
|
+
}
|
|
7936
|
+
};
|
|
7937
|
+
const failOutcome = (error) => {
|
|
7938
|
+
hasFatalFailure = true;
|
|
7939
|
+
outcome = { status: "failed", error };
|
|
7940
|
+
};
|
|
7905
7941
|
const responseMessageId = generateMessageId != null ? getResponseUIMessageId({
|
|
7906
7942
|
originalMessages,
|
|
7907
7943
|
responseMessageId: generateMessageId
|
|
7908
7944
|
}) : void 0;
|
|
7909
|
-
const
|
|
7945
|
+
const sourceReader = stream.getReader();
|
|
7946
|
+
let sourceReaderReleased = false;
|
|
7947
|
+
let sourceStreamCancelled = false;
|
|
7948
|
+
const releaseSourceReader = () => {
|
|
7949
|
+
if (!sourceReaderReleased) {
|
|
7950
|
+
sourceReader.releaseLock();
|
|
7951
|
+
sourceReaderReleased = true;
|
|
7952
|
+
}
|
|
7953
|
+
};
|
|
7954
|
+
const sourceStream = new ReadableStream({
|
|
7955
|
+
async pull(controller) {
|
|
7956
|
+
try {
|
|
7957
|
+
const { done, value } = await sourceReader.read();
|
|
7958
|
+
if (done) {
|
|
7959
|
+
releaseSourceReader();
|
|
7960
|
+
if (!sourceStreamCancelled) {
|
|
7961
|
+
controller.close();
|
|
7962
|
+
}
|
|
7963
|
+
} else {
|
|
7964
|
+
controller.enqueue(value);
|
|
7965
|
+
}
|
|
7966
|
+
} catch (error) {
|
|
7967
|
+
releaseSourceReader();
|
|
7968
|
+
if (!sourceStreamCancelled) {
|
|
7969
|
+
failOutcome(error);
|
|
7970
|
+
controller.error(error);
|
|
7971
|
+
}
|
|
7972
|
+
}
|
|
7973
|
+
},
|
|
7974
|
+
async cancel(reason) {
|
|
7975
|
+
sourceStreamCancelled = true;
|
|
7976
|
+
if (sourceReaderReleased) {
|
|
7977
|
+
return;
|
|
7978
|
+
}
|
|
7979
|
+
try {
|
|
7980
|
+
await sourceReader.cancel(reason);
|
|
7981
|
+
} finally {
|
|
7982
|
+
releaseSourceReader();
|
|
7983
|
+
}
|
|
7984
|
+
}
|
|
7985
|
+
});
|
|
7986
|
+
const uiMessageChunkStream = sourceStream.pipeThrough(
|
|
7910
7987
|
new TransformStream({
|
|
7911
7988
|
transform: async (part, controller) => {
|
|
7912
|
-
|
|
7913
|
-
|
|
7914
|
-
|
|
7915
|
-
|
|
7916
|
-
|
|
7917
|
-
|
|
7918
|
-
|
|
7919
|
-
|
|
7920
|
-
|
|
7921
|
-
|
|
7922
|
-
|
|
7923
|
-
if (uiMessageChunk != null) {
|
|
7924
|
-
controller.enqueue(uiMessageChunk);
|
|
7925
|
-
}
|
|
7926
|
-
if (messageMetadataValue != null && part.type !== "start" && part.type !== "finish") {
|
|
7927
|
-
controller.enqueue({
|
|
7928
|
-
type: "message-metadata",
|
|
7929
|
-
messageMetadata: messageMetadataValue
|
|
7989
|
+
try {
|
|
7990
|
+
const messageMetadataValue = messageMetadata == null ? void 0 : messageMetadata({ part });
|
|
7991
|
+
const uiMessageChunk = toUIMessageChunk(part, {
|
|
7992
|
+
tools,
|
|
7993
|
+
sendReasoning,
|
|
7994
|
+
sendSources,
|
|
7995
|
+
sendStart,
|
|
7996
|
+
sendFinish,
|
|
7997
|
+
onError,
|
|
7998
|
+
messageMetadata: messageMetadataValue,
|
|
7999
|
+
responseMessageId
|
|
7930
8000
|
});
|
|
8001
|
+
if (uiMessageChunk != null) {
|
|
8002
|
+
controller.enqueue(uiMessageChunk);
|
|
8003
|
+
}
|
|
8004
|
+
if (messageMetadataValue != null && part.type !== "start" && part.type !== "finish") {
|
|
8005
|
+
controller.enqueue({
|
|
8006
|
+
type: "message-metadata",
|
|
8007
|
+
messageMetadata: messageMetadataValue
|
|
8008
|
+
});
|
|
8009
|
+
}
|
|
8010
|
+
if (part.type === "finish") {
|
|
8011
|
+
setSourceOutcome({ status: "completed" });
|
|
8012
|
+
} else if (part.type === "abort") {
|
|
8013
|
+
setSourceOutcome({ status: "aborted" });
|
|
8014
|
+
} else if (part.type === "error") {
|
|
8015
|
+
setSourceOutcome({ status: "failed", error: part.error });
|
|
8016
|
+
}
|
|
8017
|
+
} catch (error) {
|
|
8018
|
+
failOutcome(error);
|
|
8019
|
+
throw error;
|
|
7931
8020
|
}
|
|
7932
8021
|
}
|
|
7933
8022
|
})
|
|
@@ -7937,7 +8026,8 @@ function toUIMessageStream({
|
|
|
7937
8026
|
messageId: responseMessageId != null ? responseMessageId : generateMessageId == null ? void 0 : generateMessageId(),
|
|
7938
8027
|
originalMessages,
|
|
7939
8028
|
onEnd: onEnd != null ? onEnd : onFinish,
|
|
7940
|
-
onError
|
|
8029
|
+
onError,
|
|
8030
|
+
getOutcome: () => outcome
|
|
7941
8031
|
});
|
|
7942
8032
|
}
|
|
7943
8033
|
|
|
@@ -8062,8 +8152,12 @@ function createStitchableStream() {
|
|
|
8062
8152
|
let innerStreams = [];
|
|
8063
8153
|
let controller = null;
|
|
8064
8154
|
let isClosed = false;
|
|
8155
|
+
let isCancelled = false;
|
|
8065
8156
|
let waitForNewStream = createResolvablePromise();
|
|
8066
8157
|
const terminate = () => {
|
|
8158
|
+
if (isCancelled) {
|
|
8159
|
+
return;
|
|
8160
|
+
}
|
|
8067
8161
|
isClosed = true;
|
|
8068
8162
|
waitForNewStream.resolve();
|
|
8069
8163
|
innerStreams.forEach(({ reader, onCancel }) => {
|
|
@@ -8075,6 +8169,9 @@ function createStitchableStream() {
|
|
|
8075
8169
|
};
|
|
8076
8170
|
const processPull = async () => {
|
|
8077
8171
|
var _a24;
|
|
8172
|
+
if (isCancelled) {
|
|
8173
|
+
return;
|
|
8174
|
+
}
|
|
8078
8175
|
if (isClosed && innerStreams.length === 0) {
|
|
8079
8176
|
controller == null ? void 0 : controller.close();
|
|
8080
8177
|
return;
|
|
@@ -8087,6 +8184,9 @@ function createStitchableStream() {
|
|
|
8087
8184
|
const currentStream = innerStreams[0];
|
|
8088
8185
|
try {
|
|
8089
8186
|
const { value, done } = await currentStream.reader.read();
|
|
8187
|
+
if (isCancelled) {
|
|
8188
|
+
return;
|
|
8189
|
+
}
|
|
8090
8190
|
if (done) {
|
|
8091
8191
|
innerStreams.shift();
|
|
8092
8192
|
if (innerStreams.length === 0 && isClosed) {
|
|
@@ -8098,6 +8198,9 @@ function createStitchableStream() {
|
|
|
8098
8198
|
controller == null ? void 0 : controller.enqueue(value);
|
|
8099
8199
|
}
|
|
8100
8200
|
} catch (error) {
|
|
8201
|
+
if (isCancelled) {
|
|
8202
|
+
return;
|
|
8203
|
+
}
|
|
8101
8204
|
(_a24 = currentStream.onError) == null ? void 0 : _a24.call(currentStream, error);
|
|
8102
8205
|
controller == null ? void 0 : controller.error(error);
|
|
8103
8206
|
innerStreams.shift();
|
|
@@ -8111,15 +8214,24 @@ function createStitchableStream() {
|
|
|
8111
8214
|
},
|
|
8112
8215
|
pull: processPull,
|
|
8113
8216
|
async cancel() {
|
|
8217
|
+
isCancelled = true;
|
|
8218
|
+
isClosed = true;
|
|
8219
|
+
waitForNewStream.resolve();
|
|
8114
8220
|
for (const { reader, onCancel } of innerStreams) {
|
|
8115
8221
|
onCancel == null ? void 0 : onCancel();
|
|
8116
8222
|
await reader.cancel();
|
|
8117
8223
|
}
|
|
8118
8224
|
innerStreams = [];
|
|
8119
|
-
isClosed = true;
|
|
8120
8225
|
}
|
|
8121
8226
|
}),
|
|
8122
8227
|
addStream: (innerStream, callbacks) => {
|
|
8228
|
+
var _a24;
|
|
8229
|
+
if (isCancelled) {
|
|
8230
|
+
(_a24 = callbacks == null ? void 0 : callbacks.onCancel) == null ? void 0 : _a24.call(callbacks);
|
|
8231
|
+
void innerStream.cancel().catch(() => {
|
|
8232
|
+
});
|
|
8233
|
+
return;
|
|
8234
|
+
}
|
|
8123
8235
|
if (isClosed) {
|
|
8124
8236
|
throw new Error("Cannot add inner stream: outer stream is closed");
|
|
8125
8237
|
}
|
|
@@ -8134,6 +8246,9 @@ function createStitchableStream() {
|
|
|
8134
8246
|
* finish processing and then close the outer stream.
|
|
8135
8247
|
*/
|
|
8136
8248
|
close: () => {
|
|
8249
|
+
if (isCancelled) {
|
|
8250
|
+
return;
|
|
8251
|
+
}
|
|
8137
8252
|
isClosed = true;
|
|
8138
8253
|
waitForNewStream.resolve();
|
|
8139
8254
|
if (innerStreams.length === 0) {
|
|
@@ -10889,6 +11004,7 @@ function createUIMessageStream({
|
|
|
10889
11004
|
}) {
|
|
10890
11005
|
let controller;
|
|
10891
11006
|
const ongoingStreamPromises = [];
|
|
11007
|
+
let outcome = { status: "unknown" };
|
|
10892
11008
|
const stream = new ReadableStream({
|
|
10893
11009
|
start(controllerArg) {
|
|
10894
11010
|
controller = controllerArg;
|
|
@@ -10900,6 +11016,35 @@ function createUIMessageStream({
|
|
|
10900
11016
|
} catch (e) {
|
|
10901
11017
|
}
|
|
10902
11018
|
}
|
|
11019
|
+
function setOutcome(newOutcome) {
|
|
11020
|
+
if (outcome.status === "unknown" && newOutcome.status !== "unknown") {
|
|
11021
|
+
outcome = newOutcome;
|
|
11022
|
+
}
|
|
11023
|
+
}
|
|
11024
|
+
function failOutcome(error) {
|
|
11025
|
+
outcome = { status: "failed", error };
|
|
11026
|
+
}
|
|
11027
|
+
function safeError(error) {
|
|
11028
|
+
try {
|
|
11029
|
+
controller.error(error);
|
|
11030
|
+
} catch (e) {
|
|
11031
|
+
}
|
|
11032
|
+
}
|
|
11033
|
+
function handleError(error) {
|
|
11034
|
+
failOutcome(error);
|
|
11035
|
+
let errorText;
|
|
11036
|
+
try {
|
|
11037
|
+
errorText = onError(error);
|
|
11038
|
+
} catch (onErrorError) {
|
|
11039
|
+
failOutcome(onErrorError);
|
|
11040
|
+
safeError(onErrorError);
|
|
11041
|
+
return;
|
|
11042
|
+
}
|
|
11043
|
+
safeEnqueue({
|
|
11044
|
+
type: "error",
|
|
11045
|
+
errorText
|
|
11046
|
+
});
|
|
11047
|
+
}
|
|
10903
11048
|
try {
|
|
10904
11049
|
const result = execute({
|
|
10905
11050
|
writer: {
|
|
@@ -10917,38 +11062,29 @@ function createUIMessageStream({
|
|
|
10917
11062
|
safeEnqueue(value);
|
|
10918
11063
|
}
|
|
10919
11064
|
})().catch((error) => {
|
|
10920
|
-
|
|
10921
|
-
type: "error",
|
|
10922
|
-
errorText: onError(error)
|
|
10923
|
-
});
|
|
11065
|
+
handleError(error);
|
|
10924
11066
|
})
|
|
10925
11067
|
);
|
|
10926
11068
|
},
|
|
11069
|
+
setOutcome,
|
|
10927
11070
|
onError
|
|
10928
11071
|
}
|
|
10929
11072
|
});
|
|
10930
11073
|
if (result) {
|
|
10931
11074
|
ongoingStreamPromises.push(
|
|
10932
11075
|
result.catch((error) => {
|
|
10933
|
-
|
|
10934
|
-
type: "error",
|
|
10935
|
-
errorText: onError(error)
|
|
10936
|
-
});
|
|
11076
|
+
handleError(error);
|
|
10937
11077
|
})
|
|
10938
11078
|
);
|
|
10939
11079
|
}
|
|
10940
11080
|
} catch (error) {
|
|
10941
|
-
|
|
10942
|
-
type: "error",
|
|
10943
|
-
errorText: onError(error)
|
|
10944
|
-
});
|
|
11081
|
+
handleError(error);
|
|
10945
11082
|
}
|
|
10946
|
-
const waitForStreams =
|
|
11083
|
+
const waitForStreams = (async () => {
|
|
10947
11084
|
while (ongoingStreamPromises.length > 0) {
|
|
10948
11085
|
await ongoingStreamPromises.shift();
|
|
10949
11086
|
}
|
|
10950
|
-
|
|
10951
|
-
});
|
|
11087
|
+
})();
|
|
10952
11088
|
waitForStreams.finally(() => {
|
|
10953
11089
|
try {
|
|
10954
11090
|
controller.close();
|
|
@@ -10961,7 +11097,8 @@ function createUIMessageStream({
|
|
|
10961
11097
|
originalMessages,
|
|
10962
11098
|
onStepEnd: onStepEnd != null ? onStepEnd : onStepFinish,
|
|
10963
11099
|
onEnd: onEnd != null ? onEnd : onFinish,
|
|
10964
|
-
onError
|
|
11100
|
+
onError,
|
|
11101
|
+
getOutcome: () => outcome
|
|
10965
11102
|
});
|
|
10966
11103
|
}
|
|
10967
11104
|
|
|
@@ -11310,6 +11447,7 @@ async function convertToModelMessages(messages, options) {
|
|
|
11310
11447
|
import { TypeValidationError as TypeValidationError3 } from "@ai-sdk/provider";
|
|
11311
11448
|
import {
|
|
11312
11449
|
lazySchema as lazySchema2,
|
|
11450
|
+
safeValidateTypes as safeValidateTypes5,
|
|
11313
11451
|
validateTypes as validateTypes4,
|
|
11314
11452
|
zodSchema as zodSchema2
|
|
11315
11453
|
} from "@ai-sdk/provider-utils";
|
|
@@ -11318,6 +11456,17 @@ var toolMetadataSchema2 = z.record(
|
|
|
11318
11456
|
jsonValueSchema.optional()
|
|
11319
11457
|
);
|
|
11320
11458
|
var providerReferenceSchema2 = z.record(z.string(), z.string());
|
|
11459
|
+
function isEmptyObject(value) {
|
|
11460
|
+
return value != null && typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === 0;
|
|
11461
|
+
}
|
|
11462
|
+
function asDynamicToolPart(toolPart) {
|
|
11463
|
+
const { type, ...part } = toolPart;
|
|
11464
|
+
return {
|
|
11465
|
+
...part,
|
|
11466
|
+
type: "dynamic-tool",
|
|
11467
|
+
toolName: type.slice(5)
|
|
11468
|
+
};
|
|
11469
|
+
}
|
|
11321
11470
|
var uiMessagesSchema = lazySchema2(
|
|
11322
11471
|
() => zodSchema2(
|
|
11323
11472
|
z.array(
|
|
@@ -11653,11 +11802,13 @@ var uiMessagesSchema = lazySchema2(
|
|
|
11653
11802
|
).nonempty("Messages array must not be empty")
|
|
11654
11803
|
)
|
|
11655
11804
|
);
|
|
11656
|
-
async function
|
|
11805
|
+
async function safeValidateUIMessagesInternal({
|
|
11657
11806
|
messages,
|
|
11658
11807
|
metadataSchema,
|
|
11659
11808
|
dataSchemas,
|
|
11660
11809
|
tools
|
|
11810
|
+
}, {
|
|
11811
|
+
convertMissingTerminalToolsToDynamic
|
|
11661
11812
|
}) {
|
|
11662
11813
|
try {
|
|
11663
11814
|
if (messages == null) {
|
|
@@ -11686,7 +11837,8 @@ async function safeValidateUIMessages({
|
|
|
11686
11837
|
});
|
|
11687
11838
|
}
|
|
11688
11839
|
}
|
|
11689
|
-
|
|
11840
|
+
const shouldValidateToolParts = tools != null || convertMissingTerminalToolsToDynamic;
|
|
11841
|
+
if (dataSchemas || shouldValidateToolParts) {
|
|
11690
11842
|
for (const [msgIdx, message] of validatedMessages.entries()) {
|
|
11691
11843
|
for (const [partIdx, part] of message.parts.entries()) {
|
|
11692
11844
|
if (dataSchemas && part.type.startsWith("data-")) {
|
|
@@ -11717,11 +11869,17 @@ async function safeValidateUIMessages({
|
|
|
11717
11869
|
}
|
|
11718
11870
|
});
|
|
11719
11871
|
}
|
|
11720
|
-
if (
|
|
11872
|
+
if (shouldValidateToolParts && part.type.startsWith("tool-")) {
|
|
11721
11873
|
const toolPart = part;
|
|
11722
11874
|
const toolName = toolPart.type.slice(5);
|
|
11723
|
-
const tool2 = getOwn(tools, toolName);
|
|
11724
|
-
|
|
11875
|
+
const tool2 = tools == null ? void 0 : getOwn(tools, toolName);
|
|
11876
|
+
const isTerminal = toolPart.state === "output-available" || toolPart.state === "output-error" || toolPart.state === "output-denied";
|
|
11877
|
+
if (!tool2 && isTerminal) {
|
|
11878
|
+
if (tools != null || convertMissingTerminalToolsToDynamic) {
|
|
11879
|
+
message.parts[partIdx] = asDynamicToolPart(
|
|
11880
|
+
toolPart
|
|
11881
|
+
);
|
|
11882
|
+
}
|
|
11725
11883
|
continue;
|
|
11726
11884
|
}
|
|
11727
11885
|
if (!tool2) {
|
|
@@ -11738,15 +11896,39 @@ async function safeValidateUIMessages({
|
|
|
11738
11896
|
})
|
|
11739
11897
|
};
|
|
11740
11898
|
}
|
|
11741
|
-
|
|
11742
|
-
|
|
11899
|
+
const inputValidationContext = {
|
|
11900
|
+
field: `messages[${msgIdx}].parts[${partIdx}].input`,
|
|
11901
|
+
entityName: toolName,
|
|
11902
|
+
entityId: toolPart.toolCallId
|
|
11903
|
+
};
|
|
11904
|
+
let convertToDynamic = false;
|
|
11905
|
+
if (toolPart.state === "output-error") {
|
|
11906
|
+
if (toolPart.input !== void 0) {
|
|
11907
|
+
const result = await safeValidateTypes5({
|
|
11908
|
+
value: toolPart.input,
|
|
11909
|
+
schema: tool2.inputSchema,
|
|
11910
|
+
context: inputValidationContext
|
|
11911
|
+
});
|
|
11912
|
+
convertToDynamic = !result.success;
|
|
11913
|
+
}
|
|
11914
|
+
} else if (toolPart.state === "output-available") {
|
|
11915
|
+
const result = await safeValidateTypes5({
|
|
11743
11916
|
value: toolPart.input,
|
|
11744
11917
|
schema: tool2.inputSchema,
|
|
11745
|
-
context:
|
|
11746
|
-
|
|
11747
|
-
|
|
11748
|
-
|
|
11918
|
+
context: inputValidationContext
|
|
11919
|
+
});
|
|
11920
|
+
if (!result.success) {
|
|
11921
|
+
if (isEmptyObject(toolPart.input)) {
|
|
11922
|
+
convertToDynamic = true;
|
|
11923
|
+
} else {
|
|
11924
|
+
throw result.error;
|
|
11749
11925
|
}
|
|
11926
|
+
}
|
|
11927
|
+
} else if (toolPart.state === "input-available" || toolPart.state === "approval-requested" || toolPart.state === "approval-responded" || toolPart.state === "output-denied") {
|
|
11928
|
+
await validateTypes4({
|
|
11929
|
+
value: toolPart.input,
|
|
11930
|
+
schema: tool2.inputSchema,
|
|
11931
|
+
context: inputValidationContext
|
|
11750
11932
|
});
|
|
11751
11933
|
}
|
|
11752
11934
|
if (toolPart.state === "output-available" && tool2.outputSchema) {
|
|
@@ -11760,6 +11942,11 @@ async function safeValidateUIMessages({
|
|
|
11760
11942
|
}
|
|
11761
11943
|
});
|
|
11762
11944
|
}
|
|
11945
|
+
if (convertToDynamic) {
|
|
11946
|
+
message.parts[partIdx] = asDynamicToolPart(
|
|
11947
|
+
toolPart
|
|
11948
|
+
);
|
|
11949
|
+
}
|
|
11763
11950
|
}
|
|
11764
11951
|
}
|
|
11765
11952
|
}
|
|
@@ -11776,17 +11963,23 @@ async function safeValidateUIMessages({
|
|
|
11776
11963
|
};
|
|
11777
11964
|
}
|
|
11778
11965
|
}
|
|
11779
|
-
async function
|
|
11780
|
-
|
|
11781
|
-
|
|
11782
|
-
|
|
11783
|
-
|
|
11784
|
-
|
|
11785
|
-
const response = await safeValidateUIMessages(
|
|
11786
|
-
|
|
11787
|
-
|
|
11788
|
-
|
|
11789
|
-
|
|
11966
|
+
async function safeValidateUIMessages(options) {
|
|
11967
|
+
return safeValidateUIMessagesInternal(options, {
|
|
11968
|
+
convertMissingTerminalToolsToDynamic: false
|
|
11969
|
+
});
|
|
11970
|
+
}
|
|
11971
|
+
async function validateUIMessages(options) {
|
|
11972
|
+
const response = await safeValidateUIMessages(options);
|
|
11973
|
+
if (!response.success)
|
|
11974
|
+
throw response.error;
|
|
11975
|
+
return response.data;
|
|
11976
|
+
}
|
|
11977
|
+
async function validateUIMessagesForAgent(options) {
|
|
11978
|
+
const response = await safeValidateUIMessagesInternal(options, {
|
|
11979
|
+
// Agent tool sets can include ephemeral tools (for example, tools from a
|
|
11980
|
+
// disconnected MCP server), so terminal history is converted to dynamic
|
|
11981
|
+
// tool parts when those tools are no longer registered.
|
|
11982
|
+
convertMissingTerminalToolsToDynamic: true
|
|
11790
11983
|
});
|
|
11791
11984
|
if (!response.success)
|
|
11792
11985
|
throw response.error;
|
|
@@ -11807,7 +12000,7 @@ async function createAgentUIStream({
|
|
|
11807
12000
|
...uiMessageStreamOptions
|
|
11808
12001
|
}) {
|
|
11809
12002
|
var _a24;
|
|
11810
|
-
const validatedMessages = await
|
|
12003
|
+
const validatedMessages = await validateUIMessagesForAgent({
|
|
11811
12004
|
messages: uiMessages,
|
|
11812
12005
|
// tools are compatible; the casting is required because the context param is
|
|
11813
12006
|
// not available in ui messages
|
|
@@ -12851,7 +13044,7 @@ import {
|
|
|
12851
13044
|
} from "@ai-sdk/provider";
|
|
12852
13045
|
import {
|
|
12853
13046
|
asSchema as asSchema5,
|
|
12854
|
-
safeValidateTypes as
|
|
13047
|
+
safeValidateTypes as safeValidateTypes6
|
|
12855
13048
|
} from "@ai-sdk/provider-utils";
|
|
12856
13049
|
var noSchemaOutputStrategy = {
|
|
12857
13050
|
type: "no-schema",
|
|
@@ -12891,7 +13084,7 @@ var objectOutputStrategy = (schema) => ({
|
|
|
12891
13084
|
};
|
|
12892
13085
|
},
|
|
12893
13086
|
async validateFinalResult(value) {
|
|
12894
|
-
return
|
|
13087
|
+
return safeValidateTypes6({ value, schema });
|
|
12895
13088
|
},
|
|
12896
13089
|
createElementStream() {
|
|
12897
13090
|
throw new UnsupportedFunctionalityError4({
|
|
@@ -12944,7 +13137,7 @@ var arrayOutputStrategy = (schema) => {
|
|
|
12944
13137
|
const resultArray = [];
|
|
12945
13138
|
for (let i = 0; i < inputArray.length; i++) {
|
|
12946
13139
|
const element = inputArray[i];
|
|
12947
|
-
const result = await
|
|
13140
|
+
const result = await safeValidateTypes6({ value: element, schema });
|
|
12948
13141
|
if (i === inputArray.length - 1 && !isFinalDelta) {
|
|
12949
13142
|
continue;
|
|
12950
13143
|
}
|
|
@@ -12986,7 +13179,7 @@ var arrayOutputStrategy = (schema) => {
|
|
|
12986
13179
|
const inputArray = value.elements;
|
|
12987
13180
|
const resultArray = [];
|
|
12988
13181
|
for (const element of inputArray) {
|
|
12989
|
-
const result = await
|
|
13182
|
+
const result = await safeValidateTypes6({ value: element, schema });
|
|
12990
13183
|
if (!result.success) {
|
|
12991
13184
|
return result;
|
|
12992
13185
|
}
|
|
@@ -18583,7 +18776,7 @@ var DirectChatTransport = class {
|
|
|
18583
18776
|
messages,
|
|
18584
18777
|
abortSignal
|
|
18585
18778
|
}) {
|
|
18586
|
-
const validatedMessages = await
|
|
18779
|
+
const validatedMessages = await validateUIMessagesForAgent({
|
|
18587
18780
|
messages,
|
|
18588
18781
|
// tools are compatible; the casting is required because the context param is
|
|
18589
18782
|
// not available in ui messages
|
|
@@ -18633,7 +18826,7 @@ function lastAssistantMessageIsCompleteWithApprovalResponses({
|
|
|
18633
18826
|
// has at least one tool approval response
|
|
18634
18827
|
lastStepToolInvocations.filter((part) => part.state === "approval-responded").length > 0 && // all tool approvals must have a response
|
|
18635
18828
|
lastStepToolInvocations.every(
|
|
18636
|
-
(part) => part.state === "output-available" || part.state === "output-error" || part.state === "approval-responded"
|
|
18829
|
+
(part) => part.state === "output-available" || part.state === "output-error" || part.state === "output-denied" || part.state === "approval-responded"
|
|
18637
18830
|
)
|
|
18638
18831
|
);
|
|
18639
18832
|
}
|