ai 6.0.270 → 6.0.271

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/dist/index.mjs CHANGED
@@ -1193,7 +1193,7 @@ import {
1193
1193
  } from "@ai-sdk/provider-utils";
1194
1194
 
1195
1195
  // src/version.ts
1196
- var VERSION = true ? "6.0.270" : "0.0.0-test";
1196
+ var VERSION = true ? "6.0.271" : "0.0.0-test";
1197
1197
 
1198
1198
  // src/util/download/download.ts
1199
1199
  var download = async ({
@@ -6372,7 +6372,8 @@ function handleUIMessageStreamFinish({
6372
6372
  onStepFinish,
6373
6373
  onFinish,
6374
6374
  onError,
6375
- stream
6375
+ stream,
6376
+ getOutcome
6376
6377
  }) {
6377
6378
  let lastMessage = originalMessages == null ? void 0 : originalMessages[originalMessages.length - 1];
6378
6379
  if ((lastMessage == null ? void 0 : lastMessage.role) !== "assistant") {
@@ -6381,19 +6382,34 @@ function handleUIMessageStreamFinish({
6381
6382
  messageId = lastMessage.id;
6382
6383
  }
6383
6384
  let isAborted = false;
6385
+ let hasProcessingFailure = false;
6386
+ let processingError;
6387
+ const recordProcessingFailure = (error) => {
6388
+ hasProcessingFailure = true;
6389
+ processingError = error;
6390
+ };
6384
6391
  const idInjectedStream = stream.pipeThrough(
6385
6392
  new TransformStream({
6386
6393
  transform(chunk, controller) {
6387
- if (chunk.type === "start") {
6388
- const startChunk = chunk;
6389
- if (startChunk.messageId == null && messageId != null) {
6390
- startChunk.messageId = messageId;
6394
+ try {
6395
+ let outputChunk = chunk;
6396
+ if (chunk.type === "start") {
6397
+ const startChunk = chunk;
6398
+ if (startChunk.messageId == null && messageId != null) {
6399
+ outputChunk = {
6400
+ ...startChunk,
6401
+ messageId
6402
+ };
6403
+ }
6391
6404
  }
6405
+ if (chunk.type === "abort") {
6406
+ isAborted = true;
6407
+ }
6408
+ controller.enqueue(outputChunk);
6409
+ } catch (error) {
6410
+ recordProcessingFailure(error);
6411
+ throw error;
6392
6412
  }
6393
- if (chunk.type === "abort") {
6394
- isAborted = true;
6395
- }
6396
- controller.enqueue(chunk);
6397
6413
  }
6398
6414
  })
6399
6415
  );
@@ -6406,19 +6422,28 @@ function handleUIMessageStreamFinish({
6406
6422
  // will be overridden by the stream
6407
6423
  });
6408
6424
  const runUpdateMessageJob = async (job) => {
6409
- await job({ state, write: () => {
6410
- } });
6425
+ try {
6426
+ await job({ state, write: () => {
6427
+ } });
6428
+ } catch (error) {
6429
+ recordProcessingFailure(error);
6430
+ throw error;
6431
+ }
6411
6432
  };
6412
6433
  let finishCalled = false;
6413
6434
  const callOnFinish = async () => {
6435
+ var _a22;
6414
6436
  if (finishCalled || !onFinish) {
6415
6437
  return;
6416
6438
  }
6417
6439
  finishCalled = true;
6418
6440
  const isContinuation = state.message.id === (lastMessage == null ? void 0 : lastMessage.id);
6441
+ const declaredOutcome = (_a22 = getOutcome == null ? void 0 : getOutcome()) != null ? _a22 : { status: "unknown" };
6442
+ const outcome = hasProcessingFailure ? { status: "failed", error: processingError } : declaredOutcome.status === "unknown" && isAborted ? { status: "aborted" } : declaredOutcome;
6419
6443
  await onFinish({
6420
- isAborted,
6444
+ isAborted: isAborted || outcome.status === "aborted",
6421
6445
  isContinuation,
6446
+ outcome,
6422
6447
  responseMessage: state.message,
6423
6448
  messages: [
6424
6449
  ...isContinuation ? originalMessages.slice(0, -1) : originalMessages,
@@ -6442,7 +6467,13 @@ function handleUIMessageStreamFinish({
6442
6467
  ]
6443
6468
  });
6444
6469
  } catch (error) {
6445
- onError(error);
6470
+ try {
6471
+ onError(error);
6472
+ } catch (onErrorError) {
6473
+ recordProcessingFailure(onErrorError);
6474
+ await callOnFinish();
6475
+ throw onErrorError;
6476
+ }
6446
6477
  }
6447
6478
  };
6448
6479
  return processUIMessageStream({
@@ -8601,6 +8632,17 @@ var DefaultStreamTextResult = class {
8601
8632
  onError = () => "An error occurred."
8602
8633
  // prevent leaking server error details to the client by default
8603
8634
  } = {}) {
8635
+ let outcome = { status: "unknown" };
8636
+ let hasFatalFailure = false;
8637
+ const setSourceOutcome = (newOutcome) => {
8638
+ if (!hasFatalFailure && outcome.status !== "completed" && outcome.status !== "aborted" && newOutcome.status !== "unknown" && (outcome.status === "unknown" || newOutcome.status !== "failed")) {
8639
+ outcome = newOutcome;
8640
+ }
8641
+ };
8642
+ const failOutcome = (error) => {
8643
+ hasFatalFailure = true;
8644
+ outcome = { status: "failed", error };
8645
+ };
8604
8646
  const responseMessageId = generateMessageId != null ? getResponseUIMessageId({
8605
8647
  originalMessages,
8606
8648
  responseMessageId: generateMessageId
@@ -8613,7 +8655,51 @@ var DefaultStreamTextResult = class {
8613
8655
  }
8614
8656
  return (tool2 == null ? void 0 : tool2.type) === "dynamic" ? true : void 0;
8615
8657
  };
8616
- const baseStream = this.fullStream.pipeThrough(
8658
+ const trackFatalFailures = (stream) => {
8659
+ const reader = stream.getReader();
8660
+ let readerReleased = false;
8661
+ let streamCancelled = false;
8662
+ const releaseReader = () => {
8663
+ if (!readerReleased) {
8664
+ reader.releaseLock();
8665
+ readerReleased = true;
8666
+ }
8667
+ };
8668
+ return new ReadableStream({
8669
+ async pull(controller) {
8670
+ try {
8671
+ const { done, value } = await reader.read();
8672
+ if (done) {
8673
+ releaseReader();
8674
+ if (!streamCancelled) {
8675
+ controller.close();
8676
+ }
8677
+ } else {
8678
+ controller.enqueue(value);
8679
+ }
8680
+ } catch (error) {
8681
+ releaseReader();
8682
+ if (!streamCancelled) {
8683
+ failOutcome(error);
8684
+ controller.error(error);
8685
+ }
8686
+ }
8687
+ },
8688
+ async cancel(reason) {
8689
+ streamCancelled = true;
8690
+ if (readerReleased) {
8691
+ return;
8692
+ }
8693
+ try {
8694
+ await reader.cancel(reason);
8695
+ } finally {
8696
+ releaseReader();
8697
+ }
8698
+ }
8699
+ });
8700
+ };
8701
+ const sourceStream = trackFatalFailures(this.fullStream);
8702
+ const convertedStream = sourceStream.pipeThrough(
8617
8703
  new TransformStream({
8618
8704
  transform: async (part, controller) => {
8619
8705
  const messageMetadataValue = messageMetadata == null ? void 0 : messageMetadata({ part });
@@ -8850,16 +8936,25 @@ var DefaultStreamTextResult = class {
8850
8936
  messageMetadata: messageMetadataValue
8851
8937
  });
8852
8938
  }
8939
+ if (part.type === "finish") {
8940
+ setSourceOutcome({ status: "completed" });
8941
+ } else if (part.type === "abort") {
8942
+ setSourceOutcome({ status: "aborted" });
8943
+ } else if (part.type === "error") {
8944
+ setSourceOutcome({ status: "failed", error: part.error });
8945
+ }
8853
8946
  }
8854
8947
  })
8855
8948
  );
8949
+ const baseStream = trackFatalFailures(convertedStream);
8856
8950
  return createAsyncIterableStream(
8857
8951
  handleUIMessageStreamFinish({
8858
8952
  stream: baseStream,
8859
8953
  messageId: responseMessageId != null ? responseMessageId : generateMessageId == null ? void 0 : generateMessageId(),
8860
8954
  originalMessages,
8861
8955
  onFinish,
8862
- onError
8956
+ onError,
8957
+ getOutcome: () => outcome
8863
8958
  })
8864
8959
  );
8865
8960
  }
@@ -9052,6 +9147,7 @@ function createUIMessageStream({
9052
9147
  }) {
9053
9148
  let controller;
9054
9149
  const ongoingStreamPromises = [];
9150
+ let outcome = { status: "unknown" };
9055
9151
  const stream = new ReadableStream({
9056
9152
  start(controllerArg) {
9057
9153
  controller = controllerArg;
@@ -9063,6 +9159,35 @@ function createUIMessageStream({
9063
9159
  } catch (error) {
9064
9160
  }
9065
9161
  }
9162
+ function setOutcome(newOutcome) {
9163
+ if (outcome.status === "unknown" && newOutcome.status !== "unknown") {
9164
+ outcome = newOutcome;
9165
+ }
9166
+ }
9167
+ function failOutcome(error) {
9168
+ outcome = { status: "failed", error };
9169
+ }
9170
+ function safeError(error) {
9171
+ try {
9172
+ controller.error(error);
9173
+ } catch (e) {
9174
+ }
9175
+ }
9176
+ function handleError(error) {
9177
+ failOutcome(error);
9178
+ let errorText;
9179
+ try {
9180
+ errorText = onError(error);
9181
+ } catch (onErrorError) {
9182
+ failOutcome(onErrorError);
9183
+ safeError(onErrorError);
9184
+ return;
9185
+ }
9186
+ safeEnqueue({
9187
+ type: "error",
9188
+ errorText
9189
+ });
9190
+ }
9066
9191
  try {
9067
9192
  const result = execute({
9068
9193
  writer: {
@@ -9080,38 +9205,29 @@ function createUIMessageStream({
9080
9205
  safeEnqueue(value);
9081
9206
  }
9082
9207
  })().catch((error) => {
9083
- safeEnqueue({
9084
- type: "error",
9085
- errorText: onError(error)
9086
- });
9208
+ handleError(error);
9087
9209
  })
9088
9210
  );
9089
9211
  },
9212
+ setOutcome,
9090
9213
  onError
9091
9214
  }
9092
9215
  });
9093
9216
  if (result) {
9094
9217
  ongoingStreamPromises.push(
9095
9218
  result.catch((error) => {
9096
- safeEnqueue({
9097
- type: "error",
9098
- errorText: onError(error)
9099
- });
9219
+ handleError(error);
9100
9220
  })
9101
9221
  );
9102
9222
  }
9103
9223
  } catch (error) {
9104
- safeEnqueue({
9105
- type: "error",
9106
- errorText: onError(error)
9107
- });
9224
+ handleError(error);
9108
9225
  }
9109
- const waitForStreams = new Promise(async (resolve3) => {
9226
+ const waitForStreams = (async () => {
9110
9227
  while (ongoingStreamPromises.length > 0) {
9111
9228
  await ongoingStreamPromises.shift();
9112
9229
  }
9113
- resolve3();
9114
- });
9230
+ })();
9115
9231
  waitForStreams.finally(() => {
9116
9232
  try {
9117
9233
  controller.close();
@@ -9124,7 +9240,8 @@ function createUIMessageStream({
9124
9240
  originalMessages,
9125
9241
  onStepFinish,
9126
9242
  onFinish,
9127
- onError
9243
+ onError,
9244
+ getOutcome: () => outcome
9128
9245
  });
9129
9246
  }
9130
9247
 
@@ -9442,6 +9559,7 @@ import {
9442
9559
  } from "@ai-sdk/provider";
9443
9560
  import {
9444
9561
  lazySchema as lazySchema2,
9562
+ safeValidateTypes as safeValidateTypes5,
9445
9563
  validateTypes as validateTypes3,
9446
9564
  zodSchema as zodSchema2
9447
9565
  } from "@ai-sdk/provider-utils";
@@ -9450,6 +9568,17 @@ var toolMetadataSchema2 = z8.record(
9450
9568
  z8.string(),
9451
9569
  jsonValueSchema.optional()
9452
9570
  );
9571
+ function isEmptyObject(value) {
9572
+ return value != null && typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === 0;
9573
+ }
9574
+ function asDynamicToolPart(toolPart) {
9575
+ const { type, ...part } = toolPart;
9576
+ return {
9577
+ ...part,
9578
+ type: "dynamic-tool",
9579
+ toolName: type.slice(5)
9580
+ };
9581
+ }
9453
9582
  var uiMessagesSchema = lazySchema2(
9454
9583
  () => zodSchema2(
9455
9584
  z8.array(
@@ -9753,11 +9882,13 @@ var uiMessagesSchema = lazySchema2(
9753
9882
  ).nonempty("Messages array must not be empty")
9754
9883
  )
9755
9884
  );
9756
- async function safeValidateUIMessages({
9885
+ async function safeValidateUIMessagesInternal({
9757
9886
  messages,
9758
9887
  metadataSchema,
9759
9888
  dataSchemas,
9760
9889
  tools
9890
+ }, {
9891
+ convertMissingTerminalToolsToDynamic
9761
9892
  }) {
9762
9893
  try {
9763
9894
  if (messages == null) {
@@ -9786,7 +9917,8 @@ async function safeValidateUIMessages({
9786
9917
  });
9787
9918
  }
9788
9919
  }
9789
- if (dataSchemas || tools) {
9920
+ const shouldValidateToolParts = tools != null || convertMissingTerminalToolsToDynamic;
9921
+ if (dataSchemas || shouldValidateToolParts) {
9790
9922
  for (const [msgIdx, message] of validatedMessages.entries()) {
9791
9923
  for (const [partIdx, part] of message.parts.entries()) {
9792
9924
  if (dataSchemas && part.type.startsWith("data-")) {
@@ -9817,11 +9949,17 @@ async function safeValidateUIMessages({
9817
9949
  }
9818
9950
  });
9819
9951
  }
9820
- if (tools && part.type.startsWith("tool-")) {
9952
+ if (shouldValidateToolParts && part.type.startsWith("tool-")) {
9821
9953
  const toolPart = part;
9822
9954
  const toolName = toolPart.type.slice(5);
9823
- const tool2 = tools[toolName];
9824
- if (!tool2 && (toolPart.state === "output-available" || toolPart.state === "output-error" || toolPart.state === "output-denied")) {
9955
+ const tool2 = tools == null ? void 0 : tools[toolName];
9956
+ const isTerminal = toolPart.state === "output-available" || toolPart.state === "output-error" || toolPart.state === "output-denied";
9957
+ if (!tool2 && isTerminal) {
9958
+ if (tools != null || convertMissingTerminalToolsToDynamic) {
9959
+ message.parts[partIdx] = asDynamicToolPart(
9960
+ toolPart
9961
+ );
9962
+ }
9825
9963
  continue;
9826
9964
  }
9827
9965
  if (!tool2) {
@@ -9838,15 +9976,39 @@ async function safeValidateUIMessages({
9838
9976
  })
9839
9977
  };
9840
9978
  }
9841
- if (toolPart.state === "input-available") {
9842
- await validateTypes3({
9979
+ const inputValidationContext = {
9980
+ field: `messages[${msgIdx}].parts[${partIdx}].input`,
9981
+ entityName: toolName,
9982
+ entityId: toolPart.toolCallId
9983
+ };
9984
+ let convertToDynamic = false;
9985
+ if (toolPart.state === "output-error") {
9986
+ if (toolPart.input !== void 0) {
9987
+ const result = await safeValidateTypes5({
9988
+ value: toolPart.input,
9989
+ schema: tool2.inputSchema,
9990
+ context: inputValidationContext
9991
+ });
9992
+ convertToDynamic = !result.success;
9993
+ }
9994
+ } else if (toolPart.state === "output-available") {
9995
+ const result = await safeValidateTypes5({
9843
9996
  value: toolPart.input,
9844
9997
  schema: tool2.inputSchema,
9845
- context: {
9846
- field: `messages[${msgIdx}].parts[${partIdx}].input`,
9847
- entityName: toolName,
9848
- entityId: toolPart.toolCallId
9998
+ context: inputValidationContext
9999
+ });
10000
+ if (!result.success) {
10001
+ if (isEmptyObject(toolPart.input)) {
10002
+ convertToDynamic = true;
10003
+ } else {
10004
+ throw result.error;
9849
10005
  }
10006
+ }
10007
+ } else if (toolPart.state === "input-available" || toolPart.state === "approval-requested" || toolPart.state === "approval-responded" || toolPart.state === "output-denied") {
10008
+ await validateTypes3({
10009
+ value: toolPart.input,
10010
+ schema: tool2.inputSchema,
10011
+ context: inputValidationContext
9850
10012
  });
9851
10013
  }
9852
10014
  if (toolPart.state === "output-available" && tool2.outputSchema) {
@@ -9860,6 +10022,11 @@ async function safeValidateUIMessages({
9860
10022
  }
9861
10023
  });
9862
10024
  }
10025
+ if (convertToDynamic) {
10026
+ message.parts[partIdx] = asDynamicToolPart(
10027
+ toolPart
10028
+ );
10029
+ }
9863
10030
  }
9864
10031
  }
9865
10032
  }
@@ -9876,17 +10043,23 @@ async function safeValidateUIMessages({
9876
10043
  };
9877
10044
  }
9878
10045
  }
9879
- async function validateUIMessages({
9880
- messages,
9881
- metadataSchema,
9882
- dataSchemas,
9883
- tools
9884
- }) {
9885
- const response = await safeValidateUIMessages({
9886
- messages,
9887
- metadataSchema,
9888
- dataSchemas,
9889
- tools
10046
+ async function safeValidateUIMessages(options) {
10047
+ return safeValidateUIMessagesInternal(options, {
10048
+ convertMissingTerminalToolsToDynamic: false
10049
+ });
10050
+ }
10051
+ async function validateUIMessages(options) {
10052
+ const response = await safeValidateUIMessages(options);
10053
+ if (!response.success)
10054
+ throw response.error;
10055
+ return response.data;
10056
+ }
10057
+ async function validateUIMessagesForAgent(options) {
10058
+ const response = await safeValidateUIMessagesInternal(options, {
10059
+ // Agent tool sets can include ephemeral tools (for example, tools from a
10060
+ // disconnected MCP server), so terminal history is converted to dynamic
10061
+ // tool parts when those tools are no longer registered.
10062
+ convertMissingTerminalToolsToDynamic: true
9890
10063
  });
9891
10064
  if (!response.success)
9892
10065
  throw response.error;
@@ -9905,7 +10078,7 @@ async function createAgentUIStream({
9905
10078
  ...uiMessageStreamOptions
9906
10079
  }) {
9907
10080
  var _a22;
9908
- const validatedMessages = await validateUIMessages({
10081
+ const validatedMessages = await validateUIMessagesForAgent({
9909
10082
  messages: uiMessages,
9910
10083
  tools: agent.tools
9911
10084
  });
@@ -10605,7 +10778,7 @@ import {
10605
10778
  } from "@ai-sdk/provider";
10606
10779
  import {
10607
10780
  asSchema as asSchema5,
10608
- safeValidateTypes as safeValidateTypes5
10781
+ safeValidateTypes as safeValidateTypes6
10609
10782
  } from "@ai-sdk/provider-utils";
10610
10783
  var noSchemaOutputStrategy = {
10611
10784
  type: "no-schema",
@@ -10645,7 +10818,7 @@ var objectOutputStrategy = (schema) => ({
10645
10818
  };
10646
10819
  },
10647
10820
  async validateFinalResult(value) {
10648
- return safeValidateTypes5({ value, schema });
10821
+ return safeValidateTypes6({ value, schema });
10649
10822
  },
10650
10823
  createElementStream() {
10651
10824
  throw new UnsupportedFunctionalityError3({
@@ -10691,7 +10864,7 @@ var arrayOutputStrategy = (schema) => {
10691
10864
  const resultArray = [];
10692
10865
  for (let i = 0; i < inputArray.length; i++) {
10693
10866
  const element = inputArray[i];
10694
- const result = await safeValidateTypes5({ value: element, schema });
10867
+ const result = await safeValidateTypes6({ value: element, schema });
10695
10868
  if (i === inputArray.length - 1 && !isFinalDelta) {
10696
10869
  continue;
10697
10870
  }
@@ -10733,7 +10906,7 @@ var arrayOutputStrategy = (schema) => {
10733
10906
  const inputArray = value.elements;
10734
10907
  const resultArray = [];
10735
10908
  for (const element of inputArray) {
10736
- const result = await safeValidateTypes5({ value: element, schema });
10909
+ const result = await safeValidateTypes6({ value: element, schema });
10737
10910
  if (!result.success) {
10738
10911
  return result;
10739
10912
  }
@@ -14469,7 +14642,7 @@ var DirectChatTransport = class {
14469
14642
  messages,
14470
14643
  abortSignal
14471
14644
  }) {
14472
- const validatedMessages = await validateUIMessages({
14645
+ const validatedMessages = await validateUIMessagesForAgent({
14473
14646
  messages,
14474
14647
  tools: this.agent.tools
14475
14648
  });