@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.
- package/CHANGELOG.md +1172 -3
- package/LICENSE.md +15 -0
- package/dist/agent/hooks.d.ts +66 -0
- package/dist/agent/hooks.d.ts.map +1 -0
- package/dist/{src/agent → agent}/types.d.ts +2 -0
- package/dist/agent/types.d.ts.map +1 -0
- package/dist/index.cjs +1515 -293
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +8 -2
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1506 -286
- package/dist/index.js.map +1 -1
- package/dist/lib/ai-sdk/index.d.ts +5 -0
- package/dist/lib/ai-sdk/index.d.ts.map +1 -0
- package/dist/lib/ai-sdk/memory/resolveInitialMessages.d.ts +13 -0
- package/dist/lib/ai-sdk/memory/resolveInitialMessages.d.ts.map +1 -0
- package/dist/{src/lib → lib}/ai-sdk/transformers/AISdkNetworkTransformer.d.ts +4 -3
- package/dist/lib/ai-sdk/transformers/AISdkNetworkTransformer.d.ts.map +1 -0
- package/dist/lib/ai-sdk/transformers/types.d.ts +11 -0
- package/dist/lib/ai-sdk/transformers/types.d.ts.map +1 -0
- package/dist/lib/ai-sdk/types.d.ts +116 -0
- package/dist/lib/ai-sdk/types.d.ts.map +1 -0
- package/dist/lib/ai-sdk/utils/fromCoreUserMessageToUIMessage.d.ts +11 -0
- package/dist/lib/ai-sdk/utils/fromCoreUserMessageToUIMessage.d.ts.map +1 -0
- package/dist/{src/lib → lib}/ai-sdk/utils/toAssistantUIMessage.d.ts +3 -2
- package/dist/lib/ai-sdk/utils/toAssistantUIMessage.d.ts.map +1 -0
- package/dist/{src/lib → lib}/ai-sdk/utils/toUIMessage.d.ts +4 -3
- package/dist/lib/ai-sdk/utils/toUIMessage.d.ts.map +1 -0
- package/dist/lib/use-mutation.d.ts +28 -0
- package/dist/lib/use-mutation.d.ts.map +1 -0
- package/dist/mastra-client-context.d.ts +14 -0
- package/dist/mastra-client-context.d.ts.map +1 -0
- package/dist/mastra-react-provider.d.ts +5 -0
- package/dist/mastra-react-provider.d.ts.map +1 -0
- package/dist/react.css +184 -322
- package/dist/{src/ui → ui}/Code/Code.d.ts +2 -1
- package/dist/ui/Code/Code.d.ts.map +1 -0
- package/dist/ui/Code/highlight.d.ts +4 -0
- package/dist/ui/Code/highlight.d.ts.map +1 -0
- package/dist/ui/Code/index.d.ts +2 -0
- package/dist/ui/Code/index.d.ts.map +1 -0
- package/dist/{src/ui → ui}/Entity/Entity.d.ts +2 -1
- package/dist/ui/Entity/Entity.d.ts.map +1 -0
- package/dist/{src/ui → ui}/Entity/Entry.d.ts +2 -1
- package/dist/ui/Entity/Entry.d.ts.map +1 -0
- package/dist/{src/ui → ui}/Entity/ToolApproval.d.ts +1 -0
- package/dist/ui/Entity/ToolApproval.d.ts.map +1 -0
- package/dist/{src/ui → ui}/Entity/context.d.ts +4 -3
- package/dist/ui/Entity/context.d.ts.map +1 -0
- package/dist/ui/Entity/index.d.ts +5 -0
- package/dist/ui/Entity/index.d.ts.map +1 -0
- package/dist/{src/ui → ui}/Entity/types.d.ts +1 -0
- package/dist/ui/Entity/types.d.ts.map +1 -0
- package/dist/{src/ui → ui}/Icon/Icon.d.ts +2 -1
- package/dist/ui/Icon/Icon.d.ts.map +1 -0
- package/dist/ui/Icon/index.d.ts +2 -0
- package/dist/ui/Icon/index.d.ts.map +1 -0
- package/dist/{src/ui → ui}/IconButton/IconButton.d.ts +2 -1
- package/dist/ui/IconButton/IconButton.d.ts.map +1 -0
- package/dist/ui/IconButton/index.d.ts +2 -0
- package/dist/ui/IconButton/index.d.ts.map +1 -0
- package/dist/{src/ui → ui}/Icons/AgentIcon.d.ts +2 -1
- package/dist/ui/Icons/AgentIcon.d.ts.map +1 -0
- package/dist/{src/ui → ui}/Icons/ToolsIcon.d.ts +2 -1
- package/dist/ui/Icons/ToolsIcon.d.ts.map +1 -0
- package/dist/{src/ui → ui}/Icons/WorkflowIcon.d.ts +2 -1
- package/dist/ui/Icons/WorkflowIcon.d.ts.map +1 -0
- package/dist/ui/Icons/index.d.ts +4 -0
- package/dist/ui/Icons/index.d.ts.map +1 -0
- package/dist/{src/ui → ui}/Message/Message.d.ts +2 -1
- package/dist/ui/Message/Message.d.ts.map +1 -0
- package/dist/ui/Message/index.d.ts +2 -0
- package/dist/ui/Message/index.d.ts.map +1 -0
- package/dist/{src/ui → ui}/Tooltip/Tooltip.d.ts +2 -1
- package/dist/ui/Tooltip/Tooltip.d.ts.map +1 -0
- package/dist/ui/Tooltip/index.d.ts +2 -0
- package/dist/ui/Tooltip/index.d.ts.map +1 -0
- package/dist/ui/index.d.ts +8 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/workflows/hooks.d.ts +34 -0
- package/dist/workflows/hooks.d.ts.map +1 -0
- package/dist/workflows/index.d.ts +3 -0
- package/dist/workflows/index.d.ts.map +1 -0
- package/dist/workflows/types.d.ts +122 -0
- package/dist/workflows/types.d.ts.map +1 -0
- package/dist/workflows/use-stream-workflow.d.ts +39 -0
- package/dist/workflows/use-stream-workflow.d.ts.map +1 -0
- package/package.json +34 -23
- package/dist/src/agent/hooks.d.ts +0 -46
- package/dist/src/index.d.ts +0 -6
- package/dist/src/lib/ai-sdk/index.d.ts +0 -3
- package/dist/src/lib/ai-sdk/memory/resolveInitialMessages.d.ts +0 -2
- package/dist/src/lib/ai-sdk/transformers/types.d.ts +0 -10
- package/dist/src/lib/ai-sdk/types.d.ts +0 -14
- package/dist/src/lib/ai-sdk/utils/toAssistantUIMessage.test.d.ts +0 -1
- package/dist/src/mastra-client-context.d.ts +0 -10
- package/dist/src/mastra-react-provider.d.ts +0 -4
- package/dist/src/ui/Code/highlight.d.ts +0 -3
- package/dist/src/ui/Code/index.d.ts +0 -1
- package/dist/src/ui/Entity/Entity.stories.d.ts +0 -22
- package/dist/src/ui/Entity/index.d.ts +0 -4
- package/dist/src/ui/Icon/index.d.ts +0 -1
- package/dist/src/ui/IconButton/IconButton.stories.d.ts +0 -12
- package/dist/src/ui/IconButton/index.d.ts +0 -1
- package/dist/src/ui/Icons/index.d.ts +0 -3
- package/dist/src/ui/Message/Message.stories.d.ts +0 -13
- package/dist/src/ui/Message/index.d.ts +0 -1
- package/dist/src/ui/Tooltip/Tooltip.stories.d.ts +0 -12
- package/dist/src/ui/Tooltip/index.d.ts +0 -1
- 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
|
-
|
|
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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const
|
|
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
|
-
|
|
20
|
-
|
|
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
|
-
|
|
24
|
-
|
|
40
|
+
headers: isLocalUrl(baseUrl) ? { ...mastraClientHeaders, "x-mastra-dev-playground": "true" } : mastraClientHeaders,
|
|
41
|
+
apiPrefix
|
|
25
42
|
});
|
|
26
43
|
};
|
|
27
|
-
|
|
28
|
-
|
|
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
|
-
|
|
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.
|
|
175
|
+
text: chunk.payload.reason
|
|
114
176
|
}
|
|
115
177
|
],
|
|
116
178
|
metadata: {
|
|
117
179
|
...metadata,
|
|
118
|
-
status: "
|
|
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
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
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
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
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
|
-
|
|
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
|
|
270
|
-
toolCallId
|
|
368
|
+
toolName,
|
|
369
|
+
toolCallId,
|
|
271
370
|
state: "output-error",
|
|
272
371
|
input: toolPart.input,
|
|
273
|
-
errorText: String(
|
|
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
|
|
281
|
-
toolCallId
|
|
388
|
+
toolName,
|
|
389
|
+
toolCallId,
|
|
282
390
|
state: "output-available",
|
|
283
391
|
input: toolPart.input,
|
|
284
|
-
output
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
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
|
-
|
|
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
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
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
|
|
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:
|
|
504
|
-
args:
|
|
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
|
-
|
|
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-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
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
|
|
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
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
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
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
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
|
-
|
|
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
|
|
1035
|
-
|
|
1036
|
-
|
|
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
|
-
|
|
1049
|
-
...threadId ? { threadId,
|
|
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 ({
|
|
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
|
|
1084
|
-
|
|
1085
|
-
runId
|
|
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
|
-
|
|
1098
|
-
...threadId ? { threadId,
|
|
1099
|
-
providerOptions
|
|
1761
|
+
requestContext,
|
|
1762
|
+
...threadId ? { memory: { thread: threadId, resource: resourceId || agentId } } : {},
|
|
1763
|
+
providerOptions,
|
|
1764
|
+
requireToolApproval,
|
|
1765
|
+
tracingOptions
|
|
1100
1766
|
});
|
|
1101
|
-
|
|
1102
|
-
|
|
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
|
-
|
|
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
|
|
1129
|
-
|
|
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
|
|
1141
|
-
|
|
1142
|
-
...threadId ? { thread: threadId,
|
|
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
|
|
1156
|
-
|
|
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
|
|
1959
|
+
await generate({ ...args, coreUserMessages });
|
|
1159
1960
|
} else if (mode === "stream") {
|
|
1160
|
-
await stream({ ...args, coreUserMessages
|
|
1961
|
+
await stream({ ...args, coreUserMessages });
|
|
1161
1962
|
} else if (mode === "network") {
|
|
1162
|
-
await network({ ...args, coreUserMessages
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2070
|
+
var ToolApproval = ({ className, ...props }) => {
|
|
1266
2071
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: className || ToolApprovalClass, ...props });
|
|
1267
2072
|
};
|
|
1268
|
-
|
|
1269
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2081
|
+
var ToolApprovalHeader = ({ className, ...props }) => {
|
|
1277
2082
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: className || ToolApprovalHeaderClass, ...props });
|
|
1278
2083
|
};
|
|
1279
|
-
|
|
1280
|
-
|
|
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
|
-
|
|
1284
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1293
|
-
|
|
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
|
-
|
|
1313
|
-
|
|
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
|
-
|
|
2107
|
+
var TooltipTrigger = (props) => {
|
|
1317
2108
|
return /* @__PURE__ */ jsxRuntime.jsx(reactTooltip.TooltipTrigger, { ...props, asChild: true });
|
|
1318
2109
|
};
|
|
1319
|
-
|
|
1320
|
-
|
|
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
|
|
1336
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1446
|
-
|
|
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
|
-
|
|
1453
|
-
|
|
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
|
-
|
|
1457
|
-
|
|
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
|
-
|
|
1461
|
-
|
|
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
|
-
|
|
1465
|
-
|
|
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
|
-
|
|
1469
|
-
|
|
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
|
-
|
|
1473
|
-
|
|
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
|
-
|
|
1485
|
-
|
|
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
|