ai 7.0.107 → 7.0.109

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,28 @@
1
1
  # ai
2
2
 
3
+ ## 7.0.109
4
+
5
+ ### Patch Changes
6
+
7
+ - 0343bb1: fix(ai): keep replacement completion requests loading and cancellable when an earlier request settles
8
+ - 2b105fa: fix(ai): preserve overlapping text blocks in reasoning extraction streams
9
+ - 125f493: fix(harness): forward validated `toolsContext` to host-executed tools in alignment with `ToolLoopAgent`
10
+
11
+ ## 7.0.108
12
+
13
+ ### Patch Changes
14
+
15
+ - 3f6852a: fix(ai): prevent direct execution of tools governed by tool callers
16
+ - 6317504: fix(ai): stop pending tool-call repairs when generation is cancelled
17
+ - 3cb2dcd: fix(ai): preserve file data when adapting v3 language models
18
+ - ccf98e7: fix(ai): prevent `streamText` from executing tool calls that violate tool choice
19
+ - Updated dependencies [20dd00a]
20
+ - Updated dependencies [7cf7cee]
21
+ - Updated dependencies [c42576a]
22
+ - Updated dependencies [d85dcf5]
23
+ - Updated dependencies [fd9b3f3]
24
+ - @ai-sdk/gateway@4.0.88
25
+
3
26
  ## 7.0.107
4
27
 
5
28
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -3159,6 +3159,7 @@ declare class NoSuchToolError extends AISDKError {
3159
3159
  * @param options.tools - The tools that are available.
3160
3160
  * @param options.inputSchema - A function that returns the JSON Schema for a tool.
3161
3161
  * @param options.error - The error that occurred while parsing the tool call.
3162
+ * @param options.abortSignal - An optional signal for cancelling the repair.
3162
3163
  */
3163
3164
  type ToolCallRepairFunction<TOOLS extends ToolSet> = (options: {
3164
3165
  instructions: Instructions | undefined;
@@ -3173,6 +3174,7 @@ type ToolCallRepairFunction<TOOLS extends ToolSet> = (options: {
3173
3174
  toolName: string;
3174
3175
  }) => PromiseLike<JSONSchema7>;
3175
3176
  error: NoSuchToolError | InvalidToolInputError;
3177
+ abortSignal?: AbortSignal;
3176
3178
  }) => Promise<LanguageModelV4ToolCall | null>;
3177
3179
 
3178
3180
  type ToolOutput<TOOLS extends ToolSet> = TypedToolResult<TOOLS> | TypedToolError<TOOLS>;
@@ -3329,18 +3331,22 @@ type ToolInputRefinement<TOOLS extends ToolSet> = {
3329
3331
  */
3330
3332
  type IsEmptyObject<OBJECT> = keyof OBJECT extends never ? true : false;
3331
3333
  /**
3332
- * Helper type to make the toolsContext parameter optional, required, or
3333
- * unavailable based on the tool set.
3334
+ * Makes the toolsContext setting optional, required, or unavailable based on
3335
+ * the tool set.
3334
3336
  */
3335
- type ToolsContextParameter<TOOLS extends ToolSet> = {
3336
- tools?: TOOLS;
3337
- } & (IsEmptyObject<InferToolSetContext<TOOLS>> extends true ? {
3337
+ type ToolsContextSettings<TOOLS extends ToolSet> = IsEmptyObject<InferToolSetContext<TOOLS>> extends true ? {
3338
3338
  toolsContext?: never;
3339
3339
  } : HasRequiredKey<InferToolSetContext<TOOLS>> extends true ? {
3340
3340
  toolsContext: InferToolSetContext<TOOLS>;
3341
3341
  } : {
3342
3342
  toolsContext?: InferToolSetContext<TOOLS>;
3343
- });
3343
+ };
3344
+ /**
3345
+ * Helper type for request options that include both tools and their context.
3346
+ */
3347
+ type ToolsContextParameter<TOOLS extends ToolSet> = {
3348
+ tools?: TOOLS;
3349
+ } & ToolsContextSettings<TOOLS>;
3344
3350
 
3345
3351
  type StreamTextInclude = {
3346
3352
  /**
@@ -5397,7 +5403,7 @@ type UIMessageStreamOnStepEndCallback<UI_MESSAGE extends UIMessage> = (event: {
5397
5403
  type UIMessageStreamOnStepFinishCallback<UI_MESSAGE extends UIMessage> = UIMessageStreamOnStepEndCallback<UI_MESSAGE>;
5398
5404
 
5399
5405
  declare const getOriginalFetch: () => typeof fetch;
5400
- declare function callCompletionApi({ api, prompt, credentials, headers, body, streamProtocol, setCompletion, setLoading, setError, setAbortController, onFinish, onError, fetch, }: {
5406
+ declare function callCompletionApi({ api, prompt, credentials, headers, body, streamProtocol, setCompletion, setLoading, setError, setAbortController, getAbortController, onFinish, onError, fetch, }: {
5401
5407
  api: string;
5402
5408
  prompt: string;
5403
5409
  credentials: RequestCredentials | undefined;
@@ -5408,6 +5414,7 @@ declare function callCompletionApi({ api, prompt, credentials, headers, body, st
5408
5414
  setLoading: (loading: boolean) => void;
5409
5415
  setError: (error: Error | undefined) => void;
5410
5416
  setAbortController: (abortController: AbortController | null) => void;
5417
+ getAbortController?: () => AbortController | null | undefined;
5411
5418
  onFinish: ((prompt: string, completion: string) => void) | undefined;
5412
5419
  onError: ((error: Error) => void) | undefined;
5413
5420
  fetch: ReturnType<typeof getOriginalFetch> | undefined;
package/dist/index.js CHANGED
@@ -774,6 +774,9 @@ function asImageModelV4(model) {
774
774
  });
775
775
  }
776
776
 
777
+ // src/model/as-language-model-v4.ts
778
+ import { convertUint8ArrayToBase64 } from "@ai-sdk/provider-utils";
779
+
777
780
  // src/model/as-language-model-v3.ts
778
781
  function asLanguageModelV3(model) {
779
782
  if (model.specificationVersion === "v3") {
@@ -861,11 +864,131 @@ function asLanguageModelV4(model) {
861
864
  const v3Model = model.specificationVersion === "v2" ? asLanguageModelV3(model) : model;
862
865
  return new Proxy(v3Model, {
863
866
  get(target, prop) {
864
- if (prop === "specificationVersion") return "v4";
865
- return target[prop];
867
+ switch (prop) {
868
+ case "specificationVersion":
869
+ return "v4";
870
+ case "doGenerate":
871
+ return async (options) => {
872
+ const result = await target.doGenerate({
873
+ ...options,
874
+ prompt: convertV4PromptToV3(options.prompt)
875
+ });
876
+ return {
877
+ ...result,
878
+ content: result.content.map(convertV3ContentToV4)
879
+ };
880
+ };
881
+ case "doStream":
882
+ return async (options) => {
883
+ const result = await target.doStream({
884
+ ...options,
885
+ prompt: convertV4PromptToV3(options.prompt)
886
+ });
887
+ return {
888
+ ...result,
889
+ stream: convertV3StreamToV4(result.stream)
890
+ };
891
+ };
892
+ default:
893
+ return target[prop];
894
+ }
866
895
  }
867
896
  });
868
897
  }
898
+ function convertV4PromptToV3(prompt) {
899
+ return prompt.map((message) => {
900
+ if (message.role === "system") {
901
+ return message;
902
+ }
903
+ return {
904
+ ...message,
905
+ content: message.content.map((part) => {
906
+ switch (part.type) {
907
+ case "file":
908
+ return {
909
+ ...part,
910
+ data: convertV4FileDataToV3(part.data)
911
+ };
912
+ case "tool-result":
913
+ return {
914
+ ...part,
915
+ output: convertV4ToolResultOutputToV3(part.output)
916
+ };
917
+ default:
918
+ return part;
919
+ }
920
+ })
921
+ };
922
+ });
923
+ }
924
+ function convertV4FileDataToV3(data) {
925
+ switch (data.type) {
926
+ case "data":
927
+ return data.data;
928
+ case "url":
929
+ return data.url;
930
+ case "reference":
931
+ case "text":
932
+ return data;
933
+ }
934
+ }
935
+ function convertV4ToolResultOutputToV3(output) {
936
+ if (output.type !== "content") {
937
+ return output;
938
+ }
939
+ return {
940
+ ...output,
941
+ value: output.value.map((part) => {
942
+ if (part.type !== "file") {
943
+ return part;
944
+ }
945
+ switch (part.data.type) {
946
+ case "data":
947
+ return {
948
+ type: "file-data",
949
+ data: typeof part.data.data === "string" ? part.data.data : convertUint8ArrayToBase64(part.data.data),
950
+ mediaType: part.mediaType,
951
+ filename: part.filename,
952
+ providerOptions: part.providerOptions
953
+ };
954
+ case "url":
955
+ return {
956
+ type: "file-url",
957
+ url: part.data.url.toString(),
958
+ providerOptions: part.providerOptions
959
+ };
960
+ case "reference":
961
+ return {
962
+ type: "file-id",
963
+ fileId: part.data.reference,
964
+ providerOptions: part.providerOptions
965
+ };
966
+ case "text":
967
+ return part;
968
+ }
969
+ })
970
+ };
971
+ }
972
+ function convertV3ContentToV4(content) {
973
+ return content.type === "file" ? {
974
+ ...content,
975
+ data: { type: "data", data: content.data }
976
+ } : content;
977
+ }
978
+ function convertV3StreamToV4(stream) {
979
+ return stream.pipeThrough(
980
+ new TransformStream({
981
+ transform(chunk, controller) {
982
+ controller.enqueue(
983
+ chunk.type === "file" ? {
984
+ ...chunk,
985
+ data: { type: "data", data: chunk.data }
986
+ } : chunk
987
+ );
988
+ }
989
+ })
990
+ );
991
+ }
869
992
 
870
993
  // src/model/as-reranking-model-v4.ts
871
994
  function asRerankingModelV4(model) {
@@ -1211,7 +1334,7 @@ import {
1211
1334
  } from "@ai-sdk/provider-utils";
1212
1335
 
1213
1336
  // src/version.ts
1214
- var VERSION = true ? "7.0.107" : "0.0.0-test";
1337
+ var VERSION = true ? "7.0.109" : "0.0.0-test";
1215
1338
 
1216
1339
  // src/util/download/download.ts
1217
1340
  var download = async ({
@@ -3010,7 +3133,7 @@ function collectToolApprovals({
3010
3133
  // src/generate-text/generated-file.ts
3011
3134
  import {
3012
3135
  convertBase64ToUint8Array,
3013
- convertUint8ArrayToBase64
3136
+ convertUint8ArrayToBase64 as convertUint8ArrayToBase642
3014
3137
  } from "@ai-sdk/provider-utils";
3015
3138
  var DefaultGeneratedFile = class {
3016
3139
  constructor({
@@ -3027,7 +3150,7 @@ var DefaultGeneratedFile = class {
3027
3150
  // lazy conversion with caching to avoid unnecessary conversion overhead:
3028
3151
  get base64() {
3029
3152
  if (this.base64Data == null) {
3030
- this.base64Data = convertUint8ArrayToBase64(this.uint8ArrayData);
3153
+ this.base64Data = convertUint8ArrayToBase642(this.uint8ArrayData);
3031
3154
  }
3032
3155
  return this.base64Data;
3033
3156
  }
@@ -4439,7 +4562,8 @@ async function parseToolCall({
4439
4562
  repairToolCall,
4440
4563
  refineToolInput,
4441
4564
  messages,
4442
- instructions
4565
+ instructions,
4566
+ abortSignal
4443
4567
  }) {
4444
4568
  try {
4445
4569
  if (tools == null) {
@@ -4462,20 +4586,26 @@ async function parseToolCall({
4462
4586
  }
4463
4587
  let repairedToolCall = null;
4464
4588
  try {
4465
- repairedToolCall = await repairToolCall({
4466
- toolCall,
4467
- tools,
4468
- inputSchema: async ({ toolName }) => {
4469
- var _a25;
4470
- const inputSchema = (_a25 = getOwn(tools, toolName)) == null ? void 0 : _a25.inputSchema;
4471
- return await asSchema3(inputSchema).jsonSchema;
4472
- },
4473
- instructions,
4474
- system: instructions,
4475
- messages,
4476
- error
4589
+ abortSignal == null ? void 0 : abortSignal.throwIfAborted();
4590
+ repairedToolCall = await waitForPromiseWithAbortSignal({
4591
+ promise: repairToolCall({
4592
+ toolCall,
4593
+ tools,
4594
+ inputSchema: async ({ toolName }) => {
4595
+ var _a25;
4596
+ const inputSchema = (_a25 = getOwn(tools, toolName)) == null ? void 0 : _a25.inputSchema;
4597
+ return await asSchema3(inputSchema).jsonSchema;
4598
+ },
4599
+ instructions,
4600
+ system: instructions,
4601
+ messages,
4602
+ error,
4603
+ abortSignal
4604
+ }),
4605
+ abortSignal
4477
4606
  });
4478
4607
  } catch (repairError) {
4608
+ abortSignal == null ? void 0 : abortSignal.throwIfAborted();
4479
4609
  throw new ToolCallRepairError({
4480
4610
  cause: repairError,
4481
4611
  originalError: error
@@ -4484,12 +4614,15 @@ async function parseToolCall({
4484
4614
  if (repairedToolCall == null) {
4485
4615
  throw error;
4486
4616
  }
4487
- return await refineParsedToolCallInput({
4617
+ const parsedRepairedToolCall = await refineParsedToolCallInput({
4488
4618
  toolCall: await doParseToolCall({ toolCall: repairedToolCall, tools }),
4489
4619
  refineToolInput
4490
4620
  });
4621
+ abortSignal == null ? void 0 : abortSignal.throwIfAborted();
4622
+ return parsedRepairedToolCall;
4491
4623
  }
4492
4624
  } catch (error) {
4625
+ abortSignal == null ? void 0 : abortSignal.throwIfAborted();
4493
4626
  const parsedInput = await safeParseJSON3({ text: toolCall.input });
4494
4627
  const input = parsedInput.success ? parsedInput.value : toolCall.input;
4495
4628
  const tool3 = getOwn(tools, toolCall.toolName);
@@ -4508,6 +4641,34 @@ async function parseToolCall({
4508
4641
  };
4509
4642
  }
4510
4643
  }
4644
+ async function waitForPromiseWithAbortSignal({
4645
+ promise,
4646
+ abortSignal
4647
+ }) {
4648
+ if (abortSignal == null) {
4649
+ return await promise;
4650
+ }
4651
+ return await new Promise((resolve3, reject) => {
4652
+ const cleanup = () => {
4653
+ abortSignal.removeEventListener("abort", onAbort);
4654
+ };
4655
+ const onAbort = () => {
4656
+ cleanup();
4657
+ reject(abortSignal.reason);
4658
+ };
4659
+ Promise.resolve(promise).then((value) => {
4660
+ cleanup();
4661
+ resolve3(value);
4662
+ }).catch((error) => {
4663
+ cleanup();
4664
+ reject(error);
4665
+ });
4666
+ abortSignal.addEventListener("abort", onAbort, { once: true });
4667
+ if (abortSignal.aborted) {
4668
+ onAbort();
4669
+ }
4670
+ });
4671
+ }
4511
4672
  async function refineParsedToolCallInput({
4512
4673
  toolCall,
4513
4674
  refineToolInput
@@ -5514,7 +5675,7 @@ function sortToolResultContentByToolCallOrder({
5514
5675
  import { convertBase64ToUint8Array as convertBase64ToUint8Array2 } from "@ai-sdk/provider-utils";
5515
5676
 
5516
5677
  // src/util/canonical-hash.ts
5517
- import { convertUint8ArrayToBase64 as convertUint8ArrayToBase642 } from "@ai-sdk/provider-utils";
5678
+ import { convertUint8ArrayToBase64 as convertUint8ArrayToBase643 } from "@ai-sdk/provider-utils";
5518
5679
  var encoder = new TextEncoder();
5519
5680
  function canonicalJSON(value) {
5520
5681
  if (value === null || value === void 0) {
@@ -5533,7 +5694,7 @@ function canonicalJSON(value) {
5533
5694
  return `{${entries.join(",")}}`;
5534
5695
  }
5535
5696
  function toBase64url(bytes) {
5536
- return convertUint8ArrayToBase642(bytes).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
5697
+ return convertUint8ArrayToBase643(bytes).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
5537
5698
  }
5538
5699
  async function hashCanonical(value) {
5539
5700
  const digest = await crypto.subtle.digest(
@@ -6191,11 +6352,12 @@ async function generateText({
6191
6352
  ).map(
6192
6353
  (toolCall) => parseToolCall({
6193
6354
  toolCall,
6194
- tools: stepExecutionTools,
6355
+ tools: stepModelTools,
6195
6356
  repairToolCall,
6196
6357
  refineToolInput,
6197
6358
  instructions: stepInstructions,
6198
- messages: stepMessages
6359
+ messages: stepMessages,
6360
+ abortSignal: mergedAbortSignal
6199
6361
  })
6200
6362
  )
6201
6363
  );
@@ -9089,6 +9251,7 @@ async function streamLanguageModelCall({
9089
9251
  messages: standardizedPrompt.messages,
9090
9252
  repairToolCall,
9091
9253
  refineToolInput,
9254
+ abortSignal,
9092
9255
  callId: effectiveCallId,
9093
9256
  provider: resolvedModel.provider,
9094
9257
  modelId: resolvedModel.modelId,
@@ -9111,6 +9274,7 @@ function createLanguageModelV4StreamPartToLanguageModelStreamPartTransform({
9111
9274
  messages,
9112
9275
  repairToolCall,
9113
9276
  refineToolInput,
9277
+ abortSignal,
9114
9278
  callId,
9115
9279
  provider,
9116
9280
  modelId,
@@ -9298,27 +9462,28 @@ function createLanguageModelV4StreamPartToLanguageModelStreamPartTransform({
9298
9462
  },
9299
9463
  callbacks: onLanguageModelCallEnd
9300
9464
  });
9465
+ const enforcedToolChoice = toolChoice.type === "required" || toolChoice.type === "tool" ? toolChoice : void 0;
9466
+ const toolChoiceViolationError = enforcedToolChoice != null && ![...toolCallsByToolCallId.values()].some(
9467
+ (toolCall) => enforcedToolChoice.type === "required" || toolCall.toolName === enforcedToolChoice.toolName
9468
+ ) ? new ToolChoiceViolationError({
9469
+ toolChoice: enforcedToolChoice,
9470
+ finishReason: chunk.finishReason.unified,
9471
+ provider,
9472
+ modelId,
9473
+ content: rawModelCallContent
9474
+ }) : void 0;
9301
9475
  controller.enqueue({
9302
9476
  type: "model-call-end",
9303
- finishReason: chunk.finishReason.unified,
9477
+ finishReason: toolChoiceViolationError == null ? chunk.finishReason.unified : "error",
9304
9478
  rawFinishReason: chunk.finishReason.raw,
9305
9479
  usage,
9306
9480
  providerMetadata: chunk.providerMetadata,
9307
9481
  performance
9308
9482
  });
9309
- const enforcedToolChoice = toolChoice.type === "required" || toolChoice.type === "tool" ? toolChoice : void 0;
9310
- if (enforcedToolChoice != null && ![...toolCallsByToolCallId.values()].some(
9311
- (toolCall) => enforcedToolChoice.type === "required" || toolCall.toolName === enforcedToolChoice.toolName
9312
- )) {
9483
+ if (toolChoiceViolationError != null) {
9313
9484
  controller.enqueue({
9314
9485
  type: "error",
9315
- error: new ToolChoiceViolationError({
9316
- toolChoice: enforcedToolChoice,
9317
- finishReason: chunk.finishReason.unified,
9318
- provider,
9319
- modelId,
9320
- content: rawModelCallContent
9321
- })
9486
+ error: toolChoiceViolationError
9322
9487
  });
9323
9488
  break;
9324
9489
  }
@@ -9333,7 +9498,8 @@ function createLanguageModelV4StreamPartToLanguageModelStreamPartTransform({
9333
9498
  repairToolCall,
9334
9499
  refineToolInput,
9335
9500
  instructions,
9336
- messages
9501
+ messages,
9502
+ abortSignal
9337
9503
  });
9338
9504
  toolCallsByToolCallId.set(toolCall.toolCallId, toolCall);
9339
9505
  controller.enqueue(toolCall);
@@ -12935,16 +13101,16 @@ import {
12935
13101
  // src/prompt/data-content.ts
12936
13102
  import {
12937
13103
  convertBase64ToUint8Array as convertBase64ToUint8Array3,
12938
- convertUint8ArrayToBase64 as convertUint8ArrayToBase643
13104
+ convertUint8ArrayToBase64 as convertUint8ArrayToBase644
12939
13105
  } from "@ai-sdk/provider-utils";
12940
13106
  function convertDataContentToBase64String(content) {
12941
13107
  if (typeof content === "string") {
12942
13108
  return content;
12943
13109
  }
12944
13110
  if (content instanceof ArrayBuffer) {
12945
- return convertUint8ArrayToBase643(new Uint8Array(content));
13111
+ return convertUint8ArrayToBase644(new Uint8Array(content));
12946
13112
  }
12947
- return convertUint8ArrayToBase643(content);
13113
+ return convertUint8ArrayToBase644(content);
12948
13114
  }
12949
13115
  function convertDataContentToUint8Array(content) {
12950
13116
  if (content instanceof Uint8Array) {
@@ -17264,18 +17430,19 @@ function extractReasoningMiddleware({
17264
17430
  wrapStream: async ({ doStream }) => {
17265
17431
  const { stream, ...rest } = await doStream();
17266
17432
  const reasoningExtractions = createIdMap();
17267
- let delayedTextStart;
17433
+ let reasoningIdCounter = 0;
17434
+ const delayedTextStarts = createIdMap();
17268
17435
  return {
17269
17436
  stream: stream.pipeThrough(
17270
17437
  new TransformStream({
17271
17438
  transform: (chunk, controller) => {
17272
17439
  if (chunk.type === "text-start") {
17273
- delayedTextStart = chunk;
17440
+ delayedTextStarts[chunk.id] = chunk;
17274
17441
  return;
17275
17442
  }
17276
- if (chunk.type === "text-end" && delayedTextStart) {
17277
- controller.enqueue(delayedTextStart);
17278
- delayedTextStart = void 0;
17443
+ if (chunk.type === "text-end" && delayedTextStarts[chunk.id] != null) {
17444
+ controller.enqueue(delayedTextStarts[chunk.id]);
17445
+ delete delayedTextStarts[chunk.id];
17279
17446
  }
17280
17447
  if (chunk.type !== "text-delta") {
17281
17448
  controller.enqueue(chunk);
@@ -17288,31 +17455,37 @@ function extractReasoningMiddleware({
17288
17455
  afterSwitch: false,
17289
17456
  isReasoning: startWithReasoning,
17290
17457
  buffer: "",
17291
- idCounter: 0,
17458
+ reasoningId: void 0,
17292
17459
  textId: chunk.id
17293
17460
  };
17294
17461
  }
17295
17462
  const activeExtraction = reasoningExtractions[chunk.id];
17296
17463
  activeExtraction.buffer += chunk.delta;
17464
+ function getReasoningId() {
17465
+ var _a25;
17466
+ return (_a25 = activeExtraction.reasoningId) != null ? _a25 : activeExtraction.reasoningId = `reasoning-${reasoningIdCounter++}`;
17467
+ }
17297
17468
  function publish(text2) {
17298
17469
  if (text2.length > 0) {
17299
17470
  const prefix = activeExtraction.afterSwitch && (activeExtraction.isReasoning ? !activeExtraction.isFirstReasoning : !activeExtraction.isFirstText) ? separator : "";
17300
17471
  if (activeExtraction.isReasoning && (activeExtraction.afterSwitch || activeExtraction.isFirstReasoning)) {
17301
17472
  controller.enqueue({
17302
17473
  type: "reasoning-start",
17303
- id: `reasoning-${activeExtraction.idCounter}`
17474
+ id: getReasoningId()
17304
17475
  });
17305
17476
  }
17306
17477
  if (activeExtraction.isReasoning) {
17307
17478
  controller.enqueue({
17308
17479
  type: "reasoning-delta",
17309
17480
  delta: prefix + text2,
17310
- id: `reasoning-${activeExtraction.idCounter}`
17481
+ id: getReasoningId()
17311
17482
  });
17312
17483
  } else {
17313
- if (delayedTextStart) {
17314
- controller.enqueue(delayedTextStart);
17315
- delayedTextStart = void 0;
17484
+ if (delayedTextStarts[activeExtraction.textId] != null) {
17485
+ controller.enqueue(
17486
+ delayedTextStarts[activeExtraction.textId]
17487
+ );
17488
+ delete delayedTextStarts[activeExtraction.textId];
17316
17489
  }
17317
17490
  controller.enqueue({
17318
17491
  type: "text-delta",
@@ -17349,13 +17522,14 @@ function extractReasoningMiddleware({
17349
17522
  if (activeExtraction.isFirstReasoning) {
17350
17523
  controller.enqueue({
17351
17524
  type: "reasoning-start",
17352
- id: `reasoning-${activeExtraction.idCounter}`
17525
+ id: getReasoningId()
17353
17526
  });
17354
17527
  }
17355
17528
  controller.enqueue({
17356
17529
  type: "reasoning-end",
17357
- id: `reasoning-${activeExtraction.idCounter++}`
17530
+ id: getReasoningId()
17358
17531
  });
17532
+ activeExtraction.reasoningId = void 0;
17359
17533
  }
17360
17534
  activeExtraction.isReasoning = !activeExtraction.isReasoning;
17361
17535
  activeExtraction.afterSwitch = true;
@@ -21495,14 +21669,16 @@ async function callCompletionApi({
21495
21669
  setLoading,
21496
21670
  setError,
21497
21671
  setAbortController,
21672
+ getAbortController,
21498
21673
  onFinish,
21499
21674
  onError,
21500
21675
  fetch: fetch2 = getOriginalFetch()
21501
21676
  }) {
21677
+ const abortController = new AbortController();
21678
+ const isCurrentRequest = () => getAbortController == null || getAbortController() === abortController;
21502
21679
  try {
21503
21680
  setLoading(true);
21504
21681
  setError(void 0);
21505
- const abortController = new AbortController();
21506
21682
  setAbortController(abortController);
21507
21683
  setCompletion("");
21508
21684
  const response = await fetch2(api, {
@@ -21543,7 +21719,9 @@ async function callCompletionApi({
21543
21719
  stream: response.body,
21544
21720
  onTextPart: (chunk) => {
21545
21721
  result += chunk;
21546
- setCompletion(result);
21722
+ if (isCurrentRequest()) {
21723
+ setCompletion(result);
21724
+ }
21547
21725
  }
21548
21726
  });
21549
21727
  break;
@@ -21562,7 +21740,9 @@ async function callCompletionApi({
21562
21740
  const streamPart = part.value;
21563
21741
  if (streamPart.type === "text-delta") {
21564
21742
  result += streamPart.delta;
21565
- setCompletion(result);
21743
+ if (isCurrentRequest()) {
21744
+ setCompletion(result);
21745
+ }
21566
21746
  } else if (streamPart.type === "error") {
21567
21747
  throw new UIMessageStreamError({
21568
21748
  chunkType: "error",
@@ -21591,11 +21771,9 @@ async function callCompletionApi({
21591
21771
  if (onFinish) {
21592
21772
  onFinish(prompt, result);
21593
21773
  }
21594
- setAbortController(null);
21595
21774
  return result;
21596
21775
  } catch (err) {
21597
21776
  if (err.name === "AbortError") {
21598
- setAbortController(null);
21599
21777
  return null;
21600
21778
  }
21601
21779
  if (err instanceof Error) {
@@ -21603,9 +21781,14 @@ async function callCompletionApi({
21603
21781
  onError(err);
21604
21782
  }
21605
21783
  }
21606
- setError(err);
21784
+ if (isCurrentRequest()) {
21785
+ setError(err);
21786
+ }
21607
21787
  } finally {
21608
- setLoading(false);
21788
+ if (isCurrentRequest()) {
21789
+ setAbortController(null);
21790
+ setLoading(false);
21791
+ }
21609
21792
  }
21610
21793
  }
21611
21794