ai 7.0.99 → 7.0.101

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,19 @@
1
1
  # ai
2
2
 
3
+ ## 7.0.101
4
+
5
+ ### Patch Changes
6
+
7
+ - 6aa7c54: fix(ai): serialize tool output JSON values
8
+
9
+ ## 7.0.100
10
+
11
+ ### Patch Changes
12
+
13
+ - 6431635: feat(ai): expose typed AI SDK errors for UI transport and completion failures
14
+ - Updated dependencies [23a0fff]
15
+ - @ai-sdk/gateway@4.0.81
16
+
3
17
  ## 7.0.99
4
18
 
5
19
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -7519,9 +7519,11 @@ declare class UnsupportedModelVersionError extends AISDKError {
7519
7519
 
7520
7520
  declare const symbol$5: unique symbol;
7521
7521
  /**
7522
- * Error thrown when a UI message stream contains invalid or out-of-sequence chunks.
7522
+ * Error thrown when a UI message stream reports an error or contains invalid
7523
+ * or out-of-sequence chunks.
7523
7524
  *
7524
7525
  * This typically occurs when:
7526
+ * - An error chunk is received
7525
7527
  * - A delta chunk is received without a corresponding start chunk
7526
7528
  * - An end chunk is received without a corresponding start chunk
7527
7529
  * - A tool invocation is not found for the given toolCallId
@@ -7535,7 +7537,8 @@ declare class UIMessageStreamError extends AISDKError {
7535
7537
  */
7536
7538
  readonly chunkType: string;
7537
7539
  /**
7538
- * The ID associated with the failing chunk (part ID or toolCallId).
7540
+ * The ID associated with the failing chunk (part ID or toolCallId), or an
7541
+ * empty string when the chunk does not have an ID.
7539
7542
  */
7540
7543
  readonly chunkId: string;
7541
7544
  constructor({ chunkType, chunkId, message, }: {
package/dist/index.js CHANGED
@@ -1178,7 +1178,7 @@ import {
1178
1178
  } from "@ai-sdk/provider-utils";
1179
1179
 
1180
1180
  // src/version.ts
1181
- var VERSION = true ? "7.0.99" : "0.0.0-test";
1181
+ var VERSION = true ? "7.0.101" : "0.0.0-test";
1182
1182
 
1183
1183
  // src/util/download/download.ts
1184
1184
  var download = async ({
@@ -2007,6 +2007,9 @@ function getMediaTypeFromUrl(url, fallbackMediaType = "application/octet-stream"
2007
2007
 
2008
2008
  // src/prompt/create-tool-model-output.ts
2009
2009
  import { getErrorMessage as getErrorMessage3 } from "@ai-sdk/provider";
2010
+ import {
2011
+ parseJSON
2012
+ } from "@ai-sdk/provider-utils";
2010
2013
  async function createToolModelOutput({
2011
2014
  toolCallId,
2012
2015
  input,
@@ -2017,15 +2020,19 @@ async function createToolModelOutput({
2017
2020
  if (errorMode === "text") {
2018
2021
  return { type: "error-text", value: getErrorMessage3(output) };
2019
2022
  } else if (errorMode === "json") {
2020
- return { type: "error-json", value: toJSONValue(output) };
2023
+ return { type: "error-json", value: await toJSONValue(output) };
2021
2024
  }
2022
2025
  if (tool2 == null ? void 0 : tool2.toModelOutput) {
2023
2026
  return await tool2.toModelOutput({ toolCallId, input, output });
2024
2027
  }
2025
- return typeof output === "string" ? { type: "text", value: output } : { type: "json", value: toJSONValue(output) };
2028
+ return typeof output === "string" ? { type: "text", value: output } : { type: "json", value: await toJSONValue(output) };
2026
2029
  }
2027
- function toJSONValue(value) {
2028
- return value === void 0 ? null : value;
2030
+ async function toJSONValue(value) {
2031
+ if (value === void 0) {
2032
+ return null;
2033
+ }
2034
+ const serialized = JSON.stringify(value);
2035
+ return serialized === void 0 ? null : await parseJSON({ text: serialized });
2029
2036
  }
2030
2037
 
2031
2038
  // src/prompt/prepare-language-model-call-options.ts
@@ -18974,6 +18981,26 @@ import {
18974
18981
  withUserAgentSuffix as withUserAgentSuffix16,
18975
18982
  getRuntimeEnvironmentUserAgent as getRuntimeEnvironmentUserAgent2
18976
18983
  } from "@ai-sdk/provider-utils";
18984
+ import { EmptyResponseBodyError as EmptyResponseBodyError2 } from "@ai-sdk/provider";
18985
+
18986
+ // src/ui/create-ui-api-call-error.ts
18987
+ import { APICallError as APICallError3 } from "@ai-sdk/provider";
18988
+ async function createUIApiCallError({
18989
+ response,
18990
+ url,
18991
+ fallbackMessage
18992
+ }) {
18993
+ const responseBody = await response.text();
18994
+ return new APICallError3({
18995
+ message: responseBody || fallbackMessage,
18996
+ url,
18997
+ // UI requests can contain prompts, messages, and other sensitive values.
18998
+ // Keep them out of client-facing error objects.
18999
+ requestBodyValues: void 0,
19000
+ statusCode: response.status,
19001
+ responseBody
19002
+ });
19003
+ }
18977
19004
 
18978
19005
  // src/ui/process-text-stream.ts
18979
19006
  async function processTextStream({
@@ -19033,12 +19060,16 @@ async function callCompletionApi({
19033
19060
  throw err;
19034
19061
  });
19035
19062
  if (!response.ok) {
19036
- throw new Error(
19037
- await response.text() || "Failed to fetch the chat response."
19038
- );
19063
+ throw await createUIApiCallError({
19064
+ response,
19065
+ url: api,
19066
+ fallbackMessage: "Failed to fetch the chat response."
19067
+ });
19039
19068
  }
19040
19069
  if (!response.body) {
19041
- throw new Error("The response body is empty.");
19070
+ throw new EmptyResponseBodyError2({
19071
+ message: "The response body is empty."
19072
+ });
19042
19073
  }
19043
19074
  let result = "";
19044
19075
  switch (streamProtocol) {
@@ -19068,7 +19099,11 @@ async function callCompletionApi({
19068
19099
  result += streamPart.delta;
19069
19100
  setCompletion(result);
19070
19101
  } else if (streamPart.type === "error") {
19071
- throw new Error(streamPart.errorText);
19102
+ throw new UIMessageStreamError({
19103
+ chunkType: "error",
19104
+ chunkId: "",
19105
+ message: streamPart.errorText
19106
+ });
19072
19107
  }
19073
19108
  }
19074
19109
  })
@@ -19081,7 +19116,11 @@ async function callCompletionApi({
19081
19116
  }
19082
19117
  default: {
19083
19118
  const exhaustiveCheck = streamProtocol;
19084
- throw new Error(`Unknown stream protocol: ${exhaustiveCheck}`);
19119
+ throw new InvalidArgumentError({
19120
+ parameter: "streamProtocol",
19121
+ value: exhaustiveCheck,
19122
+ message: `Unknown stream protocol: ${exhaustiveCheck}`
19123
+ });
19085
19124
  }
19086
19125
  }
19087
19126
  if (onFinish) {
@@ -19111,12 +19150,16 @@ import {
19111
19150
  } from "@ai-sdk/provider-utils";
19112
19151
 
19113
19152
  // src/ui/convert-file-list-to-file-ui-parts.ts
19153
+ import { UnsupportedFunctionalityError as UnsupportedFunctionalityError6 } from "@ai-sdk/provider";
19114
19154
  async function convertFileListToFileUIParts(files) {
19115
19155
  if (files == null) {
19116
19156
  return [];
19117
19157
  }
19118
19158
  if (!globalThis.FileList || !(files instanceof globalThis.FileList)) {
19119
- throw new Error("FileList is not supported in the current environment");
19159
+ throw new UnsupportedFunctionalityError6({
19160
+ functionality: "FileList",
19161
+ message: "FileList is not supported in the current environment"
19162
+ });
19120
19163
  }
19121
19164
  return Promise.all(
19122
19165
  Array.from(files).map(async (file) => {
@@ -19148,6 +19191,7 @@ import {
19148
19191
  normalizeHeaders,
19149
19192
  resolve as resolve2
19150
19193
  } from "@ai-sdk/provider-utils";
19194
+ import { EmptyResponseBodyError as EmptyResponseBodyError3 } from "@ai-sdk/provider";
19151
19195
  var HttpChatTransport = class {
19152
19196
  constructor({
19153
19197
  api = "/api/chat",
@@ -19212,12 +19256,16 @@ var HttpChatTransport = class {
19212
19256
  signal: abortSignal
19213
19257
  });
19214
19258
  if (!response.ok) {
19215
- throw new Error(
19216
- await response.text() || "Failed to fetch the chat response."
19217
- );
19259
+ throw await createUIApiCallError({
19260
+ response,
19261
+ url: api,
19262
+ fallbackMessage: "Failed to fetch the chat response."
19263
+ });
19218
19264
  }
19219
19265
  if (!response.body) {
19220
- throw new Error("The response body is empty.");
19266
+ throw new EmptyResponseBodyError3({
19267
+ message: "The response body is empty."
19268
+ });
19221
19269
  }
19222
19270
  return this.processResponseStream(response.body);
19223
19271
  }
@@ -19252,12 +19300,16 @@ var HttpChatTransport = class {
19252
19300
  return null;
19253
19301
  }
19254
19302
  if (!response.ok) {
19255
- throw new Error(
19256
- await response.text() || "Failed to fetch the chat response."
19257
- );
19303
+ throw await createUIApiCallError({
19304
+ response,
19305
+ url: api,
19306
+ fallbackMessage: "Failed to fetch the chat response."
19307
+ });
19258
19308
  }
19259
19309
  if (!response.body) {
19260
- throw new Error("The response body is empty.");
19310
+ throw new EmptyResponseBodyError3({
19311
+ message: "The response body is empty."
19312
+ });
19261
19313
  }
19262
19314
  return this.processResponseStream(response.body);
19263
19315
  }
@@ -19347,12 +19399,18 @@ var AbstractChat = class {
19347
19399
  (m) => m.id === message.messageId
19348
19400
  );
19349
19401
  if (messageIndex === -1) {
19350
- throw new Error(`message with id ${message.messageId} not found`);
19402
+ throw new InvalidArgumentError({
19403
+ parameter: "message.messageId",
19404
+ value: message.messageId,
19405
+ message: `message with id ${message.messageId} not found`
19406
+ });
19351
19407
  }
19352
19408
  if (this.state.messages[messageIndex].role !== "user") {
19353
- throw new Error(
19354
- `message with id ${message.messageId} is not a user message`
19355
- );
19409
+ throw new InvalidArgumentError({
19410
+ parameter: "message.messageId",
19411
+ value: message.messageId,
19412
+ message: `message with id ${message.messageId} is not a user message`
19413
+ });
19356
19414
  }
19357
19415
  this.state.messages = this.state.messages.slice(0, messageIndex + 1);
19358
19416
  this.state.replaceMessage(messageIndex, {
@@ -19385,7 +19443,11 @@ var AbstractChat = class {
19385
19443
  } = {}) => {
19386
19444
  const messageIndex = messageId == null ? this.state.messages.length - 1 : this.state.messages.findIndex((message) => message.id === messageId);
19387
19445
  if (messageIndex === -1) {
19388
- throw new Error(`message ${messageId} not found`);
19446
+ throw new InvalidArgumentError({
19447
+ parameter: "messageId",
19448
+ value: messageId,
19449
+ message: `message ${messageId} not found`
19450
+ });
19389
19451
  }
19390
19452
  this.state.messages = this.state.messages.slice(
19391
19453
  0,