ai 7.0.108 → 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,13 @@
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
+
3
11
  ## 7.0.108
4
12
 
5
13
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -3331,18 +3331,22 @@ type ToolInputRefinement<TOOLS extends ToolSet> = {
3331
3331
  */
3332
3332
  type IsEmptyObject<OBJECT> = keyof OBJECT extends never ? true : false;
3333
3333
  /**
3334
- * Helper type to make the toolsContext parameter optional, required, or
3335
- * unavailable based on the tool set.
3334
+ * Makes the toolsContext setting optional, required, or unavailable based on
3335
+ * the tool set.
3336
3336
  */
3337
- type ToolsContextParameter<TOOLS extends ToolSet> = {
3338
- tools?: TOOLS;
3339
- } & (IsEmptyObject<InferToolSetContext<TOOLS>> extends true ? {
3337
+ type ToolsContextSettings<TOOLS extends ToolSet> = IsEmptyObject<InferToolSetContext<TOOLS>> extends true ? {
3340
3338
  toolsContext?: never;
3341
3339
  } : HasRequiredKey<InferToolSetContext<TOOLS>> extends true ? {
3342
3340
  toolsContext: InferToolSetContext<TOOLS>;
3343
3341
  } : {
3344
3342
  toolsContext?: InferToolSetContext<TOOLS>;
3345
- });
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>;
3346
3350
 
3347
3351
  type StreamTextInclude = {
3348
3352
  /**
@@ -5399,7 +5403,7 @@ type UIMessageStreamOnStepEndCallback<UI_MESSAGE extends UIMessage> = (event: {
5399
5403
  type UIMessageStreamOnStepFinishCallback<UI_MESSAGE extends UIMessage> = UIMessageStreamOnStepEndCallback<UI_MESSAGE>;
5400
5404
 
5401
5405
  declare const getOriginalFetch: () => typeof fetch;
5402
- 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, }: {
5403
5407
  api: string;
5404
5408
  prompt: string;
5405
5409
  credentials: RequestCredentials | undefined;
@@ -5410,6 +5414,7 @@ declare function callCompletionApi({ api, prompt, credentials, headers, body, st
5410
5414
  setLoading: (loading: boolean) => void;
5411
5415
  setError: (error: Error | undefined) => void;
5412
5416
  setAbortController: (abortController: AbortController | null) => void;
5417
+ getAbortController?: () => AbortController | null | undefined;
5413
5418
  onFinish: ((prompt: string, completion: string) => void) | undefined;
5414
5419
  onError: ((error: Error) => void) | undefined;
5415
5420
  fetch: ReturnType<typeof getOriginalFetch> | undefined;
package/dist/index.js CHANGED
@@ -1334,7 +1334,7 @@ import {
1334
1334
  } from "@ai-sdk/provider-utils";
1335
1335
 
1336
1336
  // src/version.ts
1337
- var VERSION = true ? "7.0.108" : "0.0.0-test";
1337
+ var VERSION = true ? "7.0.109" : "0.0.0-test";
1338
1338
 
1339
1339
  // src/util/download/download.ts
1340
1340
  var download = async ({
@@ -17430,18 +17430,19 @@ function extractReasoningMiddleware({
17430
17430
  wrapStream: async ({ doStream }) => {
17431
17431
  const { stream, ...rest } = await doStream();
17432
17432
  const reasoningExtractions = createIdMap();
17433
- let delayedTextStart;
17433
+ let reasoningIdCounter = 0;
17434
+ const delayedTextStarts = createIdMap();
17434
17435
  return {
17435
17436
  stream: stream.pipeThrough(
17436
17437
  new TransformStream({
17437
17438
  transform: (chunk, controller) => {
17438
17439
  if (chunk.type === "text-start") {
17439
- delayedTextStart = chunk;
17440
+ delayedTextStarts[chunk.id] = chunk;
17440
17441
  return;
17441
17442
  }
17442
- if (chunk.type === "text-end" && delayedTextStart) {
17443
- controller.enqueue(delayedTextStart);
17444
- delayedTextStart = void 0;
17443
+ if (chunk.type === "text-end" && delayedTextStarts[chunk.id] != null) {
17444
+ controller.enqueue(delayedTextStarts[chunk.id]);
17445
+ delete delayedTextStarts[chunk.id];
17445
17446
  }
17446
17447
  if (chunk.type !== "text-delta") {
17447
17448
  controller.enqueue(chunk);
@@ -17454,31 +17455,37 @@ function extractReasoningMiddleware({
17454
17455
  afterSwitch: false,
17455
17456
  isReasoning: startWithReasoning,
17456
17457
  buffer: "",
17457
- idCounter: 0,
17458
+ reasoningId: void 0,
17458
17459
  textId: chunk.id
17459
17460
  };
17460
17461
  }
17461
17462
  const activeExtraction = reasoningExtractions[chunk.id];
17462
17463
  activeExtraction.buffer += chunk.delta;
17464
+ function getReasoningId() {
17465
+ var _a25;
17466
+ return (_a25 = activeExtraction.reasoningId) != null ? _a25 : activeExtraction.reasoningId = `reasoning-${reasoningIdCounter++}`;
17467
+ }
17463
17468
  function publish(text2) {
17464
17469
  if (text2.length > 0) {
17465
17470
  const prefix = activeExtraction.afterSwitch && (activeExtraction.isReasoning ? !activeExtraction.isFirstReasoning : !activeExtraction.isFirstText) ? separator : "";
17466
17471
  if (activeExtraction.isReasoning && (activeExtraction.afterSwitch || activeExtraction.isFirstReasoning)) {
17467
17472
  controller.enqueue({
17468
17473
  type: "reasoning-start",
17469
- id: `reasoning-${activeExtraction.idCounter}`
17474
+ id: getReasoningId()
17470
17475
  });
17471
17476
  }
17472
17477
  if (activeExtraction.isReasoning) {
17473
17478
  controller.enqueue({
17474
17479
  type: "reasoning-delta",
17475
17480
  delta: prefix + text2,
17476
- id: `reasoning-${activeExtraction.idCounter}`
17481
+ id: getReasoningId()
17477
17482
  });
17478
17483
  } else {
17479
- if (delayedTextStart) {
17480
- controller.enqueue(delayedTextStart);
17481
- delayedTextStart = void 0;
17484
+ if (delayedTextStarts[activeExtraction.textId] != null) {
17485
+ controller.enqueue(
17486
+ delayedTextStarts[activeExtraction.textId]
17487
+ );
17488
+ delete delayedTextStarts[activeExtraction.textId];
17482
17489
  }
17483
17490
  controller.enqueue({
17484
17491
  type: "text-delta",
@@ -17515,13 +17522,14 @@ function extractReasoningMiddleware({
17515
17522
  if (activeExtraction.isFirstReasoning) {
17516
17523
  controller.enqueue({
17517
17524
  type: "reasoning-start",
17518
- id: `reasoning-${activeExtraction.idCounter}`
17525
+ id: getReasoningId()
17519
17526
  });
17520
17527
  }
17521
17528
  controller.enqueue({
17522
17529
  type: "reasoning-end",
17523
- id: `reasoning-${activeExtraction.idCounter++}`
17530
+ id: getReasoningId()
17524
17531
  });
17532
+ activeExtraction.reasoningId = void 0;
17525
17533
  }
17526
17534
  activeExtraction.isReasoning = !activeExtraction.isReasoning;
17527
17535
  activeExtraction.afterSwitch = true;
@@ -21661,14 +21669,16 @@ async function callCompletionApi({
21661
21669
  setLoading,
21662
21670
  setError,
21663
21671
  setAbortController,
21672
+ getAbortController,
21664
21673
  onFinish,
21665
21674
  onError,
21666
21675
  fetch: fetch2 = getOriginalFetch()
21667
21676
  }) {
21677
+ const abortController = new AbortController();
21678
+ const isCurrentRequest = () => getAbortController == null || getAbortController() === abortController;
21668
21679
  try {
21669
21680
  setLoading(true);
21670
21681
  setError(void 0);
21671
- const abortController = new AbortController();
21672
21682
  setAbortController(abortController);
21673
21683
  setCompletion("");
21674
21684
  const response = await fetch2(api, {
@@ -21709,7 +21719,9 @@ async function callCompletionApi({
21709
21719
  stream: response.body,
21710
21720
  onTextPart: (chunk) => {
21711
21721
  result += chunk;
21712
- setCompletion(result);
21722
+ if (isCurrentRequest()) {
21723
+ setCompletion(result);
21724
+ }
21713
21725
  }
21714
21726
  });
21715
21727
  break;
@@ -21728,7 +21740,9 @@ async function callCompletionApi({
21728
21740
  const streamPart = part.value;
21729
21741
  if (streamPart.type === "text-delta") {
21730
21742
  result += streamPart.delta;
21731
- setCompletion(result);
21743
+ if (isCurrentRequest()) {
21744
+ setCompletion(result);
21745
+ }
21732
21746
  } else if (streamPart.type === "error") {
21733
21747
  throw new UIMessageStreamError({
21734
21748
  chunkType: "error",
@@ -21757,11 +21771,9 @@ async function callCompletionApi({
21757
21771
  if (onFinish) {
21758
21772
  onFinish(prompt, result);
21759
21773
  }
21760
- setAbortController(null);
21761
21774
  return result;
21762
21775
  } catch (err) {
21763
21776
  if (err.name === "AbortError") {
21764
- setAbortController(null);
21765
21777
  return null;
21766
21778
  }
21767
21779
  if (err instanceof Error) {
@@ -21769,9 +21781,14 @@ async function callCompletionApi({
21769
21781
  onError(err);
21770
21782
  }
21771
21783
  }
21772
- setError(err);
21784
+ if (isCurrentRequest()) {
21785
+ setError(err);
21786
+ }
21773
21787
  } finally {
21774
- setLoading(false);
21788
+ if (isCurrentRequest()) {
21789
+ setAbortController(null);
21790
+ setLoading(false);
21791
+ }
21775
21792
  }
21776
21793
  }
21777
21794