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.js CHANGED
@@ -1304,7 +1304,7 @@ function detectMediaType({
1304
1304
  var import_provider_utils3 = require("@ai-sdk/provider-utils");
1305
1305
 
1306
1306
  // src/version.ts
1307
- var VERSION = true ? "6.0.270" : "0.0.0-test";
1307
+ var VERSION = true ? "6.0.271" : "0.0.0-test";
1308
1308
 
1309
1309
  // src/util/download/download.ts
1310
1310
  var download = async ({
@@ -6446,7 +6446,8 @@ function handleUIMessageStreamFinish({
6446
6446
  onStepFinish,
6447
6447
  onFinish,
6448
6448
  onError,
6449
- stream
6449
+ stream,
6450
+ getOutcome
6450
6451
  }) {
6451
6452
  let lastMessage = originalMessages == null ? void 0 : originalMessages[originalMessages.length - 1];
6452
6453
  if ((lastMessage == null ? void 0 : lastMessage.role) !== "assistant") {
@@ -6455,19 +6456,34 @@ function handleUIMessageStreamFinish({
6455
6456
  messageId = lastMessage.id;
6456
6457
  }
6457
6458
  let isAborted = false;
6459
+ let hasProcessingFailure = false;
6460
+ let processingError;
6461
+ const recordProcessingFailure = (error) => {
6462
+ hasProcessingFailure = true;
6463
+ processingError = error;
6464
+ };
6458
6465
  const idInjectedStream = stream.pipeThrough(
6459
6466
  new TransformStream({
6460
6467
  transform(chunk, controller) {
6461
- if (chunk.type === "start") {
6462
- const startChunk = chunk;
6463
- if (startChunk.messageId == null && messageId != null) {
6464
- startChunk.messageId = messageId;
6468
+ try {
6469
+ let outputChunk = chunk;
6470
+ if (chunk.type === "start") {
6471
+ const startChunk = chunk;
6472
+ if (startChunk.messageId == null && messageId != null) {
6473
+ outputChunk = {
6474
+ ...startChunk,
6475
+ messageId
6476
+ };
6477
+ }
6465
6478
  }
6479
+ if (chunk.type === "abort") {
6480
+ isAborted = true;
6481
+ }
6482
+ controller.enqueue(outputChunk);
6483
+ } catch (error) {
6484
+ recordProcessingFailure(error);
6485
+ throw error;
6466
6486
  }
6467
- if (chunk.type === "abort") {
6468
- isAborted = true;
6469
- }
6470
- controller.enqueue(chunk);
6471
6487
  }
6472
6488
  })
6473
6489
  );
@@ -6480,19 +6496,28 @@ function handleUIMessageStreamFinish({
6480
6496
  // will be overridden by the stream
6481
6497
  });
6482
6498
  const runUpdateMessageJob = async (job) => {
6483
- await job({ state, write: () => {
6484
- } });
6499
+ try {
6500
+ await job({ state, write: () => {
6501
+ } });
6502
+ } catch (error) {
6503
+ recordProcessingFailure(error);
6504
+ throw error;
6505
+ }
6485
6506
  };
6486
6507
  let finishCalled = false;
6487
6508
  const callOnFinish = async () => {
6509
+ var _a22;
6488
6510
  if (finishCalled || !onFinish) {
6489
6511
  return;
6490
6512
  }
6491
6513
  finishCalled = true;
6492
6514
  const isContinuation = state.message.id === (lastMessage == null ? void 0 : lastMessage.id);
6515
+ const declaredOutcome = (_a22 = getOutcome == null ? void 0 : getOutcome()) != null ? _a22 : { status: "unknown" };
6516
+ const outcome = hasProcessingFailure ? { status: "failed", error: processingError } : declaredOutcome.status === "unknown" && isAborted ? { status: "aborted" } : declaredOutcome;
6493
6517
  await onFinish({
6494
- isAborted,
6518
+ isAborted: isAborted || outcome.status === "aborted",
6495
6519
  isContinuation,
6520
+ outcome,
6496
6521
  responseMessage: state.message,
6497
6522
  messages: [
6498
6523
  ...isContinuation ? originalMessages.slice(0, -1) : originalMessages,
@@ -6516,7 +6541,13 @@ function handleUIMessageStreamFinish({
6516
6541
  ]
6517
6542
  });
6518
6543
  } catch (error) {
6519
- onError(error);
6544
+ try {
6545
+ onError(error);
6546
+ } catch (onErrorError) {
6547
+ recordProcessingFailure(onErrorError);
6548
+ await callOnFinish();
6549
+ throw onErrorError;
6550
+ }
6520
6551
  }
6521
6552
  };
6522
6553
  return processUIMessageStream({
@@ -8673,6 +8704,17 @@ var DefaultStreamTextResult = class {
8673
8704
  onError = () => "An error occurred."
8674
8705
  // prevent leaking server error details to the client by default
8675
8706
  } = {}) {
8707
+ let outcome = { status: "unknown" };
8708
+ let hasFatalFailure = false;
8709
+ const setSourceOutcome = (newOutcome) => {
8710
+ if (!hasFatalFailure && outcome.status !== "completed" && outcome.status !== "aborted" && newOutcome.status !== "unknown" && (outcome.status === "unknown" || newOutcome.status !== "failed")) {
8711
+ outcome = newOutcome;
8712
+ }
8713
+ };
8714
+ const failOutcome = (error) => {
8715
+ hasFatalFailure = true;
8716
+ outcome = { status: "failed", error };
8717
+ };
8676
8718
  const responseMessageId = generateMessageId != null ? getResponseUIMessageId({
8677
8719
  originalMessages,
8678
8720
  responseMessageId: generateMessageId
@@ -8685,7 +8727,51 @@ var DefaultStreamTextResult = class {
8685
8727
  }
8686
8728
  return (tool2 == null ? void 0 : tool2.type) === "dynamic" ? true : void 0;
8687
8729
  };
8688
- const baseStream = this.fullStream.pipeThrough(
8730
+ const trackFatalFailures = (stream) => {
8731
+ const reader = stream.getReader();
8732
+ let readerReleased = false;
8733
+ let streamCancelled = false;
8734
+ const releaseReader = () => {
8735
+ if (!readerReleased) {
8736
+ reader.releaseLock();
8737
+ readerReleased = true;
8738
+ }
8739
+ };
8740
+ return new ReadableStream({
8741
+ async pull(controller) {
8742
+ try {
8743
+ const { done, value } = await reader.read();
8744
+ if (done) {
8745
+ releaseReader();
8746
+ if (!streamCancelled) {
8747
+ controller.close();
8748
+ }
8749
+ } else {
8750
+ controller.enqueue(value);
8751
+ }
8752
+ } catch (error) {
8753
+ releaseReader();
8754
+ if (!streamCancelled) {
8755
+ failOutcome(error);
8756
+ controller.error(error);
8757
+ }
8758
+ }
8759
+ },
8760
+ async cancel(reason) {
8761
+ streamCancelled = true;
8762
+ if (readerReleased) {
8763
+ return;
8764
+ }
8765
+ try {
8766
+ await reader.cancel(reason);
8767
+ } finally {
8768
+ releaseReader();
8769
+ }
8770
+ }
8771
+ });
8772
+ };
8773
+ const sourceStream = trackFatalFailures(this.fullStream);
8774
+ const convertedStream = sourceStream.pipeThrough(
8689
8775
  new TransformStream({
8690
8776
  transform: async (part, controller) => {
8691
8777
  const messageMetadataValue = messageMetadata == null ? void 0 : messageMetadata({ part });
@@ -8922,16 +9008,25 @@ var DefaultStreamTextResult = class {
8922
9008
  messageMetadata: messageMetadataValue
8923
9009
  });
8924
9010
  }
9011
+ if (part.type === "finish") {
9012
+ setSourceOutcome({ status: "completed" });
9013
+ } else if (part.type === "abort") {
9014
+ setSourceOutcome({ status: "aborted" });
9015
+ } else if (part.type === "error") {
9016
+ setSourceOutcome({ status: "failed", error: part.error });
9017
+ }
8925
9018
  }
8926
9019
  })
8927
9020
  );
9021
+ const baseStream = trackFatalFailures(convertedStream);
8928
9022
  return createAsyncIterableStream(
8929
9023
  handleUIMessageStreamFinish({
8930
9024
  stream: baseStream,
8931
9025
  messageId: responseMessageId != null ? responseMessageId : generateMessageId == null ? void 0 : generateMessageId(),
8932
9026
  originalMessages,
8933
9027
  onFinish,
8934
- onError
9028
+ onError,
9029
+ getOutcome: () => outcome
8935
9030
  })
8936
9031
  );
8937
9032
  }
@@ -9122,6 +9217,7 @@ function createUIMessageStream({
9122
9217
  }) {
9123
9218
  let controller;
9124
9219
  const ongoingStreamPromises = [];
9220
+ let outcome = { status: "unknown" };
9125
9221
  const stream = new ReadableStream({
9126
9222
  start(controllerArg) {
9127
9223
  controller = controllerArg;
@@ -9133,6 +9229,35 @@ function createUIMessageStream({
9133
9229
  } catch (error) {
9134
9230
  }
9135
9231
  }
9232
+ function setOutcome(newOutcome) {
9233
+ if (outcome.status === "unknown" && newOutcome.status !== "unknown") {
9234
+ outcome = newOutcome;
9235
+ }
9236
+ }
9237
+ function failOutcome(error) {
9238
+ outcome = { status: "failed", error };
9239
+ }
9240
+ function safeError(error) {
9241
+ try {
9242
+ controller.error(error);
9243
+ } catch (e) {
9244
+ }
9245
+ }
9246
+ function handleError(error) {
9247
+ failOutcome(error);
9248
+ let errorText;
9249
+ try {
9250
+ errorText = onError(error);
9251
+ } catch (onErrorError) {
9252
+ failOutcome(onErrorError);
9253
+ safeError(onErrorError);
9254
+ return;
9255
+ }
9256
+ safeEnqueue({
9257
+ type: "error",
9258
+ errorText
9259
+ });
9260
+ }
9136
9261
  try {
9137
9262
  const result = execute({
9138
9263
  writer: {
@@ -9150,38 +9275,29 @@ function createUIMessageStream({
9150
9275
  safeEnqueue(value);
9151
9276
  }
9152
9277
  })().catch((error) => {
9153
- safeEnqueue({
9154
- type: "error",
9155
- errorText: onError(error)
9156
- });
9278
+ handleError(error);
9157
9279
  })
9158
9280
  );
9159
9281
  },
9282
+ setOutcome,
9160
9283
  onError
9161
9284
  }
9162
9285
  });
9163
9286
  if (result) {
9164
9287
  ongoingStreamPromises.push(
9165
9288
  result.catch((error) => {
9166
- safeEnqueue({
9167
- type: "error",
9168
- errorText: onError(error)
9169
- });
9289
+ handleError(error);
9170
9290
  })
9171
9291
  );
9172
9292
  }
9173
9293
  } catch (error) {
9174
- safeEnqueue({
9175
- type: "error",
9176
- errorText: onError(error)
9177
- });
9294
+ handleError(error);
9178
9295
  }
9179
- const waitForStreams = new Promise(async (resolve3) => {
9296
+ const waitForStreams = (async () => {
9180
9297
  while (ongoingStreamPromises.length > 0) {
9181
9298
  await ongoingStreamPromises.shift();
9182
9299
  }
9183
- resolve3();
9184
- });
9300
+ })();
9185
9301
  waitForStreams.finally(() => {
9186
9302
  try {
9187
9303
  controller.close();
@@ -9194,7 +9310,8 @@ function createUIMessageStream({
9194
9310
  originalMessages,
9195
9311
  onStepFinish,
9196
9312
  onFinish,
9197
- onError
9313
+ onError,
9314
+ getOutcome: () => outcome
9198
9315
  });
9199
9316
  }
9200
9317
 
@@ -9512,6 +9629,17 @@ var toolMetadataSchema2 = import_v48.z.record(
9512
9629
  import_v48.z.string(),
9513
9630
  jsonValueSchema.optional()
9514
9631
  );
9632
+ function isEmptyObject(value) {
9633
+ return value != null && typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === 0;
9634
+ }
9635
+ function asDynamicToolPart(toolPart) {
9636
+ const { type, ...part } = toolPart;
9637
+ return {
9638
+ ...part,
9639
+ type: "dynamic-tool",
9640
+ toolName: type.slice(5)
9641
+ };
9642
+ }
9515
9643
  var uiMessagesSchema = (0, import_provider_utils24.lazySchema)(
9516
9644
  () => (0, import_provider_utils24.zodSchema)(
9517
9645
  import_v48.z.array(
@@ -9815,11 +9943,13 @@ var uiMessagesSchema = (0, import_provider_utils24.lazySchema)(
9815
9943
  ).nonempty("Messages array must not be empty")
9816
9944
  )
9817
9945
  );
9818
- async function safeValidateUIMessages({
9946
+ async function safeValidateUIMessagesInternal({
9819
9947
  messages,
9820
9948
  metadataSchema,
9821
9949
  dataSchemas,
9822
9950
  tools
9951
+ }, {
9952
+ convertMissingTerminalToolsToDynamic
9823
9953
  }) {
9824
9954
  try {
9825
9955
  if (messages == null) {
@@ -9848,7 +9978,8 @@ async function safeValidateUIMessages({
9848
9978
  });
9849
9979
  }
9850
9980
  }
9851
- if (dataSchemas || tools) {
9981
+ const shouldValidateToolParts = tools != null || convertMissingTerminalToolsToDynamic;
9982
+ if (dataSchemas || shouldValidateToolParts) {
9852
9983
  for (const [msgIdx, message] of validatedMessages.entries()) {
9853
9984
  for (const [partIdx, part] of message.parts.entries()) {
9854
9985
  if (dataSchemas && part.type.startsWith("data-")) {
@@ -9879,11 +10010,17 @@ async function safeValidateUIMessages({
9879
10010
  }
9880
10011
  });
9881
10012
  }
9882
- if (tools && part.type.startsWith("tool-")) {
10013
+ if (shouldValidateToolParts && part.type.startsWith("tool-")) {
9883
10014
  const toolPart = part;
9884
10015
  const toolName = toolPart.type.slice(5);
9885
- const tool2 = tools[toolName];
9886
- if (!tool2 && (toolPart.state === "output-available" || toolPart.state === "output-error" || toolPart.state === "output-denied")) {
10016
+ const tool2 = tools == null ? void 0 : tools[toolName];
10017
+ const isTerminal = toolPart.state === "output-available" || toolPart.state === "output-error" || toolPart.state === "output-denied";
10018
+ if (!tool2 && isTerminal) {
10019
+ if (tools != null || convertMissingTerminalToolsToDynamic) {
10020
+ message.parts[partIdx] = asDynamicToolPart(
10021
+ toolPart
10022
+ );
10023
+ }
9887
10024
  continue;
9888
10025
  }
9889
10026
  if (!tool2) {
@@ -9900,15 +10037,39 @@ async function safeValidateUIMessages({
9900
10037
  })
9901
10038
  };
9902
10039
  }
9903
- if (toolPart.state === "input-available") {
9904
- await (0, import_provider_utils24.validateTypes)({
10040
+ const inputValidationContext = {
10041
+ field: `messages[${msgIdx}].parts[${partIdx}].input`,
10042
+ entityName: toolName,
10043
+ entityId: toolPart.toolCallId
10044
+ };
10045
+ let convertToDynamic = false;
10046
+ if (toolPart.state === "output-error") {
10047
+ if (toolPart.input !== void 0) {
10048
+ const result = await (0, import_provider_utils24.safeValidateTypes)({
10049
+ value: toolPart.input,
10050
+ schema: tool2.inputSchema,
10051
+ context: inputValidationContext
10052
+ });
10053
+ convertToDynamic = !result.success;
10054
+ }
10055
+ } else if (toolPart.state === "output-available") {
10056
+ const result = await (0, import_provider_utils24.safeValidateTypes)({
9905
10057
  value: toolPart.input,
9906
10058
  schema: tool2.inputSchema,
9907
- context: {
9908
- field: `messages[${msgIdx}].parts[${partIdx}].input`,
9909
- entityName: toolName,
9910
- entityId: toolPart.toolCallId
10059
+ context: inputValidationContext
10060
+ });
10061
+ if (!result.success) {
10062
+ if (isEmptyObject(toolPart.input)) {
10063
+ convertToDynamic = true;
10064
+ } else {
10065
+ throw result.error;
9911
10066
  }
10067
+ }
10068
+ } else if (toolPart.state === "input-available" || toolPart.state === "approval-requested" || toolPart.state === "approval-responded" || toolPart.state === "output-denied") {
10069
+ await (0, import_provider_utils24.validateTypes)({
10070
+ value: toolPart.input,
10071
+ schema: tool2.inputSchema,
10072
+ context: inputValidationContext
9912
10073
  });
9913
10074
  }
9914
10075
  if (toolPart.state === "output-available" && tool2.outputSchema) {
@@ -9922,6 +10083,11 @@ async function safeValidateUIMessages({
9922
10083
  }
9923
10084
  });
9924
10085
  }
10086
+ if (convertToDynamic) {
10087
+ message.parts[partIdx] = asDynamicToolPart(
10088
+ toolPart
10089
+ );
10090
+ }
9925
10091
  }
9926
10092
  }
9927
10093
  }
@@ -9938,17 +10104,23 @@ async function safeValidateUIMessages({
9938
10104
  };
9939
10105
  }
9940
10106
  }
9941
- async function validateUIMessages({
9942
- messages,
9943
- metadataSchema,
9944
- dataSchemas,
9945
- tools
9946
- }) {
9947
- const response = await safeValidateUIMessages({
9948
- messages,
9949
- metadataSchema,
9950
- dataSchemas,
9951
- tools
10107
+ async function safeValidateUIMessages(options) {
10108
+ return safeValidateUIMessagesInternal(options, {
10109
+ convertMissingTerminalToolsToDynamic: false
10110
+ });
10111
+ }
10112
+ async function validateUIMessages(options) {
10113
+ const response = await safeValidateUIMessages(options);
10114
+ if (!response.success)
10115
+ throw response.error;
10116
+ return response.data;
10117
+ }
10118
+ async function validateUIMessagesForAgent(options) {
10119
+ const response = await safeValidateUIMessagesInternal(options, {
10120
+ // Agent tool sets can include ephemeral tools (for example, tools from a
10121
+ // disconnected MCP server), so terminal history is converted to dynamic
10122
+ // tool parts when those tools are no longer registered.
10123
+ convertMissingTerminalToolsToDynamic: true
9952
10124
  });
9953
10125
  if (!response.success)
9954
10126
  throw response.error;
@@ -9967,7 +10139,7 @@ async function createAgentUIStream({
9967
10139
  ...uiMessageStreamOptions
9968
10140
  }) {
9969
10141
  var _a22;
9970
- const validatedMessages = await validateUIMessages({
10142
+ const validatedMessages = await validateUIMessagesForAgent({
9971
10143
  messages: uiMessages,
9972
10144
  tools: agent.tools
9973
10145
  });
@@ -14488,7 +14660,7 @@ var DirectChatTransport = class {
14488
14660
  messages,
14489
14661
  abortSignal
14490
14662
  }) {
14491
- const validatedMessages = await validateUIMessages({
14663
+ const validatedMessages = await validateUIMessagesForAgent({
14492
14664
  messages,
14493
14665
  tools: this.agent.tools
14494
14666
  });