@mastra/react 0.0.0-unified-sidebar-20251010130811 → 0.0.0-vnext-20251104230439

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.
Files changed (48) hide show
  1. package/CHANGELOG.md +162 -2
  2. package/dist/index.cjs +1818 -0
  3. package/dist/index.cjs.map +1 -0
  4. package/dist/{index.es.js → index.js} +782 -128
  5. package/dist/index.js.map +1 -0
  6. package/dist/react.css +719 -0
  7. package/dist/src/agent/hooks.d.ts +23 -6
  8. package/dist/src/agent/types.d.ts +1 -0
  9. package/dist/src/index.d.ts +1 -0
  10. package/dist/src/lib/ai-sdk/index.d.ts +1 -0
  11. package/dist/src/lib/ai-sdk/memory/resolveInitialMessages.d.ts +10 -0
  12. package/dist/src/lib/ai-sdk/memory/resolveInitialMessages.test.d.ts +1 -0
  13. package/dist/src/lib/ai-sdk/transformers/AISdkNetworkTransformer.d.ts +1 -0
  14. package/dist/src/lib/ai-sdk/transformers/AISdkNetworkTransformer.test.d.ts +1 -0
  15. package/dist/src/lib/ai-sdk/types.d.ts +7 -0
  16. package/dist/src/lib/ai-sdk/utils/fromCoreUserMessageToUIMessage.d.ts +10 -0
  17. package/dist/src/lib/ai-sdk/utils/fromCoreUserMessageToUIMessage.test.d.ts +1 -0
  18. package/dist/src/lib/ai-sdk/utils/toUIMessage.test.d.ts +1 -0
  19. package/dist/src/ui/Code/Code.d.ts +13 -0
  20. package/dist/src/ui/Code/highlight.d.ts +3 -0
  21. package/dist/src/ui/Code/index.d.ts +1 -0
  22. package/dist/src/ui/Entity/Entity.d.ts +13 -0
  23. package/dist/src/ui/Entity/Entity.stories.d.ts +22 -0
  24. package/dist/src/ui/Entity/Entry.d.ts +9 -0
  25. package/dist/src/ui/Entity/ToolApproval.d.ts +10 -0
  26. package/dist/src/ui/Entity/context.d.ts +10 -0
  27. package/dist/src/ui/Entity/index.d.ts +4 -0
  28. package/dist/src/ui/Entity/types.d.ts +1 -0
  29. package/dist/src/ui/Icon/Icon.d.ts +11 -0
  30. package/dist/src/ui/Icon/index.d.ts +1 -0
  31. package/dist/src/ui/IconButton/IconButton.d.ts +8 -0
  32. package/dist/src/ui/IconButton/IconButton.stories.d.ts +12 -0
  33. package/dist/src/ui/IconButton/index.d.ts +1 -0
  34. package/dist/src/ui/Icons/AgentIcon.d.ts +2 -0
  35. package/dist/src/ui/Icons/ToolsIcon.d.ts +2 -0
  36. package/dist/src/ui/Icons/WorkflowIcon.d.ts +2 -0
  37. package/dist/src/ui/Icons/index.d.ts +3 -0
  38. package/dist/src/ui/Message/Message.d.ts +25 -0
  39. package/dist/src/ui/Message/Message.stories.d.ts +13 -0
  40. package/dist/src/ui/Message/index.d.ts +1 -0
  41. package/dist/src/ui/Tooltip/Tooltip.d.ts +8 -0
  42. package/dist/src/ui/Tooltip/Tooltip.stories.d.ts +12 -0
  43. package/dist/src/ui/Tooltip/index.d.ts +1 -0
  44. package/dist/src/ui/index.d.ts +7 -0
  45. package/package.json +46 -11
  46. package/dist/index.cjs.js +0 -1109
  47. package/dist/index.cjs.js.map +0 -1
  48. package/dist/index.es.js.map +0 -1
package/dist/index.cjs.js DELETED
@@ -1,1109 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
-
5
- const jsxRuntime = require('react/jsx-runtime');
6
- const react = require('react');
7
- const clientJs = require('@mastra/client-js');
8
- const reactDom = require('react-dom');
9
-
10
- const MastraClientContext = react.createContext({});
11
- const MastraClientProvider = ({ children, baseUrl, headers }) => {
12
- const client = createMastraClient(baseUrl, headers);
13
- return /* @__PURE__ */ jsxRuntime.jsx(MastraClientContext.Provider, { value: client, children });
14
- };
15
- const useMastraClient = () => react.useContext(MastraClientContext);
16
- const createMastraClient = (baseUrl, mastraClientHeaders = {}) => {
17
- return new clientJs.MastraClient({
18
- baseUrl: baseUrl || "",
19
- // only add the header if the baseUrl is not provided i.e it's a local dev environment
20
- headers: !baseUrl ? { ...mastraClientHeaders, "x-mastra-dev-playground": "true" } : mastraClientHeaders
21
- });
22
- };
23
-
24
- const MastraReactProvider = ({ children, baseUrl, headers }) => {
25
- return /* @__PURE__ */ jsxRuntime.jsx(MastraClientProvider, { baseUrl, headers, children });
26
- };
27
-
28
- const mapWorkflowStreamChunkToWatchResult = (prev, chunk) => {
29
- if (chunk.type === "workflow-start") {
30
- return {
31
- input: prev?.input,
32
- status: "running",
33
- steps: prev?.steps || {}
34
- };
35
- }
36
- if (chunk.type === "workflow-canceled") {
37
- return {
38
- ...prev,
39
- status: "canceled"
40
- };
41
- }
42
- if (chunk.type === "workflow-finish") {
43
- const finalStatus = chunk.payload.workflowStatus;
44
- const prevSteps = prev?.steps ?? {};
45
- const lastStep = Object.values(prevSteps).pop();
46
- return {
47
- ...prev,
48
- status: chunk.payload.workflowStatus,
49
- ...finalStatus === "success" && lastStep?.status === "success" ? { result: lastStep?.output } : finalStatus === "failed" && lastStep?.status === "failed" ? { error: lastStep?.error } : {}
50
- };
51
- }
52
- const { stepCallId, stepName, ...newPayload } = chunk.payload ?? {};
53
- const newSteps = {
54
- ...prev?.steps,
55
- [chunk.payload.id]: {
56
- ...prev?.steps?.[chunk.payload.id],
57
- ...newPayload
58
- }
59
- };
60
- if (chunk.type === "workflow-step-start") {
61
- return {
62
- ...prev,
63
- steps: newSteps
64
- };
65
- }
66
- if (chunk.type === "workflow-step-suspended") {
67
- const suspendedStepIds = Object.entries(newSteps).flatMap(
68
- ([stepId, stepResult]) => {
69
- if (stepResult?.status === "suspended") {
70
- const nestedPath = stepResult?.suspendPayload?.__workflow_meta?.path;
71
- return nestedPath ? [[stepId, ...nestedPath]] : [[stepId]];
72
- }
73
- return [];
74
- }
75
- );
76
- return {
77
- ...prev,
78
- status: "suspended",
79
- steps: newSteps,
80
- suspendPayload: chunk.payload.suspendPayload,
81
- suspended: suspendedStepIds
82
- };
83
- }
84
- if (chunk.type === "workflow-step-waiting") {
85
- return {
86
- ...prev,
87
- status: "waiting",
88
- steps: newSteps
89
- };
90
- }
91
- if (chunk.type === "workflow-step-result") {
92
- return {
93
- ...prev,
94
- steps: newSteps
95
- };
96
- }
97
- return prev;
98
- };
99
- const toUIMessage = ({ chunk, conversation, metadata }) => {
100
- const result = [...conversation];
101
- switch (chunk.type) {
102
- case "tripwire": {
103
- const newMessage = {
104
- id: `tripwire-${chunk.runId + Date.now()}`,
105
- role: "assistant",
106
- parts: [
107
- {
108
- type: "text",
109
- text: chunk.payload.tripwireReason
110
- }
111
- ],
112
- metadata: {
113
- ...metadata,
114
- status: "warning"
115
- }
116
- };
117
- return [...result, newMessage];
118
- }
119
- case "start": {
120
- const newMessage = {
121
- id: `start-${chunk.runId + Date.now()}`,
122
- role: "assistant",
123
- parts: [],
124
- metadata
125
- };
126
- return [...result, newMessage];
127
- }
128
- case "text-start":
129
- case "text-delta": {
130
- const lastMessage = result[result.length - 1];
131
- if (!lastMessage || lastMessage.role !== "assistant") return result;
132
- const parts = [...lastMessage.parts];
133
- let textPartIndex = parts.findIndex((part) => part.type === "text");
134
- if (chunk.type === "text-start") {
135
- if (textPartIndex === -1) {
136
- parts.push({
137
- type: "text",
138
- text: "",
139
- state: "streaming",
140
- providerMetadata: chunk.payload.providerMetadata
141
- });
142
- }
143
- } else {
144
- if (textPartIndex === -1) {
145
- parts.push({
146
- type: "text",
147
- text: chunk.payload.text,
148
- state: "streaming",
149
- providerMetadata: chunk.payload.providerMetadata
150
- });
151
- } else {
152
- const textPart = parts[textPartIndex];
153
- if (textPart.type === "text") {
154
- parts[textPartIndex] = {
155
- ...textPart,
156
- text: textPart.text + chunk.payload.text,
157
- state: "streaming"
158
- };
159
- }
160
- }
161
- }
162
- return [
163
- ...result.slice(0, -1),
164
- {
165
- ...lastMessage,
166
- parts
167
- }
168
- ];
169
- }
170
- case "reasoning-delta": {
171
- const lastMessage = result[result.length - 1];
172
- if (!lastMessage || lastMessage.role !== "assistant") {
173
- const newMessage = {
174
- id: `reasoning-${chunk.runId + Date.now()}`,
175
- role: "assistant",
176
- parts: [
177
- {
178
- type: "reasoning",
179
- text: chunk.payload.text,
180
- state: "streaming",
181
- providerMetadata: chunk.payload.providerMetadata
182
- }
183
- ],
184
- metadata
185
- };
186
- return [...result, newMessage];
187
- }
188
- const parts = [...lastMessage.parts];
189
- let reasoningPartIndex = parts.findIndex((part) => part.type === "reasoning");
190
- if (reasoningPartIndex === -1) {
191
- parts.push({
192
- type: "reasoning",
193
- text: chunk.payload.text,
194
- state: "streaming",
195
- providerMetadata: chunk.payload.providerMetadata
196
- });
197
- } else {
198
- const reasoningPart = parts[reasoningPartIndex];
199
- if (reasoningPart.type === "reasoning") {
200
- parts[reasoningPartIndex] = {
201
- ...reasoningPart,
202
- text: reasoningPart.text + chunk.payload.text,
203
- state: "streaming"
204
- };
205
- }
206
- }
207
- return [
208
- ...result.slice(0, -1),
209
- {
210
- ...lastMessage,
211
- parts
212
- }
213
- ];
214
- }
215
- case "tool-call": {
216
- const lastMessage = result[result.length - 1];
217
- if (!lastMessage || lastMessage.role !== "assistant") {
218
- const newMessage = {
219
- id: `tool-call-${chunk.runId + Date.now()}`,
220
- role: "assistant",
221
- parts: [
222
- {
223
- type: "dynamic-tool",
224
- toolName: chunk.payload.toolName,
225
- toolCallId: chunk.payload.toolCallId,
226
- state: "input-available",
227
- input: chunk.payload.args,
228
- callProviderMetadata: chunk.payload.providerMetadata
229
- }
230
- ],
231
- metadata
232
- };
233
- return [...result, newMessage];
234
- }
235
- const parts = [...lastMessage.parts];
236
- parts.push({
237
- type: "dynamic-tool",
238
- toolName: chunk.payload.toolName,
239
- toolCallId: chunk.payload.toolCallId,
240
- state: "input-available",
241
- input: chunk.payload.args,
242
- callProviderMetadata: chunk.payload.providerMetadata
243
- });
244
- return [
245
- ...result.slice(0, -1),
246
- {
247
- ...lastMessage,
248
- parts
249
- }
250
- ];
251
- }
252
- case "tool-result": {
253
- const lastMessage = result[result.length - 1];
254
- if (!lastMessage || lastMessage.role !== "assistant") return result;
255
- const parts = [...lastMessage.parts];
256
- const toolPartIndex = parts.findIndex(
257
- (part) => part.type === "dynamic-tool" && "toolCallId" in part && part.toolCallId === chunk.payload.toolCallId
258
- );
259
- if (toolPartIndex !== -1) {
260
- const toolPart = parts[toolPartIndex];
261
- if (toolPart.type === "dynamic-tool") {
262
- if (chunk.payload.isError) {
263
- parts[toolPartIndex] = {
264
- type: "dynamic-tool",
265
- toolName: toolPart.toolName,
266
- toolCallId: toolPart.toolCallId,
267
- state: "output-error",
268
- input: toolPart.input,
269
- errorText: String(chunk.payload.result),
270
- callProviderMetadata: chunk.payload.providerMetadata
271
- };
272
- } else {
273
- const isWorkflow = Boolean(chunk.payload.result?.result?.steps);
274
- parts[toolPartIndex] = {
275
- type: "dynamic-tool",
276
- toolName: toolPart.toolName,
277
- toolCallId: toolPart.toolCallId,
278
- state: "output-available",
279
- input: toolPart.input,
280
- output: isWorkflow ? chunk.payload.result?.result : chunk.payload.result,
281
- callProviderMetadata: chunk.payload.providerMetadata
282
- };
283
- }
284
- }
285
- }
286
- return [
287
- ...result.slice(0, -1),
288
- {
289
- ...lastMessage,
290
- parts
291
- }
292
- ];
293
- }
294
- case "tool-output": {
295
- const lastMessage = result[result.length - 1];
296
- if (!lastMessage || lastMessage.role !== "assistant") return result;
297
- const parts = [...lastMessage.parts];
298
- const toolPartIndex = parts.findIndex(
299
- (part) => part.type === "dynamic-tool" && "toolCallId" in part && part.toolCallId === chunk.payload.toolCallId
300
- );
301
- if (toolPartIndex !== -1) {
302
- const toolPart = parts[toolPartIndex];
303
- if (toolPart.type === "dynamic-tool") {
304
- if (chunk.payload.output?.type?.startsWith("workflow-")) {
305
- const existingWorkflowState = toolPart.output || {};
306
- const updatedWorkflowState = mapWorkflowStreamChunkToWatchResult(
307
- existingWorkflowState,
308
- chunk.payload.output
309
- );
310
- parts[toolPartIndex] = {
311
- ...toolPart,
312
- output: updatedWorkflowState
313
- };
314
- } else {
315
- const currentOutput = toolPart.output || [];
316
- const existingOutput = Array.isArray(currentOutput) ? currentOutput : [];
317
- parts[toolPartIndex] = {
318
- ...toolPart,
319
- output: [...existingOutput, chunk.payload.output]
320
- };
321
- }
322
- }
323
- }
324
- return [
325
- ...result.slice(0, -1),
326
- {
327
- ...lastMessage,
328
- parts
329
- }
330
- ];
331
- }
332
- case "source": {
333
- const lastMessage = result[result.length - 1];
334
- if (!lastMessage || lastMessage.role !== "assistant") return result;
335
- const parts = [...lastMessage.parts];
336
- if (chunk.payload.sourceType === "url") {
337
- parts.push({
338
- type: "source-url",
339
- sourceId: chunk.payload.id,
340
- url: chunk.payload.url || "",
341
- title: chunk.payload.title,
342
- providerMetadata: chunk.payload.providerMetadata
343
- });
344
- } else if (chunk.payload.sourceType === "document") {
345
- parts.push({
346
- type: "source-document",
347
- sourceId: chunk.payload.id,
348
- mediaType: chunk.payload.mimeType || "application/octet-stream",
349
- title: chunk.payload.title,
350
- filename: chunk.payload.filename,
351
- providerMetadata: chunk.payload.providerMetadata
352
- });
353
- }
354
- return [
355
- ...result.slice(0, -1),
356
- {
357
- ...lastMessage,
358
- parts
359
- }
360
- ];
361
- }
362
- case "file": {
363
- const lastMessage = result[result.length - 1];
364
- if (!lastMessage || lastMessage.role !== "assistant") return result;
365
- const parts = [...lastMessage.parts];
366
- let url;
367
- if (typeof chunk.payload.data === "string") {
368
- url = chunk.payload.base64 ? `data:${chunk.payload.mimeType};base64,${chunk.payload.data}` : `data:${chunk.payload.mimeType},${encodeURIComponent(chunk.payload.data)}`;
369
- } else {
370
- const base64 = btoa(String.fromCharCode(...chunk.payload.data));
371
- url = `data:${chunk.payload.mimeType};base64,${base64}`;
372
- }
373
- parts.push({
374
- type: "file",
375
- mediaType: chunk.payload.mimeType,
376
- url,
377
- providerMetadata: chunk.payload.providerMetadata
378
- });
379
- return [
380
- ...result.slice(0, -1),
381
- {
382
- ...lastMessage,
383
- parts
384
- }
385
- ];
386
- }
387
- case "finish": {
388
- const lastMessage = result[result.length - 1];
389
- if (!lastMessage || lastMessage.role !== "assistant") return result;
390
- const parts = lastMessage.parts.map((part) => {
391
- if (part.type === "text" && part.state === "streaming") {
392
- return { ...part, state: "done" };
393
- }
394
- if (part.type === "reasoning" && part.state === "streaming") {
395
- return { ...part, state: "done" };
396
- }
397
- return part;
398
- });
399
- return [
400
- ...result.slice(0, -1),
401
- {
402
- ...lastMessage,
403
- parts
404
- }
405
- ];
406
- }
407
- case "error": {
408
- const newMessage = {
409
- id: `error-${chunk.runId + Date.now()}`,
410
- role: "assistant",
411
- parts: [
412
- {
413
- type: "text",
414
- text: chunk.payload.error
415
- }
416
- ],
417
- metadata: {
418
- ...metadata,
419
- status: "error"
420
- }
421
- };
422
- return [...result, newMessage];
423
- }
424
- // For all other chunk types, return conversation unchanged
425
- default:
426
- return result;
427
- }
428
- };
429
-
430
- const toAssistantUIMessage = (message) => {
431
- const extendedMessage = message;
432
- const content = message.parts.map((part) => {
433
- if (part.type === "text") {
434
- return {
435
- type: "text",
436
- text: part.text,
437
- metadata: message.metadata
438
- };
439
- }
440
- if (part.type === "reasoning") {
441
- return {
442
- type: "reasoning",
443
- text: part.text,
444
- metadata: message.metadata
445
- };
446
- }
447
- if (part.type === "source-url") {
448
- return {
449
- type: "source",
450
- sourceType: "url",
451
- id: part.sourceId,
452
- url: part.url,
453
- title: part.title,
454
- metadata: message.metadata
455
- };
456
- }
457
- if (part.type === "source-document") {
458
- return {
459
- type: "file",
460
- filename: part.filename,
461
- mimeType: part.mediaType,
462
- data: "",
463
- // Source documents don't have inline data
464
- metadata: message.metadata
465
- };
466
- }
467
- if (part.type === "file") {
468
- return {
469
- type: "file",
470
- mimeType: part.mediaType,
471
- data: part.url,
472
- // Use URL as data source
473
- metadata: message.metadata
474
- };
475
- }
476
- if (part.type === "dynamic-tool") {
477
- const baseToolCall = {
478
- type: "tool-call",
479
- toolCallId: part.toolCallId,
480
- toolName: part.toolName,
481
- argsText: JSON.stringify(part.input),
482
- args: part.input,
483
- metadata: message.metadata
484
- };
485
- if (part.state === "output-error" && "errorText" in part) {
486
- return { ...baseToolCall, result: part.errorText, isError: true };
487
- }
488
- if ("output" in part) {
489
- return { ...baseToolCall, result: part.output };
490
- }
491
- return baseToolCall;
492
- }
493
- if (part.type.startsWith("tool-") && part.state !== "input-available") {
494
- const toolName = "toolName" in part && typeof part.toolName === "string" ? part.toolName : part.type.substring(5);
495
- const baseToolCall = {
496
- type: "tool-call",
497
- toolCallId: "toolCallId" in part && typeof part.toolCallId === "string" ? part.toolCallId : "",
498
- toolName,
499
- argsText: "input" in part ? JSON.stringify(part.input) : "{}",
500
- args: "input" in part ? part.input : {},
501
- metadata: message.metadata
502
- };
503
- if ("output" in part) {
504
- return { ...baseToolCall, result: part.output };
505
- } else if ("error" in part) {
506
- return { ...baseToolCall, result: part.error, isError: true };
507
- }
508
- return baseToolCall;
509
- }
510
- return {
511
- type: "text",
512
- text: "",
513
- metadata: message.metadata
514
- };
515
- });
516
- let status;
517
- if (message.role === "assistant" && content.length > 0) {
518
- const hasStreamingParts = message.parts.some(
519
- (part) => part.type === "text" && "state" in part && part.state === "streaming" || part.type === "reasoning" && "state" in part && part.state === "streaming"
520
- );
521
- const hasToolCalls = message.parts.some((part) => part.type === "dynamic-tool" || part.type.startsWith("tool-"));
522
- const hasInputAvailableTools = message.parts.some(
523
- (part) => part.type === "dynamic-tool" && part.state === "input-available"
524
- );
525
- const hasErrorTools = message.parts.some(
526
- (part) => part.type === "dynamic-tool" && part.state === "output-error" || part.type.startsWith("tool-") && "error" in part
527
- );
528
- if (hasStreamingParts) {
529
- status = { type: "running" };
530
- } else if (hasInputAvailableTools && hasToolCalls) {
531
- status = { type: "requires-action", reason: "tool-calls" };
532
- } else if (hasErrorTools) {
533
- status = { type: "incomplete", reason: "error" };
534
- } else {
535
- status = { type: "complete", reason: "stop" };
536
- }
537
- }
538
- const threadMessage = {
539
- role: message.role,
540
- content,
541
- id: message.id,
542
- createdAt: extendedMessage.createdAt,
543
- status,
544
- attachments: extendedMessage.experimental_attachments
545
- };
546
- return threadMessage;
547
- };
548
-
549
- class AISdkNetworkTransformer {
550
- transform({ chunk, conversation, metadata }) {
551
- const newConversation = [...conversation];
552
- if (chunk.type.startsWith("agent-execution-")) {
553
- return this.handleAgentConversation(chunk, newConversation, metadata);
554
- }
555
- if (chunk.type.startsWith("workflow-execution-")) {
556
- return this.handleWorkflowConversation(chunk, newConversation, metadata);
557
- }
558
- if (chunk.type.startsWith("tool-execution-")) {
559
- return this.handleToolConversation(chunk, newConversation, metadata);
560
- }
561
- if (chunk.type === "network-execution-event-step-finish") {
562
- const newMessage = {
563
- id: `network-execution-event-step-finish-${chunk.runId}-${Date.now()}`,
564
- role: "assistant",
565
- parts: [
566
- {
567
- type: "text",
568
- text: chunk.payload?.result || "",
569
- state: "done"
570
- }
571
- ],
572
- metadata
573
- };
574
- return [...newConversation, newMessage];
575
- }
576
- return newConversation;
577
- }
578
- handleAgentConversation = (chunk, newConversation, metadata) => {
579
- if (chunk.type === "agent-execution-start") {
580
- const primitiveId = chunk.payload?.args?.primitiveId;
581
- const runId = chunk.payload.runId;
582
- if (!primitiveId || !runId) return newConversation;
583
- const newMessage = {
584
- id: `agent-execution-start-${runId}-${Date.now()}`,
585
- role: "assistant",
586
- parts: [
587
- {
588
- type: "dynamic-tool",
589
- toolName: primitiveId,
590
- toolCallId: runId,
591
- state: "input-available",
592
- input: chunk.payload.args
593
- }
594
- ],
595
- metadata: {
596
- ...metadata,
597
- selectionReason: chunk.payload?.args?.selectionReason || "",
598
- agentInput: chunk.payload?.args?.task,
599
- mode: "network",
600
- from: "AGENT"
601
- }
602
- };
603
- return [...newConversation, newMessage];
604
- }
605
- if (chunk.type === "agent-execution-end") {
606
- const lastMessage = newConversation[newConversation.length - 1];
607
- if (!lastMessage || lastMessage.role !== "assistant") return newConversation;
608
- const parts = [...lastMessage.parts];
609
- const toolPartIndex = parts.findIndex((part) => part.type === "dynamic-tool");
610
- if (toolPartIndex !== -1) {
611
- const toolPart = parts[toolPartIndex];
612
- if (toolPart.type === "dynamic-tool") {
613
- const currentOutput = toolPart.output;
614
- parts[toolPartIndex] = {
615
- type: "dynamic-tool",
616
- toolName: toolPart.toolName,
617
- toolCallId: toolPart.toolCallId,
618
- state: "output-available",
619
- input: toolPart.input,
620
- output: {
621
- ...currentOutput,
622
- result: currentOutput?.result || chunk.payload?.result || ""
623
- }
624
- };
625
- }
626
- }
627
- return [
628
- ...newConversation.slice(0, -1),
629
- {
630
- ...lastMessage,
631
- parts
632
- }
633
- ];
634
- }
635
- if (chunk.type.startsWith("agent-execution-event-")) {
636
- const lastMessage = newConversation[newConversation.length - 1];
637
- if (!lastMessage || lastMessage.role !== "assistant") return newConversation;
638
- const agentChunk = chunk.payload;
639
- const parts = [...lastMessage.parts];
640
- const toolPartIndex = parts.findIndex((part) => part.type === "dynamic-tool");
641
- if (toolPartIndex === -1) return newConversation;
642
- const toolPart = parts[toolPartIndex];
643
- if (agentChunk.type === "text-delta") {
644
- const childMessages = toolPart?.output?.childMessages || [];
645
- const lastChildMessage = childMessages[childMessages.length - 1];
646
- const textMessage = { type: "text", content: (lastChildMessage?.content || "") + agentChunk.payload.text };
647
- const nextMessages = lastChildMessage?.type === "text" ? [...childMessages.slice(0, -1), textMessage] : [...childMessages, textMessage];
648
- parts[toolPartIndex] = {
649
- ...toolPart,
650
- output: {
651
- childMessages: nextMessages
652
- }
653
- };
654
- } else if (agentChunk.type === "tool-call") {
655
- const childMessages = toolPart?.output?.childMessages || [];
656
- parts[toolPartIndex] = {
657
- ...toolPart,
658
- output: {
659
- ...toolPart?.output,
660
- childMessages: [
661
- ...childMessages,
662
- {
663
- type: "tool",
664
- toolCallId: agentChunk.payload.toolCallId,
665
- toolName: agentChunk.payload.toolName,
666
- args: agentChunk.payload.args
667
- }
668
- ]
669
- }
670
- };
671
- } else if (agentChunk.type === "tool-output") {
672
- if (agentChunk.payload?.output?.type?.startsWith("workflow-")) {
673
- const childMessages = toolPart?.output?.childMessages || [];
674
- const lastToolIndex = childMessages.length - 1;
675
- const currentMessage = childMessages[lastToolIndex];
676
- const actualExistingWorkflowState = currentMessage?.toolOutput || {};
677
- const updatedWorkflowState = mapWorkflowStreamChunkToWatchResult(
678
- actualExistingWorkflowState,
679
- agentChunk.payload.output
680
- );
681
- if (lastToolIndex >= 0 && childMessages[lastToolIndex]?.type === "tool") {
682
- parts[toolPartIndex] = {
683
- ...toolPart,
684
- output: {
685
- ...toolPart?.output,
686
- childMessages: [
687
- ...childMessages.slice(0, -1),
688
- {
689
- ...currentMessage,
690
- toolOutput: updatedWorkflowState
691
- }
692
- ]
693
- }
694
- };
695
- }
696
- }
697
- } else if (agentChunk.type === "tool-result") {
698
- const childMessages = toolPart?.output?.childMessages || [];
699
- const lastToolIndex = childMessages.length - 1;
700
- const isWorkflow = Boolean(agentChunk.payload?.result?.result?.steps);
701
- if (lastToolIndex >= 0 && childMessages[lastToolIndex]?.type === "tool") {
702
- parts[toolPartIndex] = {
703
- ...toolPart,
704
- output: {
705
- ...toolPart?.output,
706
- childMessages: [
707
- ...childMessages.slice(0, -1),
708
- {
709
- ...childMessages[lastToolIndex],
710
- toolOutput: isWorkflow ? agentChunk.payload.result.result : agentChunk.payload.result
711
- }
712
- ]
713
- }
714
- };
715
- }
716
- }
717
- return [
718
- ...newConversation.slice(0, -1),
719
- {
720
- ...lastMessage,
721
- parts
722
- }
723
- ];
724
- }
725
- return newConversation;
726
- };
727
- handleWorkflowConversation = (chunk, newConversation, metadata) => {
728
- if (chunk.type === "workflow-execution-start") {
729
- const primitiveId = chunk.payload?.args?.primitiveId;
730
- const runId = chunk.payload.runId;
731
- if (!primitiveId || !runId) return newConversation;
732
- let agentInput;
733
- try {
734
- agentInput = JSON.parse(chunk?.payload?.args?.prompt);
735
- } catch (e) {
736
- agentInput = chunk?.payload?.args?.prompt;
737
- }
738
- const newMessage = {
739
- id: `workflow-start-${runId}-${Date.now()}`,
740
- role: "assistant",
741
- parts: [
742
- {
743
- type: "dynamic-tool",
744
- toolName: primitiveId,
745
- toolCallId: runId,
746
- state: "input-available",
747
- input: chunk.payload.args
748
- }
749
- ],
750
- metadata: {
751
- ...metadata,
752
- selectionReason: chunk.payload?.args?.selectionReason || "",
753
- from: "WORKFLOW",
754
- mode: "network",
755
- agentInput
756
- }
757
- };
758
- return [...newConversation, newMessage];
759
- }
760
- if (chunk.type.startsWith("workflow-execution-event-")) {
761
- const lastMessage = newConversation[newConversation.length - 1];
762
- if (!lastMessage || lastMessage.role !== "assistant") return newConversation;
763
- const parts = [...lastMessage.parts];
764
- const toolPartIndex = parts.findIndex((part) => part.type === "dynamic-tool");
765
- if (toolPartIndex === -1) return newConversation;
766
- const toolPart = parts[toolPartIndex];
767
- if (toolPart.type !== "dynamic-tool") return newConversation;
768
- const existingWorkflowState = toolPart.output || {};
769
- const updatedWorkflowState = mapWorkflowStreamChunkToWatchResult(existingWorkflowState, chunk.payload);
770
- parts[toolPartIndex] = {
771
- ...toolPart,
772
- output: updatedWorkflowState
773
- };
774
- return [
775
- ...newConversation.slice(0, -1),
776
- {
777
- ...lastMessage,
778
- parts
779
- }
780
- ];
781
- }
782
- return newConversation;
783
- };
784
- handleToolConversation = (chunk, newConversation, metadata) => {
785
- if (chunk.type === "tool-execution-start") {
786
- const { args: argsData } = chunk.payload;
787
- const lastMessage = newConversation[newConversation.length - 1];
788
- const nestedArgs = argsData.args || {};
789
- if (!lastMessage || lastMessage.role !== "assistant") {
790
- const newMessage = {
791
- id: `tool-start-${chunk.runId}-${Date.now()}`,
792
- role: "assistant",
793
- parts: [
794
- {
795
- type: "dynamic-tool",
796
- toolName: argsData.toolName || "unknown",
797
- toolCallId: argsData.toolCallId || "unknown",
798
- state: "input-available",
799
- input: nestedArgs
800
- }
801
- ],
802
- metadata: {
803
- ...metadata,
804
- selectionReason: metadata?.mode === "network" ? metadata.selectionReason || argsData.selectionReason : "",
805
- mode: "network",
806
- agentInput: nestedArgs
807
- }
808
- };
809
- return [...newConversation, newMessage];
810
- }
811
- const parts = [...lastMessage.parts];
812
- parts.push({
813
- type: "dynamic-tool",
814
- toolName: argsData.toolName || "unknown",
815
- toolCallId: argsData.toolCallId || "unknown",
816
- state: "input-available",
817
- input: nestedArgs
818
- });
819
- return [
820
- ...newConversation.slice(0, -1),
821
- {
822
- ...lastMessage,
823
- parts
824
- }
825
- ];
826
- }
827
- if (chunk.type === "tool-execution-end") {
828
- const lastMessage = newConversation[newConversation.length - 1];
829
- if (!lastMessage || lastMessage.role !== "assistant") return newConversation;
830
- const parts = [...lastMessage.parts];
831
- const toolPartIndex = parts.findIndex(
832
- (part) => part.type === "dynamic-tool" && "toolCallId" in part && part.toolCallId === chunk.payload.toolCallId
833
- );
834
- if (toolPartIndex !== -1) {
835
- const toolPart = parts[toolPartIndex];
836
- if (toolPart.type === "dynamic-tool") {
837
- const currentOutput = toolPart.output;
838
- parts[toolPartIndex] = {
839
- type: "dynamic-tool",
840
- toolName: toolPart.toolName,
841
- toolCallId: toolPart.toolCallId,
842
- state: "output-available",
843
- input: toolPart.input,
844
- output: currentOutput?.result || chunk.payload?.result || ""
845
- };
846
- }
847
- }
848
- return [
849
- ...newConversation.slice(0, -1),
850
- {
851
- ...lastMessage,
852
- parts
853
- }
854
- ];
855
- }
856
- return newConversation;
857
- };
858
- }
859
-
860
- const resolveInitialMessages = (messages) => {
861
- return messages.map((message) => {
862
- const networkPart = message.parts.find((part) => part.type === "text" && part.text.includes('"isNetwork":true'));
863
- if (networkPart && networkPart.type === "text") {
864
- try {
865
- const json = JSON.parse(networkPart.text);
866
- if (json.isNetwork === true) {
867
- const selectionReason = json.selectionReason || "";
868
- const primitiveType = json.primitiveType || "";
869
- const primitiveId = json.primitiveId || "";
870
- const finalResult = json.finalResult;
871
- const toolCalls = finalResult?.toolCalls || [];
872
- const childMessages = [];
873
- for (const toolCall of toolCalls) {
874
- if (toolCall.type === "tool-call" && toolCall.payload) {
875
- const toolCallId = toolCall.payload.toolCallId;
876
- let toolResult;
877
- for (const message2 of finalResult?.messages || []) {
878
- for (const part of message2.content || []) {
879
- if (typeof part === "object" && part.type === "tool-result" && part.toolCallId === toolCallId) {
880
- toolResult = part;
881
- break;
882
- }
883
- }
884
- }
885
- const isWorkflow = Boolean(toolResult?.result?.result?.steps);
886
- childMessages.push({
887
- type: "tool",
888
- toolCallId: toolCall.payload.toolCallId,
889
- toolName: toolCall.payload.toolName,
890
- args: toolCall.payload.args,
891
- toolOutput: isWorkflow ? toolResult?.result?.result : toolResult?.result
892
- });
893
- }
894
- }
895
- if (finalResult && finalResult.text) {
896
- childMessages.push({
897
- type: "text",
898
- content: finalResult.text
899
- });
900
- }
901
- const result = {
902
- childMessages,
903
- result: finalResult?.text || ""
904
- };
905
- console.log("json", json);
906
- const nextMessage = {
907
- role: "assistant",
908
- parts: [
909
- {
910
- type: "dynamic-tool",
911
- toolCallId: primitiveId,
912
- toolName: primitiveId,
913
- state: "output-available",
914
- input: json.input,
915
- output: result
916
- }
917
- ],
918
- id: message.id,
919
- metadata: {
920
- ...message.metadata,
921
- mode: "network",
922
- selectionReason,
923
- agentInput: json.input,
924
- from: primitiveType === "agent" ? "AGENT" : "WORKFLOW"
925
- }
926
- };
927
- return nextMessage;
928
- }
929
- } catch (error) {
930
- return message;
931
- }
932
- }
933
- return message;
934
- });
935
- };
936
-
937
- const useChat = ({ agentId, initializeMessages }) => {
938
- const [messages, setMessages] = react.useState(
939
- () => resolveInitialMessages(initializeMessages?.() || [])
940
- );
941
- const baseClient = useMastraClient();
942
- const [isRunning, setIsRunning] = react.useState(false);
943
- const generate = async ({
944
- coreUserMessages,
945
- runtimeContext,
946
- threadId,
947
- modelSettings,
948
- signal,
949
- onFinish
950
- }) => {
951
- const {
952
- frequencyPenalty,
953
- presencePenalty,
954
- maxRetries,
955
- maxTokens,
956
- temperature,
957
- topK,
958
- topP,
959
- instructions,
960
- providerOptions,
961
- maxSteps
962
- } = modelSettings || {};
963
- setIsRunning(true);
964
- const clientWithAbort = new clientJs.MastraClient({
965
- ...baseClient.options,
966
- abortSignal: signal
967
- });
968
- const agent = clientWithAbort.getAgent(agentId);
969
- const response = await agent.generate({
970
- messages: coreUserMessages,
971
- runId: agentId,
972
- maxSteps,
973
- modelSettings: {
974
- frequencyPenalty,
975
- presencePenalty,
976
- maxRetries,
977
- maxOutputTokens: maxTokens,
978
- temperature,
979
- topK,
980
- topP
981
- },
982
- instructions,
983
- runtimeContext,
984
- ...threadId ? { threadId, resourceId: agentId } : {},
985
- providerOptions
986
- });
987
- setIsRunning(false);
988
- if (response && "uiMessages" in response.response && response.response.uiMessages) {
989
- onFinish?.(response.response.uiMessages);
990
- const mastraUIMessages = (response.response.uiMessages || []).map((message) => ({
991
- ...message,
992
- metadata: {
993
- mode: "generate"
994
- }
995
- }));
996
- setMessages((prev) => [...prev, ...mastraUIMessages]);
997
- }
998
- };
999
- const stream = async ({ coreUserMessages, runtimeContext, threadId, onChunk, modelSettings, signal }) => {
1000
- const {
1001
- frequencyPenalty,
1002
- presencePenalty,
1003
- maxRetries,
1004
- maxTokens,
1005
- temperature,
1006
- topK,
1007
- topP,
1008
- instructions,
1009
- providerOptions,
1010
- maxSteps
1011
- } = modelSettings || {};
1012
- setIsRunning(true);
1013
- const clientWithAbort = new clientJs.MastraClient({
1014
- ...baseClient.options,
1015
- abortSignal: signal
1016
- });
1017
- const agent = clientWithAbort.getAgent(agentId);
1018
- const response = await agent.stream({
1019
- messages: coreUserMessages,
1020
- runId: agentId,
1021
- maxSteps,
1022
- modelSettings: {
1023
- frequencyPenalty,
1024
- presencePenalty,
1025
- maxRetries,
1026
- maxOutputTokens: maxTokens,
1027
- temperature,
1028
- topK,
1029
- topP
1030
- },
1031
- instructions,
1032
- runtimeContext,
1033
- ...threadId ? { threadId, resourceId: agentId } : {},
1034
- providerOptions
1035
- });
1036
- if (!response.body) {
1037
- setIsRunning(false);
1038
- throw new Error("[Stream] No response body");
1039
- }
1040
- await response.processDataStream({
1041
- onChunk: async (chunk) => {
1042
- reactDom.flushSync(() => {
1043
- setMessages((prev) => toUIMessage({ chunk, conversation: prev, metadata: { mode: "stream" } }));
1044
- });
1045
- onChunk?.(chunk);
1046
- }
1047
- });
1048
- setIsRunning(false);
1049
- };
1050
- const network = async ({
1051
- coreUserMessages,
1052
- runtimeContext,
1053
- threadId,
1054
- onNetworkChunk,
1055
- modelSettings,
1056
- signal
1057
- }) => {
1058
- const { frequencyPenalty, presencePenalty, maxRetries, maxTokens, temperature, topK, topP, maxSteps } = modelSettings || {};
1059
- setIsRunning(true);
1060
- const clientWithAbort = new clientJs.MastraClient({
1061
- ...baseClient.options,
1062
- abortSignal: signal
1063
- });
1064
- const agent = clientWithAbort.getAgent(agentId);
1065
- const response = await agent.network({
1066
- messages: coreUserMessages,
1067
- maxSteps,
1068
- modelSettings: {
1069
- frequencyPenalty,
1070
- presencePenalty,
1071
- maxRetries,
1072
- maxOutputTokens: maxTokens,
1073
- temperature,
1074
- topK,
1075
- topP
1076
- },
1077
- runId: agentId,
1078
- runtimeContext,
1079
- ...threadId ? { thread: threadId, resourceId: agentId } : {}
1080
- });
1081
- const transformer = new AISdkNetworkTransformer();
1082
- await response.processDataStream({
1083
- onChunk: async (chunk) => {
1084
- reactDom.flushSync(() => {
1085
- setMessages((prev) => transformer.transform({ chunk, conversation: prev, metadata: { mode: "network" } }));
1086
- });
1087
- onNetworkChunk?.(chunk);
1088
- }
1089
- });
1090
- setIsRunning(false);
1091
- };
1092
- return {
1093
- network,
1094
- stream,
1095
- generate,
1096
- isRunning,
1097
- messages,
1098
- setMessages,
1099
- cancelRun: () => setIsRunning(false)
1100
- };
1101
- };
1102
-
1103
- exports.MastraReactProvider = MastraReactProvider;
1104
- exports.mapWorkflowStreamChunkToWatchResult = mapWorkflowStreamChunkToWatchResult;
1105
- exports.toAssistantUIMessage = toAssistantUIMessage;
1106
- exports.toUIMessage = toUIMessage;
1107
- exports.useChat = useChat;
1108
- exports.useMastraClient = useMastraClient;
1109
- //# sourceMappingURL=index.cjs.js.map