ai 6.0.295 → 6.0.297

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 (42) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/index.d.mts +42 -11
  3. package/dist/index.d.ts +42 -11
  4. package/dist/index.js +210 -43
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +210 -43
  7. package/dist/index.mjs.map +1 -1
  8. package/dist/internal/index.js +1 -1
  9. package/dist/internal/index.mjs +1 -1
  10. package/docs/04-ai-sdk-ui/02-chatbot.mdx +10 -1
  11. package/docs/04-ai-sdk-ui/03-chatbot-message-persistence.mdx +8 -0
  12. package/docs/04-ai-sdk-ui/03-chatbot-resume-streams.mdx +10 -3
  13. package/docs/04-ai-sdk-ui/03-chatbot-tool-usage.mdx +10 -1
  14. package/docs/07-reference/01-ai-sdk-core/02-stream-text.mdx +1 -1
  15. package/docs/07-reference/01-ai-sdk-core/17-create-agent-ui-stream.mdx +3 -3
  16. package/docs/07-reference/01-ai-sdk-core/18-create-agent-ui-stream-response.mdx +2 -2
  17. package/docs/07-reference/01-ai-sdk-core/18-pipe-agent-ui-stream-to-response.mdx +3 -3
  18. package/docs/07-reference/02-ai-sdk-ui/41-create-ui-message-stream-response.mdx +7 -0
  19. package/docs/07-reference/02-ai-sdk-ui/42-pipe-ui-message-stream-to-response.mdx +7 -0
  20. package/package.json +2 -2
  21. package/src/agent/create-agent-ui-stream-response.ts +5 -2
  22. package/src/agent/create-agent-ui-stream.ts +5 -3
  23. package/src/agent/pipe-agent-ui-stream-to-response.ts +5 -2
  24. package/src/embed/embed-many.ts +5 -3
  25. package/src/generate-image/generate-image.ts +7 -2
  26. package/src/generate-text/smooth-stream.ts +24 -9
  27. package/src/generate-text/stream-text-result.ts +5 -0
  28. package/src/generate-text/stream-text.ts +4 -1
  29. package/src/generate-video/generate-video.ts +6 -4
  30. package/src/registry/provider-registry.ts +1 -1
  31. package/src/ui/chat.ts +13 -4
  32. package/src/ui/http-chat-transport.ts +27 -1
  33. package/src/ui/last-assistant-message-is-complete-with-tool-calls.ts +15 -3
  34. package/src/ui/process-ui-message-stream.ts +59 -18
  35. package/src/ui/ui-messages.ts +14 -0
  36. package/src/ui/validate-ui-messages.ts +2 -0
  37. package/src/ui-message-stream/create-sse-stream-with-keep-alive.ts +89 -0
  38. package/src/ui-message-stream/create-ui-message-stream-response.ts +7 -1
  39. package/src/ui-message-stream/pipe-ui-message-stream-to-response.ts +7 -1
  40. package/src/ui-message-stream/ui-message-stream-response-init.ts +7 -0
  41. package/src/util/get-own.ts +18 -0
  42. package/src/util/set-own.ts +16 -0
package/dist/index.js CHANGED
@@ -1334,7 +1334,7 @@ function detectMediaType({
1334
1334
  var import_provider_utils3 = require("@ai-sdk/provider-utils");
1335
1335
 
1336
1336
  // src/version.ts
1337
- var VERSION = true ? "6.0.295" : "0.0.0-test";
1337
+ var VERSION = true ? "6.0.297" : "0.0.0-test";
1338
1338
 
1339
1339
  // src/util/download/download.ts
1340
1340
  var download = async ({
@@ -5712,6 +5712,75 @@ function pipeTextStreamToResponse({
5712
5712
  });
5713
5713
  }
5714
5714
 
5715
+ // src/ui-message-stream/create-sse-stream-with-keep-alive.ts
5716
+ var STREAM_OPEN_COMMENT = ": stream-open\n\n";
5717
+ var KEEP_ALIVE_COMMENT = ": keep-alive\n\n";
5718
+ function createSseStreamWithKeepAlive({
5719
+ stream,
5720
+ keepAliveMs
5721
+ }) {
5722
+ if (keepAliveMs == null) {
5723
+ return stream;
5724
+ }
5725
+ if (!Number.isFinite(keepAliveMs) || keepAliveMs <= 0 || keepAliveMs > 2147483647) {
5726
+ throw new Error(
5727
+ "keepAliveMs must be a positive finite timer duration no greater than 2147483647"
5728
+ );
5729
+ }
5730
+ const reader = stream.getReader();
5731
+ let keepAliveTimeout;
5732
+ let isCancelled = false;
5733
+ const clearKeepAliveTimeout = () => {
5734
+ clearTimeout(keepAliveTimeout);
5735
+ keepAliveTimeout = void 0;
5736
+ };
5737
+ const scheduleKeepAlive = (controller) => {
5738
+ clearKeepAliveTimeout();
5739
+ keepAliveTimeout = setTimeout(() => {
5740
+ if (isCancelled) {
5741
+ return;
5742
+ }
5743
+ if (controller.desiredSize != null && controller.desiredSize > 0) {
5744
+ controller.enqueue(KEEP_ALIVE_COMMENT);
5745
+ }
5746
+ scheduleKeepAlive(controller);
5747
+ }, keepAliveMs);
5748
+ };
5749
+ return new ReadableStream({
5750
+ start(controller) {
5751
+ controller.enqueue(STREAM_OPEN_COMMENT);
5752
+ scheduleKeepAlive(controller);
5753
+ },
5754
+ pull(controller) {
5755
+ return reader.read().then(
5756
+ (result) => {
5757
+ clearKeepAliveTimeout();
5758
+ if (isCancelled) {
5759
+ return;
5760
+ }
5761
+ if (result.done) {
5762
+ controller.close();
5763
+ } else {
5764
+ controller.enqueue(result.value);
5765
+ scheduleKeepAlive(controller);
5766
+ }
5767
+ },
5768
+ (error) => {
5769
+ clearKeepAliveTimeout();
5770
+ if (!isCancelled) {
5771
+ throw error;
5772
+ }
5773
+ }
5774
+ );
5775
+ },
5776
+ async cancel(reason) {
5777
+ isCancelled = true;
5778
+ clearKeepAliveTimeout();
5779
+ await reader.cancel(reason);
5780
+ }
5781
+ });
5782
+ }
5783
+
5715
5784
  // src/ui-message-stream/json-to-sse-transform-stream.ts
5716
5785
  var JsonToSseTransformStream = class extends TransformStream {
5717
5786
  constructor() {
@@ -5744,9 +5813,13 @@ function createUIMessageStreamResponse({
5744
5813
  statusText,
5745
5814
  headers,
5746
5815
  stream,
5816
+ keepAliveMs,
5747
5817
  consumeSseStream
5748
5818
  }) {
5749
- let sseStream = stream.pipeThrough(new JsonToSseTransformStream());
5819
+ let sseStream = createSseStreamWithKeepAlive({
5820
+ stream: stream.pipeThrough(new JsonToSseTransformStream()),
5821
+ keepAliveMs
5822
+ });
5750
5823
  if (consumeSseStream) {
5751
5824
  const [stream1, stream2] = sseStream.tee();
5752
5825
  sseStream = stream1;
@@ -5998,16 +6071,43 @@ function createStreamingUIMessageState({
5998
6071
  lastMessage,
5999
6072
  messageId
6000
6073
  }) {
6074
+ var _a23;
6075
+ const message = (lastMessage == null ? void 0 : lastMessage.role) === "assistant" ? lastMessage : {
6076
+ id: messageId,
6077
+ metadata: void 0,
6078
+ role: "assistant",
6079
+ parts: []
6080
+ };
6081
+ const partialToolCalls = createIdMap();
6082
+ const lastStepStartIndex = message.parts.findLastIndex(
6083
+ (part) => part.type === "step-start"
6084
+ );
6085
+ let staticToolIndex = 0;
6086
+ for (const part of message.parts.slice(lastStepStartIndex + 1)) {
6087
+ if (!isToolUIPart(part)) {
6088
+ continue;
6089
+ }
6090
+ const index = staticToolIndex;
6091
+ if (isStaticToolUIPart(part)) {
6092
+ staticToolIndex++;
6093
+ }
6094
+ if (part.state !== "input-streaming") {
6095
+ continue;
6096
+ }
6097
+ partialToolCalls[part.toolCallId] = {
6098
+ text: (_a23 = part.rawInput) != null ? _a23 : "",
6099
+ index,
6100
+ toolName: part.type === "dynamic-tool" ? part.toolName : getStaticToolName(part),
6101
+ dynamic: part.type === "dynamic-tool",
6102
+ title: part.title,
6103
+ toolMetadata: part.toolMetadata
6104
+ };
6105
+ }
6001
6106
  return {
6002
- message: (lastMessage == null ? void 0 : lastMessage.role) === "assistant" ? lastMessage : {
6003
- id: messageId,
6004
- metadata: void 0,
6005
- role: "assistant",
6006
- parts: []
6007
- },
6107
+ message,
6008
6108
  activeTextParts: createIdMap(),
6009
6109
  activeReasoningParts: createIdMap(),
6010
- partialToolCalls: createIdMap()
6110
+ partialToolCalls
6011
6111
  };
6012
6112
  }
6013
6113
  function processUIMessageStream({
@@ -6023,7 +6123,7 @@ function processUIMessageStream({
6023
6123
  new TransformStream({
6024
6124
  async transform(chunk, controller) {
6025
6125
  await runUpdateMessageJob(async ({ state, write }) => {
6026
- var _a23, _b, _c, _d;
6126
+ var _a23, _b, _c, _d, _e, _f, _g, _h;
6027
6127
  function getCurrentStepParts() {
6028
6128
  const parts = state.message.parts;
6029
6129
  let currentStepStartIndex = parts.length - 1;
@@ -6108,7 +6208,7 @@ function processUIMessageStream({
6108
6208
  }
6109
6209
  }
6110
6210
  function updateDynamicToolPart(options, existingPart) {
6111
- var _a24, _b2;
6211
+ var _a24;
6112
6212
  const part = existingPart != null ? existingPart : getCurrentStepParts().find(
6113
6213
  (part2) => part2.type === "dynamic-tool" && part2.toolCallId === options.toolCallId
6114
6214
  );
@@ -6120,7 +6220,7 @@ function processUIMessageStream({
6120
6220
  anyPart.input = anyOptions.input;
6121
6221
  anyPart.output = anyOptions.output;
6122
6222
  anyPart.errorText = anyOptions.errorText;
6123
- anyPart.rawInput = (_a24 = anyOptions.rawInput) != null ? _a24 : anyPart.rawInput;
6223
+ anyPart.rawInput = anyOptions.rawInput;
6124
6224
  anyPart.preliminary = anyOptions.preliminary;
6125
6225
  if (options.title !== void 0) {
6126
6226
  anyPart.title = options.title;
@@ -6128,7 +6228,7 @@ function processUIMessageStream({
6128
6228
  if (options.toolMetadata !== void 0) {
6129
6229
  anyPart.toolMetadata = options.toolMetadata;
6130
6230
  }
6131
- anyPart.providerExecuted = (_b2 = anyOptions.providerExecuted) != null ? _b2 : part.providerExecuted;
6231
+ anyPart.providerExecuted = (_a24 = anyOptions.providerExecuted) != null ? _a24 : part.providerExecuted;
6132
6232
  const providerMetadata = anyOptions.providerMetadata;
6133
6233
  if (providerMetadata != null) {
6134
6234
  if (options.state === "output-available" || options.state === "output-error") {
@@ -6344,6 +6444,7 @@ function processUIMessageStream({
6344
6444
  toolName: partialToolCall.toolName,
6345
6445
  state: "input-streaming",
6346
6446
  input: partialArgs,
6447
+ rawInput: partialToolCall.text,
6347
6448
  title: partialToolCall.title,
6348
6449
  toolMetadata: partialToolCall.toolMetadata
6349
6450
  });
@@ -6353,6 +6454,7 @@ function processUIMessageStream({
6353
6454
  toolName: partialToolCall.toolName,
6354
6455
  state: "input-streaming",
6355
6456
  input: partialArgs,
6457
+ rawInput: partialToolCall.text,
6356
6458
  title: partialToolCall.title,
6357
6459
  toolMetadata: partialToolCall.toolMetadata
6358
6460
  });
@@ -6457,7 +6559,7 @@ function processUIMessageStream({
6457
6559
  providerExecuted: chunk.providerExecuted,
6458
6560
  providerMetadata: chunk.providerMetadata,
6459
6561
  title: toolInvocation.title,
6460
- toolMetadata: toolInvocation.toolMetadata
6562
+ toolMetadata: (_e = chunk.toolMetadata) != null ? _e : toolInvocation.toolMetadata
6461
6563
  },
6462
6564
  toolInvocation
6463
6565
  );
@@ -6473,7 +6575,7 @@ function processUIMessageStream({
6473
6575
  preliminary: chunk.preliminary,
6474
6576
  providerMetadata: chunk.providerMetadata,
6475
6577
  title: toolInvocation.title,
6476
- toolMetadata: toolInvocation.toolMetadata
6578
+ toolMetadata: (_f = chunk.toolMetadata) != null ? _f : toolInvocation.toolMetadata
6477
6579
  },
6478
6580
  toolInvocation
6479
6581
  );
@@ -6494,7 +6596,7 @@ function processUIMessageStream({
6494
6596
  providerExecuted: chunk.providerExecuted,
6495
6597
  providerMetadata: chunk.providerMetadata,
6496
6598
  title: toolInvocation.title,
6497
- toolMetadata: toolInvocation.toolMetadata
6599
+ toolMetadata: (_g = chunk.toolMetadata) != null ? _g : toolInvocation.toolMetadata
6498
6600
  },
6499
6601
  toolInvocation
6500
6602
  );
@@ -6510,7 +6612,7 @@ function processUIMessageStream({
6510
6612
  providerExecuted: chunk.providerExecuted,
6511
6613
  providerMetadata: chunk.providerMetadata,
6512
6614
  title: toolInvocation.title,
6513
- toolMetadata: toolInvocation.toolMetadata
6615
+ toolMetadata: (_h = chunk.toolMetadata) != null ? _h : toolInvocation.toolMetadata
6514
6616
  },
6515
6617
  toolInvocation
6516
6618
  );
@@ -6741,9 +6843,13 @@ function pipeUIMessageStreamToResponse({
6741
6843
  statusText,
6742
6844
  headers,
6743
6845
  stream,
6846
+ keepAliveMs,
6744
6847
  consumeSseStream
6745
6848
  }) {
6746
- let sseStream = stream.pipeThrough(new JsonToSseTransformStream());
6849
+ let sseStream = createSseStreamWithKeepAlive({
6850
+ stream: stream.pipeThrough(new JsonToSseTransformStream()),
6851
+ keepAliveMs
6852
+ });
6747
6853
  if (consumeSseStream) {
6748
6854
  const [stream1, stream2] = sseStream.tee();
6749
6855
  sseStream = stream1;
@@ -8905,7 +9011,7 @@ var DefaultStreamTextResult = class {
8905
9011
  sendStart = true,
8906
9012
  sendFinish = true,
8907
9013
  onError = () => "An error occurred."
8908
- // prevent leaking server error details to the client by default
9014
+ // masks errors except provider-executed tool execution errors
8909
9015
  } = {}) {
8910
9016
  let outcome = { status: "unknown" };
8911
9017
  let hasFatalFailure = false;
@@ -9943,6 +10049,7 @@ var uiMessagesSchema = (0, import_provider_utils24.lazySchema)(() => {
9943
10049
  toolMetadata: toolMetadataSchema2.optional(),
9944
10050
  state: import_v48.z.literal("input-streaming"),
9945
10051
  input: import_v48.z.unknown().optional(),
10052
+ rawInput: import_v48.z.string().optional(),
9946
10053
  providerExecuted: import_v48.z.boolean().optional(),
9947
10054
  callProviderMetadata: providerMetadataSchema.optional(),
9948
10055
  output: import_v48.z.never().optional(),
@@ -10039,6 +10146,7 @@ var uiMessagesSchema = (0, import_provider_utils24.lazySchema)(() => {
10039
10146
  providerExecuted: import_v48.z.boolean().optional(),
10040
10147
  callProviderMetadata: providerMetadataSchema.optional(),
10041
10148
  input: import_v48.z.unknown().optional(),
10149
+ rawInput: import_v48.z.string().optional(),
10042
10150
  output: import_v48.z.never().optional(),
10043
10151
  errorText: import_v48.z.never().optional(),
10044
10152
  approval: import_v48.z.never().optional()
@@ -10332,8 +10440,9 @@ async function createAgentUIStream({
10332
10440
  ...uiMessageStreamOptions
10333
10441
  }) {
10334
10442
  var _a23;
10443
+ const inputMessages = uiMessages != null ? uiMessages : uiMessageStreamOptions.originalMessages;
10335
10444
  const validatedMessages = await validateUIMessagesForAgent({
10336
- messages: uiMessages,
10445
+ messages: inputMessages,
10337
10446
  tools: agent.tools
10338
10447
  });
10339
10448
  const modelMessages = await convertToModelMessages(validatedMessages, {
@@ -10359,6 +10468,7 @@ async function createAgentUIStreamResponse({
10359
10468
  headers,
10360
10469
  status,
10361
10470
  statusText,
10471
+ keepAliveMs,
10362
10472
  consumeSseStream,
10363
10473
  ...options
10364
10474
  }) {
@@ -10366,6 +10476,7 @@ async function createAgentUIStreamResponse({
10366
10476
  headers,
10367
10477
  status,
10368
10478
  statusText,
10479
+ keepAliveMs,
10369
10480
  consumeSseStream,
10370
10481
  stream: await createAgentUIStream(options)
10371
10482
  });
@@ -10377,6 +10488,7 @@ async function pipeAgentUIStreamToResponse({
10377
10488
  headers,
10378
10489
  status,
10379
10490
  statusText,
10491
+ keepAliveMs,
10380
10492
  consumeSseStream,
10381
10493
  ...options
10382
10494
  }) {
@@ -10385,6 +10497,7 @@ async function pipeAgentUIStreamToResponse({
10385
10497
  headers,
10386
10498
  status,
10387
10499
  statusText,
10500
+ keepAliveMs,
10388
10501
  consumeSseStream,
10389
10502
  stream: await createAgentUIStream(options)
10390
10503
  });
@@ -10519,6 +10632,21 @@ var DefaultEmbedResult = class {
10519
10632
  }
10520
10633
  };
10521
10634
 
10635
+ // src/util/get-own.ts
10636
+ function getOwn(obj, key) {
10637
+ return obj != null && Object.hasOwn(obj, key) ? obj[key] : void 0;
10638
+ }
10639
+
10640
+ // src/util/set-own.ts
10641
+ function setOwn(object2, key, value) {
10642
+ Object.defineProperty(object2, key, {
10643
+ value,
10644
+ enumerable: true,
10645
+ configurable: true,
10646
+ writable: true
10647
+ });
10648
+ }
10649
+
10522
10650
  // src/embed/embed-many.ts
10523
10651
  var import_provider_utils28 = require("@ai-sdk/provider-utils");
10524
10652
 
@@ -10768,10 +10896,10 @@ async function embedMany({
10768
10896
  for (const [providerName, metadata] of Object.entries(
10769
10897
  result.providerMetadata
10770
10898
  )) {
10771
- providerMetadata[providerName] = {
10772
- ...providerMetadata[providerName],
10899
+ setOwn(providerMetadata, providerName, {
10900
+ ...getOwn(providerMetadata, providerName),
10773
10901
  ...metadata
10774
- };
10902
+ });
10775
10903
  }
10776
10904
  }
10777
10905
  }
@@ -10967,10 +11095,13 @@ async function generateImage({
10967
11095
  delete providerMetadata[providerName].images;
10968
11096
  }
10969
11097
  } else {
10970
- (_b = providerMetadata[providerName]) != null ? _b : providerMetadata[providerName] = { images: [] };
10971
- providerMetadata[providerName].images.push(
11098
+ const currentEntry = (_b = getOwn(providerMetadata, providerName)) != null ? _b : {
11099
+ images: []
11100
+ };
11101
+ currentEntry.images.push(
10972
11102
  ...result.providerMetadata[providerName].images
10973
11103
  );
11104
+ setOwn(providerMetadata, providerName, currentEntry);
10974
11105
  }
10975
11106
  }
10976
11107
  }
@@ -12737,21 +12868,32 @@ function smoothStream({
12737
12868
  controller.enqueue(chunk);
12738
12869
  return;
12739
12870
  }
12740
- if ((chunk.type !== type || chunk.id !== id) && (buffer.length > 0 || providerMetadata != null)) {
12871
+ if (chunk.text.length === 0 && chunk.providerMetadata != null) {
12872
+ flushBuffer(controller);
12873
+ controller.enqueue(chunk);
12874
+ return;
12875
+ }
12876
+ if (buffer.length > 0 && (chunk.type !== type || chunk.id !== id || providerMetadata != null || chunk.providerMetadata != null)) {
12741
12877
  flushBuffer(controller);
12742
12878
  }
12743
12879
  buffer += chunk.text;
12744
12880
  id = chunk.id;
12745
12881
  type = chunk.type;
12746
- if (chunk.providerMetadata != null) {
12747
- providerMetadata = chunk.providerMetadata;
12748
- }
12882
+ providerMetadata = chunk.providerMetadata;
12749
12883
  let match;
12750
12884
  while ((match = detectChunk(buffer)) != null) {
12751
- controller.enqueue({ type, text: match, id });
12885
+ controller.enqueue({
12886
+ type,
12887
+ text: match,
12888
+ id,
12889
+ ...providerMetadata != null ? { providerMetadata } : {}
12890
+ });
12752
12891
  buffer = buffer.slice(match.length);
12753
12892
  await delay(isDocumentHidden() ? null : delayInMs);
12754
12893
  }
12894
+ if (buffer.length === 0) {
12895
+ providerMetadata = void 0;
12896
+ }
12755
12897
  }
12756
12898
  });
12757
12899
  };
@@ -12903,12 +13045,12 @@ async function experimental_generateVideo({
12903
13045
  for (const [providerName, metadata] of Object.entries(
12904
13046
  result.providerMetadata
12905
13047
  )) {
12906
- const existingMetadata = providerMetadata[providerName];
13048
+ const existingMetadata = getOwn(providerMetadata, providerName);
12907
13049
  if (existingMetadata != null && typeof existingMetadata === "object") {
12908
- providerMetadata[providerName] = {
13050
+ setOwn(providerMetadata, providerName, {
12909
13051
  ...existingMetadata,
12910
13052
  ...metadata
12911
- };
13053
+ });
12912
13054
  if ("videos" in existingMetadata && Array.isArray(existingMetadata.videos) && "videos" in metadata && Array.isArray(metadata.videos)) {
12913
13055
  providerMetadata[providerName].videos = [
12914
13056
  ...existingMetadata.videos,
@@ -12916,7 +13058,7 @@ async function experimental_generateVideo({
12916
13058
  ];
12917
13059
  }
12918
13060
  } else {
12919
- providerMetadata[providerName] = metadata;
13061
+ setOwn(providerMetadata, providerName, metadata);
12920
13062
  }
12921
13063
  }
12922
13064
  }
@@ -13787,7 +13929,7 @@ var DefaultProviderRegistry = class {
13787
13929
  languageModelMiddleware,
13788
13930
  imageModelMiddleware
13789
13931
  }) {
13790
- this.providers = {};
13932
+ this.providers = /* @__PURE__ */ Object.create(null);
13791
13933
  this.separator = separator;
13792
13934
  this.languageModelMiddleware = languageModelMiddleware;
13793
13935
  this.imageModelMiddleware = imageModelMiddleware;
@@ -14296,6 +14438,10 @@ var import_provider_utils42 = require("@ai-sdk/provider-utils");
14296
14438
 
14297
14439
  // src/ui/http-chat-transport.ts
14298
14440
  var import_provider_utils41 = require("@ai-sdk/provider-utils");
14441
+ function appendPathToUrl(url, path) {
14442
+ const queryOrFragmentStart = url.search(/[?#]/);
14443
+ return queryOrFragmentStart === -1 ? `${url}${path}` : `${url.slice(0, queryOrFragmentStart)}${path}${url.slice(queryOrFragmentStart)}`;
14444
+ }
14299
14445
  var HttpChatTransport = class {
14300
14446
  constructor({
14301
14447
  api = "/api/chat",
@@ -14370,7 +14516,7 @@ var HttpChatTransport = class {
14370
14516
  return this.processResponseStream(response.body);
14371
14517
  }
14372
14518
  async reconnectToStream(options) {
14373
- var _a23, _b, _c, _d, _e;
14519
+ var _a23, _b, _c, _d;
14374
14520
  const resolvedBody = await (0, import_provider_utils41.resolve)(this.body);
14375
14521
  const resolvedHeaders = await (0, import_provider_utils41.resolve)(this.headers);
14376
14522
  const resolvedCredentials = await (0, import_provider_utils41.resolve)(this.credentials);
@@ -14386,10 +14532,23 @@ var HttpChatTransport = class {
14386
14532
  credentials: resolvedCredentials,
14387
14533
  requestMetadata: options.metadata
14388
14534
  }));
14389
- const api = (_b = preparedRequest == null ? void 0 : preparedRequest.api) != null ? _b : `${this.api}/${options.chatId}/stream`;
14535
+ let api = preparedRequest == null ? void 0 : preparedRequest.api;
14536
+ if (api == null) {
14537
+ if (options.chatId === "." || options.chatId === "..") {
14538
+ throw new InvalidArgumentError({
14539
+ parameter: "chatId",
14540
+ value: options.chatId,
14541
+ message: 'Chat IDs must not be "." or ".." when using the default reconnect URL.'
14542
+ });
14543
+ }
14544
+ api = appendPathToUrl(
14545
+ this.api,
14546
+ `/${encodeURIComponent(options.chatId)}/stream`
14547
+ );
14548
+ }
14390
14549
  const headers = (preparedRequest == null ? void 0 : preparedRequest.headers) !== void 0 ? (0, import_provider_utils41.normalizeHeaders)(preparedRequest.headers) : baseHeaders;
14391
- const credentials = (_c = preparedRequest == null ? void 0 : preparedRequest.credentials) != null ? _c : resolvedCredentials;
14392
- const fetch2 = (_d = this.fetch) != null ? _d : globalThis.fetch;
14550
+ const credentials = (_b = preparedRequest == null ? void 0 : preparedRequest.credentials) != null ? _b : resolvedCredentials;
14551
+ const fetch2 = (_c = this.fetch) != null ? _c : globalThis.fetch;
14393
14552
  const response = await fetch2(api, {
14394
14553
  method: "GET",
14395
14554
  headers,
@@ -14401,7 +14560,7 @@ var HttpChatTransport = class {
14401
14560
  }
14402
14561
  if (!response.ok) {
14403
14562
  throw new Error(
14404
- (_e = await response.text()) != null ? _e : "Failed to fetch the chat response."
14563
+ (_d = await response.text()) != null ? _d : "Failed to fetch the chat response."
14405
14564
  );
14406
14565
  }
14407
14566
  if (!response.body) {
@@ -14796,6 +14955,9 @@ var AbstractChat = class {
14796
14955
  const lastMessage = this.lastMessage;
14797
14956
  const responseMessageIndex = trigger === "submit-message" && messageId != null ? this.state.messages.findIndex((message) => message.id === messageId) : this.state.messages.length - 1;
14798
14957
  const responseMessage = responseMessageIndex === -1 ? lastMessage : this.state.messages[responseMessageIndex];
14958
+ const resumableResponseMessage = trigger === "resume-stream" && (responseMessage == null ? void 0 : responseMessage.role) === "assistant" && responseMessage.parts.some(
14959
+ (part) => isToolUIPart(part) && part.state === "input-streaming"
14960
+ ) ? this.state.snapshot(responseMessage) : void 0;
14799
14961
  const usesEarlierAssistantMessage = responseMessageIndex !== -1 && responseMessageIndex < this.state.messages.length - 1 && (responseMessage == null ? void 0 : responseMessage.role) === "assistant";
14800
14962
  let isAbort = false;
14801
14963
  let isDisconnect = false;
@@ -14804,7 +14966,7 @@ var AbstractChat = class {
14804
14966
  try {
14805
14967
  const response = {
14806
14968
  state: trigger === "resume-stream" && this.resumableStreamState != null ? this.resumableStreamState : createStreamingUIMessageState({
14807
- lastMessage: trigger === "resume-stream" || trigger === "regenerate-message" ? void 0 : this.state.snapshot(responseMessage),
14969
+ lastMessage: trigger === "resume-stream" ? resumableResponseMessage : trigger === "regenerate-message" ? void 0 : this.state.snapshot(responseMessage),
14808
14970
  messageId: this.generateId()
14809
14971
  }),
14810
14972
  abortController
@@ -15030,8 +15192,13 @@ function lastAssistantMessageIsCompleteWithToolCalls({
15030
15192
  const lastStepStartIndex = message.parts.reduce((lastIndex, part, index) => {
15031
15193
  return part.type === "step-start" ? index : lastIndex;
15032
15194
  }, -1);
15033
- const lastStepToolInvocations = message.parts.slice(lastStepStartIndex + 1).filter(isToolUIPart).filter((part) => !part.providerExecuted);
15034
- return lastStepToolInvocations.length > 0 && lastStepToolInvocations.every(
15195
+ const lastStepParts = message.parts.slice(lastStepStartIndex + 1);
15196
+ const lastStepToolInvocations = lastStepParts.filter(isToolUIPart).filter((part) => !part.providerExecuted);
15197
+ const lastToolInvocationIndex = lastStepParts.reduce(
15198
+ (lastIndex, part, index) => isToolUIPart(part) && !part.providerExecuted ? index : lastIndex,
15199
+ -1
15200
+ );
15201
+ return lastStepToolInvocations.length > 0 && !lastStepParts.slice(lastToolInvocationIndex + 1).some((part) => part.type === "text" && part.state !== "done") && lastStepToolInvocations.every(
15035
15202
  (part) => part.state === "output-available" && part.preliminary !== true || part.state === "output-error"
15036
15203
  );
15037
15204
  }