@mastra/react 0.0.5 → 0.0.6-alpha.1

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 +30 -0
  2. package/dist/index.cjs +1554 -0
  3. package/dist/index.cjs.map +1 -0
  4. package/dist/index.js +1491 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/react.css +719 -0
  7. package/dist/src/agent/hooks.d.ts +25 -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 +10 -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 +45 -11
  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.es.js DELETED
@@ -1,937 +0,0 @@
1
- import { jsx } from 'react/jsx-runtime';
2
- import { createContext, useContext, useState } from 'react';
3
- import { MastraClient } from '@mastra/client-js';
4
- import { flushSync } from 'react-dom';
5
-
6
- const MastraClientContext = createContext({});
7
- const MastraClientProvider = ({ children, baseUrl, headers }) => {
8
- const client = createMastraClient(baseUrl, headers);
9
- return /* @__PURE__ */ jsx(MastraClientContext.Provider, { value: client, children });
10
- };
11
- const useMastraClient = () => useContext(MastraClientContext);
12
- const createMastraClient = (baseUrl, mastraClientHeaders = {}) => {
13
- return new MastraClient({
14
- baseUrl: baseUrl || "",
15
- // only add the header if the baseUrl is not provided i.e it's a local dev environment
16
- headers: !baseUrl ? { ...mastraClientHeaders, "x-mastra-dev-playground": "true" } : mastraClientHeaders
17
- });
18
- };
19
-
20
- const MastraReactProvider = ({ children, baseUrl, headers }) => {
21
- return /* @__PURE__ */ jsx(MastraClientProvider, { baseUrl, headers, children });
22
- };
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
- const mapWorkflowStreamChunkToWatchResult = (prev, chunk) => {
184
- if (chunk.type === "workflow-start") {
185
- return {
186
- input: prev?.input,
187
- status: "running",
188
- steps: prev?.steps || {}
189
- };
190
- }
191
- if (chunk.type === "workflow-canceled") {
192
- return {
193
- ...prev,
194
- status: "canceled"
195
- };
196
- }
197
- if (chunk.type === "workflow-finish") {
198
- const finalStatus = chunk.payload.workflowStatus;
199
- const prevSteps = prev?.steps ?? {};
200
- const lastStep = Object.values(prevSteps).pop();
201
- return {
202
- ...prev,
203
- status: chunk.payload.workflowStatus,
204
- ...finalStatus === "success" && lastStep?.status === "success" ? { result: lastStep?.output } : finalStatus === "failed" && lastStep?.status === "failed" ? { error: lastStep?.error } : {}
205
- };
206
- }
207
- const { stepCallId, stepName, ...newPayload } = chunk.payload ?? {};
208
- const newSteps = {
209
- ...prev?.steps,
210
- [chunk.payload.id]: {
211
- ...prev?.steps?.[chunk.payload.id],
212
- ...newPayload
213
- }
214
- };
215
- if (chunk.type === "workflow-step-start") {
216
- return {
217
- ...prev,
218
- steps: newSteps
219
- };
220
- }
221
- if (chunk.type === "workflow-step-suspended") {
222
- const suspendedStepIds = Object.entries(newSteps).flatMap(
223
- ([stepId, stepResult]) => {
224
- if (stepResult?.status === "suspended") {
225
- const nestedPath = stepResult?.suspendPayload?.__workflow_meta?.path;
226
- return nestedPath ? [[stepId, ...nestedPath]] : [[stepId]];
227
- }
228
- return [];
229
- }
230
- );
231
- return {
232
- ...prev,
233
- status: "suspended",
234
- steps: newSteps,
235
- suspendPayload: chunk.payload.suspendPayload,
236
- suspended: suspendedStepIds
237
- };
238
- }
239
- if (chunk.type === "workflow-step-waiting") {
240
- return {
241
- ...prev,
242
- status: "waiting",
243
- steps: newSteps
244
- };
245
- }
246
- if (chunk.type === "workflow-step-result") {
247
- return {
248
- ...prev,
249
- steps: newSteps
250
- };
251
- }
252
- return prev;
253
- };
254
- const toUIMessage = ({
255
- chunk,
256
- conversation
257
- }) => {
258
- const result = [...conversation];
259
- switch (chunk.type) {
260
- case "start": {
261
- const newMessage = {
262
- id: chunk.runId,
263
- role: "assistant",
264
- parts: []
265
- };
266
- return [...result, newMessage];
267
- }
268
- case "text-start":
269
- case "text-delta": {
270
- const lastMessage = result[result.length - 1];
271
- if (!lastMessage || lastMessage.role !== "assistant") return result;
272
- const parts = [...lastMessage.parts];
273
- let textPartIndex = parts.findIndex((part) => part.type === "text");
274
- if (chunk.type === "text-start") {
275
- if (textPartIndex === -1) {
276
- parts.push({
277
- type: "text",
278
- text: "",
279
- state: "streaming",
280
- providerMetadata: chunk.payload.providerMetadata
281
- });
282
- }
283
- } else {
284
- if (textPartIndex === -1) {
285
- parts.push({
286
- type: "text",
287
- text: chunk.payload.text,
288
- state: "streaming",
289
- providerMetadata: chunk.payload.providerMetadata
290
- });
291
- } else {
292
- const textPart = parts[textPartIndex];
293
- if (textPart.type === "text") {
294
- parts[textPartIndex] = {
295
- ...textPart,
296
- text: textPart.text + chunk.payload.text,
297
- state: "streaming"
298
- };
299
- }
300
- }
301
- }
302
- return [
303
- ...result.slice(0, -1),
304
- {
305
- ...lastMessage,
306
- parts
307
- }
308
- ];
309
- }
310
- case "reasoning-delta": {
311
- const lastMessage = result[result.length - 1];
312
- if (!lastMessage || lastMessage.role !== "assistant") {
313
- const newMessage = {
314
- id: chunk.runId,
315
- role: "assistant",
316
- parts: [
317
- {
318
- type: "reasoning",
319
- text: chunk.payload.text,
320
- state: "streaming",
321
- providerMetadata: chunk.payload.providerMetadata
322
- }
323
- ]
324
- };
325
- return [...result, newMessage];
326
- }
327
- const parts = [...lastMessage.parts];
328
- let reasoningPartIndex = parts.findIndex((part) => part.type === "reasoning");
329
- if (reasoningPartIndex === -1) {
330
- parts.push({
331
- type: "reasoning",
332
- text: chunk.payload.text,
333
- state: "streaming",
334
- providerMetadata: chunk.payload.providerMetadata
335
- });
336
- } else {
337
- const reasoningPart = parts[reasoningPartIndex];
338
- if (reasoningPart.type === "reasoning") {
339
- parts[reasoningPartIndex] = {
340
- ...reasoningPart,
341
- text: reasoningPart.text + chunk.payload.text,
342
- state: "streaming"
343
- };
344
- }
345
- }
346
- return [
347
- ...result.slice(0, -1),
348
- {
349
- ...lastMessage,
350
- parts
351
- }
352
- ];
353
- }
354
- case "tool-call": {
355
- const lastMessage = result[result.length - 1];
356
- if (!lastMessage || lastMessage.role !== "assistant") {
357
- const newMessage = {
358
- id: chunk.runId,
359
- role: "assistant",
360
- parts: [
361
- {
362
- type: "dynamic-tool",
363
- toolName: chunk.payload.toolName,
364
- toolCallId: chunk.payload.toolCallId,
365
- state: "input-available",
366
- input: chunk.payload.args,
367
- callProviderMetadata: chunk.payload.providerMetadata
368
- }
369
- ]
370
- };
371
- return [...result, newMessage];
372
- }
373
- const parts = [...lastMessage.parts];
374
- parts.push({
375
- type: "dynamic-tool",
376
- toolName: chunk.payload.toolName,
377
- toolCallId: chunk.payload.toolCallId,
378
- state: "input-available",
379
- input: chunk.payload.args,
380
- callProviderMetadata: chunk.payload.providerMetadata
381
- });
382
- return [
383
- ...result.slice(0, -1),
384
- {
385
- ...lastMessage,
386
- parts
387
- }
388
- ];
389
- }
390
- case "tool-result": {
391
- const lastMessage = result[result.length - 1];
392
- if (!lastMessage || lastMessage.role !== "assistant") return result;
393
- const parts = [...lastMessage.parts];
394
- const toolPartIndex = parts.findIndex(
395
- (part) => part.type === "dynamic-tool" && "toolCallId" in part && part.toolCallId === chunk.payload.toolCallId
396
- );
397
- if (toolPartIndex !== -1) {
398
- const toolPart = parts[toolPartIndex];
399
- if (toolPart.type === "dynamic-tool") {
400
- if (chunk.payload.isError) {
401
- parts[toolPartIndex] = {
402
- type: "dynamic-tool",
403
- toolName: toolPart.toolName,
404
- toolCallId: toolPart.toolCallId,
405
- state: "output-error",
406
- input: toolPart.input,
407
- errorText: String(chunk.payload.result),
408
- callProviderMetadata: chunk.payload.providerMetadata
409
- };
410
- } else {
411
- parts[toolPartIndex] = {
412
- type: "dynamic-tool",
413
- toolName: toolPart.toolName,
414
- toolCallId: toolPart.toolCallId,
415
- state: "output-available",
416
- input: toolPart.input,
417
- output: toolPart.output,
418
- callProviderMetadata: chunk.payload.providerMetadata
419
- };
420
- }
421
- }
422
- }
423
- return [
424
- ...result.slice(0, -1),
425
- {
426
- ...lastMessage,
427
- parts
428
- }
429
- ];
430
- }
431
- case "tool-output": {
432
- const lastMessage = result[result.length - 1];
433
- if (!lastMessage || lastMessage.role !== "assistant") return result;
434
- const parts = [...lastMessage.parts];
435
- const toolPartIndex = parts.findIndex(
436
- (part) => part.type === "dynamic-tool" && "toolCallId" in part && part.toolCallId === chunk.payload.toolCallId
437
- );
438
- if (toolPartIndex !== -1) {
439
- const toolPart = parts[toolPartIndex];
440
- if (toolPart.type === "dynamic-tool") {
441
- if (chunk.payload.output?.type?.startsWith("workflow-")) {
442
- const existingWorkflowState = toolPart.output || {};
443
- const updatedWorkflowState = mapWorkflowStreamChunkToWatchResult(
444
- existingWorkflowState,
445
- chunk.payload.output
446
- );
447
- parts[toolPartIndex] = {
448
- ...toolPart,
449
- output: updatedWorkflowState
450
- };
451
- } else {
452
- const currentOutput = toolPart.output || [];
453
- const existingOutput = Array.isArray(currentOutput) ? currentOutput : [];
454
- parts[toolPartIndex] = {
455
- ...toolPart,
456
- output: [...existingOutput, chunk.payload.output]
457
- };
458
- }
459
- }
460
- }
461
- return [
462
- ...result.slice(0, -1),
463
- {
464
- ...lastMessage,
465
- parts
466
- }
467
- ];
468
- }
469
- case "source": {
470
- const lastMessage = result[result.length - 1];
471
- if (!lastMessage || lastMessage.role !== "assistant") return result;
472
- const parts = [...lastMessage.parts];
473
- if (chunk.payload.sourceType === "url") {
474
- parts.push({
475
- type: "source-url",
476
- sourceId: chunk.payload.id,
477
- url: chunk.payload.url || "",
478
- title: chunk.payload.title,
479
- providerMetadata: chunk.payload.providerMetadata
480
- });
481
- } else if (chunk.payload.sourceType === "document") {
482
- parts.push({
483
- type: "source-document",
484
- sourceId: chunk.payload.id,
485
- mediaType: chunk.payload.mimeType || "application/octet-stream",
486
- title: chunk.payload.title,
487
- filename: chunk.payload.filename,
488
- providerMetadata: chunk.payload.providerMetadata
489
- });
490
- }
491
- return [
492
- ...result.slice(0, -1),
493
- {
494
- ...lastMessage,
495
- parts
496
- }
497
- ];
498
- }
499
- case "file": {
500
- const lastMessage = result[result.length - 1];
501
- if (!lastMessage || lastMessage.role !== "assistant") return result;
502
- const parts = [...lastMessage.parts];
503
- let url;
504
- if (typeof chunk.payload.data === "string") {
505
- url = chunk.payload.base64 ? `data:${chunk.payload.mimeType};base64,${chunk.payload.data}` : `data:${chunk.payload.mimeType},${encodeURIComponent(chunk.payload.data)}`;
506
- } else {
507
- const base64 = btoa(String.fromCharCode(...chunk.payload.data));
508
- url = `data:${chunk.payload.mimeType};base64,${base64}`;
509
- }
510
- parts.push({
511
- type: "file",
512
- mediaType: chunk.payload.mimeType,
513
- url,
514
- providerMetadata: chunk.payload.providerMetadata
515
- });
516
- return [
517
- ...result.slice(0, -1),
518
- {
519
- ...lastMessage,
520
- parts
521
- }
522
- ];
523
- }
524
- case "finish": {
525
- const lastMessage = result[result.length - 1];
526
- if (!lastMessage || lastMessage.role !== "assistant") return result;
527
- const parts = lastMessage.parts.map((part) => {
528
- if (part.type === "text" && part.state === "streaming") {
529
- return { ...part, state: "done" };
530
- }
531
- if (part.type === "reasoning" && part.state === "streaming") {
532
- return { ...part, state: "done" };
533
- }
534
- return part;
535
- });
536
- return [
537
- ...result.slice(0, -1),
538
- {
539
- ...lastMessage,
540
- parts
541
- }
542
- ];
543
- }
544
- 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
- const newMessage = {
703
- id: chunk.runId,
704
- role: "assistant",
705
- parts: [
706
- {
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
- }
718
- }
719
- ]
720
- };
721
- return [...result, newMessage];
722
- }
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];
820
- }
821
- return result;
822
- };
823
-
824
- const toAssistantUIMessage = (message) => {
825
- const extendedMessage = message;
826
- const content = message.parts.map((part) => {
827
- if (part.type === "text") {
828
- return {
829
- type: "text",
830
- text: part.text
831
- };
832
- }
833
- if (part.type === "reasoning") {
834
- return {
835
- type: "reasoning",
836
- text: part.text
837
- };
838
- }
839
- if (part.type === "source-url") {
840
- return {
841
- type: "source",
842
- sourceType: "url",
843
- id: part.sourceId,
844
- url: part.url,
845
- title: part.title
846
- };
847
- }
848
- if (part.type === "source-document") {
849
- return {
850
- type: "file",
851
- filename: part.filename,
852
- mimeType: part.mediaType,
853
- data: ""
854
- // Source documents don't have inline data
855
- };
856
- }
857
- if (part.type === "file") {
858
- return {
859
- type: "file",
860
- mimeType: part.mediaType,
861
- data: part.url
862
- // Use URL as data source
863
- };
864
- }
865
- if (part.type === "dynamic-tool") {
866
- const baseToolCall = {
867
- type: "tool-call",
868
- toolCallId: part.toolCallId,
869
- toolName: part.toolName,
870
- argsText: JSON.stringify(part.input)
871
- };
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) {
875
- return { ...baseToolCall, result: part.errorText, isError: true };
876
- }
877
- return baseToolCall;
878
- }
879
- if (part.type.startsWith("tool-")) {
880
- const toolName = "toolName" in part && typeof part.toolName === "string" ? part.toolName : part.type.substring(5);
881
- const baseToolCall = {
882
- type: "tool-call",
883
- toolCallId: "toolCallId" in part && typeof part.toolCallId === "string" ? part.toolCallId : "",
884
- toolName,
885
- argsText: "input" in part ? JSON.stringify(part.input) : "{}"
886
- };
887
- if ("output" in part) {
888
- return { ...baseToolCall, result: part.output };
889
- } else if ("error" in part) {
890
- return { ...baseToolCall, result: part.error, isError: true };
891
- }
892
- return baseToolCall;
893
- }
894
- return {
895
- type: "text",
896
- text: ""
897
- };
898
- });
899
- let status;
900
- if (message.role === "assistant" && content.length > 0) {
901
- const hasStreamingParts = message.parts.some(
902
- (part) => part.type === "text" && "state" in part && part.state === "streaming" || part.type === "reasoning" && "state" in part && part.state === "streaming"
903
- );
904
- const hasToolCalls = message.parts.some((part) => part.type === "dynamic-tool" || part.type.startsWith("tool-"));
905
- const hasInputAvailableTools = message.parts.some(
906
- (part) => part.type === "dynamic-tool" && part.state === "input-available"
907
- );
908
- const hasErrorTools = message.parts.some(
909
- (part) => part.type === "dynamic-tool" && part.state === "output-error" || part.type.startsWith("tool-") && "error" in part
910
- );
911
- if (hasStreamingParts) {
912
- status = { type: "running" };
913
- } else if (hasInputAvailableTools && hasToolCalls) {
914
- status = { type: "requires-action", reason: "tool-calls" };
915
- } else if (hasErrorTools) {
916
- status = { type: "incomplete", reason: "error" };
917
- } else {
918
- status = { type: "complete", reason: "stop" };
919
- }
920
- }
921
- const metadata = extendedMessage.metadata ? {
922
- custom: extendedMessage.metadata
923
- } : void 0;
924
- const threadMessage = {
925
- role: message.role,
926
- content,
927
- id: message.id,
928
- createdAt: extendedMessage.createdAt,
929
- status,
930
- metadata,
931
- attachments: extendedMessage.experimental_attachments
932
- };
933
- return threadMessage;
934
- };
935
-
936
- export { MastraReactProvider, mapWorkflowStreamChunkToWatchResult, toAssistantUIMessage, toNetworkUIMessage, toUIMessage, useChat, useMastraClient };
937
- //# sourceMappingURL=index.es.js.map