ai 7.0.128 → 7.0.129

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.
Files changed (44) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/dist/index.d.ts +18 -3
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +148 -32
  5. package/dist/index.js.map +1 -1
  6. package/dist/internal/index.d.ts +10 -2
  7. package/dist/internal/index.d.ts.map +1 -1
  8. package/dist/internal/index.js +68 -16
  9. package/dist/internal/index.js.map +1 -1
  10. package/docs/02-foundations/06-provider-options.mdx +11 -10
  11. package/docs/03-agents/02-building-agents.mdx +16 -11
  12. package/docs/03-agents/07-workflow-agent.mdx +3 -3
  13. package/docs/03-ai-sdk-core/17-runtime-and-tool-context.mdx +18 -14
  14. package/docs/03-ai-sdk-core/25-settings.mdx +3 -2
  15. package/docs/03-ai-sdk-core/26-reasoning.mdx +12 -5
  16. package/docs/03-ai-sdk-core/32-decisions.mdx +17 -20
  17. package/docs/03-ai-sdk-core/35-image-generation.mdx +2 -0
  18. package/docs/04-ai-sdk-ui/21-error-handling.mdx +28 -3
  19. package/docs/07-reference/01-ai-sdk-core/01-generate-text.mdx +2 -2
  20. package/docs/07-reference/01-ai-sdk-core/02-stream-text.mdx +2 -2
  21. package/package.json +15 -15
  22. package/src/generate-object/generate-object.ts +10 -0
  23. package/src/generate-object/stream-object.ts +10 -0
  24. package/src/generate-speech/index.ts +13 -1
  25. package/src/generate-text/generate-text.ts +3 -1
  26. package/src/generate-text/tool-approval-signature.ts +7 -4
  27. package/src/global.ts +2 -1
  28. package/src/logger/deprecations.ts +72 -0
  29. package/src/logger/log-warnings.ts +25 -3
  30. package/src/model/as-language-model-v3.ts +4 -0
  31. package/src/prompt/convert-to-language-model-prompt.ts +7 -1
  32. package/src/realtime/encode-realtime-frame.ts +7 -2
  33. package/src/transcribe/index.ts +13 -1
  34. package/src/types/index.ts +1 -0
  35. package/src/types/language-model.ts +9 -1
  36. package/src/types/usage.ts +21 -0
  37. package/src/ui/chat.ts +16 -8
  38. package/src/ui/convert-to-model-messages.ts +40 -8
  39. package/src/ui/http-chat-transport.ts +5 -3
  40. package/src/ui/process-text-stream.ts +5 -1
  41. package/src/ui/text-stream-chat-transport.ts +3 -1
  42. package/src/ui/ui-messages.ts +8 -0
  43. package/src/ui/unavailable-tool.ts +17 -0
  44. package/src/ui/validate-ui-messages.ts +10 -2
package/dist/index.js CHANGED
@@ -532,6 +532,35 @@ var RetryError = class extends AISDKError$1 {
532
532
  /** @deprecated Use `Experimental_DecisionUnsupportedQuestionTypeError` instead. */
533
533
  const Experimental_EvaluationUnsupportedQuestionTypeError = Experimental_DecisionUnsupportedQuestionTypeError$1;
534
534
  //#endregion
535
+ //#region src/logger/deprecations.ts
536
+ const deprecationCodes = /* @__PURE__ */ new Map([
537
+ ["generateObject", "AISDK_DEP_GENERATE_OBJECT"],
538
+ ["streamObject", "AISDK_DEP_STREAM_OBJECT"],
539
+ ["experimental_generateSpeech", "AISDK_DEP_EXPERIMENTAL_GENERATE_SPEECH"],
540
+ ["experimental_transcribe", "AISDK_DEP_EXPERIMENTAL_TRANSCRIBE"],
541
+ ["\"image\" content part", "AISDK_DEP_IMAGE_CONTENT_PART"],
542
+ ["\"tool-result\" content of type \"file-data\"", "AISDK_DEP_TOOL_RESULT_FILE_DATA"],
543
+ ["\"tool-result\" content of type \"file-url\"", "AISDK_DEP_TOOL_RESULT_FILE_URL"],
544
+ ["\"tool-result\" content of type \"file-id\"", "AISDK_DEP_TOOL_RESULT_FILE_ID"],
545
+ ["\"tool-result\" content of type \"file-reference\"", "AISDK_DEP_TOOL_RESULT_FILE_REFERENCE"],
546
+ ["\"tool-result\" content of type \"image-data\"", "AISDK_DEP_TOOL_RESULT_IMAGE_DATA"],
547
+ ["\"tool-result\" content of type \"image-url\"", "AISDK_DEP_TOOL_RESULT_IMAGE_URL"],
548
+ ["\"tool-result\" content of type \"image-file-id\"", "AISDK_DEP_TOOL_RESULT_IMAGE_FILE_ID"],
549
+ ["\"tool-result\" content of type \"image-file-reference\"", "AISDK_DEP_TOOL_RESULT_IMAGE_FILE_REFERENCE"],
550
+ ["rawInput in output-error UI message parts", "AISDK_DEP_UI_MESSAGE_RAW_INPUT"]
551
+ ]);
552
+ /**
553
+ * Escape punctuation and UTF-16 code units without losing case or collapsing
554
+ * distinct settings. Underscores are escaped too, so `__` separates code parts.
555
+ */
556
+ function encodeCodePart(value) {
557
+ return value.replace(/[^a-zA-Z0-9]/g, (character) => `_${character.charCodeAt(0).toString(16).toUpperCase().padStart(4, "0")}`);
558
+ }
559
+ function getDeprecationCode({ setting, provider }) {
560
+ if (provider == null) return deprecationCodes.get(setting) ?? `AISDK_DEP_SETTING_${encodeCodePart(setting)}`;
561
+ return `AISDK_DEP_PROVIDER_${encodeCodePart(provider)}__${encodeCodePart(setting)}`;
562
+ }
563
+ //#endregion
535
564
  //#region src/logger/log-warnings.ts
536
565
  /**
537
566
  * Formats a warning object into a human-readable string with clear AI SDK branding.
@@ -562,9 +591,13 @@ function formatWarning({ warning, provider, model }) {
562
591
  }
563
592
  const FIRST_WARNING_INFO_MESSAGE = "AI SDK Warning System: To turn off warning logging, set the AI_SDK_LOG_WARNINGS global to false.";
564
593
  let hasLoggedBefore = false;
565
- function emitWarning({ message, type }) {
566
- if (typeof process !== "undefined" && typeof process.emitWarning === "function") process.emitWarning(message, { type });
567
- else console.warn(message);
594
+ const emittedDeprecationCodes = /* @__PURE__ */ new Set();
595
+ function emitWarning({ message, type, code }) {
596
+ if (typeof process !== "undefined" && typeof process.emitWarning === "function") process.emitWarning(message, code == null ? { type } : {
597
+ type,
598
+ code
599
+ });
600
+ else console.warn(code == null ? message : `[${code}] ${message}`);
568
601
  }
569
602
  /**
570
603
  * Logs warnings to the console or uses a custom logger if configured.
@@ -572,7 +605,9 @@ function emitWarning({ message, type }) {
572
605
  * The behavior can be customized via the `AI_SDK_LOG_WARNINGS` global variable:
573
606
  * - If set to `false`, warnings are suppressed.
574
607
  * - If set to a function, that function is called with the warnings.
575
- * - Otherwise, warnings are logged to the console using `console.warn`.
608
+ * - Otherwise, warnings use `process.emitWarning` when available, falling back
609
+ * to `console.warn`. Deprecations have stable codes and are emitted once per
610
+ * code by the default logger. Custom loggers receive every warning.
576
611
  *
577
612
  * @param options - The options containing warnings and context.
578
613
  * @param options.warnings - The warnings to log.
@@ -594,14 +629,25 @@ const logWarnings = (options) => {
594
629
  type: "Warning"
595
630
  });
596
631
  }
597
- for (const warning of options.warnings) emitWarning({
598
- message: formatWarning({
599
- warning,
600
- provider: options.provider,
601
- model: options.model
602
- }),
603
- type: warning.type === "deprecated" ? "DeprecationWarning" : "Warning"
604
- });
632
+ for (const warning of options.warnings) {
633
+ const code = warning.type === "deprecated" ? getDeprecationCode({
634
+ setting: warning.setting,
635
+ provider: options.provider
636
+ }) : void 0;
637
+ if (code != null) {
638
+ if (emittedDeprecationCodes.has(code)) continue;
639
+ emittedDeprecationCodes.add(code);
640
+ }
641
+ emitWarning({
642
+ message: formatWarning({
643
+ warning,
644
+ provider: options.provider,
645
+ model: options.model
646
+ }),
647
+ type: warning.type === "deprecated" ? "DeprecationWarning" : "Warning",
648
+ code
649
+ });
650
+ }
605
651
  };
606
652
  //#endregion
607
653
  //#region src/util/log-v2-compatibility-warning.ts
@@ -724,7 +770,8 @@ function convertV2UsageToV3(usage) {
724
770
  total: usage.outputTokens,
725
771
  text: void 0,
726
772
  reasoning: usage.reasoningTokens
727
- }
773
+ },
774
+ raw: usage.totalTokens == null ? void 0 : { totalTokens: usage.totalTokens }
728
775
  };
729
776
  }
730
777
  //#endregion
@@ -1127,7 +1174,7 @@ function cloneValue(value) {
1127
1174
  }
1128
1175
  //#endregion
1129
1176
  //#region src/version.ts
1130
- const VERSION = "7.0.128";
1177
+ const VERSION = "7.0.129";
1131
1178
  //#endregion
1132
1179
  //#region src/util/download/download.ts
1133
1180
  /**
@@ -1383,7 +1430,7 @@ async function convertToLanguageModelPrompt({ prompt, supportedUrls, download, a
1383
1430
  const lastContentPart = lastCombinedMessage.content.at(-1);
1384
1431
  if (lastContentPart != null && lastCombinedMessage.providerOptions != null) lastContentPart.providerOptions = mergeObjects(lastCombinedMessage.providerOptions, lastContentPart.providerOptions);
1385
1432
  lastCombinedMessage.content.push(...message.content);
1386
- lastCombinedMessage.providerOptions = message.providerOptions;
1433
+ lastCombinedMessage.providerOptions = lastContentPart == null ? mergeObjects(lastCombinedMessage.providerOptions, message.providerOptions) : message.providerOptions;
1387
1434
  } else combinedMessages.push(message);
1388
1435
  }
1389
1436
  const toolCallIds = /* @__PURE__ */ new Set();
@@ -2497,6 +2544,7 @@ function createNullLanguageModelUsage() {
2497
2544
  };
2498
2545
  }
2499
2546
  function addLanguageModelUsage(usage1, usage2) {
2547
+ const raw = isNullLanguageModelUsage(usage1) ? usage2.raw : isNullLanguageModelUsage(usage2) ? usage1.raw : void 0;
2500
2548
  return {
2501
2549
  inputTokens: addTokenCounts(usage1.inputTokens, usage2.inputTokens),
2502
2550
  inputTokenDetails: {
@@ -2509,9 +2557,13 @@ function addLanguageModelUsage(usage1, usage2) {
2509
2557
  textTokens: addTokenCounts(usage1.outputTokenDetails?.textTokens, usage2.outputTokenDetails?.textTokens),
2510
2558
  reasoningTokens: addTokenCounts(usage1.outputTokenDetails?.reasoningTokens, usage2.outputTokenDetails?.reasoningTokens)
2511
2559
  },
2512
- totalTokens: addTokenCounts(usage1.totalTokens, usage2.totalTokens)
2560
+ totalTokens: addTokenCounts(usage1.totalTokens, usage2.totalTokens),
2561
+ ...raw == null ? {} : { raw }
2513
2562
  };
2514
2563
  }
2564
+ function isNullLanguageModelUsage(usage) {
2565
+ return usage.inputTokens == null && usage.inputTokenDetails?.noCacheTokens == null && usage.inputTokenDetails?.cacheReadTokens == null && usage.inputTokenDetails?.cacheWriteTokens == null && usage.outputTokens == null && usage.outputTokenDetails?.textTokens == null && usage.outputTokenDetails?.reasoningTokens == null && usage.totalTokens == null && usage.raw == null;
2566
+ }
2515
2567
  function addTokenCounts(tokenCount1, tokenCount2) {
2516
2568
  return tokenCount1 == null && tokenCount2 == null ? void 0 : (tokenCount1 ?? 0) + (tokenCount2 ?? 0);
2517
2569
  }
@@ -10574,6 +10626,15 @@ function readUIMessageStream({ message, stream, onError, terminateOnError = fals
10574
10626
  return createAsyncIterableStream(outputStream);
10575
10627
  }
10576
10628
  //#endregion
10629
+ //#region src/ui/unavailable-tool.ts
10630
+ function markToolPartAsUnavailable(part) {
10631
+ part.dynamic = false;
10632
+ return part;
10633
+ }
10634
+ function isToolPartFromUnavailableTool(part) {
10635
+ return part.type === "dynamic-tool" && part.dynamic === false;
10636
+ }
10637
+ //#endregion
10577
10638
  //#region src/ui/warn-if-ui-message-has-deprecated-raw-input.ts
10578
10639
  const rawInputDeprecationWarning = {
10579
10640
  type: "deprecated",
@@ -10604,6 +10665,20 @@ async function convertToModelMessages(messages, options) {
10604
10665
  ...message,
10605
10666
  parts: message.parts.filter((part) => !isToolUIPart(part) || (part.state !== "approval-requested" || messageIndex >= lastUserMessageIndex) && (!options?.ignoreIncompleteToolCalls || part.state === "approval-responded" || part.state === "output-available" && part.preliminary !== true || part.state === "output-error" || part.state === "output-denied"))
10606
10667
  }));
10668
+ async function createModelOutput({ toolPart, toolName, output, errorMode }) {
10669
+ const tool = getOwn(options?.tools, toolName);
10670
+ if (errorMode === "none" && tool == null && isToolPartFromUnavailableTool(toolPart)) return {
10671
+ type: "text",
10672
+ value: "Tool output omitted because the tool is no longer available."
10673
+ };
10674
+ return createToolModelOutput({
10675
+ toolCallId: toolPart.toolCallId,
10676
+ input: toolPart.input,
10677
+ output,
10678
+ tool,
10679
+ errorMode
10680
+ });
10681
+ }
10607
10682
  for (const message of messages) switch (message.role) {
10608
10683
  case "system": {
10609
10684
  const textParts = message.parts.filter((part) => part.type === "text");
@@ -10717,11 +10792,10 @@ async function convertToModelMessages(messages, options) {
10717
10792
  type: "tool-result",
10718
10793
  toolCallId: part.toolCallId,
10719
10794
  toolName,
10720
- output: await createToolModelOutput({
10721
- toolCallId: part.toolCallId,
10722
- input: part.input,
10795
+ output: await createModelOutput({
10796
+ toolPart: part,
10797
+ toolName,
10723
10798
  output: part.state === "output-error" ? part.errorText : part.output,
10724
- tool: getOwn(options?.tools, toolName),
10725
10799
  errorMode: part.state === "output-error" ? "json" : "none"
10726
10800
  }),
10727
10801
  ...resultProviderMetadata != null ? { providerOptions: resultProviderMetadata } : {}
@@ -10778,11 +10852,10 @@ async function convertToModelMessages(messages, options) {
10778
10852
  type: "tool-result",
10779
10853
  toolCallId: toolPart.toolCallId,
10780
10854
  toolName,
10781
- output: await createToolModelOutput({
10782
- toolCallId: toolPart.toolCallId,
10783
- input: toolPart.input,
10855
+ output: await createModelOutput({
10856
+ toolPart,
10857
+ toolName,
10784
10858
  output: toolPart.state === "output-error" ? toolPart.errorText : toolPart.output,
10785
- tool: getOwn(options?.tools, toolName),
10786
10859
  errorMode: toolPart.state === "output-error" ? "text" : "none"
10787
10860
  }),
10788
10861
  ...toolPart.callProviderMetadata != null ? { providerOptions: toolPart.callProviderMetadata } : {}
@@ -10823,11 +10896,11 @@ function isEmptyObject(value) {
10823
10896
  }
10824
10897
  function asDynamicToolPart(toolPart) {
10825
10898
  const { type, ...part } = toolPart;
10826
- return {
10899
+ return markToolPartAsUnavailable({
10827
10900
  ...part,
10828
10901
  type: "dynamic-tool",
10829
10902
  toolName: type.slice(5)
10830
- };
10903
+ });
10831
10904
  }
10832
10905
  function getToolPartInputSchemaInput(toolPart) {
10833
10906
  return toolPart.approval != null && Object.prototype.hasOwnProperty.call(toolPart.approval, "inputSchemaInput") ? { value: toolPart.approval.inputSchemaInput } : void 0;
@@ -10913,6 +10986,7 @@ const uiMessagesSchema = lazySchema(() => {
10913
10986
  }),
10914
10987
  z.object({
10915
10988
  type: z.literal("dynamic-tool"),
10989
+ dynamic: z.literal(false).optional(),
10916
10990
  toolName: z.string(),
10917
10991
  toolCallId: z.string(),
10918
10992
  title: z.string().optional(),
@@ -10928,6 +11002,7 @@ const uiMessagesSchema = lazySchema(() => {
10928
11002
  }),
10929
11003
  z.object({
10930
11004
  type: z.literal("dynamic-tool"),
11005
+ dynamic: z.literal(false).optional(),
10931
11006
  toolName: z.string(),
10932
11007
  toolCallId: z.string(),
10933
11008
  title: z.string().optional(),
@@ -10942,6 +11017,7 @@ const uiMessagesSchema = lazySchema(() => {
10942
11017
  }),
10943
11018
  z.object({
10944
11019
  type: z.literal("dynamic-tool"),
11020
+ dynamic: z.literal(false).optional(),
10945
11021
  toolName: z.string(),
10946
11022
  toolCallId: z.string(),
10947
11023
  title: z.string().optional(),
@@ -10956,6 +11032,7 @@ const uiMessagesSchema = lazySchema(() => {
10956
11032
  }),
10957
11033
  z.object({
10958
11034
  type: z.literal("dynamic-tool"),
11035
+ dynamic: z.literal(false).optional(),
10959
11036
  toolName: z.string(),
10960
11037
  toolCallId: z.string(),
10961
11038
  title: z.string().optional(),
@@ -10970,6 +11047,7 @@ const uiMessagesSchema = lazySchema(() => {
10970
11047
  }),
10971
11048
  z.object({
10972
11049
  type: z.literal("dynamic-tool"),
11050
+ dynamic: z.literal(false).optional(),
10973
11051
  toolName: z.string(),
10974
11052
  toolCallId: z.string(),
10975
11053
  title: z.string().optional(),
@@ -10986,6 +11064,7 @@ const uiMessagesSchema = lazySchema(() => {
10986
11064
  }),
10987
11065
  z.object({
10988
11066
  type: z.literal("dynamic-tool"),
11067
+ dynamic: z.literal(false).optional(),
10989
11068
  toolName: z.string(),
10990
11069
  toolCallId: z.string(),
10991
11070
  title: z.string().optional(),
@@ -11002,6 +11081,7 @@ const uiMessagesSchema = lazySchema(() => {
11002
11081
  }),
11003
11082
  z.object({
11004
11083
  type: z.literal("dynamic-tool"),
11084
+ dynamic: z.literal(false).optional(),
11005
11085
  toolName: z.string(),
11006
11086
  toolCallId: z.string(),
11007
11087
  title: z.string().optional(),
@@ -13288,6 +13368,11 @@ const originalGenerateId$1 = createIdGenerator$1({
13288
13368
  * @deprecated Use `generateText` with an `output` setting instead.
13289
13369
  */
13290
13370
  async function generateObject(options) {
13371
+ logWarnings({ warnings: [{
13372
+ type: "deprecated",
13373
+ setting: "generateObject",
13374
+ message: "Use generateText with an output setting instead."
13375
+ }] });
13291
13376
  const { model: modelArg, output = "object", instructions, system, prompt, messages, allowSystemInMessages, maxRetries: maxRetriesArg, abortSignal, headers, experimental_repairText, repairText = experimental_repairText, experimental_telemetry, telemetry = experimental_telemetry, experimental_download: download, providerOptions, onStart, experimental_onStart, onStepStart, experimental_onStepStart, onStepEnd, onStepFinish, onFinish, _internal: { generateId = originalGenerateId$1, currentDate = () => /* @__PURE__ */ new Date() } = {}, ...settings } = options;
13292
13377
  const model = resolveLanguageModel(modelArg);
13293
13378
  const enumValues = "enum" in options ? options.enum : void 0;
@@ -13693,6 +13778,11 @@ async function markPromiseAsHandled(promise) {
13693
13778
  * @deprecated Use `streamText` with an `output` setting instead.
13694
13779
  */
13695
13780
  function streamObject(options) {
13781
+ logWarnings({ warnings: [{
13782
+ type: "deprecated",
13783
+ setting: "streamObject",
13784
+ message: "Use streamText with an output setting instead."
13785
+ }] });
13696
13786
  const { model, output = "object", instructions, system, prompt, messages, allowSystemInMessages, maxRetries, abortSignal, headers, experimental_repairText, repairText = experimental_repairText, experimental_telemetry, telemetry = experimental_telemetry, experimental_download: download, providerOptions, onStart, experimental_onStart, onStepStart, experimental_onStepStart, onStepEnd, onStepFinish, onError = ({ error }) => {
13697
13787
  console.error(error);
13698
13788
  }, onFinish, _internal: { generateId = originalGenerateId, currentDate = () => /* @__PURE__ */ new Date(), now: now$1 = now } = {}, ...settings } = options;
@@ -14343,7 +14433,14 @@ var DefaultSpeechResult = class {
14343
14433
  /**
14344
14434
  * @deprecated Use `generateSpeech` instead.
14345
14435
  */
14346
- const experimental_generateSpeech = generateSpeech;
14436
+ const experimental_generateSpeech = (options) => {
14437
+ logWarnings({ warnings: [{
14438
+ type: "deprecated",
14439
+ setting: "experimental_generateSpeech",
14440
+ message: "Use generateSpeech instead."
14441
+ }] });
14442
+ return generateSpeech(options);
14443
+ };
14347
14444
  //#endregion
14348
14445
  //#region src/generate-text/prune-messages.ts
14349
14446
  /**
@@ -16136,7 +16233,11 @@ const REALTIME_MAX_FRAME_BYTES = 131072;
16136
16233
  const REALTIME_MAX_BUFFERED_BYTES = 131072;
16137
16234
  /** Serialize once, measuring the exact payload passed to the browser. */
16138
16235
  function encodeRealtimeFrame(value) {
16139
- if (value instanceof ArrayBuffer || ArrayBuffer.isView(value)) return {
16236
+ if (value instanceof ArrayBuffer) return {
16237
+ data: value,
16238
+ byteLength: value.byteLength
16239
+ };
16240
+ if (ArrayBuffer.isView(value)) return {
16140
16241
  data: value,
16141
16242
  byteLength: value.byteLength
16142
16243
  };
@@ -19051,7 +19152,14 @@ function getBase64ByteLength(value) {
19051
19152
  /**
19052
19153
  * @deprecated Use `transcribe` instead.
19053
19154
  */
19054
- const experimental_transcribe = transcribe;
19155
+ const experimental_transcribe = (options) => {
19156
+ logWarnings({ warnings: [{
19157
+ type: "deprecated",
19158
+ setting: "experimental_transcribe",
19159
+ message: "Use transcribe instead."
19160
+ }] });
19161
+ return transcribe(options);
19162
+ };
19055
19163
  //#endregion
19056
19164
  //#region src/translate/stream-translate.ts
19057
19165
  /**
@@ -19366,7 +19474,9 @@ async function convertFileListToFileUIParts(files) {
19366
19474
  //#region src/ui/http-chat-transport.ts
19367
19475
  function appendPathToUrl(url, path) {
19368
19476
  const queryOrFragmentStart = url.search(/[?#]/);
19369
- return queryOrFragmentStart === -1 ? `${url}${path}` : `${url.slice(0, queryOrFragmentStart)}${path}${url.slice(queryOrFragmentStart)}`;
19477
+ const urlPath = queryOrFragmentStart === -1 ? url : url.slice(0, queryOrFragmentStart);
19478
+ const suffix = queryOrFragmentStart === -1 ? "" : url.slice(queryOrFragmentStart);
19479
+ return `${urlPath.endsWith("/") && path.startsWith("/") ? urlPath.slice(0, -1) : urlPath}${path}${suffix}`;
19370
19480
  }
19371
19481
  var HttpChatTransport = class {
19372
19482
  constructor({ api = "/api/chat", credentials, headers, body, fetch, prepareSendMessagesRequest, prepareReconnectToStreamRequest }) {
@@ -19696,7 +19806,10 @@ var AbstractChat = class {
19696
19806
  return this.state.status;
19697
19807
  }
19698
19808
  setStatus({ status, error }) {
19699
- if (this.status === status) return;
19809
+ if (this.status === status) {
19810
+ if (this.error !== error) this.state.error = error;
19811
+ return;
19812
+ }
19700
19813
  this.state.status = status;
19701
19814
  this.state.error = error;
19702
19815
  }
@@ -19874,7 +19987,10 @@ var AbstractChat = class {
19874
19987
  }
19875
19988
  if (!isCurrentRequest()) return null;
19876
19989
  isError = true;
19877
- if (err instanceof TypeError && (err.message.toLowerCase().includes("fetch") || err.message.toLowerCase().includes("network"))) isDisconnect = true;
19990
+ if (err instanceof TypeError) {
19991
+ const message = err.message.toLowerCase();
19992
+ isDisconnect = message.includes("fetch") || message.includes("network") || message === "load failed";
19993
+ }
19878
19994
  if (isDisconnect) this.resumableStreamState = activeResponse?.state;
19879
19995
  else if (this.resumableStreamState === activeResponse?.state) this.resumableStreamState = void 0;
19880
19996
  if (this.onError && err instanceof Error) this.onError(err);