@mastra/react 0.0.5 → 0.0.6-alpha.0

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