@mastra/react 0.2.30-alpha.1 → 0.2.30-alpha.3

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,23 @@
1
1
  # @mastra/react
2
2
 
3
+ ## 0.2.30-alpha.3
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [[`c04417b`](https://github.com/mastra-ai/mastra/commit/c04417ba0a2e4ded66da4352331ef29cd4bd1d79), [`cf25a03`](https://github.com/mastra-ai/mastra/commit/cf25a03132164b9dc1e5dccf7394824e33007c51), [`ba6b0c5`](https://github.com/mastra-ai/mastra/commit/ba6b0c51bfce358554fd33c7f2bcd5593633f2ff)]:
8
+ - @mastra/core@1.29.0-alpha.3
9
+ - @mastra/client-js@1.15.0-alpha.3
10
+
11
+ ## 0.2.30-alpha.2
12
+
13
+ ### Patch Changes
14
+
15
+ - The useChat hook stream now calls the new `agent.streamUntilIdle` method and the background-task chunks are processed in toUIMessage. ([#15686](https://github.com/mastra-ai/mastra/pull/15686))
16
+
17
+ - Updated dependencies [[`9e973b0`](https://github.com/mastra-ai/mastra/commit/9e973b010dacfa15ac82b0072897319f5234b90a), [`dd934a0`](https://github.com/mastra-ai/mastra/commit/dd934a0982ce0f78712fbd559e4f2410bf594b39), [`73f2809`](https://github.com/mastra-ai/mastra/commit/73f2809721db24e98cdf122539652a455211b450), [`aedeea4`](https://github.com/mastra-ai/mastra/commit/aedeea48a94f728323f040478775076b9574be50), [`441670a`](https://github.com/mastra-ai/mastra/commit/441670a02c9dc7731c52674f55481e7848a84523), [`8126d86`](https://github.com/mastra-ai/mastra/commit/8126d8638411eacfafdc29036ac998e8757ea66f), [`ae97520`](https://github.com/mastra-ai/mastra/commit/ae975206fdb0f6ef03c4d5bf94f7dc7c3f706c02), [`441670a`](https://github.com/mastra-ai/mastra/commit/441670a02c9dc7731c52674f55481e7848a84523)]:
18
+ - @mastra/core@1.29.0-alpha.2
19
+ - @mastra/client-js@1.15.0-alpha.2
20
+
3
21
  ## 0.2.30-alpha.1
4
22
 
5
23
  ### Patch Changes
@@ -1 +1 @@
1
- {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/agent/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAG/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvE,OAAO,KAAK,EAA2B,eAAe,EAAE,MAAM,eAAe,CAAC;AAC9E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAO7C,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,eAAe,EAAE,CAAC;IACpC,6FAA6F;IAC7F,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAED,UAAU,UAAU;IAClB,gBAAgB,EAAE,eAAe,EAAE,CAAC;IACpC,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAED,MAAM,MAAM,eAAe,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,gBAAgB,CAAC,EAAE,eAAe,EAAE,CAAA;CAAE,GAAG,CACtF,CAAC;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GAAG,IAAI,CAAC,YAAY,EAAE,kBAAkB,CAAC,CAAC,GAC/D,CAAC;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAAG,IAAI,CAAC,UAAU,EAAE,kBAAkB,CAAC,CAAC,GAC3D,CAAC;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GAAG,IAAI,CAAC,WAAW,EAAE,kBAAkB,CAAC,CAAC,GAC7D,CAAC;IAAE,IAAI,CAAC,EAAE,SAAS,CAAA;CAAE,GAAG,IAAI,CAAC,UAAU,EAAE,kBAAkB,CAAC,CAAC,CAChE,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG;IAAE,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC;AAEhG,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG;IACpC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/C,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG;IACrC,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7D,CAAC;AAgBF,eAAO,MAAM,OAAO,GAAI,gFAKrB,eAAe;;qCA0cyC,eAAe;;;kCA3L7B,MAAM;kCA6BN,MAAM;0CA4BE,MAAM;0CAgCN,MAAM;;;;oBAhWvB,UAAU,GAAG,UAAU;;;uCAgYT,MAAM,UAAU,MAAM;uCAiCtB,MAAM,UAAU,MAAM;;;oBA9ZtC,UAAU,GAAG,UAAU;;;CAkexD,CAAC"}
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/agent/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAG/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvE,OAAO,KAAK,EAA2B,eAAe,EAAE,MAAM,eAAe,CAAC;AAC9E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAO7C,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,eAAe,EAAE,CAAC;IACpC,6FAA6F;IAC7F,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAED,UAAU,UAAU;IAClB,gBAAgB,EAAE,eAAe,EAAE,CAAC;IACpC,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAED,MAAM,MAAM,eAAe,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,gBAAgB,CAAC,EAAE,eAAe,EAAE,CAAA;CAAE,GAAG,CACtF,CAAC;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GAAG,IAAI,CAAC,YAAY,EAAE,kBAAkB,CAAC,CAAC,GAC/D,CAAC;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAAG,IAAI,CAAC,UAAU,EAAE,kBAAkB,CAAC,CAAC,GAC3D,CAAC;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GAAG,IAAI,CAAC,WAAW,EAAE,kBAAkB,CAAC,CAAC,GAC7D,CAAC;IAAE,IAAI,CAAC,EAAE,SAAS,CAAA;CAAE,GAAG,IAAI,CAAC,UAAU,EAAE,kBAAkB,CAAC,CAAC,CAChE,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG;IAAE,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC;AAEhG,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG;IACpC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/C,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG;IACrC,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7D,CAAC;AAgBF,eAAO,MAAM,OAAO,GAAI,gFAKrB,eAAe;;qCAoeyC,eAAe;;;kCA3L7B,MAAM;kCA6BN,MAAM;0CA4BE,MAAM;0CAgCN,MAAM;;;;oBApXvB,UAAU,GAAG,UAAU;;;uCAoZT,MAAM,UAAU,MAAM;uCAiCtB,MAAM,UAAU,MAAM;;;oBAlbtC,UAAU,GAAG,UAAU;;;CAsfxD,CAAC"}
package/dist/index.cjs CHANGED
@@ -312,22 +312,6 @@ var toUIMessage = ({ chunk, conversation, metadata }) => {
312
312
  }
313
313
  ];
314
314
  }
315
- case "background-task-failed":
316
- case "background-task-completed": {
317
- const lastMessage = result[result.length - 1];
318
- if (!lastMessage || lastMessage.role !== "assistant") return result;
319
- return [
320
- ...result.slice(0, -1),
321
- {
322
- ...lastMessage,
323
- metadata: {
324
- mode: metadata.mode,
325
- ...lastMessage.metadata,
326
- runningBackgroundTasksCount: void 0
327
- }
328
- }
329
- ];
330
- }
331
315
  case "text-delta": {
332
316
  const lastMessage = result[result.length - 1];
333
317
  if (!lastMessage || lastMessage.role !== "assistant") return result;
@@ -451,113 +435,140 @@ var toUIMessage = ({ chunk, conversation, metadata }) => {
451
435
  ];
452
436
  }
453
437
  case "tool-error":
454
- case "tool-result": {
455
- const lastMessage = result[result.length - 1];
456
- if (!lastMessage || lastMessage.role !== "assistant") return result;
457
- const parts = [...lastMessage.parts];
458
- const toolPartIndex = parts.findIndex(
459
- (part) => (part.type === "dynamic-tool" || typeof part.type === "string" && part.type.startsWith("tool-")) && "toolCallId" in part && part.toolCallId === chunk.payload.toolCallId
460
- );
461
- if (toolPartIndex !== -1) {
462
- const toolPart = parts[toolPartIndex];
463
- if (toolPart.type === "dynamic-tool" || typeof toolPart.type === "string" && toolPart.type.startsWith("tool-")) {
464
- const toolName = "toolName" in toolPart && typeof toolPart.toolName === "string" ? toolPart.toolName : toolPart.type.startsWith("tool-") ? toolPart.type.substring(5) : "";
465
- const toolCallId = toolPart.toolCallId;
466
- if (chunk.type === "tool-result" && chunk.payload.isError || chunk.type === "tool-error") {
467
- const error = chunk.type === "tool-error" ? chunk.payload.error : chunk.payload.result;
468
- parts[toolPartIndex] = {
469
- type: "dynamic-tool",
470
- toolName,
471
- toolCallId,
472
- state: "output-error",
473
- input: toolPart.input,
474
- errorText: typeof error === "string" ? error : error instanceof Error ? error.message : error?.message ?? String(error),
475
- callProviderMetadata: chunk.payload.providerMetadata
476
- };
438
+ case "tool-result":
439
+ case "background-task-completed":
440
+ case "background-task-failed": {
441
+ const isBgTaskEvent = chunk.type === "background-task-completed" || chunk.type === "background-task-failed";
442
+ const location = locateToolPart(result, chunk.payload.toolCallId, isBgTaskEvent);
443
+ if (!location) return result;
444
+ const { messageIndex, toolPartIndex } = location;
445
+ const targetMessage = result[messageIndex];
446
+ if (!targetMessage || targetMessage.role !== "assistant") return result;
447
+ const parts = [...targetMessage.parts];
448
+ const toolPart = toolPartIndex >= 0 ? parts[toolPartIndex] : void 0;
449
+ if (toolPart && (toolPart.type === "dynamic-tool" || typeof toolPart.type === "string" && toolPart.type.startsWith("tool-"))) {
450
+ const toolName = "toolName" in toolPart && typeof toolPart.toolName === "string" ? toolPart.toolName : typeof toolPart.type === "string" && toolPart.type.startsWith("tool-") ? toolPart.type.substring(5) : "";
451
+ const toolCallId = toolPart.toolCallId;
452
+ if ((chunk.type === "tool-result" || chunk.type === "background-task-completed") && chunk.payload.isError || chunk.type === "tool-error" || chunk.type === "background-task-failed") {
453
+ const error = chunk.type === "tool-error" || chunk.type === "background-task-failed" ? chunk.payload.error : chunk.payload.result;
454
+ parts[toolPartIndex] = {
455
+ type: "dynamic-tool",
456
+ toolName,
457
+ toolCallId,
458
+ state: "output-error",
459
+ input: toolPart.input,
460
+ errorText: typeof error === "string" ? error : error instanceof Error ? error.message : error?.message ?? String(error),
461
+ callProviderMetadata: chunk.payload.providerMetadata
462
+ };
463
+ } else {
464
+ const isWorkflow = Boolean(chunk.payload.result?.result?.steps);
465
+ const isAgent = chunk?.from === "AGENT";
466
+ let output;
467
+ if (isWorkflow) {
468
+ output = chunk.payload.result?.result;
469
+ } else if (isAgent) {
470
+ const existingOutput = parts[toolPartIndex].output;
471
+ output = existingOutput ? {
472
+ ...chunk.payload.result,
473
+ childMessages: existingOutput.childMessages?.length ? existingOutput.childMessages : chunk.payload.result?.childMessages
474
+ } : chunk.payload.result;
477
475
  } else {
478
- const isWorkflow = Boolean(chunk.payload.result?.result?.steps);
479
- const isAgent = chunk?.from === "AGENT";
480
- let output;
481
- if (isWorkflow) {
482
- output = chunk.payload.result?.result;
483
- } else if (isAgent) {
484
- const existingOutput = parts[toolPartIndex].output;
485
- output = existingOutput ? {
486
- ...chunk.payload.result,
487
- childMessages: existingOutput.childMessages?.length ? existingOutput.childMessages : chunk.payload.result?.childMessages
488
- } : chunk.payload.result;
489
- } else {
490
- output = chunk.payload.result;
491
- }
492
- parts[toolPartIndex] = {
493
- type: "dynamic-tool",
494
- toolName,
495
- toolCallId,
496
- state: "output-available",
497
- input: toolPart.input,
498
- output,
499
- callProviderMetadata: chunk.payload.providerMetadata
500
- };
476
+ output = chunk.payload.result;
501
477
  }
478
+ parts[toolPartIndex] = {
479
+ type: "dynamic-tool",
480
+ toolName,
481
+ toolCallId,
482
+ state: "output-available",
483
+ input: toolPart.input,
484
+ output,
485
+ callProviderMetadata: chunk.payload.providerMetadata
486
+ };
502
487
  }
503
488
  }
489
+ const nextMessage = {
490
+ ...targetMessage,
491
+ parts,
492
+ metadata: mergeBgTaskMetadata(targetMessage.metadata, metadata.mode, {
493
+ resetRunningCount: isBgTaskEvent,
494
+ perTaskEntry: isBgTaskEvent ? {
495
+ toolCallId: chunk.payload.toolCallId,
496
+ completedAt: chunk.payload.completedAt,
497
+ taskId: chunk.payload.taskId
498
+ } : void 0
499
+ })
500
+ };
501
+ return [...result.slice(0, messageIndex), nextMessage, ...result.slice(messageIndex + 1)];
502
+ }
503
+ case "background-task-running": {
504
+ const location = locateToolPart(result, chunk.payload.toolCallId, true);
505
+ if (!location) return result;
506
+ const { messageIndex } = location;
507
+ const targetMessage = result[messageIndex];
508
+ if (!targetMessage || targetMessage.role !== "assistant") return result;
504
509
  return [
505
- ...result.slice(0, -1),
510
+ ...result.slice(0, messageIndex),
506
511
  {
507
- ...lastMessage,
508
- parts
509
- }
512
+ ...targetMessage,
513
+ metadata: mergeBgTaskMetadata(targetMessage.metadata, metadata.mode, {
514
+ perTaskEntry: {
515
+ toolCallId: chunk.payload.toolCallId,
516
+ startedAt: chunk.payload.startedAt,
517
+ taskId: chunk.payload.taskId
518
+ }
519
+ })
520
+ },
521
+ ...result.slice(messageIndex + 1)
510
522
  ];
511
523
  }
512
- case "tool-output": {
513
- const lastMessage = result[result.length - 1];
514
- if (!lastMessage || lastMessage.role !== "assistant") return result;
515
- const parts = [...lastMessage.parts];
516
- const toolPartIndex = parts.findIndex(
517
- (part) => (part.type === "dynamic-tool" || typeof part.type === "string" && part.type.startsWith("tool-")) && "toolCallId" in part && part.toolCallId === chunk.payload.toolCallId
518
- );
519
- if (toolPartIndex !== -1) {
520
- const toolPart = parts[toolPartIndex];
521
- if (toolPart.type === "dynamic-tool" || typeof toolPart.type === "string" && toolPart.type.startsWith("tool-")) {
522
- const toolName = "toolName" in toolPart && typeof toolPart.toolName === "string" ? toolPart.toolName : typeof toolPart.type === "string" && toolPart.type.startsWith("tool-") ? toolPart.type.substring(5) : "";
523
- const toolCallId = toolPart.toolCallId;
524
- const input = toolPart.input;
525
- if (chunk.payload.output?.type?.startsWith("workflow-")) {
526
- const existingWorkflowState = toolPart.output || {};
527
- const updatedWorkflowState = mapWorkflowStreamChunkToWatchResult(
528
- existingWorkflowState,
529
- chunk.payload.output
530
- );
531
- parts[toolPartIndex] = {
532
- type: "dynamic-tool",
533
- toolName,
534
- toolCallId,
535
- state: "input-streaming",
536
- input,
537
- output: updatedWorkflowState
538
- };
539
- } else if (chunk.payload.output?.from === "AGENT" || chunk.payload.output?.from === "USER" && chunk.payload.output?.payload?.output?.type?.startsWith("workflow-")) {
540
- return toUIMessageFromAgent(chunk.payload.output, conversation, metadata, toolCallId, toolName);
541
- } else {
542
- const currentOutput = toolPart.output || [];
543
- const existingOutput = Array.isArray(currentOutput) ? currentOutput : [];
544
- parts[toolPartIndex] = {
545
- type: "dynamic-tool",
546
- toolName,
547
- toolCallId,
548
- state: "input-streaming",
549
- input,
550
- output: [...existingOutput, chunk.payload.output]
551
- };
552
- }
524
+ case "tool-output":
525
+ case "background-task-output": {
526
+ const isBgTaskOutput = chunk.type === "background-task-output";
527
+ const location = locateToolPart(result, chunk.payload.toolCallId, isBgTaskOutput);
528
+ if (!location || location.toolPartIndex < 0) return result;
529
+ const { messageIndex, toolPartIndex } = location;
530
+ const targetMessage = result[messageIndex];
531
+ if (!targetMessage || targetMessage.role !== "assistant") return result;
532
+ const parts = [...targetMessage.parts];
533
+ const toolPart = parts[toolPartIndex];
534
+ if (toolPart.type === "dynamic-tool" || typeof toolPart.type === "string" && toolPart.type.startsWith("tool-")) {
535
+ const toolName = "toolName" in toolPart && typeof toolPart.toolName === "string" ? toolPart.toolName : typeof toolPart.type === "string" && toolPart.type.startsWith("tool-") ? toolPart.type.substring(5) : "";
536
+ const toolCallId = toolPart.toolCallId;
537
+ const input = toolPart.input;
538
+ const payloadOutput = chunk.type === "background-task-output" ? chunk.payload.payload.payload.output : chunk.payload.output;
539
+ if (payloadOutput?.type?.startsWith("workflow-")) {
540
+ const existingWorkflowState = toolPart.output || {};
541
+ const updatedWorkflowState = mapWorkflowStreamChunkToWatchResult(existingWorkflowState, payloadOutput);
542
+ parts[toolPartIndex] = {
543
+ type: "dynamic-tool",
544
+ toolName,
545
+ toolCallId,
546
+ state: "input-streaming",
547
+ input,
548
+ output: updatedWorkflowState
549
+ };
550
+ } else if (payloadOutput?.from === "AGENT" || payloadOutput?.from === "USER" && payloadOutput?.payload?.output?.type?.startsWith("workflow-")) {
551
+ return toUIMessageFromAgent(payloadOutput, conversation, metadata, toolCallId, toolName);
552
+ } else {
553
+ const currentOutput = toolPart.output || [];
554
+ const existingOutput = Array.isArray(currentOutput) ? currentOutput : [];
555
+ parts[toolPartIndex] = {
556
+ type: "dynamic-tool",
557
+ toolName,
558
+ toolCallId,
559
+ state: "input-streaming",
560
+ input,
561
+ output: [...existingOutput, payloadOutput]
562
+ };
553
563
  }
554
564
  }
555
565
  return [
556
- ...result.slice(0, -1),
566
+ ...result.slice(0, messageIndex),
557
567
  {
558
- ...lastMessage,
568
+ ...targetMessage,
559
569
  parts
560
- }
570
+ },
571
+ ...result.slice(messageIndex + 1)
561
572
  ];
562
573
  }
563
574
  case "is-task-complete": {
@@ -838,6 +849,69 @@ var toUIMessageFromAgent = (chunk, conversation, metadata, parentToolCallId, par
838
849
  }
839
850
  ];
840
851
  };
852
+ var findMessageIndexByToolCallId = (messages, toolCallId) => {
853
+ let count = 0;
854
+ for (let i = messages.length - 1; i >= 0; i--) {
855
+ const maxMessagesBack = 10;
856
+ if (count > maxMessagesBack) {
857
+ return -1;
858
+ }
859
+ const message = messages[i];
860
+ if (message.role !== "assistant") {
861
+ continue;
862
+ }
863
+ for (const part of message.parts) {
864
+ if (part.type === "dynamic-tool" && part.toolCallId === toolCallId) {
865
+ return i;
866
+ }
867
+ }
868
+ count++;
869
+ }
870
+ return -1;
871
+ };
872
+ var locateToolPart = (messages, toolCallId, allowMetadataOnlyMatch) => {
873
+ const lastMessage = messages[messages.length - 1];
874
+ if (lastMessage && lastMessage.role === "assistant") {
875
+ const toolPartIndex2 = lastMessage.parts.findIndex(
876
+ (part) => (part.type === "dynamic-tool" || typeof part.type === "string" && part.type.startsWith("tool-")) && "toolCallId" in part && part.toolCallId === toolCallId
877
+ );
878
+ if (toolPartIndex2 !== -1) {
879
+ return { messageIndex: messages.length - 1, toolPartIndex: toolPartIndex2 };
880
+ }
881
+ }
882
+ const messageIndex = findMessageIndexByToolCallId(messages, toolCallId);
883
+ if (messageIndex === -1) return null;
884
+ const message = messages[messageIndex];
885
+ if (!message || message.role !== "assistant") return null;
886
+ const toolPartIndex = message.parts.findIndex(
887
+ (part) => (part.type === "dynamic-tool" || typeof part.type === "string" && part.type.startsWith("tool-")) && "toolCallId" in part && part.toolCallId === toolCallId
888
+ );
889
+ if (toolPartIndex === -1) {
890
+ return allowMetadataOnlyMatch ? { messageIndex, toolPartIndex: -1 } : null;
891
+ }
892
+ return { messageIndex, toolPartIndex };
893
+ };
894
+ var mergeBgTaskMetadata = (existing, mode, args) => {
895
+ const existingAny = existing ?? {};
896
+ const existingBgTasks = existingAny.backgroundTasks ?? {};
897
+ const nextBgTasks = { ...existingBgTasks };
898
+ if (args.perTaskEntry) {
899
+ const { toolCallId, startedAt, completedAt, taskId } = args.perTaskEntry;
900
+ const prev = existingBgTasks[toolCallId] ?? { taskId };
901
+ nextBgTasks[toolCallId] = {
902
+ ...prev,
903
+ taskId,
904
+ ...startedAt !== void 0 ? { startedAt } : {},
905
+ ...completedAt !== void 0 ? { completedAt } : {}
906
+ };
907
+ }
908
+ return {
909
+ ...existingAny,
910
+ mode,
911
+ ...args.resetRunningCount ? { runningBackgroundTasksCount: void 0 } : {},
912
+ backgroundTasks: nextBgTasks
913
+ };
914
+ };
841
915
 
842
916
  // src/lib/ai-sdk/utils/toAssistantUIMessage.ts
843
917
  var toAssistantUIMessage = (message) => {
@@ -1745,6 +1819,7 @@ var useChat = ({
1745
1819
  const _networkRunId = react.useRef(void 0);
1746
1820
  const _onNetworkChunk = react.useRef(void 0);
1747
1821
  const _requestContext = react.useRef(propsRequestContext);
1822
+ const _streamAbortRef = react.useRef(null);
1748
1823
  const [messages, setMessages] = react.useState([]);
1749
1824
  const [toolCallApprovals, setToolCallApprovals] = react.useState({});
1750
1825
  const [networkToolCallApprovals, setNetworkToolCallApprovals] = react.useState({});
@@ -1867,13 +1942,20 @@ var useChat = ({
1867
1942
  const resolvedRequestContext = requestContext ?? propsRequestContext;
1868
1943
  _requestContext.current = resolvedRequestContext;
1869
1944
  setIsRunning(true);
1945
+ _streamAbortRef.current?.abort();
1946
+ const internalAbort = new AbortController();
1947
+ _streamAbortRef.current = internalAbort;
1948
+ if (signal) {
1949
+ if (signal.aborted) internalAbort.abort();
1950
+ else signal.addEventListener("abort", () => internalAbort.abort(), { once: true });
1951
+ }
1870
1952
  const clientWithAbort = new clientJs.MastraClient({
1871
1953
  ...baseClient.options,
1872
- abortSignal: signal
1954
+ abortSignal: internalAbort.signal
1873
1955
  });
1874
1956
  const agent = clientWithAbort.getAgent(agentId);
1875
1957
  const runId = uuid.v4();
1876
- const response = await agent.stream(coreUserMessages, {
1958
+ const response = await agent.streamUntilIdle(coreUserMessages, {
1877
1959
  runId,
1878
1960
  maxSteps,
1879
1961
  modelSettings: {
@@ -1900,6 +1982,9 @@ var useChat = ({
1900
1982
  void onChunk?.(chunk);
1901
1983
  }
1902
1984
  });
1985
+ if (_streamAbortRef.current === internalAbort) {
1986
+ _streamAbortRef.current = null;
1987
+ }
1903
1988
  setIsRunning(false);
1904
1989
  };
1905
1990
  const network = async ({