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