ai 7.0.111 → 7.0.112

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 CHANGED
@@ -1,5 +1,20 @@
1
1
  # ai
2
2
 
3
+ ## 7.0.112
4
+
5
+ ### Patch Changes
6
+
7
+ - 9a98fd9: fix(ai): prune reasoning file parts when removing reasoning
8
+ - a0553d6: feat(ai): report consumer cancellation in UI message stream end callbacks
9
+ - ffb0e76: fix(provider): preserve opaque file URI strings for provider serialization
10
+ - fde0d66: fix(ai): preserve parsed metadata and data values when validating UI messages
11
+ - Updated dependencies [ed5a1d7]
12
+ - Updated dependencies [ffb0e76]
13
+ - Updated dependencies [618dc11]
14
+ - @ai-sdk/gateway@4.0.90
15
+ - @ai-sdk/provider@4.0.18
16
+ - @ai-sdk/provider-utils@5.0.46
17
+
3
18
  ## 7.0.111
4
19
 
5
20
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -2621,6 +2621,10 @@ type InferUIMessageChunk<T extends UIMessage> = UIMessageChunk<InferUIMessageMet
2621
2621
  * This is separate from model finish reasons and individual stream chunks.
2622
2622
  * Fatal stream-processing failures override outcomes declared by the stream
2623
2623
  * owner.
2624
+ *
2625
+ * Consumer cancellation before an outcome is declared keeps the `unknown`
2626
+ * status and is reported separately through the end callback's `isCancelled`
2627
+ * property.
2624
2628
  */
2625
2629
  type UIMessageStreamOutcome = {
2626
2630
  status: 'completed';
@@ -2647,6 +2651,13 @@ type UIMessageStreamOnEndCallback<UI_MESSAGE extends UIMessage> = (event: {
2647
2651
  * Indicates whether the stream was aborted.
2648
2652
  */
2649
2653
  isAborted: boolean;
2654
+ /**
2655
+ * Indicates that the consumer cancelled the stream before an outcome was
2656
+ * declared, for example because the client disconnected.
2657
+ *
2658
+ * This property is only present when it is `true`.
2659
+ */
2660
+ isCancelled?: true;
2650
2661
  /**
2651
2662
  * The operation-level outcome of the stream. Fatal stream-processing
2652
2663
  * failures override outcomes declared by the stream owner.
package/dist/index.js CHANGED
@@ -1334,7 +1334,7 @@ import {
1334
1334
  } from "@ai-sdk/provider-utils";
1335
1335
 
1336
1336
  // src/version.ts
1337
- var VERSION = true ? "7.0.111" : "0.0.0-test";
1337
+ var VERSION = true ? "7.0.112" : "0.0.0-test";
1338
1338
 
1339
1339
  // src/util/download/download.ts
1340
1340
  var download = async ({
@@ -1463,6 +1463,13 @@ function convertUrlToFilePartData(url) {
1463
1463
  }
1464
1464
  return { data: { type: "url", url }, mediaType: void 0 };
1465
1465
  }
1466
+ function convertUrlStringToFilePartData(content) {
1467
+ const result = convertUrlToFilePartData(new URL(content));
1468
+ if (result.data.type === "url" && result.data.url.toString() !== content) {
1469
+ result.data.originalUrl = content;
1470
+ }
1471
+ return result;
1472
+ }
1466
1473
  function convertInlineDataToFilePartData(content) {
1467
1474
  if (content instanceof Uint8Array) {
1468
1475
  return { data: { type: "data", data: content }, mediaType: void 0 };
@@ -1514,7 +1521,7 @@ function convertToLanguageModelV4FilePart(content) {
1514
1521
  }
1515
1522
  if (typeof content === "string") {
1516
1523
  try {
1517
- return convertUrlToFilePartData(new URL(content));
1524
+ return convertUrlStringToFilePartData(content);
1518
1525
  } catch (e) {
1519
1526
  return convertInlineDataToFilePartData(content);
1520
1527
  }
@@ -1995,6 +2002,7 @@ function mapToolResultOutput({
1995
2002
  }
1996
2003
  case "file-url": {
1997
2004
  const mediaType = (_a25 = item.mediaType) != null ? _a25 : getMediaTypeFromUrl(item.url);
2005
+ const url = new URL(item.url);
1998
2006
  let message = `The "file-url" type for tool result content is deprecated. Use the "file" type with mediaType and { type: 'url', url } instead.`;
1999
2007
  if (!item.mediaType) {
2000
2008
  const inferenceSuffix = mediaType === "application/octet-stream" ? `Unable to infer media type from URL. Defaulting to 'application/octet-stream'.` : `Inferred media type '${mediaType}' from URL.`;
@@ -2007,7 +2015,11 @@ function mapToolResultOutput({
2007
2015
  });
2008
2016
  return {
2009
2017
  type: "file",
2010
- data: { type: "url", url: new URL(item.url) },
2018
+ data: {
2019
+ type: "url",
2020
+ url,
2021
+ ...url.toString() !== item.url ? { originalUrl: item.url } : {}
2022
+ },
2011
2023
  mediaType,
2012
2024
  providerOptions: item.providerOptions
2013
2025
  };
@@ -2063,6 +2075,7 @@ function mapToolResultOutput({
2063
2075
  };
2064
2076
  }
2065
2077
  case "image-url": {
2078
+ const url = new URL(item.url);
2066
2079
  warnings.push({
2067
2080
  type: "deprecated",
2068
2081
  setting: '"tool-result" content of type "image-url"',
@@ -2070,7 +2083,11 @@ function mapToolResultOutput({
2070
2083
  });
2071
2084
  return {
2072
2085
  type: "file",
2073
- data: { type: "url", url: new URL(item.url) },
2086
+ data: {
2087
+ type: "url",
2088
+ url,
2089
+ ...url.toString() !== item.url ? { originalUrl: item.url } : {}
2090
+ },
2074
2091
  mediaType: "image",
2075
2092
  providerOptions: item.providerOptions
2076
2093
  };
@@ -8155,7 +8172,7 @@ function handleUIMessageStreamFinish({
8155
8172
  }
8156
8173
  };
8157
8174
  let finishCalled = false;
8158
- const callOnEnd = async () => {
8175
+ const callOnEnd = async ({ isCancelled }) => {
8159
8176
  var _a25;
8160
8177
  if (finishCalled || !resolvedOnEnd) {
8161
8178
  return;
@@ -8164,8 +8181,10 @@ function handleUIMessageStreamFinish({
8164
8181
  const isContinuation = state.message.id === (lastMessage == null ? void 0 : lastMessage.id);
8165
8182
  const declaredOutcome = (_a25 = getOutcome == null ? void 0 : getOutcome()) != null ? _a25 : { status: "unknown" };
8166
8183
  const outcome = hasProcessingFailure ? { status: "failed", error: processingError } : declaredOutcome.status === "unknown" && isAborted ? { status: "aborted" } : declaredOutcome;
8184
+ const isConsumerCancellation = isCancelled && outcome.status === "unknown";
8167
8185
  await resolvedOnEnd({
8168
8186
  isAborted: isAborted || outcome.status === "aborted",
8187
+ ...isConsumerCancellation ? { isCancelled: true } : {},
8169
8188
  isContinuation,
8170
8189
  outcome,
8171
8190
  responseMessage: state.message,
@@ -8208,10 +8227,10 @@ function handleUIMessageStreamFinish({
8208
8227
  },
8209
8228
  // @ts-expect-error cancel is still new and missing from types https://developer.mozilla.org/en-US/docs/Web/API/TransformStream#browser_compatibility
8210
8229
  async cancel() {
8211
- await callOnEnd();
8230
+ await callOnEnd({ isCancelled: true });
8212
8231
  },
8213
8232
  async flush() {
8214
- await callOnEnd();
8233
+ await callOnEnd({ isCancelled: false });
8215
8234
  }
8216
8235
  })
8217
8236
  );
@@ -12889,7 +12908,7 @@ async function safeValidateUIMessagesInternal({
12889
12908
  warnIfUIMessageHasDeprecatedRawInput(validatedMessages);
12890
12909
  if (metadataSchema) {
12891
12910
  for (const [msgIdx, message] of validatedMessages.entries()) {
12892
- await validateTypes4({
12911
+ message.metadata = await validateTypes4({
12893
12912
  value: message.metadata,
12894
12913
  schema: metadataSchema,
12895
12914
  context: {
@@ -12921,7 +12940,7 @@ async function safeValidateUIMessagesInternal({
12921
12940
  })
12922
12941
  };
12923
12942
  }
12924
- await validateTypes4({
12943
+ dataPart.data = await validateTypes4({
12925
12944
  value: dataPart.data,
12926
12945
  schema: dataSchema,
12927
12946
  context: {
@@ -16493,7 +16512,9 @@ function pruneMessages({
16493
16512
  }
16494
16513
  return {
16495
16514
  ...message,
16496
- content: message.content.filter((part) => part.type !== "reasoning")
16515
+ content: message.content.filter(
16516
+ (part) => part.type !== "reasoning" && part.type !== "reasoning-file"
16517
+ )
16497
16518
  };
16498
16519
  });
16499
16520
  }