ai 6.0.293 → 6.0.295

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,22 @@
1
1
  # ai
2
2
 
3
+ ## 6.0.295
4
+
5
+ ### Patch Changes
6
+
7
+ - 0b38b6b: fix(ai): continue active UI message parts when resuming after a disconnect
8
+ - Updated dependencies [358683e]
9
+ - @ai-sdk/gateway@3.0.205
10
+
11
+ ## 6.0.294
12
+
13
+ ### Patch Changes
14
+
15
+ - 16a04d7: fix(ai): cancel response streams when clients disconnect
16
+ - Updated dependencies [29dc427]
17
+ - @ai-sdk/provider-utils@4.0.56
18
+ - @ai-sdk/gateway@3.0.204
19
+
3
20
  ## 6.0.293
4
21
 
5
22
  ### Patch Changes
package/dist/index.d.mts CHANGED
@@ -3862,6 +3862,7 @@ declare abstract class AbstractChat<UI_MESSAGE extends UIMessage> {
3862
3862
  private pendingApprovalMessageId;
3863
3863
  private activeResponse;
3864
3864
  private activeResumeRequest;
3865
+ private resumableStreamState;
3865
3866
  private jobExecutor;
3866
3867
  constructor({ generateId, id, transport, messageMetadataSchema, dataPartSchemas, state, onError, onToolCall, onFinish, onData, sendAutomaticallyWhen, }: Omit<ChatInit<UI_MESSAGE>, 'messages'> & {
3867
3868
  state: ChatState<UI_MESSAGE>;
package/dist/index.d.ts CHANGED
@@ -3862,6 +3862,7 @@ declare abstract class AbstractChat<UI_MESSAGE extends UIMessage> {
3862
3862
  private pendingApprovalMessageId;
3863
3863
  private activeResponse;
3864
3864
  private activeResumeRequest;
3865
+ private resumableStreamState;
3865
3866
  private jobExecutor;
3866
3867
  constructor({ generateId, id, transport, messageMetadataSchema, dataPartSchemas, state, onError, onToolCall, onFinish, onData, sendAutomaticallyWhen, }: Omit<ChatInit<UI_MESSAGE>, 'messages'> & {
3867
3868
  state: ChatState<UI_MESSAGE>;
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.293" : "0.0.0-test";
1337
+ var VERSION = true ? "6.0.295" : "0.0.0-test";
1338
1338
 
1339
1339
  // src/util/download/download.ts
1340
1340
  var download = async ({
@@ -5648,21 +5648,44 @@ function writeToServerResponse({
5648
5648
  response.writeHead(statusCode, headers);
5649
5649
  }
5650
5650
  const reader = stream.getReader();
5651
+ let clientDisconnected = false;
5652
+ let onDisconnect;
5653
+ const handleClose = () => {
5654
+ if (response.writableFinished) {
5655
+ return;
5656
+ }
5657
+ clientDisconnected = true;
5658
+ onDisconnect == null ? void 0 : onDisconnect();
5659
+ reader.cancel(new Error("Client disconnected.")).catch(() => {
5660
+ });
5661
+ };
5662
+ response.once("close", handleClose);
5663
+ if (response.destroyed) {
5664
+ handleClose();
5665
+ }
5651
5666
  const read = async () => {
5652
5667
  try {
5653
5668
  while (true) {
5654
5669
  const { done, value } = await reader.read();
5655
- if (done)
5670
+ if (done || clientDisconnected || response.destroyed)
5656
5671
  break;
5657
5672
  const canContinue = response.write(value);
5658
5673
  if (!canContinue) {
5659
5674
  await new Promise((resolve3) => {
5675
+ onDisconnect = resolve3;
5660
5676
  response.once("drain", resolve3);
5661
5677
  });
5678
+ onDisconnect = void 0;
5662
5679
  }
5663
5680
  }
5664
5681
  } finally {
5665
- response.end();
5682
+ response.off("close", handleClose);
5683
+ if (clientDisconnected || response.destroyed) {
5684
+ reader.cancel().catch(() => {
5685
+ });
5686
+ } else {
5687
+ response.end();
5688
+ }
5666
5689
  }
5667
5690
  };
5668
5691
  return read();
@@ -14427,6 +14450,7 @@ var AbstractChat = class {
14427
14450
  }) {
14428
14451
  this.activeResponse = void 0;
14429
14452
  this.activeResumeRequest = void 0;
14453
+ this.resumableStreamState = void 0;
14430
14454
  this.jobExecutor = new SerialJobExecutor();
14431
14455
  /**
14432
14456
  * Appends or replaces a user message to the chat list. This triggers the API call to fetch
@@ -14706,6 +14730,9 @@ var AbstractChat = class {
14706
14730
  messageId
14707
14731
  }) {
14708
14732
  var _a23, _b, _c;
14733
+ if (trigger !== "resume-stream") {
14734
+ this.resumableStreamState = void 0;
14735
+ }
14709
14736
  const abortController = new AbortController();
14710
14737
  const activeResumeRequest = trigger === "resume-stream" ? { abortController } : void 0;
14711
14738
  if (activeResumeRequest) {
@@ -14733,12 +14760,14 @@ var AbstractChat = class {
14733
14760
  }));
14734
14761
  if (isCurrentRequest()) {
14735
14762
  this.setStatus({ status: "ready" });
14763
+ this.resumableStreamState = void 0;
14736
14764
  }
14737
14765
  clearActiveResumeRequest();
14738
14766
  return;
14739
14767
  }
14740
14768
  if (reconnect == null) {
14741
14769
  this.setStatus({ status: "ready" });
14770
+ this.resumableStreamState = void 0;
14742
14771
  clearActiveResumeRequest();
14743
14772
  return;
14744
14773
  }
@@ -14747,6 +14776,7 @@ var AbstractChat = class {
14747
14776
  if (abortController.signal.aborted || err.name === "AbortError") {
14748
14777
  if (isCurrentRequest()) {
14749
14778
  this.setStatus({ status: "ready" });
14779
+ this.resumableStreamState = void 0;
14750
14780
  }
14751
14781
  clearActiveResumeRequest();
14752
14782
  return;
@@ -14773,7 +14803,7 @@ var AbstractChat = class {
14773
14803
  let activeResponse;
14774
14804
  try {
14775
14805
  const response = {
14776
- state: createStreamingUIMessageState({
14806
+ state: trigger === "resume-stream" && this.resumableStreamState != null ? this.resumableStreamState : createStreamingUIMessageState({
14777
14807
  lastMessage: trigger === "resume-stream" || trigger === "regenerate-message" ? void 0 : this.state.snapshot(responseMessage),
14778
14808
  messageId: this.generateId()
14779
14809
  }),
@@ -14852,17 +14882,26 @@ var AbstractChat = class {
14852
14882
  if (isAbort) {
14853
14883
  if (isCurrentRequest()) {
14854
14884
  this.setStatus({ status: "ready" });
14885
+ if (this.resumableStreamState === response.state) {
14886
+ this.resumableStreamState = void 0;
14887
+ }
14855
14888
  }
14856
14889
  return null;
14857
14890
  }
14858
14891
  if (isCurrentRequest()) {
14859
14892
  this.setStatus({ status: "ready" });
14893
+ if (this.resumableStreamState === response.state) {
14894
+ this.resumableStreamState = void 0;
14895
+ }
14860
14896
  }
14861
14897
  } catch (err) {
14862
14898
  if (isAbort || err.name === "AbortError") {
14863
14899
  isAbort = true;
14864
14900
  if (isCurrentRequest()) {
14865
14901
  this.setStatus({ status: "ready" });
14902
+ if (this.resumableStreamState === (activeResponse == null ? void 0 : activeResponse.state)) {
14903
+ this.resumableStreamState = void 0;
14904
+ }
14866
14905
  }
14867
14906
  return null;
14868
14907
  }
@@ -14873,6 +14912,11 @@ var AbstractChat = class {
14873
14912
  if (err instanceof TypeError && (err.message.toLowerCase().includes("fetch") || err.message.toLowerCase().includes("network"))) {
14874
14913
  isDisconnect = true;
14875
14914
  }
14915
+ if (isDisconnect) {
14916
+ this.resumableStreamState = activeResponse == null ? void 0 : activeResponse.state;
14917
+ } else if (this.resumableStreamState === (activeResponse == null ? void 0 : activeResponse.state)) {
14918
+ this.resumableStreamState = void 0;
14919
+ }
14876
14920
  if (this.onError && err instanceof Error) {
14877
14921
  this.onError(err);
14878
14922
  }