ai 6.0.302 → 6.0.303

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,16 @@
1
1
  # ai
2
2
 
3
+ ## 6.0.303
4
+
5
+ ### Patch Changes
6
+
7
+ - c0350be: fix(ai): prevent global type conflicts across SDK versions
8
+ - 88aa201: fix(ai): wait for chat stream cleanup when stopping
9
+ - 8444abe: fix(ai): discard unrelated message state when reading resumed streams
10
+ - Updated dependencies [897cb0c]
11
+ - Updated dependencies [7719e88]
12
+ - @ai-sdk/gateway@3.0.212
13
+
3
14
  ## 6.0.302
4
15
 
5
16
  ### Patch Changes
package/dist/index.d.mts CHANGED
@@ -3305,7 +3305,15 @@ interface TelemetryIntegration {
3305
3305
  onFinish?: Listener<OnFinishEvent<ToolSet>>;
3306
3306
  }
3307
3307
 
3308
+ declare const aiSdkGlobalsKey: unique symbol;
3308
3309
  declare global {
3310
+ interface AISDKGlobalTypes {
3311
+ [aiSdkGlobalsKey]: {
3312
+ provider: ProviderV3;
3313
+ logWarnings: LogWarningsFunction;
3314
+ telemetry: TelemetryIntegration;
3315
+ };
3316
+ }
3309
3317
  /**
3310
3318
  * The default provider to use for the AI SDK.
3311
3319
  * String model ids are resolved to the default provider and model id.
@@ -3314,7 +3322,7 @@ declare global {
3314
3322
  *
3315
3323
  * @see https://ai-sdk.dev/docs/ai-sdk-core/provider-management#global-provider-configuration
3316
3324
  */
3317
- var AI_SDK_DEFAULT_PROVIDER: ProviderV3 | undefined;
3325
+ var AI_SDK_DEFAULT_PROVIDER: AISDKGlobalTypes[keyof AISDKGlobalTypes]['provider'] | undefined;
3318
3326
  /**
3319
3327
  * The warning logger to use for the AI SDK.
3320
3328
  *
@@ -3322,7 +3330,7 @@ declare global {
3322
3330
  *
3323
3331
  * If set to false, no warnings are logged.
3324
3332
  */
3325
- var AI_SDK_LOG_WARNINGS: LogWarningsFunction | undefined | false;
3333
+ var AI_SDK_LOG_WARNINGS: AISDKGlobalTypes[keyof AISDKGlobalTypes]['logWarnings'] | undefined | false;
3326
3334
  /**
3327
3335
  * Globally registered telemetry integrations for the AI SDK.
3328
3336
  *
@@ -3332,7 +3340,7 @@ declare global {
3332
3340
  * Prefer using `registerTelemetryIntegration()` from `'ai'` instead of
3333
3341
  * assigning this directly.
3334
3342
  */
3335
- var AI_SDK_TELEMETRY_INTEGRATIONS: TelemetryIntegration[] | undefined;
3343
+ var AI_SDK_TELEMETRY_INTEGRATIONS: Array<AISDKGlobalTypes[keyof AISDKGlobalTypes]['telemetry']> | undefined;
3336
3344
  }
3337
3345
 
3338
3346
  type ToolLoopAgentOnStepFinishCallback<TOOLS extends ToolSet = {}> = (stepResult: OnStepFinishEvent<TOOLS>) => Promise<void> | void;
@@ -3897,6 +3905,8 @@ declare abstract class AbstractChat<UI_MESSAGE extends UIMessage> {
3897
3905
  private activeResumeRequest;
3898
3906
  private resumableStreamState;
3899
3907
  private jobExecutor;
3908
+ private activeStopCount;
3909
+ private stopGeneration;
3900
3910
  constructor({ generateId, id, transport, messageMetadataSchema, dataPartSchemas, state, onError, onToolCall, onFinish, onData, sendAutomaticallyWhen, }: Omit<ChatInit<UI_MESSAGE>, 'messages'> & {
3901
3911
  state: ChatState<UI_MESSAGE>;
3902
3912
  });
@@ -3959,12 +3969,15 @@ declare abstract class AbstractChat<UI_MESSAGE extends UIMessage> {
3959
3969
  /** @deprecated Use addToolOutput */
3960
3970
  addToolResult: ChatAddToolOutputFunction<UI_MESSAGE>;
3961
3971
  /**
3962
- * Abort the current request immediately, keep the generated tokens if any.
3972
+ * Abort the current request, keep the generated tokens if any, and wait for
3973
+ * the request pipeline to finish.
3963
3974
  */
3964
3975
  stop: () => Promise<void>;
3965
3976
  private shouldSendAutomatically;
3977
+ private runAutomaticRequest;
3966
3978
  private makeRequestForToolApproval;
3967
3979
  private makeRequest;
3980
+ private makeRequestImpl;
3968
3981
  }
3969
3982
 
3970
3983
  declare function convertFileListToFileUIParts(files: FileList | undefined): Promise<Array<FileUIPart>>;
@@ -5484,8 +5497,10 @@ type Job = () => Promise<void>;
5484
5497
  declare class SerialJobExecutor {
5485
5498
  private queue;
5486
5499
  private isProcessing;
5500
+ private idleWaiters;
5487
5501
  private processQueue;
5488
5502
  run(job: Job): Promise<void>;
5503
+ waitForIdle(): Promise<void>;
5489
5504
  }
5490
5505
 
5491
5506
  /**
package/dist/index.d.ts CHANGED
@@ -3305,7 +3305,15 @@ interface TelemetryIntegration {
3305
3305
  onFinish?: Listener<OnFinishEvent<ToolSet>>;
3306
3306
  }
3307
3307
 
3308
+ declare const aiSdkGlobalsKey: unique symbol;
3308
3309
  declare global {
3310
+ interface AISDKGlobalTypes {
3311
+ [aiSdkGlobalsKey]: {
3312
+ provider: ProviderV3;
3313
+ logWarnings: LogWarningsFunction;
3314
+ telemetry: TelemetryIntegration;
3315
+ };
3316
+ }
3309
3317
  /**
3310
3318
  * The default provider to use for the AI SDK.
3311
3319
  * String model ids are resolved to the default provider and model id.
@@ -3314,7 +3322,7 @@ declare global {
3314
3322
  *
3315
3323
  * @see https://ai-sdk.dev/docs/ai-sdk-core/provider-management#global-provider-configuration
3316
3324
  */
3317
- var AI_SDK_DEFAULT_PROVIDER: ProviderV3 | undefined;
3325
+ var AI_SDK_DEFAULT_PROVIDER: AISDKGlobalTypes[keyof AISDKGlobalTypes]['provider'] | undefined;
3318
3326
  /**
3319
3327
  * The warning logger to use for the AI SDK.
3320
3328
  *
@@ -3322,7 +3330,7 @@ declare global {
3322
3330
  *
3323
3331
  * If set to false, no warnings are logged.
3324
3332
  */
3325
- var AI_SDK_LOG_WARNINGS: LogWarningsFunction | undefined | false;
3333
+ var AI_SDK_LOG_WARNINGS: AISDKGlobalTypes[keyof AISDKGlobalTypes]['logWarnings'] | undefined | false;
3326
3334
  /**
3327
3335
  * Globally registered telemetry integrations for the AI SDK.
3328
3336
  *
@@ -3332,7 +3340,7 @@ declare global {
3332
3340
  * Prefer using `registerTelemetryIntegration()` from `'ai'` instead of
3333
3341
  * assigning this directly.
3334
3342
  */
3335
- var AI_SDK_TELEMETRY_INTEGRATIONS: TelemetryIntegration[] | undefined;
3343
+ var AI_SDK_TELEMETRY_INTEGRATIONS: Array<AISDKGlobalTypes[keyof AISDKGlobalTypes]['telemetry']> | undefined;
3336
3344
  }
3337
3345
 
3338
3346
  type ToolLoopAgentOnStepFinishCallback<TOOLS extends ToolSet = {}> = (stepResult: OnStepFinishEvent<TOOLS>) => Promise<void> | void;
@@ -3897,6 +3905,8 @@ declare abstract class AbstractChat<UI_MESSAGE extends UIMessage> {
3897
3905
  private activeResumeRequest;
3898
3906
  private resumableStreamState;
3899
3907
  private jobExecutor;
3908
+ private activeStopCount;
3909
+ private stopGeneration;
3900
3910
  constructor({ generateId, id, transport, messageMetadataSchema, dataPartSchemas, state, onError, onToolCall, onFinish, onData, sendAutomaticallyWhen, }: Omit<ChatInit<UI_MESSAGE>, 'messages'> & {
3901
3911
  state: ChatState<UI_MESSAGE>;
3902
3912
  });
@@ -3959,12 +3969,15 @@ declare abstract class AbstractChat<UI_MESSAGE extends UIMessage> {
3959
3969
  /** @deprecated Use addToolOutput */
3960
3970
  addToolResult: ChatAddToolOutputFunction<UI_MESSAGE>;
3961
3971
  /**
3962
- * Abort the current request immediately, keep the generated tokens if any.
3972
+ * Abort the current request, keep the generated tokens if any, and wait for
3973
+ * the request pipeline to finish.
3963
3974
  */
3964
3975
  stop: () => Promise<void>;
3965
3976
  private shouldSendAutomatically;
3977
+ private runAutomaticRequest;
3966
3978
  private makeRequestForToolApproval;
3967
3979
  private makeRequest;
3980
+ private makeRequestImpl;
3968
3981
  }
3969
3982
 
3970
3983
  declare function convertFileListToFileUIParts(files: FileList | undefined): Promise<Array<FileUIPart>>;
@@ -5484,8 +5497,10 @@ type Job = () => Promise<void>;
5484
5497
  declare class SerialJobExecutor {
5485
5498
  private queue;
5486
5499
  private isProcessing;
5500
+ private idleWaiters;
5487
5501
  private processQueue;
5488
5502
  run(job: Job): Promise<void>;
5503
+ waitForIdle(): Promise<void>;
5489
5504
  }
5490
5505
 
5491
5506
  /**
package/dist/index.js CHANGED
@@ -1335,7 +1335,7 @@ function detectMediaType({
1335
1335
  var import_provider_utils3 = require("@ai-sdk/provider-utils");
1336
1336
 
1337
1337
  // src/version.ts
1338
- var VERSION = true ? "6.0.302" : "0.0.0-test";
1338
+ var VERSION = true ? "6.0.303" : "0.0.0-test";
1339
1339
 
1340
1340
  // src/util/download/download.ts
1341
1341
  var download = async ({
@@ -6124,7 +6124,8 @@ function processUIMessageStream({
6124
6124
  runUpdateMessageJob,
6125
6125
  onError,
6126
6126
  onToolCall,
6127
- onData
6127
+ onData,
6128
+ resetStateOnMessageIdChange = false
6128
6129
  }) {
6129
6130
  return stream.pipeThrough(
6130
6131
  new TransformStream({
@@ -6637,6 +6638,16 @@ function processUIMessageStream({
6637
6638
  break;
6638
6639
  }
6639
6640
  case "start": {
6641
+ if (resetStateOnMessageIdChange && chunk.messageId != null && chunk.messageId !== state.message.id) {
6642
+ Object.assign(
6643
+ state,
6644
+ createStreamingUIMessageState({
6645
+ lastMessage: void 0,
6646
+ messageId: chunk.messageId
6647
+ }),
6648
+ { finishReason: void 0 }
6649
+ );
6650
+ }
6640
6651
  if (chunk.messageId != null) {
6641
6652
  state.message.id = chunk.messageId;
6642
6653
  }
@@ -9691,6 +9702,7 @@ function readUIMessageStream({
9691
9702
  consumeStream({
9692
9703
  stream: processUIMessageStream({
9693
9704
  stream,
9705
+ resetStateOnMessageIdChange: true,
9694
9706
  runUpdateMessageJob(job) {
9695
9707
  return job({
9696
9708
  state,
@@ -11997,17 +12009,24 @@ var SerialJobExecutor = class {
11997
12009
  constructor() {
11998
12010
  this.queue = [];
11999
12011
  this.isProcessing = false;
12012
+ this.idleWaiters = [];
12000
12013
  }
12001
12014
  async processQueue() {
12002
12015
  if (this.isProcessing) {
12003
12016
  return;
12004
12017
  }
12005
12018
  this.isProcessing = true;
12006
- while (this.queue.length > 0) {
12007
- await this.queue[0]();
12008
- this.queue.shift();
12019
+ try {
12020
+ while (this.queue.length > 0) {
12021
+ await this.queue[0]();
12022
+ this.queue.shift();
12023
+ }
12024
+ } finally {
12025
+ this.isProcessing = false;
12026
+ for (const resolve3 of this.idleWaiters.splice(0)) {
12027
+ resolve3();
12028
+ }
12009
12029
  }
12010
- this.isProcessing = false;
12011
12030
  }
12012
12031
  async run(job) {
12013
12032
  return new Promise((resolve3, reject) => {
@@ -12022,6 +12041,14 @@ var SerialJobExecutor = class {
12022
12041
  void this.processQueue();
12023
12042
  });
12024
12043
  }
12044
+ async waitForIdle() {
12045
+ if (!this.isProcessing && this.queue.length === 0) {
12046
+ return;
12047
+ }
12048
+ await new Promise((resolve3) => {
12049
+ this.idleWaiters.push(resolve3);
12050
+ });
12051
+ }
12025
12052
  };
12026
12053
 
12027
12054
  // src/util/simulate-readable-stream.ts
@@ -14657,6 +14684,8 @@ var AbstractChat = class {
14657
14684
  this.activeResumeRequest = void 0;
14658
14685
  this.resumableStreamState = void 0;
14659
14686
  this.jobExecutor = new SerialJobExecutor();
14687
+ this.activeStopCount = 0;
14688
+ this.stopGeneration = 0;
14660
14689
  /**
14661
14690
  * Appends or replaces a user message to the chat list. This triggers the API call to fetch
14662
14691
  * the assistant's response.
@@ -14800,17 +14829,18 @@ var AbstractChat = class {
14800
14829
  this.activeResponse.state.message.parts = this.activeResponse.state.message.parts.map(updatePart);
14801
14830
  }
14802
14831
  if (this.status !== "streaming" && this.status !== "submitted" && this.sendAutomaticallyWhen) {
14803
- this.shouldSendAutomatically().then((shouldSend) => {
14804
- var _a23;
14805
- if (shouldSend) {
14832
+ const shouldSend = await this.shouldSendAutomatically();
14833
+ if (shouldSend) {
14834
+ void this.runAutomaticRequest(() => {
14835
+ var _a23;
14806
14836
  const messageId = messageIndex === -1 ? (_a23 = this.lastMessage) == null ? void 0 : _a23.id : messages[messageIndex].id;
14807
- this.makeRequestForToolApproval({
14837
+ return this.makeRequestForToolApproval({
14808
14838
  messageId,
14809
14839
  messageIndex,
14810
14840
  ...options
14811
14841
  });
14812
- }
14813
- });
14842
+ }, shouldSend);
14843
+ }
14814
14844
  }
14815
14845
  });
14816
14846
  this.addToolOutput = async ({
@@ -14831,27 +14861,44 @@ var AbstractChat = class {
14831
14861
  this.activeResponse.state.message.parts = this.activeResponse.state.message.parts.map(updatePart);
14832
14862
  }
14833
14863
  if (this.status !== "streaming" && this.status !== "submitted" && this.sendAutomaticallyWhen) {
14834
- this.shouldSendAutomatically().then((shouldSend) => {
14835
- var _a23;
14836
- if (shouldSend) {
14837
- this.makeRequest({
14838
- trigger: "submit-message",
14839
- messageId: (_a23 = this.lastMessage) == null ? void 0 : _a23.id,
14840
- ...options
14841
- });
14842
- }
14843
- });
14864
+ const shouldSend = await this.shouldSendAutomatically();
14865
+ if (shouldSend) {
14866
+ void this.runAutomaticRequest(
14867
+ () => {
14868
+ var _a23;
14869
+ return this.makeRequest({
14870
+ trigger: "submit-message",
14871
+ messageId: (_a23 = this.lastMessage) == null ? void 0 : _a23.id,
14872
+ ...options
14873
+ });
14874
+ },
14875
+ shouldSend
14876
+ );
14877
+ }
14844
14878
  }
14845
14879
  });
14846
14880
  /** @deprecated Use addToolOutput */
14847
14881
  this.addToolResult = this.addToolOutput;
14848
14882
  /**
14849
- * Abort the current request immediately, keep the generated tokens if any.
14883
+ * Abort the current request, keep the generated tokens if any, and wait for
14884
+ * the request pipeline to finish.
14850
14885
  */
14851
14886
  this.stop = async () => {
14852
- var _a23, _b;
14853
- (_a23 = this.activeResumeRequest) == null ? void 0 : _a23.abortController.abort();
14854
- (_b = this.activeResponse) == null ? void 0 : _b.abortController.abort();
14887
+ this.activeStopCount++;
14888
+ this.stopGeneration++;
14889
+ try {
14890
+ const activeResumeRequest = this.activeResumeRequest;
14891
+ const activeResponse = this.activeResponse;
14892
+ activeResumeRequest == null ? void 0 : activeResumeRequest.abortController.abort();
14893
+ activeResponse == null ? void 0 : activeResponse.abortController.abort();
14894
+ await Promise.all([
14895
+ activeResumeRequest == null ? void 0 : activeResumeRequest.completionPromise,
14896
+ activeResponse == null ? void 0 : activeResponse.completionPromise
14897
+ ]);
14898
+ await this.jobExecutor.waitForIdle();
14899
+ } finally {
14900
+ this.activeStopCount--;
14901
+ }
14855
14902
  };
14856
14903
  this.id = id;
14857
14904
  this.transport = transport;
@@ -14912,6 +14959,17 @@ var AbstractChat = class {
14912
14959
  }
14913
14960
  return result;
14914
14961
  }
14962
+ async runAutomaticRequest(request, shouldSend) {
14963
+ const stopGeneration = this.stopGeneration;
14964
+ const startedWhileStopping = this.activeStopCount > 0;
14965
+ if (!(shouldSend != null ? shouldSend : await this.shouldSendAutomatically())) {
14966
+ return;
14967
+ }
14968
+ if (startedWhileStopping || stopGeneration !== this.stopGeneration || this.activeStopCount > 0) {
14969
+ return;
14970
+ }
14971
+ await request();
14972
+ }
14915
14973
  async makeRequestForToolApproval({
14916
14974
  messageId,
14917
14975
  messageIndex,
@@ -14931,19 +14989,31 @@ var AbstractChat = class {
14931
14989
  this.pendingApprovalMessageId = (_b = (_a23 = this.state.messages[messageIndex]) == null ? void 0 : _a23.id) != null ? _b : messageId;
14932
14990
  }
14933
14991
  }
14934
- async makeRequest({
14992
+ async makeRequest(options) {
14993
+ const completion = createResolvablePromise();
14994
+ try {
14995
+ await this.makeRequestImpl({
14996
+ ...options,
14997
+ completionPromise: completion.promise
14998
+ });
14999
+ } finally {
15000
+ completion.resolve();
15001
+ }
15002
+ }
15003
+ async makeRequestImpl({
14935
15004
  trigger,
14936
15005
  metadata,
14937
15006
  headers,
14938
15007
  body,
14939
- messageId
15008
+ messageId,
15009
+ completionPromise
14940
15010
  }) {
14941
- var _a23, _b, _c;
15011
+ var _a23, _b;
14942
15012
  if (trigger !== "resume-stream") {
14943
15013
  this.resumableStreamState = void 0;
14944
15014
  }
14945
15015
  const abortController = new AbortController();
14946
- const activeResumeRequest = trigger === "resume-stream" ? { abortController } : void 0;
15016
+ const activeResumeRequest = trigger === "resume-stream" ? { abortController, completionPromise } : void 0;
14947
15017
  if (activeResumeRequest) {
14948
15018
  (_a23 = this.activeResumeRequest) == null ? void 0 : _a23.abortController.abort();
14949
15019
  this.activeResumeRequest = activeResumeRequest;
@@ -15019,7 +15089,8 @@ var AbstractChat = class {
15019
15089
  lastMessage: trigger === "resume-stream" ? resumableResponseMessage : trigger === "regenerate-message" ? void 0 : this.state.snapshot(responseMessage),
15020
15090
  messageId: this.generateId()
15021
15091
  }),
15022
- abortController
15092
+ abortController,
15093
+ completionPromise
15023
15094
  };
15024
15095
  activeResponse = response;
15025
15096
  response.abortController.signal.addEventListener("abort", () => {
@@ -15152,14 +15223,19 @@ var AbstractChat = class {
15152
15223
  clearActiveResumeRequest();
15153
15224
  }
15154
15225
  }
15155
- if (!isError && await this.shouldSendAutomatically()) {
15156
- await this.makeRequest({
15157
- trigger: "submit-message",
15158
- messageId: (_c = this.lastMessage) == null ? void 0 : _c.id,
15159
- metadata,
15160
- headers,
15161
- body
15162
- });
15226
+ if (!isAbort && !isError) {
15227
+ await this.runAutomaticRequest(
15228
+ () => {
15229
+ var _a24;
15230
+ return this.makeRequest({
15231
+ trigger: "submit-message",
15232
+ messageId: (_a24 = this.lastMessage) == null ? void 0 : _a24.id,
15233
+ metadata,
15234
+ headers,
15235
+ body
15236
+ });
15237
+ }
15238
+ );
15163
15239
  }
15164
15240
  }
15165
15241
  };