ai 5.0.273 → 5.0.275

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,30 @@
1
1
  # ai
2
2
 
3
+ ## 5.0.275
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [7c28815]
8
+ - Updated dependencies [66941b0]
9
+ - @ai-sdk/gateway@2.0.166
10
+
11
+ ## 5.0.274
12
+
13
+ ### Patch Changes
14
+
15
+ - f47f8e0: fix: resume interrupted chat streams when the page becomes visible again
16
+
17
+ `useChat` with `resume: true` no longer starts a second resume request on mount when the chat is already submitted or streaming, e.g. when remounting with a shared `Chat` instance mid-stream.
18
+
19
+ - ab0ecab: fix(ai): update tool outputs in the message containing the matching tool call
20
+ - dc561f0: fix(ai): prevent global type conflicts across SDK versions
21
+ - c060bd2: fix(ai): wait for chat stream cleanup when stopping
22
+ - dbf4338: fix(ai): update streaming chat messages by stable ID
23
+ - 99c9177: fix(ai): discard unrelated message state when reading resumed streams
24
+ - Updated dependencies [313a602]
25
+ - Updated dependencies [ae1ebda]
26
+ - @ai-sdk/gateway@2.0.165
27
+
3
28
  ## 5.0.273
4
29
 
5
30
  ### Patch Changes
package/dist/index.d.mts CHANGED
@@ -15,7 +15,15 @@ import { ServerResponse as ServerResponse$1 } from 'http';
15
15
  type Warning = LanguageModelV2CallWarning | ImageModelV2CallWarning | SpeechModelV2CallWarning | TranscriptionModelV2CallWarning;
16
16
  type LogWarningsFunction = (warnings: Warning[]) => void;
17
17
 
18
+ declare const aiSdkGlobalsKey: unique symbol;
18
19
  declare global {
20
+ interface AISDKGlobalTypes {
21
+ [aiSdkGlobalsKey]: {
22
+ provider: ProviderV2;
23
+ logWarnings: LogWarningsFunction;
24
+ telemetry: never;
25
+ };
26
+ }
19
27
  /**
20
28
  * The default provider to use for the AI SDK.
21
29
  * String model ids are resolved to the default provider and model id.
@@ -24,7 +32,7 @@ declare global {
24
32
  *
25
33
  * @see https://ai-sdk.dev/docs/ai-sdk-core/provider-management#global-provider-configuration
26
34
  */
27
- var AI_SDK_DEFAULT_PROVIDER: ProviderV2 | undefined;
35
+ var AI_SDK_DEFAULT_PROVIDER: AISDKGlobalTypes[keyof AISDKGlobalTypes]['provider'] | undefined;
28
36
  /**
29
37
  * The warning logger to use for the AI SDK.
30
38
  *
@@ -32,7 +40,7 @@ declare global {
32
40
  *
33
41
  * If set to false, no warnings are logged.
34
42
  */
35
- var AI_SDK_LOG_WARNINGS: LogWarningsFunction | undefined | false;
43
+ var AI_SDK_LOG_WARNINGS: AISDKGlobalTypes[keyof AISDKGlobalTypes]['logWarnings'] | undefined | false;
36
44
  }
37
45
 
38
46
  type CallSettings = {
@@ -3212,8 +3220,10 @@ type Job = () => Promise<void>;
3212
3220
  declare class SerialJobExecutor {
3213
3221
  private queue;
3214
3222
  private isProcessing;
3223
+ private idleWaiters;
3215
3224
  private processQueue;
3216
3225
  run(job: Job): Promise<void>;
3226
+ waitForIdle(): Promise<void>;
3217
3227
  }
3218
3228
 
3219
3229
  /**
@@ -4188,6 +4198,8 @@ declare abstract class AbstractChat<UI_MESSAGE extends UIMessage> {
4188
4198
  private activeResumeRequest;
4189
4199
  private resumableStreamState;
4190
4200
  private jobExecutor;
4201
+ private activeStopCount;
4202
+ private stopGeneration;
4191
4203
  constructor({ generateId, id, transport, messageMetadataSchema, dataPartSchemas, state, onError, onToolCall, onFinish, onData, sendAutomaticallyWhen, }: Omit<ChatInit<UI_MESSAGE>, 'messages'> & {
4192
4204
  state: ChatState<UI_MESSAGE>;
4193
4205
  });
@@ -4273,10 +4285,14 @@ declare abstract class AbstractChat<UI_MESSAGE extends UIMessage> {
4273
4285
  errorText: string;
4274
4286
  }) => Promise<void>;
4275
4287
  /**
4276
- * Abort the current request immediately, keep the generated tokens if any.
4288
+ * Abort the current request, keep the generated tokens if any, and wait for
4289
+ * the request pipeline to finish.
4277
4290
  */
4278
4291
  stop: () => Promise<void>;
4292
+ private shouldSendAutomatically;
4293
+ private runAutomaticRequest;
4279
4294
  private makeRequest;
4295
+ private makeRequestImpl;
4280
4296
  }
4281
4297
 
4282
4298
  declare function convertFileListToFileUIParts(files: FileList | undefined): Promise<Array<FileUIPart>>;
package/dist/index.d.ts CHANGED
@@ -15,7 +15,15 @@ import { ServerResponse as ServerResponse$1 } from 'http';
15
15
  type Warning = LanguageModelV2CallWarning | ImageModelV2CallWarning | SpeechModelV2CallWarning | TranscriptionModelV2CallWarning;
16
16
  type LogWarningsFunction = (warnings: Warning[]) => void;
17
17
 
18
+ declare const aiSdkGlobalsKey: unique symbol;
18
19
  declare global {
20
+ interface AISDKGlobalTypes {
21
+ [aiSdkGlobalsKey]: {
22
+ provider: ProviderV2;
23
+ logWarnings: LogWarningsFunction;
24
+ telemetry: never;
25
+ };
26
+ }
19
27
  /**
20
28
  * The default provider to use for the AI SDK.
21
29
  * String model ids are resolved to the default provider and model id.
@@ -24,7 +32,7 @@ declare global {
24
32
  *
25
33
  * @see https://ai-sdk.dev/docs/ai-sdk-core/provider-management#global-provider-configuration
26
34
  */
27
- var AI_SDK_DEFAULT_PROVIDER: ProviderV2 | undefined;
35
+ var AI_SDK_DEFAULT_PROVIDER: AISDKGlobalTypes[keyof AISDKGlobalTypes]['provider'] | undefined;
28
36
  /**
29
37
  * The warning logger to use for the AI SDK.
30
38
  *
@@ -32,7 +40,7 @@ declare global {
32
40
  *
33
41
  * If set to false, no warnings are logged.
34
42
  */
35
- var AI_SDK_LOG_WARNINGS: LogWarningsFunction | undefined | false;
43
+ var AI_SDK_LOG_WARNINGS: AISDKGlobalTypes[keyof AISDKGlobalTypes]['logWarnings'] | undefined | false;
36
44
  }
37
45
 
38
46
  type CallSettings = {
@@ -3212,8 +3220,10 @@ type Job = () => Promise<void>;
3212
3220
  declare class SerialJobExecutor {
3213
3221
  private queue;
3214
3222
  private isProcessing;
3223
+ private idleWaiters;
3215
3224
  private processQueue;
3216
3225
  run(job: Job): Promise<void>;
3226
+ waitForIdle(): Promise<void>;
3217
3227
  }
3218
3228
 
3219
3229
  /**
@@ -4188,6 +4198,8 @@ declare abstract class AbstractChat<UI_MESSAGE extends UIMessage> {
4188
4198
  private activeResumeRequest;
4189
4199
  private resumableStreamState;
4190
4200
  private jobExecutor;
4201
+ private activeStopCount;
4202
+ private stopGeneration;
4191
4203
  constructor({ generateId, id, transport, messageMetadataSchema, dataPartSchemas, state, onError, onToolCall, onFinish, onData, sendAutomaticallyWhen, }: Omit<ChatInit<UI_MESSAGE>, 'messages'> & {
4192
4204
  state: ChatState<UI_MESSAGE>;
4193
4205
  });
@@ -4273,10 +4285,14 @@ declare abstract class AbstractChat<UI_MESSAGE extends UIMessage> {
4273
4285
  errorText: string;
4274
4286
  }) => Promise<void>;
4275
4287
  /**
4276
- * Abort the current request immediately, keep the generated tokens if any.
4288
+ * Abort the current request, keep the generated tokens if any, and wait for
4289
+ * the request pipeline to finish.
4277
4290
  */
4278
4291
  stop: () => Promise<void>;
4292
+ private shouldSendAutomatically;
4293
+ private runAutomaticRequest;
4279
4294
  private makeRequest;
4295
+ private makeRequestImpl;
4280
4296
  }
4281
4297
 
4282
4298
  declare function convertFileListToFileUIParts(files: FileList | undefined): Promise<Array<FileUIPart>>;
package/dist/index.js CHANGED
@@ -817,7 +817,7 @@ function detectMediaType({
817
817
  var import_provider_utils2 = require("@ai-sdk/provider-utils");
818
818
 
819
819
  // src/version.ts
820
- var VERSION = true ? "5.0.273" : "0.0.0-test";
820
+ var VERSION = true ? "5.0.275" : "0.0.0-test";
821
821
 
822
822
  // src/util/download/download.ts
823
823
  var download = async ({
@@ -3818,7 +3818,8 @@ function processUIMessageStream({
3818
3818
  runUpdateMessageJob,
3819
3819
  onError,
3820
3820
  onToolCall,
3821
- onData
3821
+ onData,
3822
+ resetStateOnMessageIdChange = false
3822
3823
  }) {
3823
3824
  return stream.pipeThrough(
3824
3825
  new TransformStream({
@@ -4235,6 +4236,16 @@ function processUIMessageStream({
4235
4236
  break;
4236
4237
  }
4237
4238
  case "start": {
4239
+ if (resetStateOnMessageIdChange && chunk.messageId != null && chunk.messageId !== state.message.id) {
4240
+ Object.assign(
4241
+ state,
4242
+ createStreamingUIMessageState({
4243
+ lastMessage: void 0,
4244
+ messageId: chunk.messageId
4245
+ }),
4246
+ { finishReason: void 0 }
4247
+ );
4248
+ }
4238
4249
  if (chunk.messageId != null) {
4239
4250
  state.message.id = chunk.messageId;
4240
4251
  }
@@ -8036,17 +8047,24 @@ var SerialJobExecutor = class {
8036
8047
  constructor() {
8037
8048
  this.queue = [];
8038
8049
  this.isProcessing = false;
8050
+ this.idleWaiters = [];
8039
8051
  }
8040
8052
  async processQueue() {
8041
8053
  if (this.isProcessing) {
8042
8054
  return;
8043
8055
  }
8044
8056
  this.isProcessing = true;
8045
- while (this.queue.length > 0) {
8046
- await this.queue[0]();
8047
- this.queue.shift();
8057
+ try {
8058
+ while (this.queue.length > 0) {
8059
+ await this.queue[0]();
8060
+ this.queue.shift();
8061
+ }
8062
+ } finally {
8063
+ this.isProcessing = false;
8064
+ for (const resolve2 of this.idleWaiters.splice(0)) {
8065
+ resolve2();
8066
+ }
8048
8067
  }
8049
- this.isProcessing = false;
8050
8068
  }
8051
8069
  async run(job) {
8052
8070
  return new Promise((resolve2, reject) => {
@@ -8061,6 +8079,14 @@ var SerialJobExecutor = class {
8061
8079
  void this.processQueue();
8062
8080
  });
8063
8081
  }
8082
+ async waitForIdle() {
8083
+ if (!this.isProcessing && this.queue.length === 0) {
8084
+ return;
8085
+ }
8086
+ await new Promise((resolve2) => {
8087
+ this.idleWaiters.push(resolve2);
8088
+ });
8089
+ }
8064
8090
  };
8065
8091
 
8066
8092
  // src/util/simulate-readable-stream.ts
@@ -9980,6 +10006,8 @@ var AbstractChat = class {
9980
10006
  this.activeResumeRequest = void 0;
9981
10007
  this.resumableStreamState = void 0;
9982
10008
  this.jobExecutor = new SerialJobExecutor();
10009
+ this.activeStopCount = 0;
10010
+ this.stopGeneration = 0;
9983
10011
  /**
9984
10012
  * Appends or replaces a user message to the chat list. This triggers the API call to fetch
9985
10013
  * the assistant's response.
@@ -10070,6 +10098,27 @@ var AbstractChat = class {
10070
10098
  this.resumeStream = async (options = {}) => {
10071
10099
  await this.makeRequest({ trigger: "resume-stream", ...options });
10072
10100
  };
10101
+ /**
10102
+ * Resume the stream if the latest response ended with a resumable network
10103
+ * disconnect. If a response is still active, wait for it to settle first so
10104
+ * disconnects reported shortly after the caller's trigger are handled.
10105
+ *
10106
+ * @internal
10107
+ */
10108
+ this["~resumeStreamIfDisconnected"] = async ({
10109
+ shouldResume = () => true
10110
+ } = {}) => {
10111
+ const activeResponse = this.activeResponse;
10112
+ if (this.resumableStreamState == null && activeResponse != null) {
10113
+ await activeResponse.completionPromise;
10114
+ if (this.resumableStreamState !== activeResponse.state) {
10115
+ return;
10116
+ }
10117
+ }
10118
+ if (this.resumableStreamState != null && shouldResume()) {
10119
+ await this.resumeStream();
10120
+ }
10121
+ };
10073
10122
  /**
10074
10123
  * Clear the error state and set the status to ready if the chat is in an error state.
10075
10124
  */
@@ -10086,15 +10135,21 @@ var AbstractChat = class {
10086
10135
  output,
10087
10136
  errorText
10088
10137
  }) => this.jobExecutor.run(async () => {
10089
- var _a16, _b;
10090
10138
  const messages = this.state.messages;
10091
- const lastMessage = messages[messages.length - 1];
10092
- this.state.replaceMessage(messages.length - 1, {
10093
- ...lastMessage,
10094
- parts: lastMessage.parts.map(
10095
- (part) => isToolOrDynamicToolUIPart(part) && part.toolCallId === toolCallId ? { ...part, state, output, errorText } : part
10139
+ const messageIndex = messages.findIndex(
10140
+ (message) => message.parts.some(
10141
+ (part) => isToolOrDynamicToolUIPart(part) && part.toolCallId === toolCallId
10096
10142
  )
10097
- });
10143
+ );
10144
+ if (messageIndex !== -1) {
10145
+ const message = messages[messageIndex];
10146
+ this.state.replaceMessage(messageIndex, {
10147
+ ...message,
10148
+ parts: message.parts.map(
10149
+ (part) => isToolOrDynamicToolUIPart(part) && part.toolCallId === toolCallId ? { ...part, state, output, errorText } : part
10150
+ )
10151
+ });
10152
+ }
10098
10153
  if (this.activeResponse) {
10099
10154
  this.activeResponse.state.message.parts = this.activeResponse.state.message.parts.map(
10100
10155
  (part) => isToolOrDynamicToolUIPart(part) && part.toolCallId === toolCallId ? {
@@ -10105,22 +10160,41 @@ var AbstractChat = class {
10105
10160
  } : part
10106
10161
  );
10107
10162
  }
10108
- if (this.status !== "streaming" && this.status !== "submitted" && ((_a16 = this.sendAutomaticallyWhen) == null ? void 0 : _a16.call(this, { messages: this.state.messages }))) {
10109
- this.makeRequest({
10110
- trigger: "submit-message",
10111
- messageId: (_b = this.lastMessage) == null ? void 0 : _b.id
10112
- });
10163
+ if (messageIndex !== -1 && this.status !== "streaming" && this.status !== "submitted" && this.sendAutomaticallyWhen) {
10164
+ const shouldSend = await this.shouldSendAutomatically();
10165
+ if (shouldSend) {
10166
+ void this.runAutomaticRequest(
10167
+ () => this.makeRequest({
10168
+ trigger: "submit-message",
10169
+ messageId: messages[messageIndex].id
10170
+ }),
10171
+ shouldSend
10172
+ );
10173
+ }
10113
10174
  }
10114
10175
  });
10115
10176
  /** @deprecated Use addToolOutput */
10116
10177
  this.addToolResult = this.addToolOutput;
10117
10178
  /**
10118
- * Abort the current request immediately, keep the generated tokens if any.
10179
+ * Abort the current request, keep the generated tokens if any, and wait for
10180
+ * the request pipeline to finish.
10119
10181
  */
10120
10182
  this.stop = async () => {
10121
- var _a16, _b;
10122
- (_a16 = this.activeResumeRequest) == null ? void 0 : _a16.abortController.abort();
10123
- (_b = this.activeResponse) == null ? void 0 : _b.abortController.abort();
10183
+ this.activeStopCount++;
10184
+ this.stopGeneration++;
10185
+ try {
10186
+ const activeResumeRequest = this.activeResumeRequest;
10187
+ const activeResponse = this.activeResponse;
10188
+ activeResumeRequest == null ? void 0 : activeResumeRequest.abortController.abort();
10189
+ activeResponse == null ? void 0 : activeResponse.abortController.abort();
10190
+ await Promise.all([
10191
+ activeResumeRequest == null ? void 0 : activeResumeRequest.completionPromise,
10192
+ activeResponse == null ? void 0 : activeResponse.completionPromise
10193
+ ]);
10194
+ await this.jobExecutor.waitForIdle();
10195
+ } finally {
10196
+ this.activeStopCount--;
10197
+ }
10124
10198
  };
10125
10199
  this.id = id;
10126
10200
  this.transport = transport;
@@ -10166,19 +10240,53 @@ var AbstractChat = class {
10166
10240
  set messages(messages) {
10167
10241
  this.state.messages = messages;
10168
10242
  }
10169
- async makeRequest({
10243
+ async shouldSendAutomatically() {
10244
+ if (!this.sendAutomaticallyWhen)
10245
+ return false;
10246
+ const result = this.sendAutomaticallyWhen({
10247
+ messages: this.state.messages
10248
+ });
10249
+ if (result && typeof result === "object" && "then" in result) {
10250
+ return await result;
10251
+ }
10252
+ return result;
10253
+ }
10254
+ async runAutomaticRequest(request, shouldSend) {
10255
+ const stopGeneration = this.stopGeneration;
10256
+ const startedWhileStopping = this.activeStopCount > 0;
10257
+ if (!(shouldSend != null ? shouldSend : await this.shouldSendAutomatically())) {
10258
+ return;
10259
+ }
10260
+ if (startedWhileStopping || stopGeneration !== this.stopGeneration || this.activeStopCount > 0) {
10261
+ return;
10262
+ }
10263
+ await request();
10264
+ }
10265
+ async makeRequest(options) {
10266
+ const completion = createResolvablePromise();
10267
+ try {
10268
+ await this.makeRequestImpl({
10269
+ ...options,
10270
+ completionPromise: completion.promise
10271
+ });
10272
+ } finally {
10273
+ completion.resolve();
10274
+ }
10275
+ }
10276
+ async makeRequestImpl({
10170
10277
  trigger,
10171
10278
  metadata,
10172
10279
  headers,
10173
10280
  body,
10174
- messageId
10281
+ messageId,
10282
+ completionPromise
10175
10283
  }) {
10176
- var _a16, _b, _c, _d;
10284
+ var _a16, _b;
10177
10285
  if (trigger !== "resume-stream") {
10178
10286
  this.resumableStreamState = void 0;
10179
10287
  }
10180
10288
  const abortController = new AbortController();
10181
- const activeResumeRequest = trigger === "resume-stream" ? { abortController } : void 0;
10289
+ const activeResumeRequest = trigger === "resume-stream" ? { abortController, completionPromise } : void 0;
10182
10290
  if (activeResumeRequest) {
10183
10291
  (_a16 = this.activeResumeRequest) == null ? void 0 : _a16.abortController.abort();
10184
10292
  this.activeResumeRequest = activeResumeRequest;
@@ -10191,9 +10299,13 @@ var AbstractChat = class {
10191
10299
  };
10192
10300
  this.setStatus({ status: "submitted", error: void 0 });
10193
10301
  const lastMessage = this.lastMessage;
10302
+ const responseMessageIndex = trigger === "submit-message" && messageId != null ? this.state.messages.findIndex((message) => message.id === messageId) : this.state.messages.length - 1;
10303
+ const responseMessage = responseMessageIndex === -1 ? lastMessage : this.state.messages[responseMessageIndex];
10304
+ const originalResponseMessageId = responseMessage == null ? void 0 : responseMessage.id;
10194
10305
  const resumableResponseMessage = trigger === "resume-stream" && (lastMessage == null ? void 0 : lastMessage.role) === "assistant" && lastMessage.parts.some(
10195
10306
  (part) => isToolOrDynamicToolUIPart(part) && part.state === "input-streaming"
10196
10307
  ) ? this.state.snapshot(lastMessage) : void 0;
10308
+ const usesEarlierAssistantMessage = responseMessageIndex !== -1 && responseMessageIndex < this.state.messages.length - 1 && (responseMessage == null ? void 0 : responseMessage.role) === "assistant";
10197
10309
  let isAbort = false;
10198
10310
  let isDisconnect = false;
10199
10311
  let isError = false;
@@ -10201,10 +10313,11 @@ var AbstractChat = class {
10201
10313
  try {
10202
10314
  const response = {
10203
10315
  state: trigger === "resume-stream" && this.resumableStreamState != null ? this.resumableStreamState : createStreamingUIMessageState({
10204
- lastMessage: trigger === "resume-stream" ? resumableResponseMessage : this.state.snapshot(lastMessage),
10316
+ lastMessage: trigger === "resume-stream" ? resumableResponseMessage : this.state.snapshot(responseMessage),
10205
10317
  messageId: this.generateId()
10206
10318
  }),
10207
- abortController
10319
+ abortController,
10320
+ completionPromise
10208
10321
  };
10209
10322
  activeResponse = response;
10210
10323
  response.abortController.signal.addEventListener("abort", () => {
@@ -10258,19 +10371,32 @@ var AbstractChat = class {
10258
10371
  return job({
10259
10372
  state: response.state,
10260
10373
  write: ({ updateStatus = true } = {}) => {
10261
- var _a17;
10262
10374
  if (response.abortController.signal.aborted) {
10263
10375
  return;
10264
10376
  }
10265
10377
  if (updateStatus) {
10266
10378
  this.setStatus({ status: "streaming" });
10267
10379
  }
10268
- const replaceLastMessage = response.state.message.id === ((_a17 = this.lastMessage) == null ? void 0 : _a17.id);
10269
- if (replaceLastMessage) {
10380
+ const existingMessageIndex = this.state.messages.findLastIndex(
10381
+ (message) => message.id === response.state.message.id
10382
+ );
10383
+ if (existingMessageIndex !== -1) {
10270
10384
  this.state.replaceMessage(
10271
- this.state.messages.length - 1,
10385
+ existingMessageIndex,
10272
10386
  response.state.message
10273
10387
  );
10388
+ } else if (usesEarlierAssistantMessage) {
10389
+ const originalMessageIndex = this.state.messages.findLastIndex(
10390
+ (message) => message.id === originalResponseMessageId
10391
+ );
10392
+ if (originalMessageIndex !== -1) {
10393
+ this.state.replaceMessage(
10394
+ originalMessageIndex,
10395
+ response.state.message
10396
+ );
10397
+ } else {
10398
+ this.state.pushMessage(response.state.message);
10399
+ }
10274
10400
  } else {
10275
10401
  this.state.pushMessage(response.state.message);
10276
10402
  }
@@ -10356,14 +10482,19 @@ var AbstractChat = class {
10356
10482
  clearActiveResumeRequest();
10357
10483
  }
10358
10484
  }
10359
- if (((_c = this.sendAutomaticallyWhen) == null ? void 0 : _c.call(this, { messages: this.state.messages })) && !isError) {
10360
- await this.makeRequest({
10361
- trigger: "submit-message",
10362
- messageId: (_d = this.lastMessage) == null ? void 0 : _d.id,
10363
- metadata,
10364
- headers,
10365
- body
10366
- });
10485
+ if (!isAbort && !isError) {
10486
+ await this.runAutomaticRequest(
10487
+ () => {
10488
+ var _a17;
10489
+ return this.makeRequest({
10490
+ trigger: "submit-message",
10491
+ messageId: (_a17 = this.lastMessage) == null ? void 0 : _a17.id,
10492
+ metadata,
10493
+ headers,
10494
+ body
10495
+ });
10496
+ }
10497
+ );
10367
10498
  }
10368
10499
  }
10369
10500
  };
@@ -10989,6 +11120,7 @@ function readUIMessageStream({
10989
11120
  consumeStream({
10990
11121
  stream: processUIMessageStream({
10991
11122
  stream,
11123
+ resetStateOnMessageIdChange: true,
10992
11124
  runUpdateMessageJob(job) {
10993
11125
  return job({
10994
11126
  state,