ai 5.0.22 → 5.0.24

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/dist/index.mjs CHANGED
@@ -3267,9 +3267,18 @@ async function parsePartialJson(jsonText) {
3267
3267
  function isToolUIPart(part) {
3268
3268
  return part.type.startsWith("tool-");
3269
3269
  }
3270
+ function isDynamicToolUIPart(part) {
3271
+ return part.type === "dynamic-tool";
3272
+ }
3273
+ function isToolOrDynamicToolUIPart(part) {
3274
+ return isToolUIPart(part) || isDynamicToolUIPart(part);
3275
+ }
3270
3276
  function getToolName(part) {
3271
3277
  return part.type.split("-").slice(1).join("-");
3272
3278
  }
3279
+ function getToolOrDynamicToolName(part) {
3280
+ return isDynamicToolUIPart(part) ? part.toolName : getToolName(part);
3281
+ }
3273
3282
 
3274
3283
  // src/ui/process-ui-message-stream.ts
3275
3284
  function createStreamingUIMessageState({
@@ -3762,6 +3771,23 @@ function handleUIMessageStreamFinish({
3762
3771
  await job({ state, write: () => {
3763
3772
  } });
3764
3773
  };
3774
+ let finishCalled = false;
3775
+ const callOnFinish = async () => {
3776
+ if (finishCalled || !onFinish) {
3777
+ return;
3778
+ }
3779
+ finishCalled = true;
3780
+ const isContinuation = state.message.id === (lastMessage == null ? void 0 : lastMessage.id);
3781
+ await onFinish({
3782
+ isAborted,
3783
+ isContinuation,
3784
+ responseMessage: state.message,
3785
+ messages: [
3786
+ ...isContinuation ? originalMessages.slice(0, -1) : originalMessages,
3787
+ state.message
3788
+ ]
3789
+ });
3790
+ };
3765
3791
  return processUIMessageStream({
3766
3792
  stream: idInjectedStream,
3767
3793
  runUpdateMessageJob,
@@ -3771,17 +3797,12 @@ function handleUIMessageStreamFinish({
3771
3797
  transform(chunk, controller) {
3772
3798
  controller.enqueue(chunk);
3773
3799
  },
3800
+ // @ts-expect-error cancel is still new and missing from types https://developer.mozilla.org/en-US/docs/Web/API/TransformStream#browser_compatibility
3801
+ async cancel() {
3802
+ await callOnFinish();
3803
+ },
3774
3804
  async flush() {
3775
- const isContinuation = state.message.id === (lastMessage == null ? void 0 : lastMessage.id);
3776
- await onFinish({
3777
- isAborted,
3778
- isContinuation,
3779
- responseMessage: state.message,
3780
- messages: [
3781
- ...isContinuation ? originalMessages.slice(0, -1) : originalMessages,
3782
- state.message
3783
- ]
3784
- });
3805
+ await callOnFinish();
3785
3806
  }
3786
3807
  })
3787
3808
  );
@@ -3816,12 +3837,57 @@ function pipeUIMessageStreamToResponse({
3816
3837
  // src/util/async-iterable-stream.ts
3817
3838
  function createAsyncIterableStream(source) {
3818
3839
  const stream = source.pipeThrough(new TransformStream());
3819
- stream[Symbol.asyncIterator] = () => {
3820
- const reader = stream.getReader();
3840
+ stream[Symbol.asyncIterator] = function() {
3841
+ const reader = this.getReader();
3842
+ let finished = false;
3843
+ async function cleanup(cancelStream) {
3844
+ var _a17;
3845
+ finished = true;
3846
+ try {
3847
+ if (cancelStream) {
3848
+ await ((_a17 = reader.cancel) == null ? void 0 : _a17.call(reader));
3849
+ }
3850
+ } finally {
3851
+ try {
3852
+ reader.releaseLock();
3853
+ } catch (e) {
3854
+ }
3855
+ }
3856
+ }
3821
3857
  return {
3858
+ /**
3859
+ * Reads the next chunk from the stream.
3860
+ * @returns A promise resolving to the next IteratorResult.
3861
+ */
3822
3862
  async next() {
3863
+ if (finished) {
3864
+ return { done: true, value: void 0 };
3865
+ }
3823
3866
  const { done, value } = await reader.read();
3824
- return done ? { done: true, value: void 0 } : { done: false, value };
3867
+ if (done) {
3868
+ await cleanup(true);
3869
+ return { done: true, value: void 0 };
3870
+ }
3871
+ return { done: false, value };
3872
+ },
3873
+ /**
3874
+ * Called on early exit (e.g., break from for-await).
3875
+ * Ensures the stream is cancelled and resources are released.
3876
+ * @returns A promise resolving to a completed IteratorResult.
3877
+ */
3878
+ async return() {
3879
+ await cleanup(true);
3880
+ return { done: true, value: void 0 };
3881
+ },
3882
+ /**
3883
+ * Called on early exit with error.
3884
+ * Ensures the stream is cancelled and resources are released, then rethrows the error.
3885
+ * @param err The error to throw.
3886
+ * @returns A promise that rejects with the provided error.
3887
+ */
3888
+ async throw(err) {
3889
+ await cleanup(true);
3890
+ throw err;
3825
3891
  }
3826
3892
  };
3827
3893
  };
@@ -9250,12 +9316,12 @@ var AbstractChat = class {
9250
9316
  this.state.replaceMessage(messages.length - 1, {
9251
9317
  ...lastMessage,
9252
9318
  parts: lastMessage.parts.map(
9253
- (part) => isToolUIPart(part) && part.toolCallId === toolCallId ? { ...part, state: "output-available", output } : part
9319
+ (part) => isToolOrDynamicToolUIPart(part) && part.toolCallId === toolCallId ? { ...part, state: "output-available", output } : part
9254
9320
  )
9255
9321
  });
9256
9322
  if (this.activeResponse) {
9257
9323
  this.activeResponse.state.message.parts = this.activeResponse.state.message.parts.map(
9258
- (part) => isToolUIPart(part) && part.toolCallId === toolCallId ? {
9324
+ (part) => isToolOrDynamicToolUIPart(part) && part.toolCallId === toolCallId ? {
9259
9325
  ...part,
9260
9326
  state: "output-available",
9261
9327
  output,
@@ -9439,7 +9505,7 @@ function convertToModelMessages(messages, options) {
9439
9505
  messages = messages.map((message) => ({
9440
9506
  ...message,
9441
9507
  parts: message.parts.filter(
9442
- (part) => !isToolUIPart(part) || part.state !== "input-streaming" && part.state !== "input-available"
9508
+ (part) => !isToolOrDynamicToolUIPart(part) || part.state !== "input-streaming" && part.state !== "input-available"
9443
9509
  )
9444
9510
  }));
9445
9511
  }
@@ -9518,12 +9584,7 @@ function convertToModelMessages(messages, options) {
9518
9584
  });
9519
9585
  } else if (part.type === "dynamic-tool") {
9520
9586
  const toolName = part.toolName;
9521
- if (part.state === "input-streaming") {
9522
- throw new MessageConversionError({
9523
- originalMessage: message,
9524
- message: `incomplete tool input is not supported: ${part.toolCallId}`
9525
- });
9526
- } else {
9587
+ if (part.state !== "input-streaming") {
9527
9588
  content.push({
9528
9589
  type: "tool-call",
9529
9590
  toolCallId: part.toolCallId,
@@ -9534,12 +9595,7 @@ function convertToModelMessages(messages, options) {
9534
9595
  }
9535
9596
  } else if (isToolUIPart(part)) {
9536
9597
  const toolName = getToolName(part);
9537
- if (part.state === "input-streaming") {
9538
- throw new MessageConversionError({
9539
- originalMessage: message,
9540
- message: `incomplete tool input is not supported: ${part.toolCallId}`
9541
- });
9542
- } else {
9598
+ if (part.state !== "input-streaming") {
9543
9599
  content.push({
9544
9600
  type: "tool-call",
9545
9601
  toolCallId: part.toolCallId,
@@ -9594,13 +9650,12 @@ function convertToModelMessages(messages, options) {
9594
9650
  };
9595
9651
  }
9596
9652
  default: {
9597
- throw new MessageConversionError({
9598
- originalMessage: message,
9599
- message: `Unsupported tool part state: ${toolPart.state}`
9600
- });
9653
+ return null;
9601
9654
  }
9602
9655
  }
9603
- })
9656
+ }).filter(
9657
+ (output) => output != null
9658
+ )
9604
9659
  });
9605
9660
  }
9606
9661
  block = [];
@@ -9646,7 +9701,7 @@ function lastAssistantMessageIsCompleteWithToolCalls({
9646
9701
  const lastStepStartIndex = message.parts.reduce((lastIndex, part, index) => {
9647
9702
  return part.type === "step-start" ? index : lastIndex;
9648
9703
  }, -1);
9649
- const lastStepToolInvocations = message.parts.slice(lastStepStartIndex + 1).filter((part) => isToolUIPart(part) || part.type === "dynamic-tool");
9704
+ const lastStepToolInvocations = message.parts.slice(lastStepStartIndex + 1).filter(isToolOrDynamicToolUIPart);
9650
9705
  return lastStepToolInvocations.length > 0 && lastStepToolInvocations.every((part) => part.state === "output-available");
9651
9706
  }
9652
9707
 
@@ -10111,8 +10166,10 @@ export {
10111
10166
  generateText,
10112
10167
  getTextFromDataUrl,
10113
10168
  getToolName,
10169
+ getToolOrDynamicToolName,
10114
10170
  hasToolCall,
10115
10171
  isDeepEqualData,
10172
+ isToolOrDynamicToolUIPart,
10116
10173
  isToolUIPart,
10117
10174
  jsonSchema2 as jsonSchema,
10118
10175
  lastAssistantMessageIsCompleteWithToolCalls,