ai 6.0.178 → 6.0.182

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,35 @@
1
1
  # ai
2
2
 
3
+ ## 6.0.182
4
+
5
+ ### Patch Changes
6
+
7
+ - e76a29a: fix(ai): download tool-result file URLs
8
+
9
+ ## 6.0.181
10
+
11
+ ### Patch Changes
12
+
13
+ - 538974a: fix(ui): make `input` optional on `output-error` tool and dynamic-tool UI message parts
14
+
15
+ `validateUIMessages` rejected persisted assistant messages whose `output-error` tool parts had no `input` key. This happened for any errored tool call where the SDK set `input: undefined` (e.g. `NoSuchToolError` / `InvalidToolInputError`): JSON serialization stripped the `undefined` value, and Zod 4.4+ treats a missing `z.unknown()` key as a validation failure (previously it was implicitly optional). The schema now matches the runtime shape produced by `process-ui-message-stream`, so reloading a thread that contains an errored tool call no longer throws `AI_TypeValidationError`.
16
+
17
+ ## 6.0.180
18
+
19
+ ### Patch Changes
20
+
21
+ - 253bd5a: fix(gateway): enable retry support for gateway errors
22
+ - 57ec10f: fix URL of hero animation in README
23
+ - Updated dependencies [253bd5a]
24
+ - @ai-sdk/gateway@3.0.114
25
+
26
+ ## 6.0.179
27
+
28
+ ### Patch Changes
29
+
30
+ - Updated dependencies [ee4de68]
31
+ - @ai-sdk/gateway@3.0.113
32
+
3
33
  ## 6.0.178
4
34
 
5
35
  ### Patch Changes
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- ![hero illustration](./assets/hero.gif)
1
+ ![hero illustration](https://github.com/vercel/ai/blob/HEAD/assets/hero.gif)
2
2
 
3
3
  # AI SDK
4
4
 
package/dist/index.js CHANGED
@@ -79,7 +79,7 @@ __export(src_exports, {
79
79
  createAgentUIStream: () => createAgentUIStream,
80
80
  createAgentUIStreamResponse: () => createAgentUIStreamResponse,
81
81
  createDownload: () => createDownload,
82
- createGateway: () => import_gateway3.createGateway,
82
+ createGateway: () => import_gateway4.createGateway,
83
83
  createIdGenerator: () => import_provider_utils39.createIdGenerator,
84
84
  createProviderRegistry: () => createProviderRegistry,
85
85
  createTextStreamResponse: () => createTextStreamResponse,
@@ -99,7 +99,7 @@ __export(src_exports, {
99
99
  experimental_transcribe: () => transcribe,
100
100
  extractJsonMiddleware: () => extractJsonMiddleware,
101
101
  extractReasoningMiddleware: () => extractReasoningMiddleware,
102
- gateway: () => import_gateway3.gateway,
102
+ gateway: () => import_gateway4.gateway,
103
103
  generateId: () => import_provider_utils39.generateId,
104
104
  generateImage: () => generateImage,
105
105
  generateObject: () => generateObject,
@@ -151,7 +151,7 @@ __export(src_exports, {
151
151
  zodSchema: () => import_provider_utils39.zodSchema
152
152
  });
153
153
  module.exports = __toCommonJS(src_exports);
154
- var import_gateway3 = require("@ai-sdk/gateway");
154
+ var import_gateway4 = require("@ai-sdk/gateway");
155
155
  var import_provider_utils39 = require("@ai-sdk/provider-utils");
156
156
 
157
157
  // src/agent/tool-loop-agent.ts
@@ -1254,7 +1254,7 @@ function detectMediaType({
1254
1254
  var import_provider_utils3 = require("@ai-sdk/provider-utils");
1255
1255
 
1256
1256
  // src/version.ts
1257
- var VERSION = true ? "6.0.178" : "0.0.0-test";
1257
+ var VERSION = true ? "6.0.182" : "0.0.0-test";
1258
1258
 
1259
1259
  // src/util/download/download.ts
1260
1260
  var download = async ({
@@ -1592,7 +1592,10 @@ function convertToLanguageModelMessage({
1592
1592
  type: "tool-result",
1593
1593
  toolCallId: part.toolCallId,
1594
1594
  toolName: part.toolName,
1595
- output: mapToolResultOutput(part.output),
1595
+ output: mapToolResultOutput({
1596
+ output: part.output,
1597
+ downloadedAssets
1598
+ }),
1596
1599
  providerOptions
1597
1600
  };
1598
1601
  }
@@ -1614,7 +1617,10 @@ function convertToLanguageModelMessage({
1614
1617
  type: "tool-result",
1615
1618
  toolCallId: part.toolCallId,
1616
1619
  toolName: part.toolName,
1617
- output: mapToolResultOutput(part.output),
1620
+ output: mapToolResultOutput({
1621
+ output: part.output,
1622
+ downloadedAssets
1623
+ }),
1618
1624
  providerOptions: part.providerOptions
1619
1625
  };
1620
1626
  }
@@ -1638,20 +1644,44 @@ function convertToLanguageModelMessage({
1638
1644
  }
1639
1645
  }
1640
1646
  async function downloadAssets(messages, download2, supportedUrls) {
1641
- const plannedDownloads = messages.filter((message) => message.role === "user").map((message) => message.content).filter(
1642
- (content) => Array.isArray(content)
1643
- ).flat().filter(
1644
- (part) => part.type === "image" || part.type === "file"
1645
- ).map((part) => {
1646
- var _a21;
1647
- const mediaType = (_a21 = part.mediaType) != null ? _a21 : part.type === "image" ? "image/*" : void 0;
1648
- let data = part.type === "image" ? part.image : part.data;
1649
- if (typeof data === "string") {
1650
- try {
1651
- data = new URL(data);
1652
- } catch (ignored) {
1647
+ var _a21;
1648
+ const downloadableFiles = [];
1649
+ for (const message of messages) {
1650
+ if (message.role === "user" && Array.isArray(message.content)) {
1651
+ for (const part of message.content) {
1652
+ if (part.type === "image" || part.type === "file") {
1653
+ downloadableFiles.push({
1654
+ data: part.type === "image" ? part.image : part.data,
1655
+ mediaType: (_a21 = part.mediaType) != null ? _a21 : part.type === "image" ? "image/*" : void 0
1656
+ });
1657
+ }
1653
1658
  }
1654
1659
  }
1660
+ if (message.role === "tool" || message.role === "assistant") {
1661
+ if (!Array.isArray(message.content)) {
1662
+ continue;
1663
+ }
1664
+ for (const part of message.content) {
1665
+ if (part.type !== "tool-result") {
1666
+ continue;
1667
+ }
1668
+ if (part.output.type !== "content") {
1669
+ continue;
1670
+ }
1671
+ for (const contentPart of part.output.value) {
1672
+ if (contentPart.type === "image-url" || contentPart.type === "file-url") {
1673
+ downloadableFiles.push({
1674
+ data: new URL(contentPart.url),
1675
+ mediaType: contentPart.type === "image-url" ? "image/*" : void 0
1676
+ });
1677
+ }
1678
+ }
1679
+ }
1680
+ }
1681
+ }
1682
+ const plannedDownloads = downloadableFiles.map((part) => {
1683
+ const mediaType = part.mediaType;
1684
+ const { data } = convertToLanguageModelV3DataContent(part.data);
1655
1685
  return { mediaType, data };
1656
1686
  }).filter(
1657
1687
  (part) => part.data instanceof URL
@@ -1732,13 +1762,41 @@ function convertPartToLanguageModelPart(part, downloadedAssets) {
1732
1762
  }
1733
1763
  }
1734
1764
  }
1735
- function mapToolResultOutput(output) {
1765
+ function mapToolResultOutput({
1766
+ output,
1767
+ downloadedAssets
1768
+ }) {
1736
1769
  if (output.type !== "content") {
1737
1770
  return output;
1738
1771
  }
1739
1772
  return {
1740
1773
  type: "content",
1741
1774
  value: output.value.map((item) => {
1775
+ var _a21, _b;
1776
+ if (item.type === "image-url") {
1777
+ const downloadedFile = downloadedAssets[new URL(item.url).toString()];
1778
+ if (downloadedFile) {
1779
+ return {
1780
+ type: "image-data",
1781
+ data: convertDataContentToBase64String(downloadedFile.data),
1782
+ mediaType: (_a21 = downloadedFile.mediaType) != null ? _a21 : "image/*",
1783
+ providerOptions: item.providerOptions
1784
+ };
1785
+ }
1786
+ return item;
1787
+ }
1788
+ if (item.type === "file-url") {
1789
+ const downloadedFile = downloadedAssets[new URL(item.url).toString()];
1790
+ if (downloadedFile) {
1791
+ return {
1792
+ type: "file-data",
1793
+ data: convertDataContentToBase64String(downloadedFile.data),
1794
+ mediaType: (_b = downloadedFile.mediaType) != null ? _b : "application/octet-stream",
1795
+ providerOptions: item.providerOptions
1796
+ };
1797
+ }
1798
+ return item;
1799
+ }
1742
1800
  if (item.type !== "media") {
1743
1801
  return item;
1744
1802
  }
@@ -2662,12 +2720,13 @@ function mergeObjects(base, overrides) {
2662
2720
 
2663
2721
  // src/util/retry-with-exponential-backoff.ts
2664
2722
  var import_provider26 = require("@ai-sdk/provider");
2723
+ var import_gateway3 = require("@ai-sdk/gateway");
2665
2724
  var import_provider_utils8 = require("@ai-sdk/provider-utils");
2666
2725
  function getRetryDelayInMs({
2667
2726
  error,
2668
2727
  exponentialBackoffDelay
2669
2728
  }) {
2670
- const headers = error.responseHeaders;
2729
+ const headers = import_provider26.APICallError.isInstance(error) ? error.responseHeaders : import_provider26.APICallError.isInstance(error.cause) ? error.cause.responseHeaders : void 0;
2671
2730
  if (!headers)
2672
2731
  return exponentialBackoffDelay;
2673
2732
  let ms;
@@ -2728,7 +2787,7 @@ async function _retryWithExponentialBackoff(f, {
2728
2787
  errors: newErrors
2729
2788
  });
2730
2789
  }
2731
- if (error instanceof Error && import_provider26.APICallError.isInstance(error) && error.isRetryable === true && tryNumber <= maxRetries) {
2790
+ if (error instanceof Error && (import_provider26.APICallError.isInstance(error) && error.isRetryable === true || import_gateway3.GatewayError.isInstance(error) && error.isRetryable === true) && tryNumber <= maxRetries) {
2732
2791
  await (0, import_provider_utils8.delay)(
2733
2792
  getRetryDelayInMs({
2734
2793
  error,
@@ -8834,7 +8893,7 @@ var uiMessagesSchema = (0, import_provider_utils22.lazySchema)(
8834
8893
  toolCallId: import_v48.z.string(),
8835
8894
  toolMetadata: toolMetadataSchema2.optional(),
8836
8895
  state: import_v48.z.literal("output-error"),
8837
- input: import_v48.z.unknown(),
8896
+ input: import_v48.z.unknown().optional(),
8838
8897
  rawInput: import_v48.z.unknown().optional(),
8839
8898
  providerExecuted: import_v48.z.boolean().optional(),
8840
8899
  output: import_v48.z.never().optional(),
@@ -8944,7 +9003,7 @@ var uiMessagesSchema = (0, import_provider_utils22.lazySchema)(
8944
9003
  toolMetadata: toolMetadataSchema2.optional(),
8945
9004
  state: import_v48.z.literal("output-error"),
8946
9005
  providerExecuted: import_v48.z.boolean().optional(),
8947
- input: import_v48.z.unknown(),
9006
+ input: import_v48.z.unknown().optional(),
8948
9007
  rawInput: import_v48.z.unknown().optional(),
8949
9008
  output: import_v48.z.never().optional(),
8950
9009
  errorText: import_v48.z.string(),