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