@mastra/react 0.0.0-error-handler-fix-20251020202607 → 0.0.0-execa-dynamic-import-20260304221256

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 (110) hide show
  1. package/CHANGELOG.md +1172 -3
  2. package/LICENSE.md +15 -0
  3. package/dist/agent/hooks.d.ts +66 -0
  4. package/dist/agent/hooks.d.ts.map +1 -0
  5. package/dist/{src/agent → agent}/types.d.ts +2 -0
  6. package/dist/agent/types.d.ts.map +1 -0
  7. package/dist/index.cjs +1515 -293
  8. package/dist/index.cjs.map +1 -1
  9. package/dist/index.d.ts +8 -2
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +1506 -286
  12. package/dist/index.js.map +1 -1
  13. package/dist/lib/ai-sdk/index.d.ts +5 -0
  14. package/dist/lib/ai-sdk/index.d.ts.map +1 -0
  15. package/dist/lib/ai-sdk/memory/resolveInitialMessages.d.ts +13 -0
  16. package/dist/lib/ai-sdk/memory/resolveInitialMessages.d.ts.map +1 -0
  17. package/dist/{src/lib → lib}/ai-sdk/transformers/AISdkNetworkTransformer.d.ts +4 -3
  18. package/dist/lib/ai-sdk/transformers/AISdkNetworkTransformer.d.ts.map +1 -0
  19. package/dist/lib/ai-sdk/transformers/types.d.ts +11 -0
  20. package/dist/lib/ai-sdk/transformers/types.d.ts.map +1 -0
  21. package/dist/lib/ai-sdk/types.d.ts +116 -0
  22. package/dist/lib/ai-sdk/types.d.ts.map +1 -0
  23. package/dist/lib/ai-sdk/utils/fromCoreUserMessageToUIMessage.d.ts +11 -0
  24. package/dist/lib/ai-sdk/utils/fromCoreUserMessageToUIMessage.d.ts.map +1 -0
  25. package/dist/{src/lib → lib}/ai-sdk/utils/toAssistantUIMessage.d.ts +3 -2
  26. package/dist/lib/ai-sdk/utils/toAssistantUIMessage.d.ts.map +1 -0
  27. package/dist/{src/lib → lib}/ai-sdk/utils/toUIMessage.d.ts +4 -3
  28. package/dist/lib/ai-sdk/utils/toUIMessage.d.ts.map +1 -0
  29. package/dist/lib/use-mutation.d.ts +28 -0
  30. package/dist/lib/use-mutation.d.ts.map +1 -0
  31. package/dist/mastra-client-context.d.ts +14 -0
  32. package/dist/mastra-client-context.d.ts.map +1 -0
  33. package/dist/mastra-react-provider.d.ts +5 -0
  34. package/dist/mastra-react-provider.d.ts.map +1 -0
  35. package/dist/react.css +184 -322
  36. package/dist/{src/ui → ui}/Code/Code.d.ts +2 -1
  37. package/dist/ui/Code/Code.d.ts.map +1 -0
  38. package/dist/ui/Code/highlight.d.ts +4 -0
  39. package/dist/ui/Code/highlight.d.ts.map +1 -0
  40. package/dist/ui/Code/index.d.ts +2 -0
  41. package/dist/ui/Code/index.d.ts.map +1 -0
  42. package/dist/{src/ui → ui}/Entity/Entity.d.ts +2 -1
  43. package/dist/ui/Entity/Entity.d.ts.map +1 -0
  44. package/dist/{src/ui → ui}/Entity/Entry.d.ts +2 -1
  45. package/dist/ui/Entity/Entry.d.ts.map +1 -0
  46. package/dist/{src/ui → ui}/Entity/ToolApproval.d.ts +1 -0
  47. package/dist/ui/Entity/ToolApproval.d.ts.map +1 -0
  48. package/dist/{src/ui → ui}/Entity/context.d.ts +4 -3
  49. package/dist/ui/Entity/context.d.ts.map +1 -0
  50. package/dist/ui/Entity/index.d.ts +5 -0
  51. package/dist/ui/Entity/index.d.ts.map +1 -0
  52. package/dist/{src/ui → ui}/Entity/types.d.ts +1 -0
  53. package/dist/ui/Entity/types.d.ts.map +1 -0
  54. package/dist/{src/ui → ui}/Icon/Icon.d.ts +2 -1
  55. package/dist/ui/Icon/Icon.d.ts.map +1 -0
  56. package/dist/ui/Icon/index.d.ts +2 -0
  57. package/dist/ui/Icon/index.d.ts.map +1 -0
  58. package/dist/{src/ui → ui}/IconButton/IconButton.d.ts +2 -1
  59. package/dist/ui/IconButton/IconButton.d.ts.map +1 -0
  60. package/dist/ui/IconButton/index.d.ts +2 -0
  61. package/dist/ui/IconButton/index.d.ts.map +1 -0
  62. package/dist/{src/ui → ui}/Icons/AgentIcon.d.ts +2 -1
  63. package/dist/ui/Icons/AgentIcon.d.ts.map +1 -0
  64. package/dist/{src/ui → ui}/Icons/ToolsIcon.d.ts +2 -1
  65. package/dist/ui/Icons/ToolsIcon.d.ts.map +1 -0
  66. package/dist/{src/ui → ui}/Icons/WorkflowIcon.d.ts +2 -1
  67. package/dist/ui/Icons/WorkflowIcon.d.ts.map +1 -0
  68. package/dist/ui/Icons/index.d.ts +4 -0
  69. package/dist/ui/Icons/index.d.ts.map +1 -0
  70. package/dist/{src/ui → ui}/Message/Message.d.ts +2 -1
  71. package/dist/ui/Message/Message.d.ts.map +1 -0
  72. package/dist/ui/Message/index.d.ts +2 -0
  73. package/dist/ui/Message/index.d.ts.map +1 -0
  74. package/dist/{src/ui → ui}/Tooltip/Tooltip.d.ts +2 -1
  75. package/dist/ui/Tooltip/Tooltip.d.ts.map +1 -0
  76. package/dist/ui/Tooltip/index.d.ts +2 -0
  77. package/dist/ui/Tooltip/index.d.ts.map +1 -0
  78. package/dist/ui/index.d.ts +8 -0
  79. package/dist/ui/index.d.ts.map +1 -0
  80. package/dist/workflows/hooks.d.ts +34 -0
  81. package/dist/workflows/hooks.d.ts.map +1 -0
  82. package/dist/workflows/index.d.ts +3 -0
  83. package/dist/workflows/index.d.ts.map +1 -0
  84. package/dist/workflows/types.d.ts +122 -0
  85. package/dist/workflows/types.d.ts.map +1 -0
  86. package/dist/workflows/use-stream-workflow.d.ts +39 -0
  87. package/dist/workflows/use-stream-workflow.d.ts.map +1 -0
  88. package/package.json +34 -23
  89. package/dist/src/agent/hooks.d.ts +0 -46
  90. package/dist/src/index.d.ts +0 -6
  91. package/dist/src/lib/ai-sdk/index.d.ts +0 -3
  92. package/dist/src/lib/ai-sdk/memory/resolveInitialMessages.d.ts +0 -2
  93. package/dist/src/lib/ai-sdk/transformers/types.d.ts +0 -10
  94. package/dist/src/lib/ai-sdk/types.d.ts +0 -14
  95. package/dist/src/lib/ai-sdk/utils/toAssistantUIMessage.test.d.ts +0 -1
  96. package/dist/src/mastra-client-context.d.ts +0 -10
  97. package/dist/src/mastra-react-provider.d.ts +0 -4
  98. package/dist/src/ui/Code/highlight.d.ts +0 -3
  99. package/dist/src/ui/Code/index.d.ts +0 -1
  100. package/dist/src/ui/Entity/Entity.stories.d.ts +0 -22
  101. package/dist/src/ui/Entity/index.d.ts +0 -4
  102. package/dist/src/ui/Icon/index.d.ts +0 -1
  103. package/dist/src/ui/IconButton/IconButton.stories.d.ts +0 -12
  104. package/dist/src/ui/IconButton/index.d.ts +0 -1
  105. package/dist/src/ui/Icons/index.d.ts +0 -3
  106. package/dist/src/ui/Message/Message.stories.d.ts +0 -13
  107. package/dist/src/ui/Message/index.d.ts +0 -1
  108. package/dist/src/ui/Tooltip/Tooltip.stories.d.ts +0 -12
  109. package/dist/src/ui/Tooltip/index.d.ts +0 -1
  110. package/dist/src/ui/index.d.ts +0 -7
package/dist/index.js CHANGED
@@ -1,31 +1,48 @@
1
- import { jsx, jsxs } from 'react/jsx-runtime';
2
- import { createContext, useContext, useState, Fragment, useLayoutEffect, useRef, useEffect } from 'react';
3
1
  import { MastraClient } from '@mastra/client-js';
2
+ import { createContext, useContext, useRef, useState, useEffect, useLayoutEffect, useCallback, Fragment } from 'react';
3
+ import { jsxs, jsx } from 'react/jsx-runtime';
4
+ import { v4 } from '@lukeed/uuid';
5
+ import { formatStreamCompletionFeedback, formatCompletionFeedback } from '@mastra/core/loop';
4
6
  import { ChevronDownIcon, CheckIcon, CopyIcon } from 'lucide-react';
5
7
  import { twMerge } from 'tailwind-merge';
8
+ import { TooltipProvider, Root, TooltipPortal, TooltipContent as TooltipContent$1, TooltipTrigger as TooltipTrigger$1 } from '@radix-ui/react-tooltip';
6
9
  import { toJsxRuntime } from 'hast-util-to-jsx-runtime';
7
10
  import { codeToHast } from 'shiki/bundle/web';
8
- import { TooltipProvider, Root, TooltipPortal, TooltipContent as TooltipContent$1, TooltipTrigger as TooltipTrigger$1 } from '@radix-ui/react-tooltip';
11
+ import { RequestContext } from '@mastra/core/request-context';
9
12
 
10
- const MastraClientContext = createContext({});
11
- const MastraClientProvider = ({ children, baseUrl, headers }) => {
12
- const client = createMastraClient(baseUrl, headers);
13
+ // src/mastra-client-context.tsx
14
+ var MastraClientContext = createContext({});
15
+ var MastraClientProvider = ({ children, baseUrl, headers, apiPrefix }) => {
16
+ const client = createMastraClient(baseUrl, headers, apiPrefix);
13
17
  return /* @__PURE__ */ jsx(MastraClientContext.Provider, { value: client, children });
14
18
  };
15
- const useMastraClient = () => useContext(MastraClientContext);
16
- const createMastraClient = (baseUrl, mastraClientHeaders = {}) => {
19
+ var useMastraClient = () => useContext(MastraClientContext);
20
+ var IPV4_LOOPBACK_RE = /^127\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
21
+ var isIPv4Loopback = (hostname) => {
22
+ const m = IPV4_LOOPBACK_RE.exec(hostname);
23
+ if (!m) return false;
24
+ return +m[1] <= 255 && +m[2] <= 255 && +m[3] <= 255;
25
+ };
26
+ var isLocalUrl = (url) => {
27
+ if (!url) return true;
28
+ try {
29
+ const { hostname } = new URL(url);
30
+ return hostname === "localhost" || hostname.endsWith(".localhost") || isIPv4Loopback(hostname) || hostname === "::1" || hostname === "[::1]";
31
+ } catch {
32
+ return false;
33
+ }
34
+ };
35
+ var createMastraClient = (baseUrl, mastraClientHeaders = {}, apiPrefix) => {
17
36
  return new MastraClient({
18
37
  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
38
+ headers: isLocalUrl(baseUrl) ? { ...mastraClientHeaders, "x-mastra-dev-playground": "true" } : mastraClientHeaders,
39
+ apiPrefix
21
40
  });
22
41
  };
23
-
24
- const MastraReactProvider = ({ children, baseUrl, headers }) => {
25
- return /* @__PURE__ */ jsx(MastraClientProvider, { baseUrl, headers, children });
42
+ var MastraReactProvider = ({ children, baseUrl, headers, apiPrefix }) => {
43
+ return /* @__PURE__ */ jsx(MastraClientProvider, { baseUrl, headers, apiPrefix, children });
26
44
  };
27
-
28
- const mapWorkflowStreamChunkToWatchResult = (prev, chunk) => {
45
+ var mapWorkflowStreamChunkToWatchResult = (prev, chunk) => {
29
46
  if (chunk.type === "workflow-start") {
30
47
  return {
31
48
  input: prev?.input,
@@ -46,7 +63,7 @@ const mapWorkflowStreamChunkToWatchResult = (prev, chunk) => {
46
63
  return {
47
64
  ...prev,
48
65
  status: chunk.payload.workflowStatus,
49
- ...finalStatus === "success" && lastStep?.status === "success" ? { result: lastStep?.output } : finalStatus === "failed" && lastStep?.status === "failed" ? { error: lastStep?.error } : {}
66
+ ...finalStatus === "success" && lastStep?.status === "success" ? { result: lastStep?.output } : finalStatus === "failed" && lastStep?.status === "failed" ? { error: lastStep?.error } : finalStatus === "tripwire" && chunk.payload.tripwire ? { tripwire: chunk.payload.tripwire } : {}
50
67
  };
51
68
  }
52
69
  const { stepCallId, stepName, ...newPayload } = chunk.payload ?? {};
@@ -88,6 +105,25 @@ const mapWorkflowStreamChunkToWatchResult = (prev, chunk) => {
88
105
  steps: newSteps
89
106
  };
90
107
  }
108
+ if (chunk.type === "workflow-step-progress") {
109
+ const progressSteps = {
110
+ ...prev?.steps,
111
+ [chunk.payload.id]: {
112
+ ...prev?.steps?.[chunk.payload.id],
113
+ foreachProgress: {
114
+ completedCount: chunk.payload.completedCount,
115
+ totalCount: chunk.payload.totalCount,
116
+ currentIndex: chunk.payload.currentIndex,
117
+ iterationStatus: chunk.payload.iterationStatus,
118
+ iterationOutput: chunk.payload.iterationOutput
119
+ }
120
+ }
121
+ };
122
+ return {
123
+ ...prev,
124
+ steps: progressSteps
125
+ };
126
+ }
91
127
  if (chunk.type === "workflow-step-result") {
92
128
  return {
93
129
  ...prev,
@@ -96,8 +132,36 @@ const mapWorkflowStreamChunkToWatchResult = (prev, chunk) => {
96
132
  }
97
133
  return prev;
98
134
  };
99
- const toUIMessage = ({ chunk, conversation, metadata }) => {
135
+ var toUIMessage = ({ chunk, conversation, metadata }) => {
100
136
  const result = [...conversation];
137
+ if (chunk.type.startsWith("data-")) {
138
+ const lastMessage = result[result.length - 1];
139
+ if (!lastMessage || lastMessage.role !== "assistant") {
140
+ const newMessage = {
141
+ id: `data-${chunk.runId}-${Date.now()}`,
142
+ role: "assistant",
143
+ parts: [
144
+ {
145
+ type: chunk.type,
146
+ data: "data" in chunk ? chunk.data : void 0
147
+ }
148
+ ],
149
+ metadata
150
+ };
151
+ return [...result, newMessage];
152
+ }
153
+ const updatedMessage = {
154
+ ...lastMessage,
155
+ parts: [
156
+ ...lastMessage.parts,
157
+ {
158
+ type: chunk.type,
159
+ data: "data" in chunk ? chunk.data : void 0
160
+ }
161
+ ]
162
+ };
163
+ return [...result.slice(0, -1), updatedMessage];
164
+ }
101
165
  switch (chunk.type) {
102
166
  case "tripwire": {
103
167
  const newMessage = {
@@ -106,57 +170,90 @@ const toUIMessage = ({ chunk, conversation, metadata }) => {
106
170
  parts: [
107
171
  {
108
172
  type: "text",
109
- text: chunk.payload.tripwireReason
173
+ text: chunk.payload.reason
110
174
  }
111
175
  ],
112
176
  metadata: {
113
177
  ...metadata,
114
- status: "warning"
178
+ status: "tripwire",
179
+ tripwire: {
180
+ retry: chunk.payload.retry,
181
+ tripwirePayload: chunk.payload.metadata,
182
+ processorId: chunk.payload.processorId
183
+ }
115
184
  }
116
185
  };
117
186
  return [...result, newMessage];
118
187
  }
119
188
  case "start": {
120
189
  const newMessage = {
121
- id: `start-${chunk.runId + Date.now()}`,
190
+ id: typeof chunk.payload.messageId === "string" ? chunk.payload.messageId : `start-${chunk.runId + Date.now()}`,
122
191
  role: "assistant",
123
192
  parts: [],
124
193
  metadata
125
194
  };
126
195
  return [...result, newMessage];
127
196
  }
128
- case "text-start":
129
- case "text-delta": {
197
+ case "text-start": {
130
198
  const lastMessage = result[result.length - 1];
131
199
  if (!lastMessage || lastMessage.role !== "assistant") return result;
200
+ const textId = chunk.payload.id || `text-${Date.now()}`;
201
+ const newTextPart = {
202
+ type: "text",
203
+ text: "",
204
+ state: "streaming",
205
+ textId,
206
+ providerMetadata: chunk.payload.providerMetadata
207
+ };
208
+ if (lastMessage.metadata?.completionResult) {
209
+ const newMessage = {
210
+ id: `start-${chunk.runId}-${Date.now()}`,
211
+ role: "assistant",
212
+ parts: [newTextPart],
213
+ metadata
214
+ };
215
+ return [...result, newMessage];
216
+ }
132
217
  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
- });
218
+ parts.push(newTextPart);
219
+ return [
220
+ ...result.slice(0, -1),
221
+ {
222
+ ...lastMessage,
223
+ parts
142
224
  }
225
+ ];
226
+ }
227
+ case "text-delta": {
228
+ const lastMessage = result[result.length - 1];
229
+ if (!lastMessage || lastMessage.role !== "assistant") return result;
230
+ const parts = [...lastMessage.parts];
231
+ const textId = chunk.payload.id;
232
+ let textPartIndex = textId ? parts.findLastIndex((part) => part.type === "text" && part.textId === textId) : -1;
233
+ if (textPartIndex === -1) {
234
+ textPartIndex = parts.findLastIndex(
235
+ (part) => part.type === "text" && part.state === "streaming"
236
+ );
237
+ }
238
+ if (textPartIndex === -1) {
239
+ const newTextPart = {
240
+ type: "text",
241
+ text: chunk.payload.text,
242
+ state: "streaming",
243
+ textId,
244
+ providerMetadata: chunk.payload.providerMetadata
245
+ };
246
+ parts.push(newTextPart);
143
247
  } 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
- }
248
+ const textPart = parts[textPartIndex];
249
+ if (textPart.type === "text") {
250
+ const extendedTextPart = textPart;
251
+ const updatedTextPart = {
252
+ ...extendedTextPart,
253
+ text: extendedTextPart.text + chunk.payload.text,
254
+ state: "streaming"
255
+ };
256
+ parts[textPartIndex] = updatedTextPart;
160
257
  }
161
258
  }
162
259
  return [
@@ -249,35 +346,48 @@ const toUIMessage = ({ chunk, conversation, metadata }) => {
249
346
  }
250
347
  ];
251
348
  }
349
+ case "tool-error":
252
350
  case "tool-result": {
253
351
  const lastMessage = result[result.length - 1];
254
352
  if (!lastMessage || lastMessage.role !== "assistant") return result;
255
353
  const parts = [...lastMessage.parts];
256
354
  const toolPartIndex = parts.findIndex(
257
- (part) => part.type === "dynamic-tool" && "toolCallId" in part && part.toolCallId === chunk.payload.toolCallId
355
+ (part) => (part.type === "dynamic-tool" || typeof part.type === "string" && part.type.startsWith("tool-")) && "toolCallId" in part && part.toolCallId === chunk.payload.toolCallId
258
356
  );
259
357
  if (toolPartIndex !== -1) {
260
358
  const toolPart = parts[toolPartIndex];
261
- if (toolPart.type === "dynamic-tool") {
262
- if (chunk.payload.isError) {
359
+ if (toolPart.type === "dynamic-tool" || typeof toolPart.type === "string" && toolPart.type.startsWith("tool-")) {
360
+ const toolName = "toolName" in toolPart && typeof toolPart.toolName === "string" ? toolPart.toolName : toolPart.type.startsWith("tool-") ? toolPart.type.substring(5) : "";
361
+ const toolCallId = toolPart.toolCallId;
362
+ if (chunk.type === "tool-result" && chunk.payload.isError || chunk.type === "tool-error") {
363
+ const error = chunk.type === "tool-error" ? chunk.payload.error : chunk.payload.result;
263
364
  parts[toolPartIndex] = {
264
365
  type: "dynamic-tool",
265
- toolName: toolPart.toolName,
266
- toolCallId: toolPart.toolCallId,
366
+ toolName,
367
+ toolCallId,
267
368
  state: "output-error",
268
369
  input: toolPart.input,
269
- errorText: String(chunk.payload.result),
370
+ errorText: typeof error === "string" ? error : error instanceof Error ? error.message : error?.message ?? String(error),
270
371
  callProviderMetadata: chunk.payload.providerMetadata
271
372
  };
272
373
  } else {
273
374
  const isWorkflow = Boolean(chunk.payload.result?.result?.steps);
375
+ const isAgent = chunk?.from === "AGENT";
376
+ let output;
377
+ if (isWorkflow) {
378
+ output = chunk.payload.result?.result;
379
+ } else if (isAgent) {
380
+ output = parts[toolPartIndex].output ?? chunk.payload.result;
381
+ } else {
382
+ output = chunk.payload.result;
383
+ }
274
384
  parts[toolPartIndex] = {
275
385
  type: "dynamic-tool",
276
- toolName: toolPart.toolName,
277
- toolCallId: toolPart.toolCallId,
386
+ toolName,
387
+ toolCallId,
278
388
  state: "output-available",
279
389
  input: toolPart.input,
280
- output: isWorkflow ? chunk.payload.result?.result : chunk.payload.result,
390
+ output,
281
391
  callProviderMetadata: chunk.payload.providerMetadata
282
392
  };
283
393
  }
@@ -296,11 +406,14 @@ const toUIMessage = ({ chunk, conversation, metadata }) => {
296
406
  if (!lastMessage || lastMessage.role !== "assistant") return result;
297
407
  const parts = [...lastMessage.parts];
298
408
  const toolPartIndex = parts.findIndex(
299
- (part) => part.type === "dynamic-tool" && "toolCallId" in part && part.toolCallId === chunk.payload.toolCallId
409
+ (part) => (part.type === "dynamic-tool" || typeof part.type === "string" && part.type.startsWith("tool-")) && "toolCallId" in part && part.toolCallId === chunk.payload.toolCallId
300
410
  );
301
411
  if (toolPartIndex !== -1) {
302
412
  const toolPart = parts[toolPartIndex];
303
- if (toolPart.type === "dynamic-tool") {
413
+ if (toolPart.type === "dynamic-tool" || typeof toolPart.type === "string" && toolPart.type.startsWith("tool-")) {
414
+ const toolName = "toolName" in toolPart && typeof toolPart.toolName === "string" ? toolPart.toolName : typeof toolPart.type === "string" && toolPart.type.startsWith("tool-") ? toolPart.type.substring(5) : "";
415
+ const toolCallId = toolPart.toolCallId;
416
+ const input = toolPart.input;
304
417
  if (chunk.payload.output?.type?.startsWith("workflow-")) {
305
418
  const existingWorkflowState = toolPart.output || {};
306
419
  const updatedWorkflowState = mapWorkflowStreamChunkToWatchResult(
@@ -308,14 +421,24 @@ const toUIMessage = ({ chunk, conversation, metadata }) => {
308
421
  chunk.payload.output
309
422
  );
310
423
  parts[toolPartIndex] = {
311
- ...toolPart,
424
+ type: "dynamic-tool",
425
+ toolName,
426
+ toolCallId,
427
+ state: "input-streaming",
428
+ input,
312
429
  output: updatedWorkflowState
313
430
  };
431
+ } else if (chunk.payload.output?.from === "AGENT" || chunk.payload.output?.from === "USER" && chunk.payload.output?.payload?.output?.type?.startsWith("workflow-")) {
432
+ return toUIMessageFromAgent(chunk.payload.output, conversation, metadata, toolCallId, toolName);
314
433
  } else {
315
434
  const currentOutput = toolPart.output || [];
316
435
  const existingOutput = Array.isArray(currentOutput) ? currentOutput : [];
317
436
  parts[toolPartIndex] = {
318
- ...toolPart,
437
+ type: "dynamic-tool",
438
+ toolName,
439
+ toolCallId,
440
+ state: "input-streaming",
441
+ input,
319
442
  output: [...existingOutput, chunk.payload.output]
320
443
  };
321
444
  }
@@ -329,6 +452,36 @@ const toUIMessage = ({ chunk, conversation, metadata }) => {
329
452
  }
330
453
  ];
331
454
  }
455
+ case "is-task-complete": {
456
+ if (chunk.payload.suppressFeedback) return result;
457
+ const feedback = formatStreamCompletionFeedback(
458
+ {
459
+ complete: chunk.payload.passed,
460
+ scorers: chunk.payload.results,
461
+ totalDuration: chunk.payload.duration,
462
+ timedOut: chunk.payload.timedOut,
463
+ completionReason: chunk.payload.reason
464
+ },
465
+ chunk.payload.maxIterationReached
466
+ );
467
+ const newMessage = {
468
+ id: `is-task-complete-${chunk.runId + Date.now()}`,
469
+ role: "assistant",
470
+ parts: [
471
+ {
472
+ type: "text",
473
+ text: feedback
474
+ }
475
+ ],
476
+ metadata: {
477
+ ...metadata,
478
+ completionResult: {
479
+ passed: chunk.payload.passed
480
+ }
481
+ }
482
+ };
483
+ return [...result, newMessage];
484
+ }
332
485
  case "source": {
333
486
  const lastMessage = result[result.length - 1];
334
487
  if (!lastMessage || lastMessage.role !== "assistant") return result;
@@ -384,15 +537,61 @@ const toUIMessage = ({ chunk, conversation, metadata }) => {
384
537
  }
385
538
  ];
386
539
  }
540
+ case "tool-call-approval": {
541
+ const lastMessage = result[result.length - 1];
542
+ if (!lastMessage || lastMessage.role !== "assistant") return result;
543
+ const lastRequireApprovalMetadata = lastMessage.metadata?.mode === "stream" ? lastMessage.metadata?.requireApprovalMetadata : {};
544
+ return [
545
+ ...result.slice(0, -1),
546
+ {
547
+ ...lastMessage,
548
+ metadata: {
549
+ ...lastMessage.metadata,
550
+ mode: "stream",
551
+ requireApprovalMetadata: {
552
+ ...lastRequireApprovalMetadata,
553
+ [chunk.payload.toolName]: {
554
+ toolCallId: chunk.payload.toolCallId,
555
+ toolName: chunk.payload.toolName,
556
+ args: chunk.payload.args
557
+ }
558
+ }
559
+ }
560
+ }
561
+ ];
562
+ }
563
+ case "tool-call-suspended": {
564
+ const lastMessage = result[result.length - 1];
565
+ if (!lastMessage || lastMessage.role !== "assistant") return result;
566
+ const lastSuspendedTools = lastMessage.metadata?.mode === "stream" ? lastMessage.metadata?.suspendedTools : {};
567
+ return [
568
+ ...result.slice(0, -1),
569
+ {
570
+ ...lastMessage,
571
+ metadata: {
572
+ ...lastMessage.metadata,
573
+ mode: "stream",
574
+ suspendedTools: {
575
+ ...lastSuspendedTools,
576
+ [chunk.payload.toolName]: {
577
+ toolCallId: chunk.payload.toolCallId,
578
+ toolName: chunk.payload.toolName,
579
+ args: chunk.payload.args,
580
+ suspendPayload: chunk.payload.suspendPayload
581
+ }
582
+ }
583
+ }
584
+ }
585
+ ];
586
+ }
387
587
  case "finish": {
388
588
  const lastMessage = result[result.length - 1];
389
589
  if (!lastMessage || lastMessage.role !== "assistant") return result;
390
590
  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" };
591
+ if (typeof part === "object" && part !== null && "type" in part && "state" in part && part.state === "streaming") {
592
+ if (part.type === "text" || part.type === "reasoning") {
593
+ return { ...part, state: "done" };
594
+ }
396
595
  }
397
596
  return part;
398
597
  });
@@ -426,8 +625,116 @@ const toUIMessage = ({ chunk, conversation, metadata }) => {
426
625
  return result;
427
626
  }
428
627
  };
628
+ var toUIMessageFromAgent = (chunk, conversation, metadata, parentToolCallId, parentToolName) => {
629
+ const lastMessage = conversation[conversation.length - 1];
630
+ if (!lastMessage || lastMessage.role !== "assistant") return conversation;
631
+ const parts = [...lastMessage.parts];
632
+ if (chunk.type === "text-delta") {
633
+ const agentChunk = chunk.payload;
634
+ const toolPartIndex = parts.findIndex(
635
+ (part) => part.type === "dynamic-tool" && (parentToolCallId && part.toolCallId === parentToolCallId || parentToolName && part.toolName === parentToolName)
636
+ );
637
+ if (toolPartIndex === -1) return conversation;
638
+ const toolPart = parts[toolPartIndex];
639
+ const childMessages = toolPart?.output?.childMessages || [];
640
+ const lastChildMessage = childMessages[childMessages.length - 1];
641
+ const textMessage = { type: "text", content: (lastChildMessage?.content || "") + agentChunk.text };
642
+ const nextMessages = lastChildMessage?.type === "text" ? [...childMessages.slice(0, -1), textMessage] : [...childMessages, textMessage];
643
+ parts[toolPartIndex] = {
644
+ ...toolPart,
645
+ output: {
646
+ childMessages: nextMessages
647
+ }
648
+ };
649
+ } else if (chunk.type === "tool-call") {
650
+ const agentChunk = chunk.payload;
651
+ const toolPartIndex = parts.findIndex(
652
+ (part) => part.type === "dynamic-tool" && (parentToolCallId && part.toolCallId === parentToolCallId || parentToolName && part.toolName === parentToolName)
653
+ );
654
+ if (toolPartIndex === -1) return conversation;
655
+ const toolPart = parts[toolPartIndex];
656
+ const childMessages = toolPart?.output?.childMessages || [];
657
+ parts[toolPartIndex] = {
658
+ ...toolPart,
659
+ output: {
660
+ ...toolPart?.output,
661
+ childMessages: [
662
+ ...childMessages,
663
+ {
664
+ type: "tool",
665
+ toolCallId: agentChunk.toolCallId,
666
+ toolName: agentChunk.toolName,
667
+ args: agentChunk.args
668
+ }
669
+ ]
670
+ }
671
+ };
672
+ } else if (chunk.type === "tool-output") {
673
+ const agentChunk = chunk.payload;
674
+ const toolPartIndex = parts.findIndex(
675
+ (part) => part.type === "dynamic-tool" && (parentToolCallId && part.toolCallId === parentToolCallId || parentToolName && part.toolName === parentToolName)
676
+ );
677
+ if (toolPartIndex === -1) return conversation;
678
+ const toolPart = parts[toolPartIndex];
679
+ if (agentChunk?.output?.type?.startsWith("workflow-")) {
680
+ const childMessages = toolPart?.output?.childMessages || [];
681
+ const lastToolIndex = childMessages.length - 1;
682
+ const currentMessage = childMessages[lastToolIndex];
683
+ const actualExistingWorkflowState = currentMessage?.toolOutput || {};
684
+ const updatedWorkflowState = mapWorkflowStreamChunkToWatchResult(actualExistingWorkflowState, agentChunk.output);
685
+ if (lastToolIndex >= 0 && childMessages[lastToolIndex]?.type === "tool") {
686
+ parts[toolPartIndex] = {
687
+ ...toolPart,
688
+ output: {
689
+ ...toolPart?.output,
690
+ childMessages: [
691
+ ...childMessages.slice(0, -1),
692
+ {
693
+ ...currentMessage,
694
+ toolOutput: { ...updatedWorkflowState, runId: agentChunk.output.runId }
695
+ }
696
+ ]
697
+ }
698
+ };
699
+ }
700
+ }
701
+ } else if (chunk.type === "tool-result") {
702
+ const agentChunk = chunk.payload;
703
+ const toolPartIndex = parts.findIndex(
704
+ (part) => part.type === "dynamic-tool" && (parentToolCallId && part.toolCallId === parentToolCallId || parentToolName && part.toolName === parentToolName)
705
+ );
706
+ if (toolPartIndex === -1) return conversation;
707
+ const toolPart = parts[toolPartIndex];
708
+ const childMessages = toolPart?.output?.childMessages || [];
709
+ const lastToolIndex = childMessages.length - 1;
710
+ const isWorkflow = agentChunk?.toolName?.startsWith("workflow-");
711
+ if (lastToolIndex >= 0 && childMessages[lastToolIndex]?.type === "tool") {
712
+ parts[toolPartIndex] = {
713
+ ...toolPart,
714
+ output: {
715
+ ...toolPart?.output,
716
+ childMessages: [
717
+ ...childMessages.slice(0, -1),
718
+ {
719
+ ...childMessages[lastToolIndex],
720
+ toolOutput: isWorkflow ? { ...agentChunk.result?.result, runId: agentChunk.result?.runId } : agentChunk.result
721
+ }
722
+ ]
723
+ }
724
+ };
725
+ }
726
+ }
727
+ return [
728
+ ...conversation.slice(0, -1),
729
+ {
730
+ ...lastMessage,
731
+ parts
732
+ }
733
+ ];
734
+ };
429
735
 
430
- const toAssistantUIMessage = (message) => {
736
+ // src/lib/ai-sdk/utils/toAssistantUIMessage.ts
737
+ var toAssistantUIMessage = (message) => {
431
738
  const extendedMessage = message;
432
739
  const content = message.parts.map((part) => {
433
740
  if (part.type === "text") {
@@ -465,13 +772,23 @@ const toAssistantUIMessage = (message) => {
465
772
  };
466
773
  }
467
774
  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
- };
775
+ const type = part.mediaType.includes("image/") ? "image" : "file";
776
+ if (type === "file") {
777
+ return {
778
+ type,
779
+ mimeType: part.mediaType,
780
+ data: part.url,
781
+ // Use URL as data source
782
+ metadata: message.metadata
783
+ };
784
+ }
785
+ if (type === "image") {
786
+ return {
787
+ type,
788
+ image: part.url,
789
+ metadata: message.metadata
790
+ };
791
+ }
475
792
  }
476
793
  if (part.type === "dynamic-tool") {
477
794
  const baseToolCall = {
@@ -491,13 +808,14 @@ const toAssistantUIMessage = (message) => {
491
808
  return baseToolCall;
492
809
  }
493
810
  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);
811
+ const toolName2 = "toolName" in part && typeof part.toolName === "string" ? part.toolName : part.type.substring(5);
812
+ const { suspendedToolRunId, ...cleanInput } = "input" in part ? part.input : {};
495
813
  const baseToolCall = {
496
814
  type: "tool-call",
497
815
  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 : {},
816
+ toolName: toolName2,
817
+ argsText: JSON.stringify(cleanInput ?? {}),
818
+ args: cleanInput ?? {},
501
819
  metadata: message.metadata
502
820
  };
503
821
  if ("output" in part) {
@@ -507,6 +825,31 @@ const toAssistantUIMessage = (message) => {
507
825
  }
508
826
  return baseToolCall;
509
827
  }
828
+ const toolName = "toolName" in part && typeof part.toolName === "string" ? part.toolName : part.type.startsWith("tool-") ? part.type.substring(5) : "";
829
+ const requireApprovalMetadata = extendedMessage.metadata?.requireApprovalMetadata;
830
+ const suspendedTools = extendedMessage.metadata?.suspendedTools;
831
+ const partToolCallId = "toolCallId" in part && typeof part.toolCallId === "string" ? part.toolCallId : void 0;
832
+ const suspensionData = toolName ? requireApprovalMetadata?.[toolName] ?? suspendedTools?.[toolName] : void 0;
833
+ if (suspensionData) {
834
+ const { suspendedToolRunId, ...cleanInput } = "input" in part ? part.input : {};
835
+ return {
836
+ type: "tool-call",
837
+ toolCallId: partToolCallId,
838
+ toolName,
839
+ argsText: JSON.stringify(cleanInput ?? {}),
840
+ args: cleanInput,
841
+ metadata: extendedMessage.metadata
842
+ };
843
+ }
844
+ if (part.type.startsWith("data-")) {
845
+ return {
846
+ type: "data",
847
+ name: part.type.substring(5),
848
+ // Extract name from 'data-{name}'
849
+ data: part.data,
850
+ metadata: message.metadata
851
+ };
852
+ }
510
853
  return {
511
854
  type: "text",
512
855
  text: "",
@@ -546,7 +889,153 @@ const toAssistantUIMessage = (message) => {
546
889
  return threadMessage;
547
890
  };
548
891
 
549
- class AISdkNetworkTransformer {
892
+ // src/lib/ai-sdk/memory/resolveInitialMessages.ts
893
+ var resolveInitialMessages = (messages) => {
894
+ const messagesLength = messages.length;
895
+ return messages.map((message, index) => {
896
+ const networkPart = message.parts.find(
897
+ (part) => typeof part === "object" && part !== null && "type" in part && part.type === "text" && "text" in part && typeof part.text === "string" && part.text.includes('"isNetwork":true')
898
+ );
899
+ if (networkPart && networkPart.type === "text") {
900
+ try {
901
+ const json = JSON.parse(networkPart.text);
902
+ if (json.isNetwork === true) {
903
+ const selectionReason = json.selectionReason || "";
904
+ const primitiveType = json.primitiveType || "";
905
+ const primitiveId = json.primitiveId || "";
906
+ const finalResult = json.finalResult;
907
+ const messages2 = finalResult?.messages || [];
908
+ const childMessages = [];
909
+ const toolResultMap = /* @__PURE__ */ new Map();
910
+ for (const msg of messages2) {
911
+ if (Array.isArray(msg.content)) {
912
+ for (const part of msg.content) {
913
+ if (typeof part === "object" && part.type === "tool-result") {
914
+ toolResultMap.set(part.toolCallId, part);
915
+ }
916
+ }
917
+ }
918
+ }
919
+ for (const msg of messages2) {
920
+ if (msg.type === "tool-call" && Array.isArray(msg.content)) {
921
+ for (const part of msg.content) {
922
+ if (typeof part === "object" && part.type === "tool-call") {
923
+ const toolCallContent = part;
924
+ const toolResult = toolResultMap.get(toolCallContent.toolCallId);
925
+ const isWorkflow = Boolean(toolResult?.result?.result?.steps);
926
+ childMessages.push({
927
+ type: "tool",
928
+ toolCallId: toolCallContent.toolCallId,
929
+ toolName: toolCallContent.toolName,
930
+ args: toolCallContent.args,
931
+ toolOutput: isWorkflow ? toolResult?.result?.result : toolResult?.result
932
+ });
933
+ }
934
+ }
935
+ }
936
+ }
937
+ if (finalResult && finalResult.text) {
938
+ childMessages.push({
939
+ type: "text",
940
+ content: finalResult.text
941
+ });
942
+ }
943
+ const result = primitiveType === "tool" ? finalResult?.result : {
944
+ childMessages,
945
+ result: finalResult?.text || ""
946
+ };
947
+ const nextMessage = {
948
+ role: "assistant",
949
+ parts: [
950
+ {
951
+ type: "dynamic-tool",
952
+ toolCallId: primitiveId,
953
+ toolName: primitiveId,
954
+ state: "output-available",
955
+ input: json.input,
956
+ output: result
957
+ }
958
+ ],
959
+ id: message.id,
960
+ metadata: {
961
+ ...message.metadata,
962
+ mode: "network",
963
+ selectionReason,
964
+ agentInput: json.input,
965
+ hasMoreMessages: index < messagesLength - 1,
966
+ from: primitiveType === "agent" ? "AGENT" : primitiveType === "tool" ? "TOOL" : "WORKFLOW"
967
+ }
968
+ };
969
+ return nextMessage;
970
+ }
971
+ } catch {
972
+ return message;
973
+ }
974
+ }
975
+ const extendedMessage = message;
976
+ const pendingToolApprovals = extendedMessage.metadata?.pendingToolApprovals;
977
+ if (pendingToolApprovals && typeof pendingToolApprovals === "object") {
978
+ return {
979
+ ...message,
980
+ metadata: {
981
+ ...message.metadata,
982
+ mode: "stream",
983
+ requireApprovalMetadata: pendingToolApprovals
984
+ }
985
+ };
986
+ }
987
+ const suspendedTools = extendedMessage.metadata?.suspendedTools;
988
+ if (suspendedTools && typeof suspendedTools === "object") {
989
+ return {
990
+ ...message,
991
+ metadata: {
992
+ ...message.metadata,
993
+ mode: "stream",
994
+ suspendedTools
995
+ }
996
+ };
997
+ }
998
+ return message;
999
+ })?.filter((message) => {
1000
+ const completionModes = ["generate", "stream", "network"];
1001
+ if (message.role === "assistant" && completionModes.includes(message?.metadata?.mode)) {
1002
+ const meta = message.metadata;
1003
+ if (meta?.isTaskCompleteResult?.suppressFeedback || meta?.completionResult?.suppressFeedback) {
1004
+ return false;
1005
+ }
1006
+ return true;
1007
+ }
1008
+ return true;
1009
+ });
1010
+ };
1011
+ var resolveToChildMessages = (messages) => {
1012
+ const assistantMessage = messages.find((message) => message.role === "assistant");
1013
+ if (!assistantMessage) return [];
1014
+ const parts = assistantMessage.parts;
1015
+ let childMessages = [];
1016
+ for (const part of parts) {
1017
+ const toolPart = part;
1018
+ if (part.type.startsWith("tool-")) {
1019
+ const toolName = part.type.substring("tool-".length);
1020
+ const isWorkflow = toolName.startsWith("workflow-");
1021
+ childMessages.push({
1022
+ type: "tool",
1023
+ toolCallId: toolPart.toolCallId,
1024
+ toolName,
1025
+ args: toolPart.input,
1026
+ toolOutput: isWorkflow ? { ...toolPart.output?.result, runId: toolPart.output?.runId } : toolPart.output
1027
+ });
1028
+ }
1029
+ if (part.type === "text") {
1030
+ childMessages.push({
1031
+ type: "text",
1032
+ content: toolPart.text
1033
+ });
1034
+ }
1035
+ }
1036
+ return childMessages;
1037
+ };
1038
+ var AISdkNetworkTransformer = class {
550
1039
  transform({ chunk, conversation, metadata }) {
551
1040
  const newConversation = [...conversation];
552
1041
  if (chunk.type === "routing-agent-text-delta") {
@@ -561,11 +1050,42 @@ class AISdkNetworkTransformer {
561
1050
  if (chunk.type.startsWith("tool-execution-")) {
562
1051
  return this.handleToolConversation(chunk, newConversation, metadata);
563
1052
  }
564
- if (chunk.type === "network-execution-event-step-finish") {
565
- const lastMessage = newConversation[newConversation.length - 1];
566
- if (!lastMessage || lastMessage.role !== "assistant") return newConversation;
567
- const agentChunk = chunk.payload;
568
- const parts = [...lastMessage.parts];
1053
+ if (chunk.type === "network-validation-end") {
1054
+ if (chunk.payload.suppressFeedback) return newConversation;
1055
+ const feedback = formatCompletionFeedback(
1056
+ {
1057
+ complete: chunk.payload.passed,
1058
+ scorers: chunk.payload.results,
1059
+ totalDuration: chunk.payload.duration,
1060
+ timedOut: chunk.payload.timedOut,
1061
+ completionReason: chunk.payload.reason
1062
+ },
1063
+ chunk.payload.maxIterationReached
1064
+ );
1065
+ const newMessage = {
1066
+ id: `network-validation-end-${chunk.payload.runId}-${Date.now()}`,
1067
+ role: "assistant",
1068
+ parts: [
1069
+ {
1070
+ type: "text",
1071
+ text: feedback
1072
+ }
1073
+ ],
1074
+ metadata: {
1075
+ ...metadata,
1076
+ mode: "network",
1077
+ completionResult: {
1078
+ passed: chunk.payload.passed
1079
+ }
1080
+ }
1081
+ };
1082
+ return [...newConversation, newMessage];
1083
+ }
1084
+ if (chunk.type === "network-execution-event-step-finish") {
1085
+ const lastMessage = newConversation[newConversation.length - 1];
1086
+ if (!lastMessage || lastMessage.role !== "assistant") return newConversation;
1087
+ const agentChunk = chunk.payload;
1088
+ const parts = [...lastMessage.parts];
569
1089
  const textPartIndex = parts.findIndex((part) => part.type === "text");
570
1090
  if (textPartIndex === -1) {
571
1091
  parts.push({
@@ -663,6 +1183,54 @@ class AISdkNetworkTransformer {
663
1183
  };
664
1184
  return [...newConversation, newMessage];
665
1185
  }
1186
+ if (chunk.type === "agent-execution-approval") {
1187
+ const lastMessage = newConversation[newConversation.length - 1];
1188
+ if (!lastMessage || lastMessage.role !== "assistant") return newConversation;
1189
+ const lastRequireApprovalMetadata = lastMessage.metadata?.mode === "network" ? lastMessage.metadata?.requireApprovalMetadata : {};
1190
+ return [
1191
+ ...newConversation.slice(0, -1),
1192
+ {
1193
+ ...lastMessage,
1194
+ metadata: {
1195
+ ...lastMessage.metadata,
1196
+ mode: "network",
1197
+ requireApprovalMetadata: {
1198
+ ...lastRequireApprovalMetadata,
1199
+ [chunk.payload.toolName]: {
1200
+ toolCallId: chunk.payload.toolCallId,
1201
+ toolName: chunk.payload.toolName,
1202
+ args: chunk.payload.args,
1203
+ runId: chunk.payload.runId
1204
+ }
1205
+ }
1206
+ }
1207
+ }
1208
+ ];
1209
+ }
1210
+ if (chunk.type === "agent-execution-suspended") {
1211
+ const lastMessage = newConversation[newConversation.length - 1];
1212
+ if (!lastMessage || lastMessage.role !== "assistant") return newConversation;
1213
+ const lastSuspendedTools = lastMessage.metadata?.mode === "network" ? lastMessage.metadata?.suspendedTools : {};
1214
+ return [
1215
+ ...newConversation.slice(0, -1),
1216
+ {
1217
+ ...lastMessage,
1218
+ metadata: {
1219
+ ...lastMessage.metadata,
1220
+ mode: "network",
1221
+ suspendedTools: {
1222
+ ...lastSuspendedTools,
1223
+ [chunk.payload.toolName]: {
1224
+ toolCallId: chunk.payload.toolCallId,
1225
+ toolName: chunk.payload.toolName,
1226
+ args: chunk.payload.args,
1227
+ suspendPayload: chunk.payload.suspendPayload
1228
+ }
1229
+ }
1230
+ }
1231
+ }
1232
+ ];
1233
+ }
666
1234
  if (chunk.type === "agent-execution-end") {
667
1235
  const lastMessage = newConversation[newConversation.length - 1];
668
1236
  if (!lastMessage || lastMessage.role !== "assistant") return newConversation;
@@ -793,7 +1361,7 @@ class AISdkNetworkTransformer {
793
1361
  let agentInput;
794
1362
  try {
795
1363
  agentInput = JSON.parse(chunk?.payload?.args?.prompt);
796
- } catch (e) {
1364
+ } catch {
797
1365
  agentInput = chunk?.payload?.args?.prompt;
798
1366
  }
799
1367
  const newMessage = {
@@ -818,6 +1386,30 @@ class AISdkNetworkTransformer {
818
1386
  };
819
1387
  return [...newConversation, newMessage];
820
1388
  }
1389
+ if (chunk.type === "workflow-execution-suspended") {
1390
+ const lastMessage = newConversation[newConversation.length - 1];
1391
+ if (!lastMessage || lastMessage.role !== "assistant") return newConversation;
1392
+ const lastSuspendedTools = lastMessage.metadata?.mode === "network" ? lastMessage.metadata?.suspendedTools : {};
1393
+ return [
1394
+ ...newConversation.slice(0, -1),
1395
+ {
1396
+ ...lastMessage,
1397
+ metadata: {
1398
+ ...lastMessage.metadata,
1399
+ mode: "network",
1400
+ suspendedTools: {
1401
+ ...lastSuspendedTools,
1402
+ [chunk.payload.toolName]: {
1403
+ toolCallId: chunk.payload.toolCallId,
1404
+ toolName: chunk.payload.toolName,
1405
+ args: chunk.payload.args,
1406
+ suspendPayload: chunk.payload.suspendPayload
1407
+ }
1408
+ }
1409
+ }
1410
+ }
1411
+ ];
1412
+ }
821
1413
  if (chunk.type.startsWith("workflow-execution-event-")) {
822
1414
  const lastMessage = newConversation[newConversation.length - 1];
823
1415
  if (!lastMessage || lastMessage.role !== "assistant") return newConversation;
@@ -885,6 +1477,54 @@ class AISdkNetworkTransformer {
885
1477
  }
886
1478
  ];
887
1479
  }
1480
+ if (chunk.type === "tool-execution-approval") {
1481
+ const lastMessage = newConversation[newConversation.length - 1];
1482
+ if (!lastMessage || lastMessage.role !== "assistant") return newConversation;
1483
+ const lastRequireApprovalMetadata = lastMessage.metadata?.mode === "network" ? lastMessage.metadata?.requireApprovalMetadata : {};
1484
+ return [
1485
+ ...newConversation.slice(0, -1),
1486
+ {
1487
+ ...lastMessage,
1488
+ metadata: {
1489
+ ...lastMessage.metadata,
1490
+ mode: "network",
1491
+ requireApprovalMetadata: {
1492
+ ...lastRequireApprovalMetadata,
1493
+ [chunk.payload.toolName]: {
1494
+ toolCallId: chunk.payload.toolCallId,
1495
+ toolName: chunk.payload.toolName,
1496
+ args: chunk.payload.args,
1497
+ runId: chunk.payload.runId
1498
+ }
1499
+ }
1500
+ }
1501
+ }
1502
+ ];
1503
+ }
1504
+ if (chunk.type === "tool-execution-suspended") {
1505
+ const lastMessage = newConversation[newConversation.length - 1];
1506
+ if (!lastMessage || lastMessage.role !== "assistant") return newConversation;
1507
+ const lastSuspendedTools = lastMessage.metadata?.mode === "network" ? lastMessage.metadata?.suspendedTools : {};
1508
+ return [
1509
+ ...newConversation.slice(0, -1),
1510
+ {
1511
+ ...lastMessage,
1512
+ metadata: {
1513
+ ...lastMessage.metadata,
1514
+ mode: "network",
1515
+ suspendedTools: {
1516
+ ...lastSuspendedTools,
1517
+ [chunk.payload.toolName]: {
1518
+ toolCallId: chunk.payload.toolCallId,
1519
+ toolName: chunk.payload.toolName,
1520
+ args: chunk.payload.args,
1521
+ suspendPayload: chunk.payload.suspendPayload
1522
+ }
1523
+ }
1524
+ }
1525
+ }
1526
+ ];
1527
+ }
888
1528
  if (chunk.type === "tool-execution-end") {
889
1529
  const lastMessage = newConversation[newConversation.length - 1];
890
1530
  if (!lastMessage || lastMessage.role !== "assistant") return newConversation;
@@ -916,98 +1556,90 @@ class AISdkNetworkTransformer {
916
1556
  }
917
1557
  return newConversation;
918
1558
  };
919
- }
1559
+ };
920
1560
 
921
- const resolveInitialMessages = (messages) => {
922
- return messages.map((message) => {
923
- const networkPart = message.parts.find((part) => part.type === "text" && part.text.includes('"isNetwork":true'));
924
- if (networkPart && networkPart.type === "text") {
925
- try {
926
- const json = JSON.parse(networkPart.text);
927
- if (json.isNetwork === true) {
928
- const selectionReason = json.selectionReason || "";
929
- const primitiveType = json.primitiveType || "";
930
- const primitiveId = json.primitiveId || "";
931
- const finalResult = json.finalResult;
932
- const toolCalls = finalResult?.toolCalls || [];
933
- const childMessages = [];
934
- for (const toolCall of toolCalls) {
935
- if (toolCall.type === "tool-call" && toolCall.payload) {
936
- const toolCallId = toolCall.payload.toolCallId;
937
- let toolResult;
938
- for (const message2 of finalResult?.messages || []) {
939
- for (const part of message2.content || []) {
940
- if (typeof part === "object" && part.type === "tool-result" && part.toolCallId === toolCallId) {
941
- toolResult = part;
942
- break;
943
- }
944
- }
945
- }
946
- const isWorkflow = Boolean(toolResult?.result?.result?.steps);
947
- childMessages.push({
948
- type: "tool",
949
- toolCallId: toolCall.payload.toolCallId,
950
- toolName: toolCall.payload.toolName,
951
- args: toolCall.payload.args,
952
- toolOutput: isWorkflow ? toolResult?.result?.result : toolResult?.result
953
- });
954
- }
955
- }
956
- if (finalResult && finalResult.text) {
957
- childMessages.push({
958
- type: "text",
959
- content: finalResult.text
960
- });
961
- }
962
- const result = {
963
- childMessages,
964
- result: finalResult?.text || ""
965
- };
966
- console.log("json", json);
967
- const nextMessage = {
968
- role: "assistant",
969
- parts: [
970
- {
971
- type: "dynamic-tool",
972
- toolCallId: primitiveId,
973
- toolName: primitiveId,
974
- state: "output-available",
975
- input: json.input,
976
- output: result
977
- }
978
- ],
979
- id: message.id,
980
- metadata: {
981
- ...message.metadata,
982
- mode: "network",
983
- selectionReason,
984
- agentInput: json.input,
985
- from: primitiveType === "agent" ? "AGENT" : "WORKFLOW"
986
- }
987
- };
988
- return nextMessage;
989
- }
990
- } catch (error) {
991
- return message;
1561
+ // src/lib/ai-sdk/utils/fromCoreUserMessageToUIMessage.tsx
1562
+ var fromCoreUserMessageToUIMessage = (coreUserMessage) => {
1563
+ const id = `user-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
1564
+ const parts = typeof coreUserMessage.content === "string" ? [
1565
+ {
1566
+ type: "text",
1567
+ text: coreUserMessage.content
1568
+ }
1569
+ ] : coreUserMessage.content.map((part) => {
1570
+ switch (part.type) {
1571
+ case "text": {
1572
+ return {
1573
+ type: "text",
1574
+ text: part.text
1575
+ };
1576
+ }
1577
+ case "image": {
1578
+ const url = typeof part.image === "string" ? part.image : part.image instanceof URL ? part.image.toString() : "";
1579
+ return {
1580
+ type: "file",
1581
+ mediaType: part.mimeType ?? "image/*",
1582
+ url
1583
+ };
1584
+ }
1585
+ case "file": {
1586
+ const url = typeof part.data === "string" ? part.data : part.data instanceof URL ? part.data.toString() : "";
1587
+ return {
1588
+ type: "file",
1589
+ mediaType: part.mimeType,
1590
+ url,
1591
+ ...part.filename !== void 0 ? { filename: part.filename } : {}
1592
+ };
1593
+ }
1594
+ default: {
1595
+ const exhaustiveCheck = part;
1596
+ throw new Error(`Unhandled content part type: ${exhaustiveCheck.type}`);
992
1597
  }
993
1598
  }
994
- return message;
995
1599
  });
1600
+ return {
1601
+ id,
1602
+ role: "user",
1603
+ parts
1604
+ };
996
1605
  };
997
1606
 
998
- const useChat = ({ agentId, initializeMessages }) => {
999
- const [messages, setMessages] = useState(
1000
- () => resolveInitialMessages(initializeMessages?.() || [])
1001
- );
1607
+ // src/agent/hooks.ts
1608
+ var extractRunIdFromMessages = (messages) => {
1609
+ for (const message of messages) {
1610
+ const pendingToolApprovals = message.metadata?.pendingToolApprovals;
1611
+ if (pendingToolApprovals && typeof pendingToolApprovals === "object") {
1612
+ const suspensionData = Object.values(pendingToolApprovals)[0];
1613
+ if (suspensionData?.runId) {
1614
+ return suspensionData.runId;
1615
+ }
1616
+ }
1617
+ }
1618
+ return void 0;
1619
+ };
1620
+ var useChat = ({ agentId, resourceId, initialMessages }) => {
1621
+ const _currentRunId = useRef(void 0);
1622
+ const _onChunk = useRef(void 0);
1623
+ const _networkRunId = useRef(void 0);
1624
+ const _onNetworkChunk = useRef(void 0);
1625
+ const [messages, setMessages] = useState([]);
1626
+ const [toolCallApprovals, setToolCallApprovals] = useState({});
1627
+ const [networkToolCallApprovals, setNetworkToolCallApprovals] = useState({});
1002
1628
  const baseClient = useMastraClient();
1003
1629
  const [isRunning, setIsRunning] = useState(false);
1630
+ useEffect(() => {
1631
+ const formattedMessages = resolveInitialMessages(initialMessages || []);
1632
+ setMessages(formattedMessages);
1633
+ _currentRunId.current = extractRunIdFromMessages(formattedMessages);
1634
+ }, [initialMessages]);
1004
1635
  const generate = async ({
1005
1636
  coreUserMessages,
1006
- runtimeContext,
1637
+ requestContext,
1007
1638
  threadId,
1008
1639
  modelSettings,
1009
1640
  signal,
1010
- onFinish
1641
+ onFinish,
1642
+ tracingOptions
1011
1643
  }) => {
1012
1644
  const {
1013
1645
  frequencyPenalty,
@@ -1019,7 +1651,8 @@ const useChat = ({ agentId, initializeMessages }) => {
1019
1651
  topP,
1020
1652
  instructions,
1021
1653
  providerOptions,
1022
- maxSteps
1654
+ maxSteps,
1655
+ requireToolApproval
1023
1656
  } = modelSettings || {};
1024
1657
  setIsRunning(true);
1025
1658
  const clientWithAbort = new MastraClient({
@@ -1027,9 +1660,10 @@ const useChat = ({ agentId, initializeMessages }) => {
1027
1660
  abortSignal: signal
1028
1661
  });
1029
1662
  const agent = clientWithAbort.getAgent(agentId);
1030
- const response = await agent.generate({
1031
- messages: coreUserMessages,
1032
- runId: agentId,
1663
+ const runId = v4();
1664
+ _currentRunId.current = runId;
1665
+ const response = await agent.generate(coreUserMessages, {
1666
+ runId,
1033
1667
  maxSteps,
1034
1668
  modelSettings: {
1035
1669
  frequencyPenalty,
@@ -1041,13 +1675,36 @@ const useChat = ({ agentId, initializeMessages }) => {
1041
1675
  topP
1042
1676
  },
1043
1677
  instructions,
1044
- runtimeContext,
1045
- ...threadId ? { threadId, resourceId: agentId } : {},
1046
- providerOptions
1678
+ requestContext,
1679
+ ...threadId ? { memory: { thread: threadId, resource: resourceId || agentId } } : {},
1680
+ providerOptions,
1681
+ tracingOptions,
1682
+ requireToolApproval
1047
1683
  });
1684
+ if (response.finishReason === "suspended" && response.suspendPayload) {
1685
+ const { toolCallId, toolName, args } = response.suspendPayload;
1686
+ if (response.response?.uiMessages) {
1687
+ const mastraUIMessages = (response.response.uiMessages || []).map((message) => ({
1688
+ ...message,
1689
+ metadata: {
1690
+ mode: "generate",
1691
+ requireApprovalMetadata: {
1692
+ [toolName]: {
1693
+ toolCallId,
1694
+ toolName,
1695
+ args
1696
+ }
1697
+ }
1698
+ }
1699
+ }));
1700
+ setMessages((prev) => [...prev, ...mastraUIMessages]);
1701
+ }
1702
+ setIsRunning(false);
1703
+ return;
1704
+ }
1048
1705
  setIsRunning(false);
1049
1706
  if (response && "uiMessages" in response.response && response.response.uiMessages) {
1050
- onFinish?.(response.response.uiMessages);
1707
+ void onFinish?.(response.response.uiMessages);
1051
1708
  const mastraUIMessages = (response.response.uiMessages || []).map((message) => ({
1052
1709
  ...message,
1053
1710
  metadata: {
@@ -1057,7 +1714,15 @@ const useChat = ({ agentId, initializeMessages }) => {
1057
1714
  setMessages((prev) => [...prev, ...mastraUIMessages]);
1058
1715
  }
1059
1716
  };
1060
- const stream = async ({ coreUserMessages, runtimeContext, threadId, onChunk, modelSettings, signal }) => {
1717
+ const stream = async ({
1718
+ coreUserMessages,
1719
+ requestContext,
1720
+ threadId,
1721
+ onChunk,
1722
+ modelSettings,
1723
+ signal,
1724
+ tracingOptions
1725
+ }) => {
1061
1726
  const {
1062
1727
  frequencyPenalty,
1063
1728
  presencePenalty,
@@ -1068,7 +1733,8 @@ const useChat = ({ agentId, initializeMessages }) => {
1068
1733
  topP,
1069
1734
  instructions,
1070
1735
  providerOptions,
1071
- maxSteps
1736
+ maxSteps,
1737
+ requireToolApproval
1072
1738
  } = modelSettings || {};
1073
1739
  setIsRunning(true);
1074
1740
  const clientWithAbort = new MastraClient({
@@ -1076,9 +1742,9 @@ const useChat = ({ agentId, initializeMessages }) => {
1076
1742
  abortSignal: signal
1077
1743
  });
1078
1744
  const agent = clientWithAbort.getAgent(agentId);
1079
- const response = await agent.stream({
1080
- messages: coreUserMessages,
1081
- runId: agentId,
1745
+ const runId = v4();
1746
+ const response = await agent.stream(coreUserMessages, {
1747
+ runId,
1082
1748
  maxSteps,
1083
1749
  modelSettings: {
1084
1750
  frequencyPenalty,
@@ -1090,29 +1756,30 @@ const useChat = ({ agentId, initializeMessages }) => {
1090
1756
  topP
1091
1757
  },
1092
1758
  instructions,
1093
- runtimeContext,
1094
- ...threadId ? { threadId, resourceId: agentId } : {},
1095
- providerOptions
1759
+ requestContext,
1760
+ ...threadId ? { memory: { thread: threadId, resource: resourceId || agentId } } : {},
1761
+ providerOptions,
1762
+ requireToolApproval,
1763
+ tracingOptions
1096
1764
  });
1097
- if (!response.body) {
1098
- setIsRunning(false);
1099
- throw new Error("[Stream] No response body");
1100
- }
1765
+ _onChunk.current = onChunk;
1766
+ _currentRunId.current = runId;
1101
1767
  await response.processDataStream({
1102
1768
  onChunk: async (chunk) => {
1103
1769
  setMessages((prev) => toUIMessage({ chunk, conversation: prev, metadata: { mode: "stream" } }));
1104
- onChunk?.(chunk);
1770
+ void onChunk?.(chunk);
1105
1771
  }
1106
1772
  });
1107
1773
  setIsRunning(false);
1108
1774
  };
1109
1775
  const network = async ({
1110
1776
  coreUserMessages,
1111
- runtimeContext,
1777
+ requestContext,
1112
1778
  threadId,
1113
1779
  onNetworkChunk,
1114
1780
  modelSettings,
1115
- signal
1781
+ signal,
1782
+ tracingOptions
1116
1783
  }) => {
1117
1784
  const { frequencyPenalty, presencePenalty, maxRetries, maxTokens, temperature, topK, topP, maxSteps } = modelSettings || {};
1118
1785
  setIsRunning(true);
@@ -1121,8 +1788,8 @@ const useChat = ({ agentId, initializeMessages }) => {
1121
1788
  abortSignal: signal
1122
1789
  });
1123
1790
  const agent = clientWithAbort.getAgent(agentId);
1124
- const response = await agent.network({
1125
- messages: coreUserMessages,
1791
+ const runId = v4();
1792
+ const response = await agent.network(coreUserMessages, {
1126
1793
  maxSteps,
1127
1794
  modelSettings: {
1128
1795
  frequencyPenalty,
@@ -1133,29 +1800,165 @@ const useChat = ({ agentId, initializeMessages }) => {
1133
1800
  topK,
1134
1801
  topP
1135
1802
  },
1136
- runId: agentId,
1137
- runtimeContext,
1138
- ...threadId ? { thread: threadId, resourceId: agentId } : {}
1803
+ runId,
1804
+ requestContext,
1805
+ ...threadId ? { memory: { thread: threadId, resource: resourceId || agentId } } : {},
1806
+ tracingOptions
1807
+ });
1808
+ _onNetworkChunk.current = onNetworkChunk;
1809
+ _networkRunId.current = runId;
1810
+ const transformer = new AISdkNetworkTransformer();
1811
+ await response.processDataStream({
1812
+ onChunk: async (chunk) => {
1813
+ setMessages((prev) => transformer.transform({ chunk, conversation: prev, metadata: { mode: "network" } }));
1814
+ void onNetworkChunk?.(chunk);
1815
+ }
1816
+ });
1817
+ setIsRunning(false);
1818
+ };
1819
+ const handleCancelRun = () => {
1820
+ setIsRunning(false);
1821
+ _currentRunId.current = void 0;
1822
+ _onChunk.current = void 0;
1823
+ _networkRunId.current = void 0;
1824
+ _onNetworkChunk.current = void 0;
1825
+ };
1826
+ const approveToolCall = async (toolCallId) => {
1827
+ const onChunk = _onChunk.current;
1828
+ const currentRunId = _currentRunId.current;
1829
+ if (!currentRunId)
1830
+ return console.info("[approveToolCall] approveToolCall can only be called after a stream has started");
1831
+ setIsRunning(true);
1832
+ setToolCallApprovals((prev) => ({ ...prev, [toolCallId]: { status: "approved" } }));
1833
+ const agent = baseClient.getAgent(agentId);
1834
+ const response = await agent.approveToolCall({ runId: currentRunId, toolCallId });
1835
+ await response.processDataStream({
1836
+ onChunk: async (chunk) => {
1837
+ setMessages((prev) => toUIMessage({ chunk, conversation: prev, metadata: { mode: "stream" } }));
1838
+ void onChunk?.(chunk);
1839
+ }
1840
+ });
1841
+ setIsRunning(false);
1842
+ };
1843
+ const declineToolCall = async (toolCallId) => {
1844
+ const onChunk = _onChunk.current;
1845
+ const currentRunId = _currentRunId.current;
1846
+ if (!currentRunId)
1847
+ return console.info("[declineToolCall] declineToolCall can only be called after a stream has started");
1848
+ setIsRunning(true);
1849
+ setToolCallApprovals((prev) => ({ ...prev, [toolCallId]: { status: "declined" } }));
1850
+ const agent = baseClient.getAgent(agentId);
1851
+ const response = await agent.declineToolCall({ runId: currentRunId, toolCallId });
1852
+ await response.processDataStream({
1853
+ onChunk: async (chunk) => {
1854
+ setMessages((prev) => toUIMessage({ chunk, conversation: prev, metadata: { mode: "stream" } }));
1855
+ void onChunk?.(chunk);
1856
+ }
1857
+ });
1858
+ setIsRunning(false);
1859
+ };
1860
+ const approveToolCallGenerate = async (toolCallId) => {
1861
+ const currentRunId = _currentRunId.current;
1862
+ if (!currentRunId)
1863
+ return console.info(
1864
+ "[approveToolCallGenerate] approveToolCallGenerate can only be called after a generate has started"
1865
+ );
1866
+ setIsRunning(true);
1867
+ setToolCallApprovals((prev) => ({ ...prev, [toolCallId]: { status: "approved" } }));
1868
+ const agent = baseClient.getAgent(agentId);
1869
+ const response = await agent.approveToolCallGenerate({ runId: currentRunId, toolCallId });
1870
+ if (response && "uiMessages" in response.response && response.response.uiMessages) {
1871
+ const mastraUIMessages = (response.response.uiMessages || []).map((message) => ({
1872
+ ...message,
1873
+ metadata: {
1874
+ mode: "generate"
1875
+ }
1876
+ }));
1877
+ setMessages((prev) => [...prev, ...mastraUIMessages]);
1878
+ }
1879
+ setIsRunning(false);
1880
+ };
1881
+ const declineToolCallGenerate = async (toolCallId) => {
1882
+ const currentRunId = _currentRunId.current;
1883
+ if (!currentRunId)
1884
+ return console.info(
1885
+ "[declineToolCallGenerate] declineToolCallGenerate can only be called after a generate has started"
1886
+ );
1887
+ setIsRunning(true);
1888
+ setToolCallApprovals((prev) => ({ ...prev, [toolCallId]: { status: "declined" } }));
1889
+ const agent = baseClient.getAgent(agentId);
1890
+ const response = await agent.declineToolCallGenerate({ runId: currentRunId, toolCallId });
1891
+ if (response && "uiMessages" in response.response && response.response.uiMessages) {
1892
+ const mastraUIMessages = (response.response.uiMessages || []).map((message) => ({
1893
+ ...message,
1894
+ metadata: {
1895
+ mode: "generate"
1896
+ }
1897
+ }));
1898
+ setMessages((prev) => [...prev, ...mastraUIMessages]);
1899
+ }
1900
+ setIsRunning(false);
1901
+ };
1902
+ const approveNetworkToolCall = async (toolName, runId) => {
1903
+ const onNetworkChunk = _onNetworkChunk.current;
1904
+ const networkRunId = runId || _networkRunId.current;
1905
+ if (!networkRunId)
1906
+ return console.info(
1907
+ "[approveNetworkToolCall] approveNetworkToolCall can only be called after a network stream has started"
1908
+ );
1909
+ setIsRunning(true);
1910
+ setNetworkToolCallApprovals((prev) => ({
1911
+ ...prev,
1912
+ [runId ? `${runId}-${toolName}` : toolName]: { status: "approved" }
1913
+ }));
1914
+ const agent = baseClient.getAgent(agentId);
1915
+ const response = await agent.approveNetworkToolCall({ runId: networkRunId });
1916
+ const transformer = new AISdkNetworkTransformer();
1917
+ await response.processDataStream({
1918
+ onChunk: async (chunk) => {
1919
+ setMessages((prev) => transformer.transform({ chunk, conversation: prev, metadata: { mode: "network" } }));
1920
+ void onNetworkChunk?.(chunk);
1921
+ }
1139
1922
  });
1923
+ setIsRunning(false);
1924
+ };
1925
+ const declineNetworkToolCall = async (toolName, runId) => {
1926
+ const onNetworkChunk = _onNetworkChunk.current;
1927
+ const networkRunId = runId || _networkRunId.current;
1928
+ if (!networkRunId)
1929
+ return console.info(
1930
+ "[declineNetworkToolCall] declineNetworkToolCall can only be called after a network stream has started"
1931
+ );
1932
+ setIsRunning(true);
1933
+ setNetworkToolCallApprovals((prev) => ({
1934
+ ...prev,
1935
+ [runId ? `${runId}-${toolName}` : toolName]: { status: "declined" }
1936
+ }));
1937
+ const agent = baseClient.getAgent(agentId);
1938
+ const response = await agent.declineNetworkToolCall({ runId: networkRunId });
1140
1939
  const transformer = new AISdkNetworkTransformer();
1141
1940
  await response.processDataStream({
1142
1941
  onChunk: async (chunk) => {
1143
1942
  setMessages((prev) => transformer.transform({ chunk, conversation: prev, metadata: { mode: "network" } }));
1144
- onNetworkChunk?.(chunk);
1943
+ void onNetworkChunk?.(chunk);
1145
1944
  }
1146
1945
  });
1147
1946
  setIsRunning(false);
1148
1947
  };
1149
1948
  const sendMessage = async ({ mode = "stream", ...args }) => {
1150
1949
  const nextMessage = { role: "user", content: [{ type: "text", text: args.message }] };
1151
- const messages2 = args.coreUserMessages ? [nextMessage, ...args.coreUserMessages] : [nextMessage];
1152
- setMessages((s) => [...s, { role: "user", parts: [{ type: "text", text: args.message }] }]);
1950
+ const coreUserMessages = [nextMessage];
1951
+ if (args.coreUserMessages) {
1952
+ coreUserMessages.push(...args.coreUserMessages);
1953
+ }
1954
+ const uiMessages = coreUserMessages.map(fromCoreUserMessageToUIMessage);
1955
+ setMessages((s) => [...s, ...uiMessages]);
1153
1956
  if (mode === "generate") {
1154
- await generate({ ...args, coreUserMessages: messages2 });
1957
+ await generate({ ...args, coreUserMessages });
1155
1958
  } else if (mode === "stream") {
1156
- await stream({ ...args, coreUserMessages: messages2 });
1959
+ await stream({ ...args, coreUserMessages });
1157
1960
  } else if (mode === "network") {
1158
- await network({ ...args, coreUserMessages: messages2 });
1961
+ await network({ ...args, coreUserMessages });
1159
1962
  }
1160
1963
  };
1161
1964
  return {
@@ -1163,30 +1966,35 @@ const useChat = ({ agentId, initializeMessages }) => {
1163
1966
  sendMessage,
1164
1967
  isRunning,
1165
1968
  messages,
1166
- cancelRun: () => setIsRunning(false)
1969
+ approveToolCall,
1970
+ declineToolCall,
1971
+ approveToolCallGenerate,
1972
+ declineToolCallGenerate,
1973
+ cancelRun: handleCancelRun,
1974
+ toolCallApprovals,
1975
+ approveNetworkToolCall,
1976
+ declineNetworkToolCall,
1977
+ networkToolCallApprovals
1167
1978
  };
1168
1979
  };
1169
-
1170
- const EntityContext = createContext({
1171
- expanded: false,
1172
- setExpanded: () => {
1173
- },
1174
- variant: "initial",
1175
- disabled: false
1176
- });
1177
- const EntityProvider = EntityContext.Provider;
1178
- const useEntity = () => useContext(EntityContext);
1179
-
1180
- const IconSizes = {
1980
+ var IconSizes = {
1181
1981
  sm: "mastra:[&>svg]:size-3",
1182
1982
  md: "mastra:[&>svg]:size-4",
1183
1983
  lg: "mastra:[&>svg]:size-5"
1184
1984
  };
1185
- const Icon = ({ children, className, size = "md", ...props }) => {
1985
+ var Icon = ({ children, className, size = "md", ...props }) => {
1186
1986
  return /* @__PURE__ */ jsx("div", { className: className || IconSizes[size], ...props, children });
1187
1987
  };
1188
-
1189
- const Entity = ({
1988
+ var EntityContext = createContext({
1989
+ expanded: false,
1990
+ setExpanded: () => {
1991
+ },
1992
+ variant: "initial",
1993
+ disabled: false
1994
+ });
1995
+ var EntityProvider = EntityContext.Provider;
1996
+ var useEntity = () => useContext(EntityContext);
1997
+ var Entity = ({
1190
1998
  className,
1191
1999
  variant = "initial",
1192
2000
  initialExpanded = false,
@@ -1196,21 +2004,21 @@ const Entity = ({
1196
2004
  const [expanded, setExpanded] = useState(initialExpanded);
1197
2005
  return /* @__PURE__ */ jsx(EntityProvider, { value: { expanded, setExpanded, variant, disabled }, children: /* @__PURE__ */ jsx("div", { className, ...props }) });
1198
2006
  };
1199
- const EntityTriggerClass = twMerge(
2007
+ var EntityTriggerClass = twMerge(
1200
2008
  "mastra:aria-disabled:cursor-not-allowed mastra:aria-disabled:bg-surface5 mastra:aria-disabled:text-text3",
1201
2009
  "mastra:aria-expanded:rounded-b-none mastra:aria-expanded:border-b-0",
1202
2010
  "mastra:bg-surface3 mastra:text-text6 mastra:hover:bg-surface4 mastra:active:bg-surface5",
1203
2011
  "mastra:rounded-lg mastra:py-2 mastra:px-4 mastra:border mastra:border-border1",
1204
2012
  "mastra:cursor-pointer mastra:inline-flex mastra:items-center mastra:gap-1 mastra:font-mono"
1205
2013
  );
1206
- const EntityTriggerVariantClasses = {
2014
+ var EntityTriggerVariantClasses = {
1207
2015
  agent: "mastra:[&_svg.mastra-icon]:text-accent1",
1208
2016
  workflow: "mastra:[&_svg.mastra-icon]:text-accent3",
1209
2017
  tool: "mastra:[&_svg.mastra-icon]:text-accent6",
1210
2018
  memory: "mastra:[&_svg.mastra-icon]:text-accent2",
1211
2019
  initial: "mastra:[&_svg.mastra-icon]:text-text3"
1212
2020
  };
1213
- const EntityTrigger = ({ className, children, ...props }) => {
2021
+ var EntityTrigger = ({ className, children, ...props }) => {
1214
2022
  const { expanded, setExpanded, variant, disabled } = useEntity();
1215
2023
  const handleClick = (e) => {
1216
2024
  if (disabled) return;
@@ -1229,17 +2037,17 @@ const EntityTrigger = ({ className, children, ...props }) => {
1229
2037
  }
1230
2038
  );
1231
2039
  };
1232
- const EntityContentClass = twMerge(
2040
+ var EntityContentClass = twMerge(
1233
2041
  "mastra:space-y-4",
1234
2042
  "mastra:rounded-lg mastra:rounded-tl-none mastra:p-4 mastra:border mastra:border-border1 mastra:-mt-[0.5px]",
1235
2043
  "mastra:bg-surface3 mastra:text-text6"
1236
2044
  );
1237
- const EntityContent = ({ className, ...props }) => {
2045
+ var EntityContent = ({ className, ...props }) => {
1238
2046
  const { expanded } = useEntity();
1239
2047
  if (!expanded) return null;
1240
2048
  return /* @__PURE__ */ jsx("div", { className: className || EntityContentClass, ...props });
1241
2049
  };
1242
- const EntityCaret = ({ className, ...props }) => {
2050
+ var EntityCaret = ({ className, ...props }) => {
1243
2051
  const { expanded } = useEntity();
1244
2052
  return /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(
1245
2053
  ChevronDownIcon,
@@ -1253,68 +2061,52 @@ const EntityCaret = ({ className, ...props }) => {
1253
2061
  }
1254
2062
  ) });
1255
2063
  };
1256
-
1257
- const ToolApprovalClass = twMerge(
2064
+ var ToolApprovalClass = twMerge(
1258
2065
  "mastra:rounded-lg mastra:border mastra:border-border1 mastra:max-w-1/2 mastra:mt-2",
1259
2066
  "mastra:bg-surface3 mastra:text-text6"
1260
2067
  );
1261
- const ToolApproval = ({ className, ...props }) => {
2068
+ var ToolApproval = ({ className, ...props }) => {
1262
2069
  return /* @__PURE__ */ jsx("div", { className: className || ToolApprovalClass, ...props });
1263
2070
  };
1264
- const ToolApprovalTitleClass = twMerge("mastra:text-text6 mastra:inline-flex mastra:items-center mastra:gap-1");
1265
- const ToolApprovalTitle = ({ className, ...props }) => {
2071
+ var ToolApprovalTitleClass = twMerge("mastra:text-text6 mastra:inline-flex mastra:items-center mastra:gap-1");
2072
+ var ToolApprovalTitle = ({ className, ...props }) => {
1266
2073
  return /* @__PURE__ */ jsx("div", { className: className || ToolApprovalTitleClass, ...props });
1267
2074
  };
1268
- const ToolApprovalHeaderClass = twMerge(
2075
+ var ToolApprovalHeaderClass = twMerge(
1269
2076
  "mastra:flex mastra:justify-between mastra:items-center mastra:gap-2",
1270
2077
  "mastra:border-b mastra:border-border1 mastra:px-4 mastra:py-2"
1271
2078
  );
1272
- const ToolApprovalHeader = ({ className, ...props }) => {
2079
+ var ToolApprovalHeader = ({ className, ...props }) => {
1273
2080
  return /* @__PURE__ */ jsx("div", { className: className || ToolApprovalHeaderClass, ...props });
1274
2081
  };
1275
- const ToolApprovalContentClass = twMerge("mastra:text-text6 mastra:p-4");
1276
- const ToolApprovalContent = ({ className, ...props }) => {
2082
+ var ToolApprovalContentClass = twMerge("mastra:text-text6 mastra:p-4");
2083
+ var ToolApprovalContent = ({ className, ...props }) => {
1277
2084
  return /* @__PURE__ */ jsx("div", { className: className || ToolApprovalContentClass, ...props });
1278
2085
  };
1279
- const ToolApprovalActionsClass = twMerge("mastra:flex mastra:gap-2 mastra:items-center");
1280
- const ToolApprovalActions = ({ className, ...props }) => {
2086
+ var ToolApprovalActionsClass = twMerge("mastra:flex mastra:gap-2 mastra:items-center");
2087
+ var ToolApprovalActions = ({ className, ...props }) => {
1281
2088
  return /* @__PURE__ */ jsx("div", { className: className || ToolApprovalActionsClass, ...props });
1282
2089
  };
1283
-
1284
- const EntryClass = "mastra:space-y-2";
1285
- const Entry = ({ className, ...props }) => {
2090
+ var EntryClass = "mastra:space-y-2";
2091
+ var Entry = ({ className, ...props }) => {
1286
2092
  return /* @__PURE__ */ jsx("div", { className: className || EntryClass, ...props });
1287
2093
  };
1288
- const EntryTitleClass = "mastra:font-mono mastra:text-sm mastra:text-text3";
1289
- const EntryTitle = ({ className, as: Root = "h3", ...props }) => {
2094
+ var EntryTitleClass = "mastra:font-mono mastra:text-sm mastra:text-text3";
2095
+ var EntryTitle = ({ className, as: Root = "h3", ...props }) => {
1290
2096
  return /* @__PURE__ */ jsx(Root, { className: className || EntryTitleClass, ...props });
1291
2097
  };
1292
-
1293
- async function highlight(code, lang) {
1294
- const out = await codeToHast(code, {
1295
- lang,
1296
- theme: "dracula-soft"
1297
- });
1298
- return toJsxRuntime(out, {
1299
- Fragment,
1300
- jsx,
1301
- jsxs
1302
- });
1303
- }
1304
-
1305
- const Tooltip = ({ children }) => {
2098
+ var Tooltip = ({ children }) => {
1306
2099
  return /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsx(Root, { children }) });
1307
2100
  };
1308
- const TooltipContentClass = "mastra:bg-surface4 mastra:text-text6 mastra mastra:rounded-lg mastra:py-1 mastra:px-2 mastra:text-xs mastra:border mastra:border-border1 mastra-tooltip-enter";
1309
- const TooltipContent = ({ children, className, ...props }) => {
2101
+ var TooltipContentClass = "mastra:bg-surface4 mastra:text-text6 mastra mastra:rounded-lg mastra:py-1 mastra:px-2 mastra:text-xs mastra:border mastra:border-border1 mastra-tooltip-enter";
2102
+ var TooltipContent = ({ children, className, ...props }) => {
1310
2103
  return /* @__PURE__ */ jsx(TooltipPortal, { children: /* @__PURE__ */ jsx(TooltipContent$1, { className: className || TooltipContentClass, ...props, children }) });
1311
2104
  };
1312
- const TooltipTrigger = (props) => {
2105
+ var TooltipTrigger = (props) => {
1313
2106
  return /* @__PURE__ */ jsx(TooltipTrigger$1, { ...props, asChild: true });
1314
2107
  };
1315
-
1316
- const IconButtonClass = "mastra:text-text3 mastra:hover:text-text6 mastra:active:text-text6 mastra:hover:bg-surface4 mastra:active:bg-surface5 mastra:rounded-md mastra:cursor-pointer";
1317
- const IconButton = ({ children, tooltip, size = "md", className, ...props }) => {
2108
+ var IconButtonClass = "mastra:text-text3 mastra:hover:text-text6 mastra:active:text-text6 mastra:hover:bg-surface4 mastra:active:bg-surface5 mastra:rounded-md mastra:cursor-pointer";
2109
+ var IconButton = ({ children, tooltip, size = "md", className, ...props }) => {
1318
2110
  return /* @__PURE__ */ jsxs(Tooltip, { children: [
1319
2111
  /* @__PURE__ */ jsx(TooltipTrigger, { children: /* @__PURE__ */ jsx(
1320
2112
  "button",
@@ -1327,9 +2119,19 @@ const IconButton = ({ children, tooltip, size = "md", className, ...props }) =>
1327
2119
  /* @__PURE__ */ jsx(TooltipContent, { children: tooltip })
1328
2120
  ] });
1329
2121
  };
1330
-
1331
- const CodeBlockClass = "mastra:rounded-lg mastra:[&>pre]:p-4 mastra:overflow-hidden mastra:[&>pre]:!bg-surface4 mastra:[&>pre>code]:leading-5 mastra:relative";
1332
- const CodeBlock = ({ code, language, className, cta }) => {
2122
+ async function highlight(code, lang) {
2123
+ const out = await codeToHast(code, {
2124
+ lang,
2125
+ theme: "dracula-soft"
2126
+ });
2127
+ return toJsxRuntime(out, {
2128
+ Fragment,
2129
+ jsx: jsx,
2130
+ jsxs: jsxs
2131
+ });
2132
+ }
2133
+ var CodeBlockClass = "mastra:rounded-lg mastra:[&>pre]:p-4 mastra:overflow-hidden mastra:[&>pre]:!bg-surface4 mastra:[&>pre>code]:leading-5 mastra:relative";
2134
+ var CodeBlock = ({ code, language, className, cta }) => {
1333
2135
  const [nodes, setNodes] = useState(null);
1334
2136
  useLayoutEffect(() => {
1335
2137
  void highlight(code, language).then(setNodes);
@@ -1339,17 +2141,16 @@ const CodeBlock = ({ code, language, className, cta }) => {
1339
2141
  cta
1340
2142
  ] });
1341
2143
  };
1342
- const CodeCopyButton = ({ code }) => {
2144
+ var CodeCopyButton = ({ code }) => {
1343
2145
  const [isCopied, setIsCopied] = useState(false);
1344
2146
  const handleCopy = () => {
1345
- navigator.clipboard.writeText(code);
2147
+ void navigator.clipboard.writeText(code);
1346
2148
  setIsCopied(true);
1347
2149
  setTimeout(() => setIsCopied(false), 2e3);
1348
2150
  };
1349
2151
  return /* @__PURE__ */ jsx("div", { className: "mastra:absolute mastra:top-2 mastra:right-2", children: /* @__PURE__ */ jsx(IconButton, { tooltip: "Copy", onClick: handleCopy, children: isCopied ? /* @__PURE__ */ jsx(CheckIcon, {}) : /* @__PURE__ */ jsx(CopyIcon, {}) }) });
1350
2152
  };
1351
-
1352
- const AgentIcon = ({ className, ...props }) => /* @__PURE__ */ jsxs(
2153
+ var AgentIcon = ({ className, ...props }) => /* @__PURE__ */ jsxs(
1353
2154
  "svg",
1354
2155
  {
1355
2156
  width: "17",
@@ -1379,8 +2180,7 @@ const AgentIcon = ({ className, ...props }) => /* @__PURE__ */ jsxs(
1379
2180
  ]
1380
2181
  }
1381
2182
  );
1382
-
1383
- const ToolsIcon = ({ className, ...props }) => /* @__PURE__ */ jsx(
2183
+ var ToolsIcon = ({ className, ...props }) => /* @__PURE__ */ jsx(
1384
2184
  "svg",
1385
2185
  {
1386
2186
  width: "17",
@@ -1401,8 +2201,7 @@ const ToolsIcon = ({ className, ...props }) => /* @__PURE__ */ jsx(
1401
2201
  )
1402
2202
  }
1403
2203
  );
1404
-
1405
- const WorkflowIcon = ({ className, ...props }) => /* @__PURE__ */ jsx(
2204
+ var WorkflowIcon = ({ className, ...props }) => /* @__PURE__ */ jsx(
1406
2205
  "svg",
1407
2206
  {
1408
2207
  width: "17",
@@ -1423,9 +2222,8 @@ const WorkflowIcon = ({ className, ...props }) => /* @__PURE__ */ jsx(
1423
2222
  )
1424
2223
  }
1425
2224
  );
1426
-
1427
- const MessageClass = "mastra:flex mastra:flex-col mastra:w-full mastra:py-4 mastra:gap-2 mastra:group";
1428
- const Message = ({ position, className, children, ...props }) => {
2225
+ var MessageClass = "mastra:flex mastra:flex-col mastra:w-full mastra:py-4 mastra:gap-2 mastra:group";
2226
+ var Message = ({ position, className, children, ...props }) => {
1429
2227
  return /* @__PURE__ */ jsx(
1430
2228
  "div",
1431
2229
  {
@@ -1438,35 +2236,35 @@ const Message = ({ position, className, children, ...props }) => {
1438
2236
  }
1439
2237
  );
1440
2238
  };
1441
- const MessageContentClass = "mastra:max-w-4/5 mastra:py-2 mastra:text-text6 mastra:rounded-lg mastra-message-content mastra:text-md";
1442
- const MessageContent = ({ children, className, isStreaming, ...props }) => {
2239
+ var MessageContentClass = "mastra:max-w-4/5 mastra:py-2 mastra:text-text6 mastra:rounded-lg mastra-message-content mastra:text-md";
2240
+ var MessageContent = ({ children, className, isStreaming, ...props }) => {
1443
2241
  return /* @__PURE__ */ jsxs("div", { className: className || MessageContentClass, ...props, children: [
1444
2242
  children,
1445
2243
  isStreaming && /* @__PURE__ */ jsx(MessageStreaming, {})
1446
2244
  ] });
1447
2245
  };
1448
- const MessageActionsClass = "mastra:gap-2 mastra:flex mastra:opacity-0 mastra:group-hover:opacity-100 mastra:group-focus-within:opacity-100 mastra:items-center";
1449
- const MessageActions = ({ children, className, ...props }) => {
2246
+ var MessageActionsClass = "mastra:gap-2 mastra:flex mastra:opacity-0 mastra:group-hover:opacity-100 mastra:group-focus-within:opacity-100 mastra:items-center";
2247
+ var MessageActions = ({ children, className, ...props }) => {
1450
2248
  return /* @__PURE__ */ jsx("div", { className: className || MessageActionsClass, ...props, children });
1451
2249
  };
1452
- const MessageUsagesClass = "mastra:flex mastra:gap-2 mastra:items-center";
1453
- const MessageUsages = ({ children, className, ...props }) => {
2250
+ var MessageUsagesClass = "mastra:flex mastra:gap-2 mastra:items-center";
2251
+ var MessageUsages = ({ children, className, ...props }) => {
1454
2252
  return /* @__PURE__ */ jsx("div", { className: className || MessageUsagesClass, ...props, children });
1455
2253
  };
1456
- const MessageUsageClass = "mastra:flex mastra:gap-2 mastra:items-center mastra:font-mono mastra:text-xs mastra:bg-surface3 mastra:rounded-lg mastra:px-2 mastra:py-1";
1457
- const MessageUsage = ({ children, className, ...props }) => {
2254
+ var MessageUsageClass = "mastra:flex mastra:gap-2 mastra:items-center mastra:font-mono mastra:text-xs mastra:bg-surface3 mastra:rounded-lg mastra:px-2 mastra:py-1";
2255
+ var MessageUsage = ({ children, className, ...props }) => {
1458
2256
  return /* @__PURE__ */ jsx("dl", { className: className || MessageUsageClass, ...props, children });
1459
2257
  };
1460
- const MessageUsageEntryClass = "mastra:text-text3 mastra:text-xs mastra:flex mastra:gap-1 mastra:items-center";
1461
- const MessageUsageEntry = ({ children, className, ...props }) => {
2258
+ var MessageUsageEntryClass = "mastra:text-text3 mastra:text-xs mastra:flex mastra:gap-1 mastra:items-center";
2259
+ var MessageUsageEntry = ({ children, className, ...props }) => {
1462
2260
  return /* @__PURE__ */ jsx("dt", { className: className || MessageUsageEntryClass, ...props, children });
1463
2261
  };
1464
- const MessageUsageValueClass = "mastra:text-text6 mastra:text-xs";
1465
- const MessageUsageValue = ({ children, className, ...props }) => {
2262
+ var MessageUsageValueClass = "mastra:text-text6 mastra:text-xs";
2263
+ var MessageUsageValue = ({ children, className, ...props }) => {
1466
2264
  return /* @__PURE__ */ jsx("dd", { className: className || MessageUsageValueClass, ...props, children });
1467
2265
  };
1468
- const MessageListClass = "mastra:overflow-y-auto mastra:h-full mastra-list";
1469
- const MessageList = ({ children, className, ...props }) => {
2266
+ var MessageListClass = "mastra:overflow-y-auto mastra:h-full mastra-list";
2267
+ var MessageList = ({ children, className, ...props }) => {
1470
2268
  const listRef = useRef(null);
1471
2269
  useEffect(() => {
1472
2270
  const scrollToBottom = () => {
@@ -1477,10 +2275,432 @@ const MessageList = ({ children, className, ...props }) => {
1477
2275
  });
1478
2276
  return /* @__PURE__ */ jsx("div", { className: className || MessageListClass, ...props, ref: listRef, children });
1479
2277
  };
1480
- const MessageStreamingClass = "mastra:inline-block mastra:w-[2px] mastra:h-[1em] mastra:bg-text5 mastra:ml-0.5 mastra:align-text-bottom mastra:animate-pulse";
1481
- const MessageStreaming = ({ className, ...props }) => {
2278
+ var MessageStreamingClass = "mastra:inline-block mastra:w-[2px] mastra:h-[1em] mastra:bg-text5 mastra:ml-0.5 mastra:align-text-bottom mastra:animate-pulse";
2279
+ var MessageStreaming = ({ className, ...props }) => {
1482
2280
  return /* @__PURE__ */ jsx("span", { className: className || MessageStreamingClass, ...props });
1483
2281
  };
2282
+ function useMutation(mutationFn) {
2283
+ const [isPending, setIsPending] = useState(false);
2284
+ const [isSuccess, setIsSuccess] = useState(false);
2285
+ const [isError, setIsError] = useState(false);
2286
+ const [error, setError] = useState(null);
2287
+ const [data, setData] = useState(void 0);
2288
+ const mutationFnRef = useRef(mutationFn);
2289
+ mutationFnRef.current = mutationFn;
2290
+ const reset = useCallback(() => {
2291
+ setIsPending(false);
2292
+ setIsSuccess(false);
2293
+ setIsError(false);
2294
+ setError(null);
2295
+ setData(void 0);
2296
+ }, []);
2297
+ const mutateAsync = useCallback(async (variables) => {
2298
+ setIsPending(true);
2299
+ setIsSuccess(false);
2300
+ setIsError(false);
2301
+ setError(null);
2302
+ try {
2303
+ const result = await mutationFnRef.current(variables);
2304
+ setData(result);
2305
+ setIsSuccess(true);
2306
+ return result;
2307
+ } catch (err) {
2308
+ const typedError = err;
2309
+ setError(typedError);
2310
+ setIsError(true);
2311
+ throw err;
2312
+ } finally {
2313
+ setIsPending(false);
2314
+ }
2315
+ }, []);
2316
+ const mutate = useCallback(
2317
+ (variables) => {
2318
+ mutateAsync(variables).catch(() => {
2319
+ });
2320
+ },
2321
+ [mutateAsync]
2322
+ );
2323
+ return {
2324
+ mutate,
2325
+ mutateAsync,
2326
+ isPending,
2327
+ isSuccess,
2328
+ isError,
2329
+ error,
2330
+ data,
2331
+ reset
2332
+ };
2333
+ }
2334
+ function useStreamWorkflow({ debugMode, tracingOptions, onError }) {
2335
+ const client = useMastraClient();
2336
+ const [streamResult, setStreamResult] = useState({});
2337
+ const [isStreaming, setIsStreaming] = useState(false);
2338
+ const readerRef = useRef(null);
2339
+ const observerRef = useRef(null);
2340
+ const resumeStreamRef = useRef(null);
2341
+ const timeTravelStreamRef = useRef(null);
2342
+ const isMountedRef = useRef(true);
2343
+ useEffect(() => {
2344
+ isMountedRef.current = true;
2345
+ return () => {
2346
+ isMountedRef.current = false;
2347
+ if (readerRef.current) {
2348
+ try {
2349
+ readerRef.current.releaseLock();
2350
+ } catch {
2351
+ }
2352
+ readerRef.current = null;
2353
+ }
2354
+ if (observerRef.current) {
2355
+ try {
2356
+ observerRef.current.releaseLock();
2357
+ } catch {
2358
+ }
2359
+ observerRef.current = null;
2360
+ }
2361
+ if (resumeStreamRef.current) {
2362
+ try {
2363
+ resumeStreamRef.current.releaseLock();
2364
+ } catch {
2365
+ }
2366
+ resumeStreamRef.current = null;
2367
+ }
2368
+ if (timeTravelStreamRef.current) {
2369
+ try {
2370
+ timeTravelStreamRef.current.releaseLock();
2371
+ } catch {
2372
+ }
2373
+ timeTravelStreamRef.current = null;
2374
+ }
2375
+ };
2376
+ }, []);
2377
+ const handleStreamError = useCallback(
2378
+ (err, defaultMessage, setStreamingState) => {
2379
+ if (err instanceof TypeError) {
2380
+ return;
2381
+ }
2382
+ const error = err instanceof Error ? err : new Error(defaultMessage);
2383
+ onError?.(error, defaultMessage);
2384
+ setStreamingState?.(false);
2385
+ },
2386
+ [onError]
2387
+ );
2388
+ const handleWorkflowFinish = useCallback((value) => {
2389
+ if (value.type === "workflow-finish") {
2390
+ const streamStatus = value.payload?.workflowStatus;
2391
+ const metadata = value.payload?.metadata;
2392
+ setStreamResult((prev) => ({
2393
+ ...prev,
2394
+ status: streamStatus
2395
+ }));
2396
+ if (streamStatus === "failed") {
2397
+ throw new Error(metadata?.errorMessage || "Workflow execution failed");
2398
+ }
2399
+ }
2400
+ }, []);
2401
+ const streamWorkflow = useMutation(
2402
+ async ({ workflowId, runId, inputData, initialState, requestContext: playgroundRequestContext, perStep }) => {
2403
+ if (readerRef.current) {
2404
+ readerRef.current.releaseLock();
2405
+ }
2406
+ if (!isMountedRef.current) return;
2407
+ setIsStreaming(true);
2408
+ setStreamResult({ input: inputData });
2409
+ const requestContext = new RequestContext();
2410
+ Object.entries(playgroundRequestContext).forEach(([key, value]) => {
2411
+ requestContext.set(key, value);
2412
+ });
2413
+ const workflow = client.getWorkflow(workflowId);
2414
+ const run = await workflow.createRun({ runId });
2415
+ const stream = await run.stream({
2416
+ inputData,
2417
+ initialState,
2418
+ requestContext,
2419
+ closeOnSuspend: true,
2420
+ tracingOptions,
2421
+ perStep: perStep ?? debugMode
2422
+ });
2423
+ if (!stream) {
2424
+ return handleStreamError(new Error("No stream returned"), "No stream returned", setIsStreaming);
2425
+ }
2426
+ const reader = stream.getReader();
2427
+ readerRef.current = reader;
2428
+ try {
2429
+ while (true) {
2430
+ if (!isMountedRef.current) break;
2431
+ const { done, value } = await reader.read();
2432
+ if (done) break;
2433
+ if (isMountedRef.current) {
2434
+ setStreamResult((prev) => {
2435
+ const newResult = mapWorkflowStreamChunkToWatchResult(prev, value);
2436
+ return newResult;
2437
+ });
2438
+ if (value.type === "workflow-step-start") {
2439
+ setIsStreaming(true);
2440
+ }
2441
+ if (value.type === "workflow-step-suspended") {
2442
+ setIsStreaming(false);
2443
+ }
2444
+ if (value.type === "workflow-finish") {
2445
+ handleWorkflowFinish(value);
2446
+ }
2447
+ }
2448
+ }
2449
+ } catch (err) {
2450
+ handleStreamError(err, "Error streaming workflow");
2451
+ } finally {
2452
+ if (isMountedRef.current) {
2453
+ setIsStreaming(false);
2454
+ }
2455
+ if (readerRef.current) {
2456
+ readerRef.current.releaseLock();
2457
+ readerRef.current = null;
2458
+ }
2459
+ }
2460
+ }
2461
+ );
2462
+ const observeWorkflowStream = useMutation(
2463
+ async ({ workflowId, runId, storeRunResult }) => {
2464
+ if (observerRef.current) {
2465
+ observerRef.current.releaseLock();
2466
+ }
2467
+ if (!isMountedRef.current) return;
2468
+ setIsStreaming(true);
2469
+ setStreamResult(storeRunResult || {});
2470
+ if (storeRunResult?.status === "suspended") {
2471
+ setIsStreaming(false);
2472
+ return;
2473
+ }
2474
+ const workflow = client.getWorkflow(workflowId);
2475
+ const run = await workflow.createRun({ runId });
2476
+ const stream = await run.observeStream();
2477
+ if (!stream) {
2478
+ return handleStreamError(new Error("No stream returned"), "No stream returned", setIsStreaming);
2479
+ }
2480
+ const reader = stream.getReader();
2481
+ observerRef.current = reader;
2482
+ try {
2483
+ while (true) {
2484
+ if (!isMountedRef.current) break;
2485
+ const { done, value } = await reader.read();
2486
+ if (done) break;
2487
+ if (isMountedRef.current) {
2488
+ setStreamResult((prev) => {
2489
+ const newResult = mapWorkflowStreamChunkToWatchResult(prev, value);
2490
+ return newResult;
2491
+ });
2492
+ if (value.type === "workflow-step-start") {
2493
+ setIsStreaming(true);
2494
+ }
2495
+ if (value.type === "workflow-step-suspended") {
2496
+ setIsStreaming(false);
2497
+ }
2498
+ if (value.type === "workflow-finish") {
2499
+ handleWorkflowFinish(value);
2500
+ }
2501
+ }
2502
+ }
2503
+ } catch (err) {
2504
+ handleStreamError(err, "Error observing workflow");
2505
+ } finally {
2506
+ if (isMountedRef.current) {
2507
+ setIsStreaming(false);
2508
+ }
2509
+ if (observerRef.current) {
2510
+ observerRef.current.releaseLock();
2511
+ observerRef.current = null;
2512
+ }
2513
+ }
2514
+ }
2515
+ );
2516
+ const resumeWorkflowStream = useMutation(
2517
+ async ({ workflowId, runId, step, resumeData, requestContext: playgroundRequestContext, perStep }) => {
2518
+ if (resumeStreamRef.current) {
2519
+ resumeStreamRef.current.releaseLock();
2520
+ }
2521
+ if (!isMountedRef.current) return;
2522
+ setIsStreaming(true);
2523
+ const workflow = client.getWorkflow(workflowId);
2524
+ const requestContext = new RequestContext();
2525
+ Object.entries(playgroundRequestContext).forEach(([key, value]) => {
2526
+ requestContext.set(key, value);
2527
+ });
2528
+ const run = await workflow.createRun({ runId });
2529
+ const stream = await run.resumeStream({
2530
+ step,
2531
+ resumeData,
2532
+ requestContext,
2533
+ tracingOptions,
2534
+ perStep: perStep ?? debugMode
2535
+ });
2536
+ if (!stream) {
2537
+ return handleStreamError(new Error("No stream returned"), "No stream returned", setIsStreaming);
2538
+ }
2539
+ const reader = stream.getReader();
2540
+ resumeStreamRef.current = reader;
2541
+ try {
2542
+ while (true) {
2543
+ if (!isMountedRef.current) break;
2544
+ const { done, value } = await reader.read();
2545
+ if (done) break;
2546
+ if (isMountedRef.current) {
2547
+ setStreamResult((prev) => {
2548
+ const newResult = mapWorkflowStreamChunkToWatchResult(prev, value);
2549
+ return newResult;
2550
+ });
2551
+ if (value.type === "workflow-step-start") {
2552
+ setIsStreaming(true);
2553
+ }
2554
+ if (value.type === "workflow-step-suspended") {
2555
+ setIsStreaming(false);
2556
+ }
2557
+ if (value.type === "workflow-finish") {
2558
+ handleWorkflowFinish(value);
2559
+ }
2560
+ }
2561
+ }
2562
+ } catch (err) {
2563
+ handleStreamError(err, "Error resuming workflow stream");
2564
+ } finally {
2565
+ if (isMountedRef.current) {
2566
+ setIsStreaming(false);
2567
+ }
2568
+ if (resumeStreamRef.current) {
2569
+ resumeStreamRef.current.releaseLock();
2570
+ resumeStreamRef.current = null;
2571
+ }
2572
+ }
2573
+ }
2574
+ );
2575
+ const timeTravelWorkflowStream = useMutation(
2576
+ async ({ workflowId, requestContext: playgroundRequestContext, runId, perStep, ...params }) => {
2577
+ if (timeTravelStreamRef.current) {
2578
+ timeTravelStreamRef.current.releaseLock();
2579
+ }
2580
+ if (!isMountedRef.current) return;
2581
+ setIsStreaming(true);
2582
+ const workflow = client.getWorkflow(workflowId);
2583
+ const requestContext = new RequestContext();
2584
+ Object.entries(playgroundRequestContext).forEach(([key, value]) => {
2585
+ requestContext.set(key, value);
2586
+ });
2587
+ const run = await workflow.createRun({ runId });
2588
+ const stream = await run.timeTravelStream({
2589
+ ...params,
2590
+ perStep: perStep ?? debugMode,
2591
+ requestContext,
2592
+ tracingOptions
2593
+ });
2594
+ if (!stream) {
2595
+ return handleStreamError(new Error("No stream returned"), "No stream returned", setIsStreaming);
2596
+ }
2597
+ const reader = stream.getReader();
2598
+ timeTravelStreamRef.current = reader;
2599
+ try {
2600
+ while (true) {
2601
+ if (!isMountedRef.current) break;
2602
+ const { done, value } = await reader.read();
2603
+ if (done) break;
2604
+ if (isMountedRef.current) {
2605
+ setStreamResult((prev) => {
2606
+ const newResult = mapWorkflowStreamChunkToWatchResult(prev, value);
2607
+ return newResult;
2608
+ });
2609
+ if (value.type === "workflow-step-start") {
2610
+ setIsStreaming(true);
2611
+ }
2612
+ if (value.type === "workflow-step-suspended") {
2613
+ setIsStreaming(false);
2614
+ }
2615
+ if (value.type === "workflow-finish") {
2616
+ handleWorkflowFinish(value);
2617
+ }
2618
+ }
2619
+ }
2620
+ } catch (err) {
2621
+ handleStreamError(err, "Error time traveling workflow stream");
2622
+ } finally {
2623
+ if (isMountedRef.current) {
2624
+ setIsStreaming(false);
2625
+ }
2626
+ if (timeTravelStreamRef.current) {
2627
+ timeTravelStreamRef.current.releaseLock();
2628
+ timeTravelStreamRef.current = null;
2629
+ }
2630
+ }
2631
+ }
2632
+ );
2633
+ const closeStreamsAndReset = useCallback(() => {
2634
+ setIsStreaming(false);
2635
+ setStreamResult({});
2636
+ if (readerRef.current) {
2637
+ try {
2638
+ readerRef.current.releaseLock();
2639
+ } catch {
2640
+ }
2641
+ readerRef.current = null;
2642
+ }
2643
+ if (observerRef.current) {
2644
+ try {
2645
+ observerRef.current.releaseLock();
2646
+ } catch {
2647
+ }
2648
+ observerRef.current = null;
2649
+ }
2650
+ if (resumeStreamRef.current) {
2651
+ try {
2652
+ resumeStreamRef.current.releaseLock();
2653
+ } catch {
2654
+ }
2655
+ resumeStreamRef.current = null;
2656
+ }
2657
+ if (timeTravelStreamRef.current) {
2658
+ try {
2659
+ timeTravelStreamRef.current.releaseLock();
2660
+ } catch {
2661
+ }
2662
+ timeTravelStreamRef.current = null;
2663
+ }
2664
+ }, []);
2665
+ return {
2666
+ streamWorkflow,
2667
+ streamResult,
2668
+ isStreaming,
2669
+ observeWorkflowStream,
2670
+ closeStreamsAndReset,
2671
+ resumeWorkflowStream,
2672
+ timeTravelWorkflowStream
2673
+ };
2674
+ }
2675
+
2676
+ // src/workflows/hooks.ts
2677
+ function useCreateWorkflowRun() {
2678
+ const client = useMastraClient();
2679
+ return useMutation(async ({ workflowId, prevRunId }) => {
2680
+ try {
2681
+ const workflow = client.getWorkflow(workflowId);
2682
+ const { runId: newRunId } = await workflow.createRun({ runId: prevRunId });
2683
+ return { runId: newRunId };
2684
+ } catch (error) {
2685
+ console.error("Error creating workflow run:", error);
2686
+ throw error;
2687
+ }
2688
+ });
2689
+ }
2690
+ function useCancelWorkflowRun() {
2691
+ const client = useMastraClient();
2692
+ return useMutation(async ({ workflowId, runId }) => {
2693
+ try {
2694
+ const workflow = client.getWorkflow(workflowId);
2695
+ const run = await workflow.createRun({ runId });
2696
+ return run.cancelRun();
2697
+ } catch (error) {
2698
+ console.error("Error canceling workflow run:", error);
2699
+ throw error;
2700
+ }
2701
+ });
2702
+ }
1484
2703
 
1485
- export { AgentIcon, CodeBlock, CodeBlockClass, CodeCopyButton, Entity, EntityCaret, EntityContent, EntityContentClass, EntityTrigger, EntityTriggerClass, EntityTriggerVariantClasses, Entry, EntryClass, EntryTitle, EntryTitleClass, Icon, IconButton, IconButtonClass, IconSizes, MastraReactProvider, Message, MessageActions, MessageActionsClass, MessageClass, MessageContent, MessageContentClass, MessageList, MessageListClass, MessageStreaming, MessageStreamingClass, MessageUsage, MessageUsageClass, MessageUsageEntry, MessageUsageEntryClass, MessageUsageValue, MessageUsageValueClass, MessageUsages, MessageUsagesClass, ToolApproval, ToolApprovalActions, ToolApprovalActionsClass, ToolApprovalClass, ToolApprovalContent, ToolApprovalContentClass, ToolApprovalHeader, ToolApprovalHeaderClass, ToolApprovalTitle, ToolApprovalTitleClass, ToolsIcon, Tooltip, TooltipContent, TooltipContentClass, TooltipTrigger, WorkflowIcon, mapWorkflowStreamChunkToWatchResult, toAssistantUIMessage, toUIMessage, useChat, useEntity, useMastraClient };
2704
+ export { AgentIcon, CodeBlock, CodeBlockClass, CodeCopyButton, Entity, EntityCaret, EntityContent, EntityContentClass, EntityTrigger, EntityTriggerClass, EntityTriggerVariantClasses, Entry, EntryClass, EntryTitle, EntryTitleClass, Icon, IconButton, IconButtonClass, IconSizes, MastraReactProvider, Message, MessageActions, MessageActionsClass, MessageClass, MessageContent, MessageContentClass, MessageList, MessageListClass, MessageStreaming, MessageStreamingClass, MessageUsage, MessageUsageClass, MessageUsageEntry, MessageUsageEntryClass, MessageUsageValue, MessageUsageValueClass, MessageUsages, MessageUsagesClass, ToolApproval, ToolApprovalActions, ToolApprovalActionsClass, ToolApprovalClass, ToolApprovalContent, ToolApprovalContentClass, ToolApprovalHeader, ToolApprovalHeaderClass, ToolApprovalTitle, ToolApprovalTitleClass, ToolsIcon, Tooltip, TooltipContent, TooltipContentClass, TooltipTrigger, WorkflowIcon, mapWorkflowStreamChunkToWatchResult, resolveToChildMessages, toAssistantUIMessage, toUIMessage, useCancelWorkflowRun, useChat, useCreateWorkflowRun, useEntity, useMastraClient, useStreamWorkflow };
1486
2705
  //# sourceMappingURL=index.js.map
2706
+ //# sourceMappingURL=index.js.map