@mastra/react 0.0.0-fix-runtimeContext-passing-chatRoute-20251008220150 → 0.0.0-unified-sidebar-20251010130811

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/dist/index.es.js CHANGED
@@ -21,165 +21,6 @@ const MastraReactProvider = ({ children, baseUrl, headers }) => {
21
21
  return /* @__PURE__ */ jsx(MastraClientProvider, { baseUrl, headers, children });
22
22
  };
23
23
 
24
- const useChat = ({ agentId, initializeMessages }) => {
25
- const [messages, setMessages] = useState(initializeMessages || []);
26
- const baseClient = useMastraClient();
27
- const [isRunning, setIsRunning] = useState(false);
28
- const generate = async ({
29
- coreUserMessages,
30
- runtimeContext,
31
- threadId,
32
- modelSettings,
33
- signal,
34
- onFinish
35
- }) => {
36
- const {
37
- frequencyPenalty,
38
- presencePenalty,
39
- maxRetries,
40
- maxTokens,
41
- temperature,
42
- topK,
43
- topP,
44
- instructions,
45
- providerOptions
46
- } = modelSettings || {};
47
- setIsRunning(true);
48
- const clientWithAbort = new MastraClient({
49
- ...baseClient.options,
50
- abortSignal: signal
51
- });
52
- const agent = clientWithAbort.getAgent(agentId);
53
- const response = await agent.generate({
54
- messages: coreUserMessages,
55
- runId: agentId,
56
- modelSettings: {
57
- frequencyPenalty,
58
- presencePenalty,
59
- maxRetries,
60
- maxOutputTokens: maxTokens,
61
- temperature,
62
- topK,
63
- topP
64
- },
65
- instructions,
66
- runtimeContext,
67
- ...threadId ? { threadId, resourceId: agentId } : {},
68
- providerOptions
69
- });
70
- setIsRunning(false);
71
- const uiMessages = response && "uiMessages" in response.response && response.response.uiMessages ? response.response.uiMessages : [];
72
- const formatted = onFinish({ messages: uiMessages, tripwireReason: response.tripwireReason });
73
- setMessages((prev) => [...prev, ...formatted]);
74
- };
75
- const stream = async ({
76
- coreUserMessages,
77
- runtimeContext,
78
- threadId,
79
- onChunk,
80
- modelSettings,
81
- signal
82
- }) => {
83
- const {
84
- frequencyPenalty,
85
- presencePenalty,
86
- maxRetries,
87
- maxTokens,
88
- temperature,
89
- topK,
90
- topP,
91
- instructions,
92
- providerOptions
93
- } = modelSettings || {};
94
- setIsRunning(true);
95
- const clientWithAbort = new MastraClient({
96
- ...baseClient.options,
97
- abortSignal: signal
98
- });
99
- const agent = clientWithAbort.getAgent(agentId);
100
- const response = await agent.stream({
101
- messages: coreUserMessages,
102
- runId: agentId,
103
- modelSettings: {
104
- frequencyPenalty,
105
- presencePenalty,
106
- maxRetries,
107
- maxOutputTokens: maxTokens,
108
- temperature,
109
- topK,
110
- topP
111
- },
112
- instructions,
113
- runtimeContext,
114
- ...threadId ? { threadId, resourceId: agentId } : {},
115
- providerOptions
116
- });
117
- if (!response.body) {
118
- setIsRunning(false);
119
- throw new Error("[Stream] No response body");
120
- }
121
- await response.processDataStream({
122
- onChunk: (chunk) => {
123
- flushSync(() => {
124
- setMessages((prev) => onChunk(chunk, prev));
125
- });
126
- return Promise.resolve();
127
- }
128
- });
129
- setIsRunning(false);
130
- };
131
- const network = async ({
132
- coreUserMessages,
133
- runtimeContext,
134
- threadId,
135
- onNetworkChunk,
136
- modelSettings,
137
- signal
138
- }) => {
139
- const { frequencyPenalty, presencePenalty, maxRetries, maxTokens, temperature, topK, topP, maxSteps } = modelSettings || {};
140
- setIsRunning(true);
141
- const clientWithAbort = new MastraClient({
142
- ...baseClient.options,
143
- abortSignal: signal
144
- });
145
- const agent = clientWithAbort.getAgent(agentId);
146
- const response = await agent.network({
147
- messages: coreUserMessages,
148
- maxSteps,
149
- modelSettings: {
150
- frequencyPenalty,
151
- presencePenalty,
152
- maxRetries,
153
- maxOutputTokens: maxTokens,
154
- temperature,
155
- topK,
156
- topP
157
- },
158
- runId: agentId,
159
- runtimeContext,
160
- ...threadId ? { thread: threadId, resourceId: agentId } : {}
161
- });
162
- await response.processDataStream({
163
- onChunk: (chunk) => {
164
- flushSync(() => {
165
- setMessages((prev) => onNetworkChunk(chunk, prev));
166
- });
167
- return Promise.resolve();
168
- }
169
- });
170
- setIsRunning(false);
171
- };
172
- return {
173
- network,
174
- stream,
175
- generate,
176
- isRunning,
177
- messages,
178
- setMessages,
179
- cancelRun: () => setIsRunning(false)
180
- };
181
- };
182
-
183
24
  const mapWorkflowStreamChunkToWatchResult = (prev, chunk) => {
184
25
  if (chunk.type === "workflow-start") {
185
26
  return {
@@ -251,17 +92,32 @@ const mapWorkflowStreamChunkToWatchResult = (prev, chunk) => {
251
92
  }
252
93
  return prev;
253
94
  };
254
- const toUIMessage = ({
255
- chunk,
256
- conversation
257
- }) => {
95
+ const toUIMessage = ({ chunk, conversation, metadata }) => {
258
96
  const result = [...conversation];
259
97
  switch (chunk.type) {
98
+ case "tripwire": {
99
+ const newMessage = {
100
+ id: `tripwire-${chunk.runId + Date.now()}`,
101
+ role: "assistant",
102
+ parts: [
103
+ {
104
+ type: "text",
105
+ text: chunk.payload.tripwireReason
106
+ }
107
+ ],
108
+ metadata: {
109
+ ...metadata,
110
+ status: "warning"
111
+ }
112
+ };
113
+ return [...result, newMessage];
114
+ }
260
115
  case "start": {
261
116
  const newMessage = {
262
- id: chunk.runId,
117
+ id: `start-${chunk.runId + Date.now()}`,
263
118
  role: "assistant",
264
- parts: []
119
+ parts: [],
120
+ metadata
265
121
  };
266
122
  return [...result, newMessage];
267
123
  }
@@ -311,7 +167,7 @@ const toUIMessage = ({
311
167
  const lastMessage = result[result.length - 1];
312
168
  if (!lastMessage || lastMessage.role !== "assistant") {
313
169
  const newMessage = {
314
- id: chunk.runId,
170
+ id: `reasoning-${chunk.runId + Date.now()}`,
315
171
  role: "assistant",
316
172
  parts: [
317
173
  {
@@ -320,7 +176,8 @@ const toUIMessage = ({
320
176
  state: "streaming",
321
177
  providerMetadata: chunk.payload.providerMetadata
322
178
  }
323
- ]
179
+ ],
180
+ metadata
324
181
  };
325
182
  return [...result, newMessage];
326
183
  }
@@ -355,7 +212,7 @@ const toUIMessage = ({
355
212
  const lastMessage = result[result.length - 1];
356
213
  if (!lastMessage || lastMessage.role !== "assistant") {
357
214
  const newMessage = {
358
- id: chunk.runId,
215
+ id: `tool-call-${chunk.runId + Date.now()}`,
359
216
  role: "assistant",
360
217
  parts: [
361
218
  {
@@ -366,7 +223,8 @@ const toUIMessage = ({
366
223
  input: chunk.payload.args,
367
224
  callProviderMetadata: chunk.payload.providerMetadata
368
225
  }
369
- ]
226
+ ],
227
+ metadata
370
228
  };
371
229
  return [...result, newMessage];
372
230
  }
@@ -408,13 +266,14 @@ const toUIMessage = ({
408
266
  callProviderMetadata: chunk.payload.providerMetadata
409
267
  };
410
268
  } else {
269
+ const isWorkflow = Boolean(chunk.payload.result?.result?.steps);
411
270
  parts[toolPartIndex] = {
412
271
  type: "dynamic-tool",
413
272
  toolName: toolPart.toolName,
414
273
  toolCallId: toolPart.toolCallId,
415
274
  state: "output-available",
416
275
  input: toolPart.input,
417
- output: toolPart.output,
276
+ output: isWorkflow ? chunk.payload.result?.result : chunk.payload.result,
418
277
  callProviderMetadata: chunk.payload.providerMetadata
419
278
  };
420
279
  }
@@ -542,283 +401,26 @@ const toUIMessage = ({
542
401
  ];
543
402
  }
544
403
  case "error": {
545
- return result;
546
- }
547
- // For all other chunk types, return conversation unchanged
548
- default:
549
- return result;
550
- }
551
- };
552
-
553
- const toNetworkUIMessage = ({
554
- chunk,
555
- conversation
556
- }) => {
557
- const result = [...conversation];
558
- if (chunk.type === "agent-execution-start" || chunk.type === "workflow-execution-start") {
559
- const primitiveId = chunk.payload?.args?.primitiveId;
560
- const runId = chunk.payload.runId;
561
- if (!primitiveId || !runId) return result;
562
- const newMessage = {
563
- id: runId,
564
- role: "assistant",
565
- parts: [
566
- {
567
- type: "dynamic-tool",
568
- toolName: primitiveId,
569
- toolCallId: runId,
570
- state: "input-available",
571
- input: chunk.payload.args,
572
- output: {
573
- networkMetadata: {
574
- selectionReason: chunk.payload?.args?.selectionReason || "",
575
- from: chunk.type === "agent-execution-start" ? "AGENT" : "WORKFLOW"
576
- },
577
- result: void 0
578
- }
579
- }
580
- ]
581
- };
582
- return [...result, newMessage];
583
- }
584
- if (chunk.type.startsWith("agent-execution-event-")) {
585
- const agentChunk = chunk.payload;
586
- const lastMessage = result[result.length - 1];
587
- if (!lastMessage || lastMessage.role !== "assistant") return result;
588
- const parts = [...lastMessage.parts];
589
- const toolPartIndex = parts.findIndex((part) => part.type === "dynamic-tool");
590
- if (toolPartIndex === -1) return result;
591
- const toolPart = parts[toolPartIndex];
592
- if (toolPart.type !== "dynamic-tool") return result;
593
- if (agentChunk.type === "text-delta") {
594
- const currentInput = toolPart.input;
595
- const messages = currentInput?.messages || [];
596
- const lastMessage2 = messages[messages.length - 1];
597
- const nextMessages = lastMessage2?.type === "text" ? [
598
- ...messages.slice(0, -1),
599
- { type: "text", content: (lastMessage2?.content || "") + agentChunk.payload.text }
600
- ] : [...messages, { type: "text", content: agentChunk.payload.text }];
601
- parts[toolPartIndex] = {
602
- ...toolPart,
603
- input: {
604
- ...currentInput,
605
- messages: nextMessages
606
- }
607
- };
608
- } else if (agentChunk.type === "tool-call") {
609
- const currentInput = toolPart.input;
610
- const messages = currentInput?.messages || [];
611
- parts[toolPartIndex] = {
612
- ...toolPart,
613
- input: {
614
- ...currentInput,
615
- messages: [
616
- ...messages,
617
- {
618
- type: "tool",
619
- toolCallId: agentChunk.payload.toolCallId,
620
- toolName: agentChunk.payload.toolName,
621
- toolInput: agentChunk.payload.args
622
- }
623
- ]
624
- }
625
- };
626
- } else if (agentChunk.type === "tool-result") {
627
- const currentInput = toolPart.input;
628
- const messages = currentInput?.messages || [];
629
- const lastToolIndex = messages.length - 1;
630
- if (lastToolIndex >= 0 && messages[lastToolIndex]?.type === "tool") {
631
- parts[toolPartIndex] = {
632
- ...toolPart,
633
- input: {
634
- ...currentInput,
635
- messages: [
636
- ...messages.slice(0, -1),
637
- {
638
- ...messages[lastToolIndex],
639
- toolOutput: agentChunk.payload.result
640
- }
641
- ]
642
- }
643
- };
644
- }
645
- } else if (agentChunk.type === "tool-output") {
646
- if (agentChunk.payload?.output?.type?.startsWith("workflow-")) {
647
- const currentOutput = toolPart.output || {};
648
- const existingWorkflowState = currentOutput.result || {};
649
- const updatedWorkflowState = mapWorkflowStreamChunkToWatchResult(
650
- existingWorkflowState,
651
- agentChunk.payload.output
652
- );
653
- parts[toolPartIndex] = {
654
- ...toolPart,
655
- output: {
656
- networkMetadata: currentOutput.networkMetadata,
657
- result: updatedWorkflowState
658
- }
659
- };
660
- }
661
- }
662
- return [
663
- ...result.slice(0, -1),
664
- {
665
- ...lastMessage,
666
- parts
667
- }
668
- ];
669
- }
670
- if (chunk.type.startsWith("workflow-execution-event-")) {
671
- const workflowChunk = chunk.payload;
672
- const lastMessage = result[result.length - 1];
673
- if (!lastMessage || lastMessage.role !== "assistant") return result;
674
- const parts = [...lastMessage.parts];
675
- const toolPartIndex = parts.findIndex((part) => part.type === "dynamic-tool");
676
- if (toolPartIndex === -1) return result;
677
- const toolPart = parts[toolPartIndex];
678
- if (toolPart.type !== "dynamic-tool") return result;
679
- const currentOutput = toolPart.output || {};
680
- const existingWorkflowState = currentOutput.result || {};
681
- const updatedWorkflowState = mapWorkflowStreamChunkToWatchResult(existingWorkflowState, workflowChunk);
682
- parts[toolPartIndex] = {
683
- ...toolPart,
684
- output: {
685
- networkMetadata: currentOutput.networkMetadata,
686
- result: updatedWorkflowState
687
- }
688
- };
689
- return [
690
- ...result.slice(0, -1),
691
- {
692
- ...lastMessage,
693
- parts
694
- }
695
- ];
696
- }
697
- if (chunk.type === "tool-execution-start") {
698
- const { args: argsData } = chunk.payload;
699
- const lastMessage = result[result.length - 1];
700
- const nestedArgs = argsData.args || {};
701
- if (!lastMessage || lastMessage.role !== "assistant") {
702
404
  const newMessage = {
703
- id: chunk.runId,
405
+ id: `error-${chunk.runId + Date.now()}`,
704
406
  role: "assistant",
705
407
  parts: [
706
408
  {
707
- type: "dynamic-tool",
708
- toolName: argsData.toolName || "unknown",
709
- toolCallId: argsData.toolCallId || "unknown",
710
- state: "input-available",
711
- input: nestedArgs,
712
- output: {
713
- networkMetadata: {
714
- selectionReason: argsData.selectionReason || ""
715
- },
716
- result: void 0
717
- }
409
+ type: "text",
410
+ text: chunk.payload.error
718
411
  }
719
- ]
412
+ ],
413
+ metadata: {
414
+ ...metadata,
415
+ status: "error"
416
+ }
720
417
  };
721
418
  return [...result, newMessage];
722
419
  }
723
- const parts = [...lastMessage.parts];
724
- parts.push({
725
- type: "dynamic-tool",
726
- toolName: argsData.toolName || "unknown",
727
- toolCallId: argsData.toolCallId || "unknown",
728
- state: "input-available",
729
- input: nestedArgs,
730
- output: {
731
- networkMetadata: {
732
- selectionReason: argsData.selectionReason || ""
733
- },
734
- result: void 0
735
- }
736
- });
737
- return [
738
- ...result.slice(0, -1),
739
- {
740
- ...lastMessage,
741
- parts
742
- }
743
- ];
744
- }
745
- if (chunk.type === "tool-execution-end") {
746
- const lastMessage = result[result.length - 1];
747
- if (!lastMessage || lastMessage.role !== "assistant") return result;
748
- const parts = [...lastMessage.parts];
749
- const toolPartIndex = parts.findIndex(
750
- (part) => part.type === "dynamic-tool" && "toolCallId" in part && part.toolCallId === chunk.payload.toolCallId
751
- );
752
- if (toolPartIndex !== -1) {
753
- const toolPart = parts[toolPartIndex];
754
- if (toolPart.type === "dynamic-tool") {
755
- const currentOutput = toolPart.output;
756
- parts[toolPartIndex] = {
757
- type: "dynamic-tool",
758
- toolName: toolPart.toolName,
759
- toolCallId: toolPart.toolCallId,
760
- state: "output-available",
761
- input: toolPart.input,
762
- output: {
763
- networkMetadata: currentOutput?.networkMetadata,
764
- result: chunk.payload.result
765
- }
766
- };
767
- }
768
- }
769
- return [
770
- ...result.slice(0, -1),
771
- {
772
- ...lastMessage,
773
- parts
774
- }
775
- ];
776
- }
777
- if (chunk.type === "agent-execution-end" || chunk.type === "workflow-execution-end") {
778
- const lastMessage = result[result.length - 1];
779
- if (!lastMessage || lastMessage.role !== "assistant") return result;
780
- const parts = [...lastMessage.parts];
781
- const toolPartIndex = parts.findIndex((part) => part.type === "dynamic-tool");
782
- if (toolPartIndex !== -1) {
783
- const toolPart = parts[toolPartIndex];
784
- if (toolPart.type === "dynamic-tool") {
785
- const currentOutput = toolPart.output;
786
- parts[toolPartIndex] = {
787
- type: "dynamic-tool",
788
- toolName: toolPart.toolName,
789
- toolCallId: toolPart.toolCallId,
790
- state: "output-available",
791
- input: toolPart.input,
792
- output: {
793
- networkMetadata: currentOutput?.networkMetadata,
794
- result: currentOutput?.result || chunk.payload?.result || ""
795
- }
796
- };
797
- }
798
- }
799
- return [
800
- ...result.slice(0, -1),
801
- {
802
- ...lastMessage,
803
- parts
804
- }
805
- ];
806
- }
807
- if (chunk.type === "network-execution-event-step-finish") {
808
- const newMessage = {
809
- id: chunk.runId,
810
- role: "assistant",
811
- parts: [
812
- {
813
- type: "text",
814
- text: chunk.payload?.result || "",
815
- state: "done"
816
- }
817
- ]
818
- };
819
- return [...result, newMessage];
420
+ // For all other chunk types, return conversation unchanged
421
+ default:
422
+ return result;
820
423
  }
821
- return result;
822
424
  };
823
425
 
824
426
  const toAssistantUIMessage = (message) => {
@@ -827,13 +429,15 @@ const toAssistantUIMessage = (message) => {
827
429
  if (part.type === "text") {
828
430
  return {
829
431
  type: "text",
830
- text: part.text
432
+ text: part.text,
433
+ metadata: message.metadata
831
434
  };
832
435
  }
833
436
  if (part.type === "reasoning") {
834
437
  return {
835
438
  type: "reasoning",
836
- text: part.text
439
+ text: part.text,
440
+ metadata: message.metadata
837
441
  };
838
442
  }
839
443
  if (part.type === "source-url") {
@@ -842,7 +446,8 @@ const toAssistantUIMessage = (message) => {
842
446
  sourceType: "url",
843
447
  id: part.sourceId,
844
448
  url: part.url,
845
- title: part.title
449
+ title: part.title,
450
+ metadata: message.metadata
846
451
  };
847
452
  }
848
453
  if (part.type === "source-document") {
@@ -850,16 +455,18 @@ const toAssistantUIMessage = (message) => {
850
455
  type: "file",
851
456
  filename: part.filename,
852
457
  mimeType: part.mediaType,
853
- data: ""
458
+ data: "",
854
459
  // Source documents don't have inline data
460
+ metadata: message.metadata
855
461
  };
856
462
  }
857
463
  if (part.type === "file") {
858
464
  return {
859
465
  type: "file",
860
466
  mimeType: part.mediaType,
861
- data: part.url
467
+ data: part.url,
862
468
  // Use URL as data source
469
+ metadata: message.metadata
863
470
  };
864
471
  }
865
472
  if (part.type === "dynamic-tool") {
@@ -867,22 +474,27 @@ const toAssistantUIMessage = (message) => {
867
474
  type: "tool-call",
868
475
  toolCallId: part.toolCallId,
869
476
  toolName: part.toolName,
870
- argsText: JSON.stringify(part.input)
477
+ argsText: JSON.stringify(part.input),
478
+ args: part.input,
479
+ metadata: message.metadata
871
480
  };
872
- if (part.state === "output-available" && "output" in part) {
873
- return { ...baseToolCall, result: part.output };
874
- } else if (part.state === "output-error" && "errorText" in part) {
481
+ if (part.state === "output-error" && "errorText" in part) {
875
482
  return { ...baseToolCall, result: part.errorText, isError: true };
876
483
  }
484
+ if ("output" in part) {
485
+ return { ...baseToolCall, result: part.output };
486
+ }
877
487
  return baseToolCall;
878
488
  }
879
- if (part.type.startsWith("tool-")) {
489
+ if (part.type.startsWith("tool-") && part.state !== "input-available") {
880
490
  const toolName = "toolName" in part && typeof part.toolName === "string" ? part.toolName : part.type.substring(5);
881
491
  const baseToolCall = {
882
492
  type: "tool-call",
883
493
  toolCallId: "toolCallId" in part && typeof part.toolCallId === "string" ? part.toolCallId : "",
884
494
  toolName,
885
- argsText: "input" in part ? JSON.stringify(part.input) : "{}"
495
+ argsText: "input" in part ? JSON.stringify(part.input) : "{}",
496
+ args: "input" in part ? part.input : {},
497
+ metadata: message.metadata
886
498
  };
887
499
  if ("output" in part) {
888
500
  return { ...baseToolCall, result: part.output };
@@ -893,7 +505,8 @@ const toAssistantUIMessage = (message) => {
893
505
  }
894
506
  return {
895
507
  type: "text",
896
- text: ""
508
+ text: "",
509
+ metadata: message.metadata
897
510
  };
898
511
  });
899
512
  let status;
@@ -918,20 +531,570 @@ const toAssistantUIMessage = (message) => {
918
531
  status = { type: "complete", reason: "stop" };
919
532
  }
920
533
  }
921
- const metadata = extendedMessage.metadata ? {
922
- custom: extendedMessage.metadata
923
- } : void 0;
924
534
  const threadMessage = {
925
535
  role: message.role,
926
536
  content,
927
537
  id: message.id,
928
538
  createdAt: extendedMessage.createdAt,
929
539
  status,
930
- metadata,
931
540
  attachments: extendedMessage.experimental_attachments
932
541
  };
933
542
  return threadMessage;
934
543
  };
935
544
 
936
- export { MastraReactProvider, mapWorkflowStreamChunkToWatchResult, toAssistantUIMessage, toNetworkUIMessage, toUIMessage, useChat, useMastraClient };
545
+ class AISdkNetworkTransformer {
546
+ transform({ chunk, conversation, metadata }) {
547
+ const newConversation = [...conversation];
548
+ if (chunk.type.startsWith("agent-execution-")) {
549
+ return this.handleAgentConversation(chunk, newConversation, metadata);
550
+ }
551
+ if (chunk.type.startsWith("workflow-execution-")) {
552
+ return this.handleWorkflowConversation(chunk, newConversation, metadata);
553
+ }
554
+ if (chunk.type.startsWith("tool-execution-")) {
555
+ return this.handleToolConversation(chunk, newConversation, metadata);
556
+ }
557
+ if (chunk.type === "network-execution-event-step-finish") {
558
+ const newMessage = {
559
+ id: `network-execution-event-step-finish-${chunk.runId}-${Date.now()}`,
560
+ role: "assistant",
561
+ parts: [
562
+ {
563
+ type: "text",
564
+ text: chunk.payload?.result || "",
565
+ state: "done"
566
+ }
567
+ ],
568
+ metadata
569
+ };
570
+ return [...newConversation, newMessage];
571
+ }
572
+ return newConversation;
573
+ }
574
+ handleAgentConversation = (chunk, newConversation, metadata) => {
575
+ if (chunk.type === "agent-execution-start") {
576
+ const primitiveId = chunk.payload?.args?.primitiveId;
577
+ const runId = chunk.payload.runId;
578
+ if (!primitiveId || !runId) return newConversation;
579
+ const newMessage = {
580
+ id: `agent-execution-start-${runId}-${Date.now()}`,
581
+ role: "assistant",
582
+ parts: [
583
+ {
584
+ type: "dynamic-tool",
585
+ toolName: primitiveId,
586
+ toolCallId: runId,
587
+ state: "input-available",
588
+ input: chunk.payload.args
589
+ }
590
+ ],
591
+ metadata: {
592
+ ...metadata,
593
+ selectionReason: chunk.payload?.args?.selectionReason || "",
594
+ agentInput: chunk.payload?.args?.task,
595
+ mode: "network",
596
+ from: "AGENT"
597
+ }
598
+ };
599
+ return [...newConversation, newMessage];
600
+ }
601
+ if (chunk.type === "agent-execution-end") {
602
+ const lastMessage = newConversation[newConversation.length - 1];
603
+ if (!lastMessage || lastMessage.role !== "assistant") return newConversation;
604
+ const parts = [...lastMessage.parts];
605
+ const toolPartIndex = parts.findIndex((part) => part.type === "dynamic-tool");
606
+ if (toolPartIndex !== -1) {
607
+ const toolPart = parts[toolPartIndex];
608
+ if (toolPart.type === "dynamic-tool") {
609
+ const currentOutput = toolPart.output;
610
+ parts[toolPartIndex] = {
611
+ type: "dynamic-tool",
612
+ toolName: toolPart.toolName,
613
+ toolCallId: toolPart.toolCallId,
614
+ state: "output-available",
615
+ input: toolPart.input,
616
+ output: {
617
+ ...currentOutput,
618
+ result: currentOutput?.result || chunk.payload?.result || ""
619
+ }
620
+ };
621
+ }
622
+ }
623
+ return [
624
+ ...newConversation.slice(0, -1),
625
+ {
626
+ ...lastMessage,
627
+ parts
628
+ }
629
+ ];
630
+ }
631
+ if (chunk.type.startsWith("agent-execution-event-")) {
632
+ const lastMessage = newConversation[newConversation.length - 1];
633
+ if (!lastMessage || lastMessage.role !== "assistant") return newConversation;
634
+ const agentChunk = chunk.payload;
635
+ const parts = [...lastMessage.parts];
636
+ const toolPartIndex = parts.findIndex((part) => part.type === "dynamic-tool");
637
+ if (toolPartIndex === -1) return newConversation;
638
+ const toolPart = parts[toolPartIndex];
639
+ if (agentChunk.type === "text-delta") {
640
+ const childMessages = toolPart?.output?.childMessages || [];
641
+ const lastChildMessage = childMessages[childMessages.length - 1];
642
+ const textMessage = { type: "text", content: (lastChildMessage?.content || "") + agentChunk.payload.text };
643
+ const nextMessages = lastChildMessage?.type === "text" ? [...childMessages.slice(0, -1), textMessage] : [...childMessages, textMessage];
644
+ parts[toolPartIndex] = {
645
+ ...toolPart,
646
+ output: {
647
+ childMessages: nextMessages
648
+ }
649
+ };
650
+ } else if (agentChunk.type === "tool-call") {
651
+ const childMessages = toolPart?.output?.childMessages || [];
652
+ parts[toolPartIndex] = {
653
+ ...toolPart,
654
+ output: {
655
+ ...toolPart?.output,
656
+ childMessages: [
657
+ ...childMessages,
658
+ {
659
+ type: "tool",
660
+ toolCallId: agentChunk.payload.toolCallId,
661
+ toolName: agentChunk.payload.toolName,
662
+ args: agentChunk.payload.args
663
+ }
664
+ ]
665
+ }
666
+ };
667
+ } else if (agentChunk.type === "tool-output") {
668
+ if (agentChunk.payload?.output?.type?.startsWith("workflow-")) {
669
+ const childMessages = toolPart?.output?.childMessages || [];
670
+ const lastToolIndex = childMessages.length - 1;
671
+ const currentMessage = childMessages[lastToolIndex];
672
+ const actualExistingWorkflowState = currentMessage?.toolOutput || {};
673
+ const updatedWorkflowState = mapWorkflowStreamChunkToWatchResult(
674
+ actualExistingWorkflowState,
675
+ agentChunk.payload.output
676
+ );
677
+ if (lastToolIndex >= 0 && childMessages[lastToolIndex]?.type === "tool") {
678
+ parts[toolPartIndex] = {
679
+ ...toolPart,
680
+ output: {
681
+ ...toolPart?.output,
682
+ childMessages: [
683
+ ...childMessages.slice(0, -1),
684
+ {
685
+ ...currentMessage,
686
+ toolOutput: updatedWorkflowState
687
+ }
688
+ ]
689
+ }
690
+ };
691
+ }
692
+ }
693
+ } else if (agentChunk.type === "tool-result") {
694
+ const childMessages = toolPart?.output?.childMessages || [];
695
+ const lastToolIndex = childMessages.length - 1;
696
+ const isWorkflow = Boolean(agentChunk.payload?.result?.result?.steps);
697
+ if (lastToolIndex >= 0 && childMessages[lastToolIndex]?.type === "tool") {
698
+ parts[toolPartIndex] = {
699
+ ...toolPart,
700
+ output: {
701
+ ...toolPart?.output,
702
+ childMessages: [
703
+ ...childMessages.slice(0, -1),
704
+ {
705
+ ...childMessages[lastToolIndex],
706
+ toolOutput: isWorkflow ? agentChunk.payload.result.result : agentChunk.payload.result
707
+ }
708
+ ]
709
+ }
710
+ };
711
+ }
712
+ }
713
+ return [
714
+ ...newConversation.slice(0, -1),
715
+ {
716
+ ...lastMessage,
717
+ parts
718
+ }
719
+ ];
720
+ }
721
+ return newConversation;
722
+ };
723
+ handleWorkflowConversation = (chunk, newConversation, metadata) => {
724
+ if (chunk.type === "workflow-execution-start") {
725
+ const primitiveId = chunk.payload?.args?.primitiveId;
726
+ const runId = chunk.payload.runId;
727
+ if (!primitiveId || !runId) return newConversation;
728
+ let agentInput;
729
+ try {
730
+ agentInput = JSON.parse(chunk?.payload?.args?.prompt);
731
+ } catch (e) {
732
+ agentInput = chunk?.payload?.args?.prompt;
733
+ }
734
+ const newMessage = {
735
+ id: `workflow-start-${runId}-${Date.now()}`,
736
+ role: "assistant",
737
+ parts: [
738
+ {
739
+ type: "dynamic-tool",
740
+ toolName: primitiveId,
741
+ toolCallId: runId,
742
+ state: "input-available",
743
+ input: chunk.payload.args
744
+ }
745
+ ],
746
+ metadata: {
747
+ ...metadata,
748
+ selectionReason: chunk.payload?.args?.selectionReason || "",
749
+ from: "WORKFLOW",
750
+ mode: "network",
751
+ agentInput
752
+ }
753
+ };
754
+ return [...newConversation, newMessage];
755
+ }
756
+ if (chunk.type.startsWith("workflow-execution-event-")) {
757
+ const lastMessage = newConversation[newConversation.length - 1];
758
+ if (!lastMessage || lastMessage.role !== "assistant") return newConversation;
759
+ const parts = [...lastMessage.parts];
760
+ const toolPartIndex = parts.findIndex((part) => part.type === "dynamic-tool");
761
+ if (toolPartIndex === -1) return newConversation;
762
+ const toolPart = parts[toolPartIndex];
763
+ if (toolPart.type !== "dynamic-tool") return newConversation;
764
+ const existingWorkflowState = toolPart.output || {};
765
+ const updatedWorkflowState = mapWorkflowStreamChunkToWatchResult(existingWorkflowState, chunk.payload);
766
+ parts[toolPartIndex] = {
767
+ ...toolPart,
768
+ output: updatedWorkflowState
769
+ };
770
+ return [
771
+ ...newConversation.slice(0, -1),
772
+ {
773
+ ...lastMessage,
774
+ parts
775
+ }
776
+ ];
777
+ }
778
+ return newConversation;
779
+ };
780
+ handleToolConversation = (chunk, newConversation, metadata) => {
781
+ if (chunk.type === "tool-execution-start") {
782
+ const { args: argsData } = chunk.payload;
783
+ const lastMessage = newConversation[newConversation.length - 1];
784
+ const nestedArgs = argsData.args || {};
785
+ if (!lastMessage || lastMessage.role !== "assistant") {
786
+ const newMessage = {
787
+ id: `tool-start-${chunk.runId}-${Date.now()}`,
788
+ role: "assistant",
789
+ parts: [
790
+ {
791
+ type: "dynamic-tool",
792
+ toolName: argsData.toolName || "unknown",
793
+ toolCallId: argsData.toolCallId || "unknown",
794
+ state: "input-available",
795
+ input: nestedArgs
796
+ }
797
+ ],
798
+ metadata: {
799
+ ...metadata,
800
+ selectionReason: metadata?.mode === "network" ? metadata.selectionReason || argsData.selectionReason : "",
801
+ mode: "network",
802
+ agentInput: nestedArgs
803
+ }
804
+ };
805
+ return [...newConversation, newMessage];
806
+ }
807
+ const parts = [...lastMessage.parts];
808
+ parts.push({
809
+ type: "dynamic-tool",
810
+ toolName: argsData.toolName || "unknown",
811
+ toolCallId: argsData.toolCallId || "unknown",
812
+ state: "input-available",
813
+ input: nestedArgs
814
+ });
815
+ return [
816
+ ...newConversation.slice(0, -1),
817
+ {
818
+ ...lastMessage,
819
+ parts
820
+ }
821
+ ];
822
+ }
823
+ if (chunk.type === "tool-execution-end") {
824
+ const lastMessage = newConversation[newConversation.length - 1];
825
+ if (!lastMessage || lastMessage.role !== "assistant") return newConversation;
826
+ const parts = [...lastMessage.parts];
827
+ const toolPartIndex = parts.findIndex(
828
+ (part) => part.type === "dynamic-tool" && "toolCallId" in part && part.toolCallId === chunk.payload.toolCallId
829
+ );
830
+ if (toolPartIndex !== -1) {
831
+ const toolPart = parts[toolPartIndex];
832
+ if (toolPart.type === "dynamic-tool") {
833
+ const currentOutput = toolPart.output;
834
+ parts[toolPartIndex] = {
835
+ type: "dynamic-tool",
836
+ toolName: toolPart.toolName,
837
+ toolCallId: toolPart.toolCallId,
838
+ state: "output-available",
839
+ input: toolPart.input,
840
+ output: currentOutput?.result || chunk.payload?.result || ""
841
+ };
842
+ }
843
+ }
844
+ return [
845
+ ...newConversation.slice(0, -1),
846
+ {
847
+ ...lastMessage,
848
+ parts
849
+ }
850
+ ];
851
+ }
852
+ return newConversation;
853
+ };
854
+ }
855
+
856
+ const resolveInitialMessages = (messages) => {
857
+ return messages.map((message) => {
858
+ const networkPart = message.parts.find((part) => part.type === "text" && part.text.includes('"isNetwork":true'));
859
+ if (networkPart && networkPart.type === "text") {
860
+ try {
861
+ const json = JSON.parse(networkPart.text);
862
+ if (json.isNetwork === true) {
863
+ const selectionReason = json.selectionReason || "";
864
+ const primitiveType = json.primitiveType || "";
865
+ const primitiveId = json.primitiveId || "";
866
+ const finalResult = json.finalResult;
867
+ const toolCalls = finalResult?.toolCalls || [];
868
+ const childMessages = [];
869
+ for (const toolCall of toolCalls) {
870
+ if (toolCall.type === "tool-call" && toolCall.payload) {
871
+ const toolCallId = toolCall.payload.toolCallId;
872
+ let toolResult;
873
+ for (const message2 of finalResult?.messages || []) {
874
+ for (const part of message2.content || []) {
875
+ if (typeof part === "object" && part.type === "tool-result" && part.toolCallId === toolCallId) {
876
+ toolResult = part;
877
+ break;
878
+ }
879
+ }
880
+ }
881
+ const isWorkflow = Boolean(toolResult?.result?.result?.steps);
882
+ childMessages.push({
883
+ type: "tool",
884
+ toolCallId: toolCall.payload.toolCallId,
885
+ toolName: toolCall.payload.toolName,
886
+ args: toolCall.payload.args,
887
+ toolOutput: isWorkflow ? toolResult?.result?.result : toolResult?.result
888
+ });
889
+ }
890
+ }
891
+ if (finalResult && finalResult.text) {
892
+ childMessages.push({
893
+ type: "text",
894
+ content: finalResult.text
895
+ });
896
+ }
897
+ const result = {
898
+ childMessages,
899
+ result: finalResult?.text || ""
900
+ };
901
+ console.log("json", json);
902
+ const nextMessage = {
903
+ role: "assistant",
904
+ parts: [
905
+ {
906
+ type: "dynamic-tool",
907
+ toolCallId: primitiveId,
908
+ toolName: primitiveId,
909
+ state: "output-available",
910
+ input: json.input,
911
+ output: result
912
+ }
913
+ ],
914
+ id: message.id,
915
+ metadata: {
916
+ ...message.metadata,
917
+ mode: "network",
918
+ selectionReason,
919
+ agentInput: json.input,
920
+ from: primitiveType === "agent" ? "AGENT" : "WORKFLOW"
921
+ }
922
+ };
923
+ return nextMessage;
924
+ }
925
+ } catch (error) {
926
+ return message;
927
+ }
928
+ }
929
+ return message;
930
+ });
931
+ };
932
+
933
+ const useChat = ({ agentId, initializeMessages }) => {
934
+ const [messages, setMessages] = useState(
935
+ () => resolveInitialMessages(initializeMessages?.() || [])
936
+ );
937
+ const baseClient = useMastraClient();
938
+ const [isRunning, setIsRunning] = useState(false);
939
+ const generate = async ({
940
+ coreUserMessages,
941
+ runtimeContext,
942
+ threadId,
943
+ modelSettings,
944
+ signal,
945
+ onFinish
946
+ }) => {
947
+ const {
948
+ frequencyPenalty,
949
+ presencePenalty,
950
+ maxRetries,
951
+ maxTokens,
952
+ temperature,
953
+ topK,
954
+ topP,
955
+ instructions,
956
+ providerOptions,
957
+ maxSteps
958
+ } = modelSettings || {};
959
+ setIsRunning(true);
960
+ const clientWithAbort = new MastraClient({
961
+ ...baseClient.options,
962
+ abortSignal: signal
963
+ });
964
+ const agent = clientWithAbort.getAgent(agentId);
965
+ const response = await agent.generate({
966
+ messages: coreUserMessages,
967
+ runId: agentId,
968
+ maxSteps,
969
+ modelSettings: {
970
+ frequencyPenalty,
971
+ presencePenalty,
972
+ maxRetries,
973
+ maxOutputTokens: maxTokens,
974
+ temperature,
975
+ topK,
976
+ topP
977
+ },
978
+ instructions,
979
+ runtimeContext,
980
+ ...threadId ? { threadId, resourceId: agentId } : {},
981
+ providerOptions
982
+ });
983
+ setIsRunning(false);
984
+ if (response && "uiMessages" in response.response && response.response.uiMessages) {
985
+ onFinish?.(response.response.uiMessages);
986
+ const mastraUIMessages = (response.response.uiMessages || []).map((message) => ({
987
+ ...message,
988
+ metadata: {
989
+ mode: "generate"
990
+ }
991
+ }));
992
+ setMessages((prev) => [...prev, ...mastraUIMessages]);
993
+ }
994
+ };
995
+ const stream = async ({ coreUserMessages, runtimeContext, threadId, onChunk, modelSettings, signal }) => {
996
+ const {
997
+ frequencyPenalty,
998
+ presencePenalty,
999
+ maxRetries,
1000
+ maxTokens,
1001
+ temperature,
1002
+ topK,
1003
+ topP,
1004
+ instructions,
1005
+ providerOptions,
1006
+ maxSteps
1007
+ } = modelSettings || {};
1008
+ setIsRunning(true);
1009
+ const clientWithAbort = new MastraClient({
1010
+ ...baseClient.options,
1011
+ abortSignal: signal
1012
+ });
1013
+ const agent = clientWithAbort.getAgent(agentId);
1014
+ const response = await agent.stream({
1015
+ messages: coreUserMessages,
1016
+ runId: agentId,
1017
+ maxSteps,
1018
+ modelSettings: {
1019
+ frequencyPenalty,
1020
+ presencePenalty,
1021
+ maxRetries,
1022
+ maxOutputTokens: maxTokens,
1023
+ temperature,
1024
+ topK,
1025
+ topP
1026
+ },
1027
+ instructions,
1028
+ runtimeContext,
1029
+ ...threadId ? { threadId, resourceId: agentId } : {},
1030
+ providerOptions
1031
+ });
1032
+ if (!response.body) {
1033
+ setIsRunning(false);
1034
+ throw new Error("[Stream] No response body");
1035
+ }
1036
+ await response.processDataStream({
1037
+ onChunk: async (chunk) => {
1038
+ flushSync(() => {
1039
+ setMessages((prev) => toUIMessage({ chunk, conversation: prev, metadata: { mode: "stream" } }));
1040
+ });
1041
+ onChunk?.(chunk);
1042
+ }
1043
+ });
1044
+ setIsRunning(false);
1045
+ };
1046
+ const network = async ({
1047
+ coreUserMessages,
1048
+ runtimeContext,
1049
+ threadId,
1050
+ onNetworkChunk,
1051
+ modelSettings,
1052
+ signal
1053
+ }) => {
1054
+ const { frequencyPenalty, presencePenalty, maxRetries, maxTokens, temperature, topK, topP, maxSteps } = modelSettings || {};
1055
+ setIsRunning(true);
1056
+ const clientWithAbort = new MastraClient({
1057
+ ...baseClient.options,
1058
+ abortSignal: signal
1059
+ });
1060
+ const agent = clientWithAbort.getAgent(agentId);
1061
+ const response = await agent.network({
1062
+ messages: coreUserMessages,
1063
+ maxSteps,
1064
+ modelSettings: {
1065
+ frequencyPenalty,
1066
+ presencePenalty,
1067
+ maxRetries,
1068
+ maxOutputTokens: maxTokens,
1069
+ temperature,
1070
+ topK,
1071
+ topP
1072
+ },
1073
+ runId: agentId,
1074
+ runtimeContext,
1075
+ ...threadId ? { thread: threadId, resourceId: agentId } : {}
1076
+ });
1077
+ const transformer = new AISdkNetworkTransformer();
1078
+ await response.processDataStream({
1079
+ onChunk: async (chunk) => {
1080
+ flushSync(() => {
1081
+ setMessages((prev) => transformer.transform({ chunk, conversation: prev, metadata: { mode: "network" } }));
1082
+ });
1083
+ onNetworkChunk?.(chunk);
1084
+ }
1085
+ });
1086
+ setIsRunning(false);
1087
+ };
1088
+ return {
1089
+ network,
1090
+ stream,
1091
+ generate,
1092
+ isRunning,
1093
+ messages,
1094
+ setMessages,
1095
+ cancelRun: () => setIsRunning(false)
1096
+ };
1097
+ };
1098
+
1099
+ export { MastraReactProvider, mapWorkflowStreamChunkToWatchResult, toAssistantUIMessage, toUIMessage, useChat, useMastraClient };
937
1100
  //# sourceMappingURL=index.es.js.map