@mastra/playground-ui 6.7.2-alpha.0 → 6.7.2-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/dist/index.cjs.js +1903 -746
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +1906 -750
- package/dist/index.es.js.map +1 -1
- package/dist/src/domains/agents/components/agent-information/agent-information.d.ts +5 -0
- package/dist/src/domains/agents/components/agent-information/agent-instructions-enhancer.d.ts +5 -0
- package/dist/src/domains/agents/components/agent-information/agent-memory-config.d.ts +5 -0
- package/dist/src/domains/agents/components/agent-information/agent-memory.d.ts +6 -0
- package/dist/src/domains/agents/components/agent-information/agent-working-memory.d.ts +5 -0
- package/dist/src/domains/agents/components/agent-information/code-display.d.ts +10 -0
- package/dist/src/domains/agents/components/agent-information/current-instructions.d.ts +15 -0
- package/dist/src/domains/agents/components/agent-information/version-actions.d.ts +8 -0
- package/dist/src/domains/agents/components/agent-information/version-history-dialog.d.ts +9 -0
- package/dist/src/domains/agents/components/agent-information/version-history.d.ts +10 -0
- package/dist/src/domains/agents/components/agent-information/version-item.d.ts +14 -0
- package/dist/src/domains/agents/hooks/use-prompt-enhancer.d.ts +19 -0
- package/dist/src/domains/agents/hooks/use-prompt-versions.d.ts +12 -0
- package/dist/src/domains/agents/index.d.ts +1 -0
- package/dist/src/lib/framework.d.ts +1 -1
- package/package.json +6 -6
package/dist/index.cjs.js
CHANGED
|
@@ -15,7 +15,7 @@ const remarkGfm = require('remark-gfm');
|
|
|
15
15
|
const reactSyntaxHighlighter = require('@assistant-ui/react-syntax-highlighter');
|
|
16
16
|
const prism = require('react-syntax-highlighter/dist/cjs/styles/prism');
|
|
17
17
|
const langJson = require('@codemirror/lang-json');
|
|
18
|
-
const highlight = require('@lezer/highlight');
|
|
18
|
+
const highlight$1 = require('@lezer/highlight');
|
|
19
19
|
const codemirrorThemeDracula = require('@uiw/codemirror-theme-dracula');
|
|
20
20
|
const CodeMirror = require('@uiw/react-codemirror');
|
|
21
21
|
const sonner = require('sonner');
|
|
@@ -4377,7 +4377,7 @@ const useCodemirrorTheme$2 = () => {
|
|
|
4377
4377
|
background: "transparent",
|
|
4378
4378
|
gutterForeground: "#939393"
|
|
4379
4379
|
},
|
|
4380
|
-
styles: [{ tag: [highlight.tags.className, highlight.tags.propertyName] }]
|
|
4380
|
+
styles: [{ tag: [highlight$1.tags.className, highlight$1.tags.propertyName] }]
|
|
4381
4381
|
}),
|
|
4382
4382
|
[]
|
|
4383
4383
|
);
|
|
@@ -4394,6 +4394,19 @@ const SyntaxHighlighter$2 = ({
|
|
|
4394
4394
|
/* @__PURE__ */ jsxRuntime.jsx(CodeMirror, { value: formattedCode, theme, extensions: [langJson.jsonLanguage] })
|
|
4395
4395
|
] });
|
|
4396
4396
|
};
|
|
4397
|
+
async function highlight(code, language) {
|
|
4398
|
+
const { codeToTokens, bundledLanguages } = await import('shiki');
|
|
4399
|
+
if (!(language in bundledLanguages)) return null;
|
|
4400
|
+
const { tokens } = await codeToTokens(code, {
|
|
4401
|
+
lang: language,
|
|
4402
|
+
defaultColor: false,
|
|
4403
|
+
themes: {
|
|
4404
|
+
light: "github-light",
|
|
4405
|
+
dark: "github-dark"
|
|
4406
|
+
}
|
|
4407
|
+
});
|
|
4408
|
+
return tokens;
|
|
4409
|
+
}
|
|
4397
4410
|
|
|
4398
4411
|
const variantClasses$2 = {
|
|
4399
4412
|
default: "text-icon3",
|
|
@@ -5289,7 +5302,7 @@ const useCodemirrorTheme$1 = () => {
|
|
|
5289
5302
|
gutterForeground: "#939393",
|
|
5290
5303
|
background: "transparent"
|
|
5291
5304
|
},
|
|
5292
|
-
styles: [{ tag: [highlight.tags.className, highlight.tags.propertyName] }]
|
|
5305
|
+
styles: [{ tag: [highlight$1.tags.className, highlight$1.tags.propertyName] }]
|
|
5293
5306
|
}),
|
|
5294
5307
|
[]
|
|
5295
5308
|
);
|
|
@@ -12792,7 +12805,7 @@ const useCodemirrorTheme = () => {
|
|
|
12792
12805
|
gutterForeground: "#939393",
|
|
12793
12806
|
background: "transparent"
|
|
12794
12807
|
},
|
|
12795
|
-
styles: [{ tag: [highlight.tags.className, highlight.tags.propertyName] }]
|
|
12808
|
+
styles: [{ tag: [highlight$1.tags.className, highlight$1.tags.propertyName] }]
|
|
12796
12809
|
}),
|
|
12797
12810
|
[]
|
|
12798
12811
|
);
|
|
@@ -15199,367 +15212,1873 @@ const AgentToolPanel = ({ toolId, agentId }) => {
|
|
|
15199
15212
|
);
|
|
15200
15213
|
};
|
|
15201
15214
|
|
|
15202
|
-
const
|
|
15203
|
-
const { Link, paths } = useLinkComponent();
|
|
15204
|
-
const tool = row.original;
|
|
15205
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
15206
|
-
EntryCell,
|
|
15207
|
-
{
|
|
15208
|
-
name: /* @__PURE__ */ jsxRuntime.jsx(Link, { className: "w-full space-y-0", href: paths.toolLink(tool.id), children: tool.id }),
|
|
15209
|
-
description: tool.description
|
|
15210
|
-
}
|
|
15211
|
-
);
|
|
15212
|
-
};
|
|
15213
|
-
const columns$1 = [
|
|
15214
|
-
{
|
|
15215
|
-
header: "Name",
|
|
15216
|
-
accessorKey: "name",
|
|
15217
|
-
cell: NameCell$1
|
|
15218
|
-
},
|
|
15219
|
-
{
|
|
15220
|
-
header: "Attached entities",
|
|
15221
|
-
accessorKey: "attachedEntities",
|
|
15222
|
-
cell: ({ row }) => {
|
|
15223
|
-
const tool = row.original;
|
|
15224
|
-
const agentsCount = tool.agents.length;
|
|
15225
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Cell, { children: /* @__PURE__ */ jsxRuntime.jsxs(Badge$1, { variant: "default", icon: /* @__PURE__ */ jsxRuntime.jsx(AgentIcon, { className: "text-accent1" }), children: [
|
|
15226
|
-
agentsCount,
|
|
15227
|
-
" agent",
|
|
15228
|
-
agentsCount > 1 ? "s" : ""
|
|
15229
|
-
] }) });
|
|
15230
|
-
}
|
|
15231
|
-
}
|
|
15232
|
-
];
|
|
15233
|
-
|
|
15234
|
-
const prepareToolsTable = (tools, agents) => {
|
|
15235
|
-
const toolsWithAgents = /* @__PURE__ */ new Map();
|
|
15236
|
-
const agentsKeys = Object.keys(agents);
|
|
15237
|
-
for (const k of agentsKeys) {
|
|
15238
|
-
const agent = agents[k];
|
|
15239
|
-
const agentToolsDict = agent.tools;
|
|
15240
|
-
const agentToolsKeys = Object.keys(agentToolsDict);
|
|
15241
|
-
for (const key of agentToolsKeys) {
|
|
15242
|
-
const tool = agentToolsDict[key];
|
|
15243
|
-
if (!toolsWithAgents.has(tool.id)) {
|
|
15244
|
-
toolsWithAgents.set(tool.id, {
|
|
15245
|
-
...tool,
|
|
15246
|
-
agents: []
|
|
15247
|
-
});
|
|
15248
|
-
}
|
|
15249
|
-
toolsWithAgents.get(tool.id).agents.push({ ...agent, id: k });
|
|
15250
|
-
}
|
|
15251
|
-
}
|
|
15252
|
-
for (const [_, tool] of Object.entries(tools)) {
|
|
15253
|
-
if (!toolsWithAgents.has(tool.id)) {
|
|
15254
|
-
toolsWithAgents.set(tool.id, {
|
|
15255
|
-
...tool,
|
|
15256
|
-
agents: []
|
|
15257
|
-
});
|
|
15258
|
-
}
|
|
15259
|
-
}
|
|
15260
|
-
return Array.from(toolsWithAgents.values());
|
|
15261
|
-
};
|
|
15262
|
-
|
|
15263
|
-
function ToolTable({ tools, agents, isLoading }) {
|
|
15264
|
-
const [search, setSearch] = React.useState("");
|
|
15265
|
-
const { navigate, paths } = useLinkComponent();
|
|
15266
|
-
const toolData = React.useMemo(() => prepareToolsTable(tools, agents), [tools, agents]);
|
|
15267
|
-
const table = reactTable.useReactTable({
|
|
15268
|
-
data: toolData,
|
|
15269
|
-
columns: columns$1,
|
|
15270
|
-
getCoreRowModel: reactTable.getCoreRowModel()
|
|
15271
|
-
});
|
|
15272
|
-
const ths = table.getHeaderGroups()[0];
|
|
15273
|
-
const rows = table.getRowModel().rows.concat();
|
|
15274
|
-
if (rows.length === 0 && !isLoading) {
|
|
15275
|
-
return /* @__PURE__ */ jsxRuntime.jsx(EmptyToolsTable, {});
|
|
15276
|
-
}
|
|
15277
|
-
const filteredRows = rows.filter((row) => row.original.id.toLowerCase().includes(search.toLowerCase()));
|
|
15278
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
15279
|
-
/* @__PURE__ */ jsxRuntime.jsx(SearchbarWrapper, { children: /* @__PURE__ */ jsxRuntime.jsx(Searchbar, { onSearch: setSearch, label: "Search tools", placeholder: "Search tools" }) }),
|
|
15280
|
-
isLoading ? /* @__PURE__ */ jsxRuntime.jsx(ToolTableSkeleton, {}) : /* @__PURE__ */ jsxRuntime.jsx(ScrollableContainer, { children: /* @__PURE__ */ jsxRuntime.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(Table$1, { children: [
|
|
15281
|
-
/* @__PURE__ */ jsxRuntime.jsx(Thead, { className: "sticky top-0", children: ths.headers.map((header) => /* @__PURE__ */ jsxRuntime.jsx(Th, { style: { width: header.column.getSize() ?? "auto" }, children: reactTable.flexRender(header.column.columnDef.header, header.getContext()) }, header.id)) }),
|
|
15282
|
-
/* @__PURE__ */ jsxRuntime.jsx(Tbody, { children: filteredRows.map((row) => {
|
|
15283
|
-
const firstAgent = row.original.agents[0];
|
|
15284
|
-
const link = firstAgent ? paths.agentToolLink(firstAgent.id, row.original.id) : paths.toolLink(row.original.id);
|
|
15285
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Row, { onClick: () => navigate(link), children: row.getVisibleCells().map((cell) => /* @__PURE__ */ jsxRuntime.jsx(React.Fragment, { children: reactTable.flexRender(cell.column.columnDef.cell, cell.getContext()) }, cell.id)) }, row.id);
|
|
15286
|
-
}) })
|
|
15287
|
-
] }) }) })
|
|
15288
|
-
] });
|
|
15289
|
-
}
|
|
15290
|
-
const ToolTableSkeleton = () => /* @__PURE__ */ jsxRuntime.jsxs(Table$1, { children: [
|
|
15291
|
-
/* @__PURE__ */ jsxRuntime.jsxs(Thead, { children: [
|
|
15292
|
-
/* @__PURE__ */ jsxRuntime.jsx(Th, { children: "Name" }),
|
|
15293
|
-
/* @__PURE__ */ jsxRuntime.jsx(Th, { children: "Used by" })
|
|
15294
|
-
] }),
|
|
15295
|
-
/* @__PURE__ */ jsxRuntime.jsx(Tbody, { children: Array.from({ length: 3 }).map((_, index) => /* @__PURE__ */ jsxRuntime.jsxs(Row, { children: [
|
|
15296
|
-
/* @__PURE__ */ jsxRuntime.jsx(Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-4 w-1/2" }) }),
|
|
15297
|
-
/* @__PURE__ */ jsxRuntime.jsx(Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-4 w-1/2" }) })
|
|
15298
|
-
] }, index)) })
|
|
15299
|
-
] });
|
|
15300
|
-
const EmptyToolsTable = () => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-full items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
15301
|
-
EmptyState,
|
|
15302
|
-
{
|
|
15303
|
-
iconSlot: /* @__PURE__ */ jsxRuntime.jsx(ToolCoinIcon, {}),
|
|
15304
|
-
titleSlot: "Configure Tools",
|
|
15305
|
-
descriptionSlot: "Mastra tools are not configured yet. You can find more information in the documentation.",
|
|
15306
|
-
actionSlot: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
15307
|
-
Button$1,
|
|
15308
|
-
{
|
|
15309
|
-
size: "lg",
|
|
15310
|
-
className: "w-full",
|
|
15311
|
-
variant: "light",
|
|
15312
|
-
as: "a",
|
|
15313
|
-
href: "https://mastra.ai/en/docs/agents/using-tools-and-mcp",
|
|
15314
|
-
target: "_blank",
|
|
15315
|
-
children: [
|
|
15316
|
-
/* @__PURE__ */ jsxRuntime.jsx(Icon, { children: /* @__PURE__ */ jsxRuntime.jsx(ToolsIcon, {}) }),
|
|
15317
|
-
"Docs"
|
|
15318
|
-
]
|
|
15319
|
-
}
|
|
15320
|
-
)
|
|
15321
|
-
}
|
|
15322
|
-
) });
|
|
15323
|
-
|
|
15324
|
-
const useExecuteTool = () => {
|
|
15215
|
+
const useMemory = (agentId) => {
|
|
15325
15216
|
const client = react$3.useMastraClient();
|
|
15326
|
-
return reactQuery.
|
|
15327
|
-
|
|
15328
|
-
|
|
15329
|
-
|
|
15330
|
-
|
|
15331
|
-
|
|
15332
|
-
|
|
15333
|
-
|
|
15334
|
-
|
|
15335
|
-
});
|
|
15336
|
-
try {
|
|
15337
|
-
const tool = client.getTool(toolId);
|
|
15338
|
-
const response = await tool.execute({ data: input, runtimeContext });
|
|
15339
|
-
return response;
|
|
15340
|
-
} catch (error) {
|
|
15341
|
-
sonner.toast.error("Error executing dev tool");
|
|
15342
|
-
console.error("Error executing dev tool:", error);
|
|
15343
|
-
throw error;
|
|
15344
|
-
}
|
|
15345
|
-
}
|
|
15217
|
+
return reactQuery.useQuery({
|
|
15218
|
+
queryKey: ["memory", agentId],
|
|
15219
|
+
queryFn: () => agentId ? client.getMemoryStatus(agentId) : null,
|
|
15220
|
+
enabled: Boolean(agentId),
|
|
15221
|
+
staleTime: 5 * 60 * 1e3,
|
|
15222
|
+
// 5 minutes
|
|
15223
|
+
gcTime: 10 * 60 * 1e3,
|
|
15224
|
+
// 10 minutes
|
|
15225
|
+
retry: false
|
|
15346
15226
|
});
|
|
15347
15227
|
};
|
|
15348
|
-
|
|
15349
|
-
const useTools = () => {
|
|
15350
|
-
const { runtimeContext } = usePlaygroundStore();
|
|
15228
|
+
const useMemoryConfig = (agentId) => {
|
|
15351
15229
|
const client = react$3.useMastraClient();
|
|
15352
15230
|
return reactQuery.useQuery({
|
|
15353
|
-
queryKey: ["
|
|
15354
|
-
queryFn: () => client.
|
|
15231
|
+
queryKey: ["memory", "config", agentId],
|
|
15232
|
+
queryFn: () => agentId ? client.getMemoryConfig({ agentId }) : null,
|
|
15233
|
+
enabled: Boolean(agentId),
|
|
15234
|
+
staleTime: 5 * 60 * 1e3,
|
|
15235
|
+
// 5 minutes
|
|
15236
|
+
gcTime: 10 * 60 * 1e3,
|
|
15237
|
+
// 10 minutes
|
|
15238
|
+
retry: false,
|
|
15239
|
+
refetchOnWindowFocus: false
|
|
15355
15240
|
});
|
|
15356
15241
|
};
|
|
15357
|
-
const
|
|
15242
|
+
const useThreads = ({
|
|
15243
|
+
resourceId,
|
|
15244
|
+
agentId,
|
|
15245
|
+
isMemoryEnabled
|
|
15246
|
+
}) => {
|
|
15358
15247
|
const client = react$3.useMastraClient();
|
|
15359
|
-
const { runtimeContext } = usePlaygroundStore();
|
|
15360
15248
|
return reactQuery.useQuery({
|
|
15361
|
-
queryKey: ["
|
|
15362
|
-
queryFn: () => client.
|
|
15249
|
+
queryKey: ["memory", "threads", resourceId, agentId],
|
|
15250
|
+
queryFn: () => isMemoryEnabled ? client.getMemoryThreads({ resourceId, agentId }) : null,
|
|
15251
|
+
enabled: Boolean(isMemoryEnabled),
|
|
15252
|
+
staleTime: 0,
|
|
15253
|
+
gcTime: 0,
|
|
15254
|
+
retry: false,
|
|
15255
|
+
refetchOnWindowFocus: false
|
|
15363
15256
|
});
|
|
15364
15257
|
};
|
|
15365
|
-
|
|
15366
|
-
const
|
|
15367
|
-
const
|
|
15368
|
-
|
|
15369
|
-
|
|
15370
|
-
|
|
15371
|
-
|
|
15372
|
-
|
|
15373
|
-
|
|
15374
|
-
|
|
15375
|
-
|
|
15376
|
-
|
|
15377
|
-
|
|
15378
|
-
|
|
15379
|
-
|
|
15380
|
-
|
|
15381
|
-
|
|
15382
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
15383
|
-
ToolExecutor,
|
|
15384
|
-
{
|
|
15385
|
-
executionResult: result,
|
|
15386
|
-
isExecutingTool: isExecuting,
|
|
15387
|
-
zodInputSchema,
|
|
15388
|
-
handleExecuteTool,
|
|
15389
|
-
toolDescription: tool.description,
|
|
15390
|
-
toolId: tool.id
|
|
15258
|
+
const useDeleteThread = () => {
|
|
15259
|
+
const client = react$3.useMastraClient();
|
|
15260
|
+
const queryClient = reactQuery.useQueryClient();
|
|
15261
|
+
return reactQuery.useMutation({
|
|
15262
|
+
mutationFn: ({ threadId, agentId, networkId }) => client.deleteThread(threadId, { agentId, networkId }),
|
|
15263
|
+
onSuccess: (_, variables) => {
|
|
15264
|
+
const { agentId, networkId } = variables;
|
|
15265
|
+
if (agentId) {
|
|
15266
|
+
queryClient.invalidateQueries({ queryKey: ["memory", "threads", agentId, agentId] });
|
|
15267
|
+
}
|
|
15268
|
+
if (networkId) {
|
|
15269
|
+
queryClient.invalidateQueries({ queryKey: ["network", "threads", networkId, networkId] });
|
|
15270
|
+
}
|
|
15271
|
+
sonner.toast.success("Chat deleted successfully");
|
|
15272
|
+
},
|
|
15273
|
+
onError: () => {
|
|
15274
|
+
sonner.toast.error("Failed to delete chat");
|
|
15391
15275
|
}
|
|
15392
|
-
);
|
|
15276
|
+
});
|
|
15393
15277
|
};
|
|
15394
|
-
|
|
15395
|
-
|
|
15396
|
-
|
|
15397
|
-
|
|
15398
|
-
|
|
15399
|
-
|
|
15400
|
-
|
|
15401
|
-
|
|
15402
|
-
|
|
15403
|
-
|
|
15404
|
-
|
|
15405
|
-
|
|
15406
|
-
|
|
15407
|
-
})
|
|
15408
|
-
|
|
15409
|
-
|
|
15410
|
-
|
|
15411
|
-
|
|
15412
|
-
|
|
15413
|
-
|
|
15414
|
-
|
|
15415
|
-
|
|
15416
|
-
|
|
15417
|
-
|
|
15418
|
-
|
|
15419
|
-
" ",
|
|
15420
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", {}),
|
|
15421
|
-
" ",
|
|
15422
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", {})
|
|
15423
|
-
]
|
|
15278
|
+
const useMemorySearch = ({
|
|
15279
|
+
agentId,
|
|
15280
|
+
resourceId,
|
|
15281
|
+
threadId
|
|
15282
|
+
}) => {
|
|
15283
|
+
const searchMemory = async (searchQuery, memoryConfig) => {
|
|
15284
|
+
if (!searchQuery.trim()) {
|
|
15285
|
+
return { results: [], count: 0, query: searchQuery };
|
|
15286
|
+
}
|
|
15287
|
+
const params = new URLSearchParams({
|
|
15288
|
+
searchQuery,
|
|
15289
|
+
resourceId,
|
|
15290
|
+
agentId
|
|
15291
|
+
});
|
|
15292
|
+
if (threadId) {
|
|
15293
|
+
params.append("threadId", threadId);
|
|
15294
|
+
}
|
|
15295
|
+
if (memoryConfig) {
|
|
15296
|
+
params.append("memoryConfig", JSON.stringify(memoryConfig));
|
|
15297
|
+
}
|
|
15298
|
+
const response = await fetch(`/api/memory/search?${params}`, {
|
|
15299
|
+
method: "GET",
|
|
15300
|
+
headers: {
|
|
15301
|
+
"Content-Type": "application/json",
|
|
15302
|
+
"x-mastra-dev-playground": "true"
|
|
15424
15303
|
}
|
|
15425
|
-
);
|
|
15304
|
+
});
|
|
15305
|
+
if (!response.ok) {
|
|
15306
|
+
const errorData = await response.json().catch(() => ({ message: "Unknown error" }));
|
|
15307
|
+
console.error("Search memory error:", errorData);
|
|
15308
|
+
throw new Error(errorData.message || errorData.error || "Failed to search memory");
|
|
15309
|
+
}
|
|
15310
|
+
return response.json();
|
|
15311
|
+
};
|
|
15312
|
+
return { searchMemory };
|
|
15313
|
+
};
|
|
15314
|
+
|
|
15315
|
+
function MarkdownRenderer({ children }) {
|
|
15316
|
+
const processedText = children.replace(/\\n/g, "\n");
|
|
15317
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Markdown, { remarkPlugins: [remarkGfm], components: COMPONENTS, className: "space-y-3", children: processedText });
|
|
15318
|
+
}
|
|
15319
|
+
const HighlightedPre = React.memo(({ children, language, ...props }) => {
|
|
15320
|
+
const [tokens, setTokens] = React.useState([]);
|
|
15321
|
+
React.useEffect(() => {
|
|
15322
|
+
highlight(children, language).then((tokens2) => {
|
|
15323
|
+
if (tokens2) setTokens(tokens2);
|
|
15324
|
+
});
|
|
15325
|
+
}, [children, language]);
|
|
15326
|
+
if (!tokens.length) {
|
|
15327
|
+
return /* @__PURE__ */ jsxRuntime.jsx("pre", { ...props, children });
|
|
15426
15328
|
}
|
|
15427
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
15428
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
15429
|
-
|
|
15430
|
-
|
|
15431
|
-
|
|
15432
|
-
|
|
15433
|
-
|
|
15434
|
-
|
|
15435
|
-
|
|
15436
|
-
|
|
15437
|
-
|
|
15329
|
+
return /* @__PURE__ */ jsxRuntime.jsx("pre", { ...props, children: /* @__PURE__ */ jsxRuntime.jsx("code", { children: tokens.map((line, lineIndex) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
15330
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: line.map((token, tokenIndex) => {
|
|
15331
|
+
const style = typeof token.htmlStyle === "string" ? void 0 : token.htmlStyle;
|
|
15332
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
15333
|
+
"span",
|
|
15334
|
+
{
|
|
15335
|
+
className: "text-shiki-light bg-shiki-light-bg dark:text-shiki-dark dark:bg-shiki-dark-bg",
|
|
15336
|
+
style,
|
|
15337
|
+
children: token.content
|
|
15338
|
+
},
|
|
15339
|
+
tokenIndex
|
|
15340
|
+
);
|
|
15341
|
+
}) }, lineIndex),
|
|
15342
|
+
lineIndex !== tokens.length - 1 && "\n"
|
|
15343
|
+
] })) }) });
|
|
15344
|
+
});
|
|
15345
|
+
HighlightedPre.displayName = "HighlightedCode";
|
|
15346
|
+
const CodeBlock = ({ children, className, language, ...restProps }) => {
|
|
15347
|
+
const code = typeof children === "string" ? children : childrenTakeAllStringContents(children);
|
|
15348
|
+
const preClass = cn(
|
|
15349
|
+
"overflow-x-scroll rounded-md border bg-background/50 p-4 font-mono text-sm [scrollbar-width:none]",
|
|
15350
|
+
className
|
|
15351
|
+
);
|
|
15352
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group/code relative mb-4", children: [
|
|
15438
15353
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
15439
|
-
|
|
15354
|
+
React.Suspense,
|
|
15440
15355
|
{
|
|
15441
|
-
|
|
15442
|
-
|
|
15443
|
-
onValueChange: onProviderChange,
|
|
15444
|
-
options: providerOptions
|
|
15356
|
+
fallback: /* @__PURE__ */ jsxRuntime.jsx("pre", { className: preClass, ...restProps, children }),
|
|
15357
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(HighlightedPre, { language, className: preClass, children: code })
|
|
15445
15358
|
}
|
|
15446
15359
|
),
|
|
15447
|
-
|
|
15448
|
-
"Reset ",
|
|
15449
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.XIcon, {})
|
|
15450
|
-
] })
|
|
15360
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "invisible absolute right-2 top-2 flex space-x-1 rounded-lg p-1 opacity-0 transition-all duration-200 group-hover/code:visible group-hover/code:opacity-100", children: /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { content: code, copyMessage: "Copied code to clipboard" }) })
|
|
15451
15361
|
] });
|
|
15362
|
+
};
|
|
15363
|
+
function childrenTakeAllStringContents(element) {
|
|
15364
|
+
if (typeof element === "string") {
|
|
15365
|
+
return element;
|
|
15366
|
+
}
|
|
15367
|
+
if (element?.props?.children) {
|
|
15368
|
+
let children = element.props.children;
|
|
15369
|
+
if (Array.isArray(children)) {
|
|
15370
|
+
return children.map((child) => childrenTakeAllStringContents(child)).join("");
|
|
15371
|
+
} else {
|
|
15372
|
+
return childrenTakeAllStringContents(children);
|
|
15373
|
+
}
|
|
15374
|
+
}
|
|
15375
|
+
return "";
|
|
15452
15376
|
}
|
|
15453
|
-
|
|
15454
|
-
|
|
15455
|
-
|
|
15456
|
-
}
|
|
15457
|
-
|
|
15458
|
-
|
|
15459
|
-
|
|
15377
|
+
const COMPONENTS = {
|
|
15378
|
+
h1: ({ children, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl font-semibold", ...props, children }),
|
|
15379
|
+
h2: ({ children, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "font-semibold text-xl", ...props, children }),
|
|
15380
|
+
h3: ({ children, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "font-semibold text-lg", ...props, children }),
|
|
15381
|
+
h4: ({ children, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "font-semibold text-base", ...props, children }),
|
|
15382
|
+
h5: ({ children, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("h5", { className: "font-medium", ...props, children }),
|
|
15383
|
+
strong: ({ children, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("strong", { className: "font-semibold", ...props, children }),
|
|
15384
|
+
a: ({ children, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("a", { className: "underline underline-offset-2", ...props, children }),
|
|
15385
|
+
blockquote: ({ children, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("blockquote", { className: "border-l-2 border-primary pl-4", ...props, children }),
|
|
15386
|
+
code: ({ children, className, ...rest }) => {
|
|
15387
|
+
const match = /language-(\w+)/.exec(className || "");
|
|
15388
|
+
return match ? /* @__PURE__ */ jsxRuntime.jsx(CodeBlock, { className, language: match[1], ...rest, children }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
15389
|
+
"code",
|
|
15390
|
+
{
|
|
15391
|
+
className: cn(
|
|
15392
|
+
"font-mono [:not(pre)>&]:rounded-md [:not(pre)>&]:bg-background/50 [:not(pre)>&]:px-1 [:not(pre)>&]:py-0.5"
|
|
15393
|
+
),
|
|
15394
|
+
...rest,
|
|
15395
|
+
children
|
|
15396
|
+
}
|
|
15397
|
+
);
|
|
15398
|
+
},
|
|
15399
|
+
pre: ({ children }) => children,
|
|
15400
|
+
ol: ({ children, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("ol", { className: "list-decimal space-y-2 pl-6", ...props, children }),
|
|
15401
|
+
ul: ({ children, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "list-disc space-y-2 pl-6", ...props, children }),
|
|
15402
|
+
li: ({ children, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("li", { className: "my-1.5", ...props, children }),
|
|
15403
|
+
table: ({ children, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("table", { className: "w-full border-collapse overflow-y-auto rounded-md border border-foreground/20", ...props, children }),
|
|
15404
|
+
th: ({ children, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
15405
|
+
"th",
|
|
15460
15406
|
{
|
|
15461
|
-
className:
|
|
15462
|
-
|
|
15463
|
-
className
|
|
15464
|
-
),
|
|
15407
|
+
className: "border border-foreground/20 px-4 py-2 text-left font-bold [&[align=center]]:text-center [&[align=right]]:text-right",
|
|
15408
|
+
...props,
|
|
15465
15409
|
children
|
|
15466
15410
|
}
|
|
15467
|
-
)
|
|
15411
|
+
),
|
|
15412
|
+
td: ({ children, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
15413
|
+
"td",
|
|
15414
|
+
{
|
|
15415
|
+
className: "border border-foreground/20 px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right",
|
|
15416
|
+
...props,
|
|
15417
|
+
children
|
|
15418
|
+
}
|
|
15419
|
+
),
|
|
15420
|
+
tr: ({ children, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("tr", { className: "m-0 border-t p-0 even:bg-muted", ...props, children }),
|
|
15421
|
+
p: ({ children, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("p", { className: "whitespace-pre-wrap leading-relaxed", ...props, children }),
|
|
15422
|
+
hr: ({ ...props }) => /* @__PURE__ */ jsxRuntime.jsx("hr", { className: "border-foreground/20", ...props })
|
|
15423
|
+
};
|
|
15424
|
+
|
|
15425
|
+
function CodeDisplay({
|
|
15426
|
+
content,
|
|
15427
|
+
height = "150px",
|
|
15428
|
+
isCopied = false,
|
|
15429
|
+
isDraft = false,
|
|
15430
|
+
onCopy,
|
|
15431
|
+
className = ""
|
|
15432
|
+
}) {
|
|
15433
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `rounded-md border ${className}`, style: { height }, children: /* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { className: "h-full", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-2 cursor-pointer hover:bg-mastra-bg-3/50 transition-colors group relative", onClick: onCopy, children: [
|
|
15434
|
+
/* @__PURE__ */ jsxRuntime.jsx("pre", { className: "text-[10px] whitespace-pre-wrap font-mono", children: content }),
|
|
15435
|
+
isDraft && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] px-1.5 py-0.5 rounded-full bg-yellow-500/20 text-yellow-500", children: "Draft - Save changes to apply" }) }),
|
|
15436
|
+
isCopied && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute top-2 right-2 text-[10px] px-1.5 py-0.5 rounded-full bg-green-500/20 text-green-500", children: "Copied!" }),
|
|
15437
|
+
onCopy && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute top-2 right-2 text-[10px] px-1.5 py-0.5 rounded-full bg-mastra-bg-3 text-mastra-el-4 opacity-0 group-hover:opacity-100 transition-opacity", children: "Click to copy" })
|
|
15438
|
+
] }) }) });
|
|
15468
15439
|
}
|
|
15469
15440
|
|
|
15470
|
-
|
|
15471
|
-
const
|
|
15441
|
+
const AgentWorkingMemory = ({ agentId }) => {
|
|
15442
|
+
const { threadExists, workingMemoryData, workingMemorySource, isLoading, isUpdating, updateWorkingMemory } = useWorkingMemory();
|
|
15443
|
+
const { data } = useMemoryConfig(agentId);
|
|
15444
|
+
const config = data?.config;
|
|
15445
|
+
const isWorkingMemoryEnabled = Boolean(config?.workingMemory?.enabled);
|
|
15446
|
+
const { isCopied, handleCopy } = useCopyToClipboard({
|
|
15447
|
+
text: workingMemoryData ?? "",
|
|
15448
|
+
copyMessage: "Working memory copied!"
|
|
15449
|
+
});
|
|
15450
|
+
const [editValue, setEditValue] = React.useState(workingMemoryData ?? "");
|
|
15451
|
+
const [isEditing, setIsEditing] = React.useState(false);
|
|
15452
|
+
React.useEffect(() => {
|
|
15453
|
+
setEditValue(workingMemoryData ?? "");
|
|
15454
|
+
}, [workingMemoryData]);
|
|
15472
15455
|
if (isLoading) {
|
|
15473
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
15456
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-32 w-full" });
|
|
15474
15457
|
}
|
|
15475
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
15476
|
-
|
|
15477
|
-
|
|
15478
|
-
|
|
15479
|
-
|
|
15480
|
-
|
|
15481
|
-
|
|
15458
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4 p-4", children: [
|
|
15459
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
15460
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mb-2", children: [
|
|
15461
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-medium text-icon5", children: "Working Memory" }),
|
|
15462
|
+
isWorkingMemoryEnabled && workingMemorySource && /* @__PURE__ */ jsxRuntime.jsx(
|
|
15463
|
+
"span",
|
|
15464
|
+
{
|
|
15465
|
+
className: cn(
|
|
15466
|
+
"text-xs font-medium px-2 py-0.5 rounded",
|
|
15467
|
+
workingMemorySource === "resource" ? "bg-purple-500/20 text-purple-400" : "bg-blue-500/20 text-blue-400"
|
|
15468
|
+
),
|
|
15469
|
+
title: workingMemorySource === "resource" ? "Shared across all threads for this agent" : "Specific to this conversation thread",
|
|
15470
|
+
children: workingMemorySource
|
|
15471
|
+
}
|
|
15472
|
+
)
|
|
15473
|
+
] }),
|
|
15474
|
+
isWorkingMemoryEnabled && !threadExists && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-icon3", children: "Send a message to the agent to enable working memory." })
|
|
15475
|
+
] }),
|
|
15476
|
+
isWorkingMemoryEnabled ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
15477
|
+
!isEditing ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: workingMemoryData ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: workingMemoryData.trim().startsWith("{") ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
15478
|
+
CodeDisplay,
|
|
15479
|
+
{
|
|
15480
|
+
content: workingMemoryData || "",
|
|
15481
|
+
isCopied,
|
|
15482
|
+
onCopy: handleCopy,
|
|
15483
|
+
className: "bg-surface3 text-sm font-mono min-h-[150px] border border-border1 rounded-lg"
|
|
15484
|
+
}
|
|
15485
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-surface3 border border-border1 rounded-lg", style: { height: "300px" }, children: /* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { className: "h-full", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
15486
|
+
"div",
|
|
15487
|
+
{
|
|
15488
|
+
className: "p-3 cursor-pointer hover:bg-surface4/20 transition-colors relative group text-[10px]",
|
|
15489
|
+
onClick: handleCopy,
|
|
15490
|
+
children: [
|
|
15491
|
+
/* @__PURE__ */ jsxRuntime.jsx(MarkdownRenderer, { children: workingMemoryData }),
|
|
15492
|
+
isCopied && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute top-2 right-2 text-[10px] px-1.5 py-0.5 rounded-full bg-green-500/20 text-green-500", children: "Copied!" }),
|
|
15493
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute top-2 right-2 text-[10px] px-1.5 py-0.5 rounded-full bg-surface3 text-icon4 opacity-0 group-hover:opacity-100 transition-opacity", children: "Click to copy" })
|
|
15494
|
+
]
|
|
15495
|
+
}
|
|
15496
|
+
) }) }) }) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-icon3 font-mono", children: 'No working memory content yet. Click "Edit Working Memory" to add content.' }) }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
15497
|
+
"textarea",
|
|
15498
|
+
{
|
|
15499
|
+
className: "w-full min-h-[150px] p-3 border border-border1 rounded-lg bg-surface3 font-mono text-sm text-icon5 resize-none",
|
|
15500
|
+
value: editValue,
|
|
15501
|
+
onChange: (e) => setEditValue(e.target.value),
|
|
15502
|
+
disabled: isUpdating,
|
|
15503
|
+
placeholder: "Enter working memory content..."
|
|
15504
|
+
}
|
|
15505
|
+
),
|
|
15506
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-2", children: !isEditing ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
15507
|
+
Button$2,
|
|
15508
|
+
{
|
|
15509
|
+
variant: "secondary",
|
|
15510
|
+
size: "sm",
|
|
15511
|
+
onClick: () => setIsEditing(true),
|
|
15512
|
+
disabled: !threadExists || isUpdating,
|
|
15513
|
+
className: "text-xs",
|
|
15514
|
+
children: "Edit Working Memory"
|
|
15515
|
+
}
|
|
15516
|
+
) }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
15517
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
15518
|
+
Button$2,
|
|
15519
|
+
{
|
|
15520
|
+
variant: "default",
|
|
15521
|
+
size: "sm",
|
|
15522
|
+
onClick: async () => {
|
|
15523
|
+
try {
|
|
15524
|
+
await updateWorkingMemory(editValue);
|
|
15525
|
+
setIsEditing(false);
|
|
15526
|
+
} catch (error) {
|
|
15527
|
+
console.error("Failed to update working memory:", error);
|
|
15528
|
+
sonner.toast.error("Failed to update working memory");
|
|
15529
|
+
}
|
|
15530
|
+
},
|
|
15531
|
+
disabled: isUpdating,
|
|
15532
|
+
className: "text-xs",
|
|
15533
|
+
children: isUpdating ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCcwIcon, { className: "w-3 h-3 animate-spin" }) : "Save Changes"
|
|
15534
|
+
}
|
|
15482
15535
|
),
|
|
15483
|
-
|
|
15484
|
-
|
|
15485
|
-
|
|
15536
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
15537
|
+
Button$2,
|
|
15538
|
+
{
|
|
15539
|
+
variant: "secondary",
|
|
15540
|
+
size: "sm",
|
|
15541
|
+
onClick: () => {
|
|
15542
|
+
setEditValue(workingMemoryData ?? "");
|
|
15543
|
+
setIsEditing(false);
|
|
15544
|
+
},
|
|
15545
|
+
disabled: isUpdating,
|
|
15546
|
+
className: "text-xs",
|
|
15547
|
+
children: "Cancel"
|
|
15548
|
+
}
|
|
15549
|
+
)
|
|
15550
|
+
] }) })
|
|
15551
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-surface3 border border-border1 rounded-lg p-4", children: [
|
|
15552
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-icon3 mb-3", children: "Working memory is not enabled for this agent. Enable it to maintain context across conversations." }),
|
|
15553
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
15554
|
+
"a",
|
|
15555
|
+
{
|
|
15556
|
+
href: "https://mastra.ai/en/docs/memory/working-memory",
|
|
15557
|
+
target: "_blank",
|
|
15558
|
+
rel: "noopener noreferrer",
|
|
15559
|
+
className: "inline-flex items-center gap-2 text-sm text-blue-400 hover:text-blue-300 transition-colors",
|
|
15560
|
+
children: [
|
|
15561
|
+
"Learn about working memory",
|
|
15562
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "w-3 h-3" })
|
|
15563
|
+
]
|
|
15564
|
+
}
|
|
15565
|
+
)
|
|
15566
|
+
] })
|
|
15567
|
+
] });
|
|
15568
|
+
};
|
|
15569
|
+
|
|
15570
|
+
const AgentMemoryConfig = ({ agentId }) => {
|
|
15571
|
+
const { data, isLoading } = useMemoryConfig(agentId);
|
|
15572
|
+
const [expandedSections, setExpandedSections] = React.useState(/* @__PURE__ */ new Set(["General", "Semantic Recall"]));
|
|
15573
|
+
const config = data?.config;
|
|
15574
|
+
const configSections = React.useMemo(() => {
|
|
15575
|
+
if (!config) return [];
|
|
15576
|
+
const memoryEnabled = !!config;
|
|
15577
|
+
const sections = [
|
|
15578
|
+
{
|
|
15579
|
+
title: "General",
|
|
15580
|
+
items: [
|
|
15581
|
+
{ label: "Memory Enabled", value: memoryEnabled, badge: memoryEnabled ? "success" : void 0 },
|
|
15582
|
+
{ label: "Last Messages", value: config.lastMessages || 0 },
|
|
15583
|
+
{
|
|
15584
|
+
label: "Auto-generate Titles",
|
|
15585
|
+
value: !!config.threads?.generateTitle,
|
|
15586
|
+
badge: config.threads?.generateTitle ? "info" : void 0
|
|
15587
|
+
}
|
|
15588
|
+
]
|
|
15589
|
+
}
|
|
15590
|
+
];
|
|
15591
|
+
if (config.semanticRecall) {
|
|
15592
|
+
const enabled = Boolean(config.semanticRecall);
|
|
15593
|
+
const semanticRecall = typeof config.semanticRecall === "object" ? config.semanticRecall : {};
|
|
15594
|
+
sections.push({
|
|
15595
|
+
title: "Semantic Recall",
|
|
15596
|
+
items: [
|
|
15597
|
+
{ label: "Enabled", value: enabled, badge: enabled ? "success" : void 0 },
|
|
15598
|
+
...enabled ? [
|
|
15599
|
+
{ label: "Scope", value: semanticRecall.scope || "thread" },
|
|
15600
|
+
{ label: "Top K Results", value: semanticRecall.topK || 5 },
|
|
15486
15601
|
{
|
|
15487
|
-
|
|
15488
|
-
|
|
15489
|
-
"grid-cols-[8rem_1fr] lg:grid-cols-[12rem_1fr]": template.imageURL
|
|
15490
|
-
}),
|
|
15491
|
-
children: [
|
|
15492
|
-
template.imageURL && /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("overflow-hidden"), children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
15493
|
-
"div",
|
|
15494
|
-
{
|
|
15495
|
-
className: "w-full h-full bg-cover thumb transition-scale duration-150",
|
|
15496
|
-
style: {
|
|
15497
|
-
backgroundImage: `url(${template.imageURL})`
|
|
15498
|
-
}
|
|
15499
|
-
}
|
|
15500
|
-
) }),
|
|
15501
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
15502
|
-
"div",
|
|
15503
|
-
{
|
|
15504
|
-
className: cn(
|
|
15505
|
-
"grid py-[.75rem] px-[1.5rem] w-full gap-[0.1rem]",
|
|
15506
|
-
"[&_svg]:w-[1em] [&_svg]:h-[1em] [&_svg]:text-icon3"
|
|
15507
|
-
),
|
|
15508
|
-
children: [
|
|
15509
|
-
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-[1rem] text-icon5", children: template.title }),
|
|
15510
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[0.875rem] text-icon4 transition-colors duration-500", children: template.description }),
|
|
15511
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "hidden 2xl:flex text-icon3 text-[0.875rem] flex-wrap items-center gap-[1rem] mt-[0.75rem]", children: [
|
|
15512
|
-
hasMetaInfo && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
15513
|
-
"ul",
|
|
15514
|
-
{
|
|
15515
|
-
className: cn(
|
|
15516
|
-
"flex gap-[1rem] text-[0.875rem] text-icon3 m-0 p-0 list-none",
|
|
15517
|
-
"[&>li]:flex [&>li]:items-center [&>li]:gap-[0.1rem] text-icon4"
|
|
15518
|
-
),
|
|
15519
|
-
children: [
|
|
15520
|
-
template?.agents && template.agents.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
|
|
15521
|
-
/* @__PURE__ */ jsxRuntime.jsx(AgentIcon, {}),
|
|
15522
|
-
" ",
|
|
15523
|
-
template.agents.length
|
|
15524
|
-
] }),
|
|
15525
|
-
template?.tools && template.tools.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
|
|
15526
|
-
/* @__PURE__ */ jsxRuntime.jsx(ToolsIcon, {}),
|
|
15527
|
-
" ",
|
|
15528
|
-
template.tools.length
|
|
15529
|
-
] }),
|
|
15530
|
-
template?.networks && template.networks.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
|
|
15531
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.NetworkIcon, {}),
|
|
15532
|
-
" ",
|
|
15533
|
-
template.networks.length
|
|
15534
|
-
] }),
|
|
15535
|
-
template?.workflows && template.workflows.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
|
|
15536
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.WorkflowIcon, {}),
|
|
15537
|
-
" ",
|
|
15538
|
-
template.workflows.length
|
|
15539
|
-
] }),
|
|
15540
|
-
template?.mcp && template.mcp.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
|
|
15541
|
-
/* @__PURE__ */ jsxRuntime.jsx(McpServerIcon, {}),
|
|
15542
|
-
" ",
|
|
15543
|
-
template.mcp.length
|
|
15544
|
-
] })
|
|
15545
|
-
]
|
|
15546
|
-
}
|
|
15547
|
-
),
|
|
15548
|
-
hasMetaInfo && template.supportedProviders && /* @__PURE__ */ jsxRuntime.jsx("small", { children: "|" }),
|
|
15549
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center text-icon3 gap-[1rem]", children: template.supportedProviders.map((provider) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "", children: provider }, provider)) })
|
|
15550
|
-
] })
|
|
15551
|
-
]
|
|
15552
|
-
}
|
|
15553
|
-
)
|
|
15554
|
-
]
|
|
15602
|
+
label: "Message Range",
|
|
15603
|
+
value: typeof semanticRecall.messageRange === "object" ? `${semanticRecall.messageRange.before || 0} before, ${semanticRecall.messageRange.after || 0} after` : `${semanticRecall.messageRange || 20} messages`
|
|
15555
15604
|
}
|
|
15556
|
-
|
|
15557
|
-
|
|
15558
|
-
|
|
15559
|
-
|
|
15560
|
-
|
|
15561
|
-
|
|
15562
|
-
|
|
15605
|
+
] : []
|
|
15606
|
+
]
|
|
15607
|
+
});
|
|
15608
|
+
}
|
|
15609
|
+
if (config.workingMemory) {
|
|
15610
|
+
sections.push({
|
|
15611
|
+
title: "Working Memory",
|
|
15612
|
+
items: [
|
|
15613
|
+
{
|
|
15614
|
+
label: "Enabled",
|
|
15615
|
+
value: config.workingMemory.enabled,
|
|
15616
|
+
badge: config.workingMemory.enabled ? "success" : void 0
|
|
15617
|
+
},
|
|
15618
|
+
...config.workingMemory.enabled ? [
|
|
15619
|
+
{ label: "Scope", value: config.workingMemory.scope || "thread" },
|
|
15620
|
+
{ label: "Template", value: config.workingMemory.template || "default" }
|
|
15621
|
+
] : []
|
|
15622
|
+
]
|
|
15623
|
+
});
|
|
15624
|
+
}
|
|
15625
|
+
return sections;
|
|
15626
|
+
}, [config]);
|
|
15627
|
+
const toggleSection = (title) => {
|
|
15628
|
+
const newExpanded = new Set(expandedSections);
|
|
15629
|
+
if (newExpanded.has(title)) {
|
|
15630
|
+
newExpanded.delete(title);
|
|
15631
|
+
} else {
|
|
15632
|
+
newExpanded.add(title);
|
|
15633
|
+
}
|
|
15634
|
+
setExpandedSections(newExpanded);
|
|
15635
|
+
};
|
|
15636
|
+
const renderValue = (value, badge) => {
|
|
15637
|
+
if (typeof value === "boolean") {
|
|
15638
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
15639
|
+
"span",
|
|
15640
|
+
{
|
|
15641
|
+
className: cn(
|
|
15642
|
+
"text-xs font-medium px-2 py-0.5 rounded",
|
|
15643
|
+
value ? badge === "info" ? "bg-blue-500/20 text-blue-400" : "bg-green-500/20 text-green-400" : "bg-red-500/20 text-red-400"
|
|
15644
|
+
),
|
|
15645
|
+
children: value ? "Yes" : "No"
|
|
15646
|
+
}
|
|
15647
|
+
);
|
|
15648
|
+
}
|
|
15649
|
+
if (badge) {
|
|
15650
|
+
const badgeColors = {
|
|
15651
|
+
success: "bg-green-500/20 text-green-400",
|
|
15652
|
+
info: "bg-blue-500/20 text-blue-400",
|
|
15653
|
+
warning: "bg-yellow-500/20 text-yellow-400"
|
|
15654
|
+
};
|
|
15655
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-xs font-medium px-2 py-0.5 rounded", badgeColors[badge]), children: value });
|
|
15656
|
+
}
|
|
15657
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-icon3", children: value });
|
|
15658
|
+
};
|
|
15659
|
+
if (isLoading) {
|
|
15660
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-32 w-full" }) });
|
|
15661
|
+
}
|
|
15662
|
+
if (!config || configSections.length === 0) {
|
|
15663
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4", children: [
|
|
15664
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-medium text-icon5 mb-3", children: "Memory Configuration" }),
|
|
15665
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-icon3", children: "No memory configuration available" })
|
|
15666
|
+
] });
|
|
15667
|
+
}
|
|
15668
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4", children: [
|
|
15669
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-medium text-icon5 mb-3", children: "Memory Configuration" }),
|
|
15670
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: configSections.map((section) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border border-border1 rounded-lg bg-surface3", children: [
|
|
15671
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
15672
|
+
"button",
|
|
15673
|
+
{
|
|
15674
|
+
onClick: () => toggleSection(section.title),
|
|
15675
|
+
className: "w-full px-3 py-2 flex items-center justify-between hover:bg-surface4 transition-colors rounded-t-lg",
|
|
15676
|
+
children: [
|
|
15677
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium text-icon5", children: section.title }),
|
|
15678
|
+
expandedSections.has(section.title) ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "w-3 h-3 text-icon3" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "w-3 h-3 text-icon3" })
|
|
15679
|
+
]
|
|
15680
|
+
}
|
|
15681
|
+
),
|
|
15682
|
+
expandedSections.has(section.title) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 pb-2 space-y-1", children: section.items.map((item) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between py-1", children: [
|
|
15683
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-icon3", children: item.label }),
|
|
15684
|
+
renderValue(item.value || "", item.badge)
|
|
15685
|
+
] }, `${section.title}-${item.label}`)) })
|
|
15686
|
+
] }, section.title)) })
|
|
15687
|
+
] });
|
|
15688
|
+
};
|
|
15689
|
+
|
|
15690
|
+
const formatRelativeTime = (date) => {
|
|
15691
|
+
const now = /* @__PURE__ */ new Date();
|
|
15692
|
+
const seconds = Math.floor((now.getTime() - date.getTime()) / 1e3);
|
|
15693
|
+
if (seconds < 60) return "just now";
|
|
15694
|
+
if (seconds < 3600) return `${Math.floor(seconds / 60)}m ago`;
|
|
15695
|
+
if (seconds < 86400) return `${Math.floor(seconds / 3600)}h ago`;
|
|
15696
|
+
if (seconds < 604800) return `${Math.floor(seconds / 86400)}d ago`;
|
|
15697
|
+
return date.toLocaleDateString();
|
|
15698
|
+
};
|
|
15699
|
+
const MemorySearch = ({
|
|
15700
|
+
searchMemory,
|
|
15701
|
+
onResultClick,
|
|
15702
|
+
className,
|
|
15703
|
+
currentThreadId,
|
|
15704
|
+
chatInputValue
|
|
15705
|
+
}) => {
|
|
15706
|
+
const [query, setQuery] = React.useState("");
|
|
15707
|
+
const [results, setResults] = React.useState([]);
|
|
15708
|
+
const [isSearching, setIsSearching] = React.useState(false);
|
|
15709
|
+
const [isOpen, setIsOpen] = React.useState(false);
|
|
15710
|
+
const [error, setError] = React.useState(null);
|
|
15711
|
+
const searchTimeoutRef = React.useRef(void 0);
|
|
15712
|
+
const dropdownRef = React.useRef(null);
|
|
15713
|
+
const prevThreadIdRef = React.useRef(currentThreadId);
|
|
15714
|
+
const lastSearchTimeRef = React.useRef(0);
|
|
15715
|
+
const pendingSearchRef = React.useRef(null);
|
|
15716
|
+
const handleSearch = React.useCallback(
|
|
15717
|
+
async (searchQuery) => {
|
|
15718
|
+
if (!searchQuery.trim()) {
|
|
15719
|
+
setError(null);
|
|
15720
|
+
return;
|
|
15721
|
+
}
|
|
15722
|
+
setIsSearching(true);
|
|
15723
|
+
setError(null);
|
|
15724
|
+
try {
|
|
15725
|
+
const response = await searchMemory(searchQuery);
|
|
15726
|
+
setResults(response.results);
|
|
15727
|
+
setIsOpen((prev) => prev || response.results.length > 0);
|
|
15728
|
+
} catch (err) {
|
|
15729
|
+
setError("Failed to search memory");
|
|
15730
|
+
console.error("Memory search error:", err);
|
|
15731
|
+
} finally {
|
|
15732
|
+
setIsSearching(false);
|
|
15733
|
+
}
|
|
15734
|
+
},
|
|
15735
|
+
[searchMemory]
|
|
15736
|
+
);
|
|
15737
|
+
const handleInputChange = React.useCallback(
|
|
15738
|
+
(e) => {
|
|
15739
|
+
const value = e.target.value;
|
|
15740
|
+
setQuery(value);
|
|
15741
|
+
if (searchTimeoutRef.current) {
|
|
15742
|
+
clearTimeout(searchTimeoutRef.current);
|
|
15743
|
+
}
|
|
15744
|
+
if (value.trim()) {
|
|
15745
|
+
const now = Date.now();
|
|
15746
|
+
const timeSinceLastSearch = now - lastSearchTimeRef.current;
|
|
15747
|
+
if (timeSinceLastSearch >= 500) {
|
|
15748
|
+
setIsSearching(true);
|
|
15749
|
+
handleSearch(value);
|
|
15750
|
+
lastSearchTimeRef.current = now;
|
|
15751
|
+
} else {
|
|
15752
|
+
setIsSearching(true);
|
|
15753
|
+
pendingSearchRef.current = value;
|
|
15754
|
+
const remainingTime = 500 - timeSinceLastSearch;
|
|
15755
|
+
searchTimeoutRef.current = setTimeout(() => {
|
|
15756
|
+
if (pendingSearchRef.current) {
|
|
15757
|
+
handleSearch(pendingSearchRef.current);
|
|
15758
|
+
lastSearchTimeRef.current = Date.now();
|
|
15759
|
+
pendingSearchRef.current = null;
|
|
15760
|
+
}
|
|
15761
|
+
}, remainingTime);
|
|
15762
|
+
}
|
|
15763
|
+
} else {
|
|
15764
|
+
setResults([]);
|
|
15765
|
+
setIsOpen(false);
|
|
15766
|
+
setIsSearching(false);
|
|
15767
|
+
pendingSearchRef.current = null;
|
|
15768
|
+
}
|
|
15769
|
+
},
|
|
15770
|
+
[handleSearch]
|
|
15771
|
+
);
|
|
15772
|
+
const handleKeyDown = React.useCallback(
|
|
15773
|
+
(e) => {
|
|
15774
|
+
if (e.key === "Enter") {
|
|
15775
|
+
e.preventDefault();
|
|
15776
|
+
if (searchTimeoutRef.current) {
|
|
15777
|
+
clearTimeout(searchTimeoutRef.current);
|
|
15778
|
+
}
|
|
15779
|
+
handleSearch(query);
|
|
15780
|
+
}
|
|
15781
|
+
},
|
|
15782
|
+
[query, handleSearch]
|
|
15783
|
+
);
|
|
15784
|
+
React.useEffect(() => {
|
|
15785
|
+
return () => {
|
|
15786
|
+
if (searchTimeoutRef.current) {
|
|
15787
|
+
clearTimeout(searchTimeoutRef.current);
|
|
15788
|
+
}
|
|
15789
|
+
};
|
|
15790
|
+
}, []);
|
|
15791
|
+
React.useEffect(() => {
|
|
15792
|
+
const handleClickOutside = (event) => {
|
|
15793
|
+
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
|
|
15794
|
+
setIsOpen(false);
|
|
15795
|
+
}
|
|
15796
|
+
};
|
|
15797
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
15798
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
15799
|
+
}, []);
|
|
15800
|
+
React.useEffect(() => {
|
|
15801
|
+
if (prevThreadIdRef.current !== currentThreadId && query.trim()) {
|
|
15802
|
+
handleSearch(query);
|
|
15803
|
+
}
|
|
15804
|
+
prevThreadIdRef.current = currentThreadId;
|
|
15805
|
+
}, [currentThreadId, query, handleSearch]);
|
|
15806
|
+
React.useEffect(() => {
|
|
15807
|
+
if (chatInputValue !== void 0 && chatInputValue !== query) {
|
|
15808
|
+
setQuery(chatInputValue);
|
|
15809
|
+
if (searchTimeoutRef.current) {
|
|
15810
|
+
clearTimeout(searchTimeoutRef.current);
|
|
15811
|
+
}
|
|
15812
|
+
if (chatInputValue.trim()) {
|
|
15813
|
+
const now = Date.now();
|
|
15814
|
+
const timeSinceLastSearch = now - lastSearchTimeRef.current;
|
|
15815
|
+
if (timeSinceLastSearch >= 500) {
|
|
15816
|
+
setIsSearching(true);
|
|
15817
|
+
handleSearch(chatInputValue);
|
|
15818
|
+
lastSearchTimeRef.current = now;
|
|
15819
|
+
} else {
|
|
15820
|
+
setIsSearching(true);
|
|
15821
|
+
pendingSearchRef.current = chatInputValue;
|
|
15822
|
+
const remainingTime = 500 - timeSinceLastSearch;
|
|
15823
|
+
searchTimeoutRef.current = setTimeout(() => {
|
|
15824
|
+
if (pendingSearchRef.current) {
|
|
15825
|
+
handleSearch(pendingSearchRef.current);
|
|
15826
|
+
lastSearchTimeRef.current = Date.now();
|
|
15827
|
+
pendingSearchRef.current = null;
|
|
15828
|
+
}
|
|
15829
|
+
}, remainingTime);
|
|
15830
|
+
}
|
|
15831
|
+
} else {
|
|
15832
|
+
setResults([]);
|
|
15833
|
+
setIsOpen(false);
|
|
15834
|
+
setIsSearching(false);
|
|
15835
|
+
pendingSearchRef.current = null;
|
|
15836
|
+
}
|
|
15837
|
+
}
|
|
15838
|
+
return () => {
|
|
15839
|
+
if (searchTimeoutRef.current) {
|
|
15840
|
+
clearTimeout(searchTimeoutRef.current);
|
|
15841
|
+
}
|
|
15842
|
+
};
|
|
15843
|
+
}, [chatInputValue]);
|
|
15844
|
+
const handleResultClick = (messageId, threadId) => {
|
|
15845
|
+
onResultClick?.(messageId, threadId);
|
|
15846
|
+
};
|
|
15847
|
+
const clearSearch = () => {
|
|
15848
|
+
setQuery("");
|
|
15849
|
+
setResults([]);
|
|
15850
|
+
setIsOpen(false);
|
|
15851
|
+
setError(null);
|
|
15852
|
+
if (searchTimeoutRef.current) {
|
|
15853
|
+
clearTimeout(searchTimeoutRef.current);
|
|
15854
|
+
}
|
|
15855
|
+
};
|
|
15856
|
+
const truncateContent = (content, maxLength = 100) => {
|
|
15857
|
+
if (content.length <= maxLength) return content;
|
|
15858
|
+
return content.substring(0, maxLength) + "...";
|
|
15859
|
+
};
|
|
15860
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col h-full", className), ref: dropdownRef, children: [
|
|
15861
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative shrink-0", children: [
|
|
15862
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-icon3" }),
|
|
15863
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
15864
|
+
Input,
|
|
15865
|
+
{
|
|
15866
|
+
type: "text",
|
|
15867
|
+
value: query,
|
|
15868
|
+
onChange: handleInputChange,
|
|
15869
|
+
onKeyDown: handleKeyDown,
|
|
15870
|
+
placeholder: "Search memory...",
|
|
15871
|
+
className: "pl-10 pr-10 bg-surface3 border-border1"
|
|
15872
|
+
}
|
|
15873
|
+
),
|
|
15874
|
+
query && /* @__PURE__ */ jsxRuntime.jsx(
|
|
15875
|
+
Button$2,
|
|
15876
|
+
{
|
|
15877
|
+
onClick: clearSearch,
|
|
15878
|
+
variant: "ghost",
|
|
15879
|
+
size: "sm",
|
|
15880
|
+
className: "absolute right-1 top-1/2 transform -translate-y-1/2 h-6 w-6 p-0",
|
|
15881
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-4 w-4" })
|
|
15882
|
+
}
|
|
15883
|
+
)
|
|
15884
|
+
] }),
|
|
15885
|
+
(isOpen || query && (isSearching || results.length === 0)) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2 flex-1 bg-surface3 border border-border1 rounded-lg shadow-lg overflow-y-auto", children: error ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(Txt, { variant: "ui-sm", className: "text-red-500", children: error }) }) : isSearching && results.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(Txt, { variant: "ui-sm", className: "text-icon3", children: "Searching..." }) }) : results.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 text-center", children: /* @__PURE__ */ jsxRuntime.jsxs(Txt, { variant: "ui-sm", className: "text-icon3", children: [
|
|
15886
|
+
'No results found for "',
|
|
15887
|
+
query,
|
|
15888
|
+
'"'
|
|
15889
|
+
] }) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-2", children: results.map((result) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
15890
|
+
"button",
|
|
15891
|
+
{
|
|
15892
|
+
onClick: () => handleResultClick(result.id, result.threadId),
|
|
15893
|
+
className: cn(
|
|
15894
|
+
"w-full px-4 py-3 hover:bg-surface4 transition-colors duration-150 text-left border-b border-border1 last:border-b-0",
|
|
15895
|
+
result.threadId !== currentThreadId && "border-l-2 border-l-blue-400"
|
|
15896
|
+
),
|
|
15897
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
15898
|
+
result.context?.before && result.context.before.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "opacity-50 text-xs space-y-1", children: result.context.before.map((msg, idx) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-2", children: [
|
|
15899
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-medium", children: [
|
|
15900
|
+
msg.role,
|
|
15901
|
+
":"
|
|
15902
|
+
] }),
|
|
15903
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-icon3", children: truncateContent(msg.content, 50) })
|
|
15904
|
+
] }, idx)) }),
|
|
15905
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-start justify-between gap-2", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
15906
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mb-1", children: [
|
|
15907
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
15908
|
+
"span",
|
|
15909
|
+
{
|
|
15910
|
+
className: cn(
|
|
15911
|
+
"text-xs font-medium px-2 py-0.5 rounded",
|
|
15912
|
+
result.role === "user" ? "bg-blue-500/20 text-blue-400" : "bg-green-500/20 text-green-400"
|
|
15913
|
+
),
|
|
15914
|
+
children: result.role
|
|
15915
|
+
}
|
|
15916
|
+
),
|
|
15917
|
+
/* @__PURE__ */ jsxRuntime.jsx(Txt, { variant: "ui-xs", className: "text-icon3", children: formatRelativeTime(new Date(result.createdAt)) }),
|
|
15918
|
+
result.threadTitle && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
15919
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
15920
|
+
Txt,
|
|
15921
|
+
{
|
|
15922
|
+
variant: "ui-xs",
|
|
15923
|
+
className: cn(
|
|
15924
|
+
"truncate max-w-[150px]",
|
|
15925
|
+
result.threadId !== currentThreadId ? "text-blue-400 font-medium" : "text-icon3"
|
|
15926
|
+
),
|
|
15927
|
+
title: result.threadTitle,
|
|
15928
|
+
children: [
|
|
15929
|
+
"• ",
|
|
15930
|
+
result.threadTitle
|
|
15931
|
+
]
|
|
15932
|
+
}
|
|
15933
|
+
),
|
|
15934
|
+
result.threadId !== currentThreadId && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "w-3 h-3 text-blue-400" })
|
|
15935
|
+
] })
|
|
15936
|
+
] }),
|
|
15937
|
+
/* @__PURE__ */ jsxRuntime.jsx(Txt, { variant: "ui-sm", className: "text-icon5 break-words", children: truncateContent(result.content) })
|
|
15938
|
+
] }) }),
|
|
15939
|
+
result.context?.after && result.context.after.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "opacity-50 text-xs space-y-1", children: result.context.after.map((msg, idx) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-2", children: [
|
|
15940
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-medium", children: [
|
|
15941
|
+
msg.role,
|
|
15942
|
+
":"
|
|
15943
|
+
] }),
|
|
15944
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-icon3", children: truncateContent(msg.content, 50) })
|
|
15945
|
+
] }, idx)) })
|
|
15946
|
+
] })
|
|
15947
|
+
},
|
|
15948
|
+
result.id
|
|
15949
|
+
)) }) })
|
|
15950
|
+
] });
|
|
15951
|
+
};
|
|
15952
|
+
|
|
15953
|
+
function AgentMemory({ agentId, threadId }) {
|
|
15954
|
+
const { threadInput: chatInputValue } = useThreadInput();
|
|
15955
|
+
const { paths, navigate } = useLinkComponent();
|
|
15956
|
+
const [searchScope, setSearchScope] = React.useState(null);
|
|
15957
|
+
const { data } = useMemoryConfig(agentId);
|
|
15958
|
+
const config = data?.config;
|
|
15959
|
+
const isSemanticRecallEnabled = Boolean(config?.semanticRecall);
|
|
15960
|
+
const { searchMemory } = useMemorySearch({
|
|
15961
|
+
agentId: agentId || "",
|
|
15962
|
+
resourceId: agentId || "",
|
|
15963
|
+
// In playground, agentId is the resourceId
|
|
15964
|
+
threadId
|
|
15965
|
+
});
|
|
15966
|
+
const searchSemanticRecall = React.useCallback(
|
|
15967
|
+
async (query) => {
|
|
15968
|
+
const result = await searchMemory(query, { lastMessages: 0 });
|
|
15969
|
+
if (result.searchScope) {
|
|
15970
|
+
setSearchScope(result.searchScope);
|
|
15971
|
+
}
|
|
15972
|
+
return result;
|
|
15973
|
+
},
|
|
15974
|
+
[searchMemory]
|
|
15975
|
+
);
|
|
15976
|
+
const handleResultClick = React.useCallback(
|
|
15977
|
+
(messageId, resultThreadId) => {
|
|
15978
|
+
if (resultThreadId && resultThreadId !== threadId) {
|
|
15979
|
+
navigate(paths.agentThreadLink(agentId, resultThreadId, messageId));
|
|
15980
|
+
} else {
|
|
15981
|
+
const messageElement = document.querySelector(`[data-message-id="${messageId}"]`);
|
|
15982
|
+
if (messageElement) {
|
|
15983
|
+
messageElement.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
15984
|
+
messageElement.classList.add("bg-surface4");
|
|
15985
|
+
setTimeout(() => {
|
|
15986
|
+
messageElement.classList.remove("bg-surface4");
|
|
15987
|
+
}, 2e3);
|
|
15988
|
+
}
|
|
15989
|
+
}
|
|
15990
|
+
},
|
|
15991
|
+
[agentId, threadId, navigate]
|
|
15992
|
+
);
|
|
15993
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col h-full", children: [
|
|
15994
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4 border-b border-border1", children: [
|
|
15995
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-2", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mb-2", children: [
|
|
15996
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-medium text-icon5", children: "Semantic Recall" }),
|
|
15997
|
+
searchScope && /* @__PURE__ */ jsxRuntime.jsx(
|
|
15998
|
+
"span",
|
|
15999
|
+
{
|
|
16000
|
+
className: cn(
|
|
16001
|
+
"text-xs font-medium px-2 py-0.5 rounded",
|
|
16002
|
+
searchScope === "resource" ? "bg-purple-500/20 text-purple-400" : "bg-blue-500/20 text-blue-400"
|
|
16003
|
+
),
|
|
16004
|
+
title: searchScope === "resource" ? "Searching across all threads" : "Searching within current thread only",
|
|
16005
|
+
children: searchScope
|
|
16006
|
+
}
|
|
16007
|
+
)
|
|
16008
|
+
] }) }),
|
|
16009
|
+
isSemanticRecallEnabled ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
16010
|
+
MemorySearch,
|
|
16011
|
+
{
|
|
16012
|
+
searchMemory: searchSemanticRecall,
|
|
16013
|
+
onResultClick: handleResultClick,
|
|
16014
|
+
currentThreadId: threadId,
|
|
16015
|
+
className: "w-full",
|
|
16016
|
+
chatInputValue
|
|
16017
|
+
}
|
|
16018
|
+
) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-surface3 border border-border1 rounded-lg p-4", children: [
|
|
16019
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-icon3 mb-3", children: "Semantic recall is not enabled for this agent. Enable it to search through conversation history." }),
|
|
16020
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
16021
|
+
"a",
|
|
16022
|
+
{
|
|
16023
|
+
href: "https://mastra.ai/en/docs/memory/semantic-recall",
|
|
16024
|
+
target: "_blank",
|
|
16025
|
+
rel: "noopener noreferrer",
|
|
16026
|
+
className: "inline-flex items-center gap-2 text-sm text-blue-400 hover:text-blue-300 transition-colors",
|
|
16027
|
+
children: [
|
|
16028
|
+
"Learn about semantic recall",
|
|
16029
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "w-3 h-3" })
|
|
16030
|
+
]
|
|
16031
|
+
}
|
|
16032
|
+
)
|
|
16033
|
+
] })
|
|
16034
|
+
] }),
|
|
16035
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-y-auto", children: [
|
|
16036
|
+
/* @__PURE__ */ jsxRuntime.jsx(AgentWorkingMemory, { agentId }),
|
|
16037
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t border-border1", children: /* @__PURE__ */ jsxRuntime.jsx(AgentMemoryConfig, { agentId }) })
|
|
16038
|
+
] })
|
|
16039
|
+
] });
|
|
16040
|
+
}
|
|
16041
|
+
|
|
16042
|
+
function CurrentInstructions({
|
|
16043
|
+
instructions,
|
|
16044
|
+
enhancedPrompt,
|
|
16045
|
+
isEnhancing,
|
|
16046
|
+
userComment,
|
|
16047
|
+
onEnhance,
|
|
16048
|
+
onCancel,
|
|
16049
|
+
onSave,
|
|
16050
|
+
onCommentChange,
|
|
16051
|
+
onShowHistory
|
|
16052
|
+
}) {
|
|
16053
|
+
const currentContent = enhancedPrompt || extractPrompt(instructions);
|
|
16054
|
+
const { isCopied, handleCopy } = useCopyToClipboard({ text: currentContent || "" });
|
|
16055
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
16056
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-4 pb-2", children: enhancedPrompt ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4", children: [
|
|
16057
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { onClick: onCancel, children: /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
16058
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "hover:bg-surface2 rounded-lg", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "text-accent2" }) }) }),
|
|
16059
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { children: "Discard prompt suggestions" })
|
|
16060
|
+
] }) }),
|
|
16061
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { onClick: onSave, disabled: !enhancedPrompt, children: /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
16062
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "hover:bg-surface2 rounded-lg", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckIcon, { className: "text-accent1" }) }) }),
|
|
16063
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { children: "Save prompt suggestions" })
|
|
16064
|
+
] }) })
|
|
16065
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: onShowHistory, children: /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
16066
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "hover:bg-surface2 rounded-lg text-icon3 hover:text-icon6", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileClock, {}) }) }),
|
|
16067
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { children: "Version history" })
|
|
16068
|
+
] }) }) }),
|
|
16069
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: clsx("p-[1px] rounded-lg overflow-hidden relative"), children: [
|
|
16070
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
16071
|
+
"div",
|
|
16072
|
+
{
|
|
16073
|
+
className: clsx(
|
|
16074
|
+
"absolute inset-0 bg-surface4 transition-all",
|
|
16075
|
+
enhancedPrompt && "bg-gradient-to-br from-accent1 to-accent3"
|
|
16076
|
+
)
|
|
16077
|
+
}
|
|
16078
|
+
),
|
|
16079
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative z-10 bg-surface4 rounded-lg", children: [
|
|
16080
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
16081
|
+
CodeDisplay,
|
|
16082
|
+
{
|
|
16083
|
+
content: currentContent || "",
|
|
16084
|
+
isCopied,
|
|
16085
|
+
isDraft: !!enhancedPrompt,
|
|
16086
|
+
onCopy: () => currentContent && handleCopy(),
|
|
16087
|
+
className: "border-none bg-surface4 text-ui-sm p-2 !h-[260px]"
|
|
16088
|
+
}
|
|
16089
|
+
),
|
|
16090
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-3", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between rounded-lg border border-border1 bg-surface5 shadow-lg disabled:bg-surface3 text-icon6 w-full py-2 px-3 gap-3 relative z-10", children: [
|
|
16091
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
16092
|
+
"textarea",
|
|
16093
|
+
{
|
|
16094
|
+
value: userComment,
|
|
16095
|
+
onChange: (e) => onCommentChange(e.target.value),
|
|
16096
|
+
placeholder: "Add your comments or requirements for enhancing your agent's prompt...",
|
|
16097
|
+
className: "resize-none text-ui-sm w-full placeholder:text-icon3 bg-transparent block disabled:text-icon3",
|
|
16098
|
+
disabled: Boolean(isEnhancing || enhancedPrompt)
|
|
16099
|
+
}
|
|
16100
|
+
),
|
|
16101
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { onClick: onEnhance, disabled: isEnhancing || !instructions || Boolean(enhancedPrompt), children: /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
16102
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "text-icon3 hover:text-icon6 disabled:hover:text-icon3", children: isEnhancing ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader, { className: "animate-spin" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Wand2, {}) }) }),
|
|
16103
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { children: isEnhancing ? "Enhancing..." : "Enhance prompt" })
|
|
16104
|
+
] }) })
|
|
16105
|
+
] }) })
|
|
16106
|
+
] })
|
|
16107
|
+
] }) })
|
|
16108
|
+
] });
|
|
16109
|
+
}
|
|
16110
|
+
|
|
16111
|
+
function usePromptEnhancer({
|
|
16112
|
+
agentId,
|
|
16113
|
+
instructions,
|
|
16114
|
+
versions,
|
|
16115
|
+
onVersionCreate,
|
|
16116
|
+
onVersionUpdate
|
|
16117
|
+
}) {
|
|
16118
|
+
const [enhancedPrompt, setEnhancedPrompt] = React.useState("");
|
|
16119
|
+
const [explanation, setExplanation] = React.useState("");
|
|
16120
|
+
const [isEnhancing, setIsEnhancing] = React.useState(false);
|
|
16121
|
+
const [userComment, setUserComment] = React.useState("");
|
|
16122
|
+
const enhancePrompt = async () => {
|
|
16123
|
+
if (!instructions) return;
|
|
16124
|
+
setIsEnhancing(true);
|
|
16125
|
+
try {
|
|
16126
|
+
const response = await fetch(`/api/agents/${agentId}/instructions/enhance`, {
|
|
16127
|
+
method: "POST",
|
|
16128
|
+
headers: {
|
|
16129
|
+
"Content-Type": "application/json",
|
|
16130
|
+
"x-mastra-dev-playground": "true"
|
|
16131
|
+
},
|
|
16132
|
+
body: JSON.stringify({
|
|
16133
|
+
instructions,
|
|
16134
|
+
comment: userComment
|
|
16135
|
+
})
|
|
16136
|
+
});
|
|
16137
|
+
if (!response.ok) {
|
|
16138
|
+
throw new Error("Failed to enhance prompt");
|
|
16139
|
+
}
|
|
16140
|
+
const data = await response.json();
|
|
16141
|
+
setEnhancedPrompt(data.new_prompt);
|
|
16142
|
+
setExplanation(data.explanation);
|
|
16143
|
+
setUserComment("");
|
|
16144
|
+
} catch (error) {
|
|
16145
|
+
console.error("Failed to enhance prompt:", error);
|
|
16146
|
+
} finally {
|
|
16147
|
+
setIsEnhancing(false);
|
|
16148
|
+
}
|
|
16149
|
+
};
|
|
16150
|
+
const clearEnhancement = () => {
|
|
16151
|
+
setEnhancedPrompt("");
|
|
16152
|
+
setExplanation("");
|
|
16153
|
+
};
|
|
16154
|
+
const applyChanges = () => {
|
|
16155
|
+
if (!enhancedPrompt) return;
|
|
16156
|
+
const draftIndex = versions.findIndex((v) => v.status === "draft");
|
|
16157
|
+
if (draftIndex !== -1) {
|
|
16158
|
+
onVersionUpdate(draftIndex, {
|
|
16159
|
+
content: enhancedPrompt,
|
|
16160
|
+
analysis: explanation,
|
|
16161
|
+
status: "published",
|
|
16162
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
16163
|
+
});
|
|
16164
|
+
} else {
|
|
16165
|
+
const newVersion = {
|
|
16166
|
+
content: enhancedPrompt,
|
|
16167
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
16168
|
+
analysis: explanation,
|
|
16169
|
+
status: "published"
|
|
16170
|
+
};
|
|
16171
|
+
onVersionCreate(newVersion);
|
|
16172
|
+
}
|
|
16173
|
+
clearEnhancement();
|
|
16174
|
+
};
|
|
16175
|
+
return {
|
|
16176
|
+
enhancedPrompt,
|
|
16177
|
+
explanation,
|
|
16178
|
+
isEnhancing,
|
|
16179
|
+
userComment,
|
|
16180
|
+
enhancePrompt,
|
|
16181
|
+
setUserComment,
|
|
16182
|
+
clearEnhancement,
|
|
16183
|
+
applyChanges
|
|
16184
|
+
};
|
|
16185
|
+
}
|
|
16186
|
+
|
|
16187
|
+
function usePromptVersions(agentId, instructions) {
|
|
16188
|
+
const [versions, setVersions] = React.useState([]);
|
|
16189
|
+
const [copiedVersions, setCopiedVersions] = React.useState({});
|
|
16190
|
+
const [isUpdating, setIsUpdating] = React.useState(false);
|
|
16191
|
+
const [versionToDelete, setVersionToDelete] = React.useState(null);
|
|
16192
|
+
const client = react$3.useMastraClient();
|
|
16193
|
+
const { runtimeContext } = usePlaygroundStore();
|
|
16194
|
+
const fetchEvalResults = async () => {
|
|
16195
|
+
try {
|
|
16196
|
+
const response = await client.getAgent(agentId).liveEvals(runtimeContext);
|
|
16197
|
+
return response?.evals;
|
|
16198
|
+
} catch (error) {
|
|
16199
|
+
console.error("Failed to fetch eval results:", error);
|
|
16200
|
+
return [];
|
|
16201
|
+
}
|
|
16202
|
+
};
|
|
16203
|
+
React.useEffect(() => {
|
|
16204
|
+
const loadVersions = async () => {
|
|
16205
|
+
const evals = await fetchEvalResults();
|
|
16206
|
+
const storedVersions = localStorage.getItem(`agent-${agentId}-versions`);
|
|
16207
|
+
if (storedVersions) {
|
|
16208
|
+
const parsedVersions = JSON.parse(storedVersions);
|
|
16209
|
+
const originalVersion = parsedVersions.find((v) => v.status === "original");
|
|
16210
|
+
if (instructions && originalVersion && originalVersion.content !== instructions) {
|
|
16211
|
+
const originalEvals = evals?.filter((m) => m.meta.instructions === instructions);
|
|
16212
|
+
const newVersions = [
|
|
16213
|
+
{
|
|
16214
|
+
content: instructions,
|
|
16215
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
16216
|
+
analysis: "Original instructions",
|
|
16217
|
+
status: "original",
|
|
16218
|
+
evals: originalEvals
|
|
16219
|
+
}
|
|
16220
|
+
];
|
|
16221
|
+
newVersions[0].evals = evals;
|
|
16222
|
+
setVersions(newVersions);
|
|
16223
|
+
localStorage.setItem(`agent-${agentId}-versions`, JSON.stringify(newVersions));
|
|
16224
|
+
} else {
|
|
16225
|
+
const updatedVersions = await Promise.all(
|
|
16226
|
+
parsedVersions.map(async (v) => {
|
|
16227
|
+
const originalEvals = evals?.filter((m) => m.meta.instructions === v.content);
|
|
16228
|
+
const version = {
|
|
16229
|
+
...v,
|
|
16230
|
+
timestamp: new Date(v.timestamp),
|
|
16231
|
+
status: v.content === instructions ? "active" : v.status === "active" ? "published" : v.status
|
|
16232
|
+
};
|
|
16233
|
+
return { ...version, evals: originalEvals };
|
|
16234
|
+
})
|
|
16235
|
+
);
|
|
16236
|
+
setVersions(updatedVersions);
|
|
16237
|
+
}
|
|
16238
|
+
} else if (instructions) {
|
|
16239
|
+
const initialVersions = [
|
|
16240
|
+
{
|
|
16241
|
+
content: instructions,
|
|
16242
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
16243
|
+
analysis: "Original instructions",
|
|
16244
|
+
status: "original",
|
|
16245
|
+
evals: []
|
|
16246
|
+
}
|
|
16247
|
+
];
|
|
16248
|
+
const originalEvals = evals?.filter((m) => m.meta.instructions === instructions);
|
|
16249
|
+
initialVersions[0].evals = originalEvals;
|
|
16250
|
+
setVersions(initialVersions);
|
|
16251
|
+
localStorage.setItem(`agent-${agentId}-versions`, JSON.stringify(initialVersions));
|
|
16252
|
+
}
|
|
16253
|
+
};
|
|
16254
|
+
loadVersions();
|
|
16255
|
+
}, [instructions, agentId]);
|
|
16256
|
+
React.useEffect(() => {
|
|
16257
|
+
if (versions.length > 0) {
|
|
16258
|
+
localStorage.setItem(`agent-${agentId}-versions`, JSON.stringify(versions));
|
|
16259
|
+
}
|
|
16260
|
+
}, [versions, agentId]);
|
|
16261
|
+
const copyToClipboard = async (text, versionIndex) => {
|
|
16262
|
+
setCopiedVersions((prev) => ({ ...prev, [versionIndex]: true }));
|
|
16263
|
+
const timer = setTimeout(() => {
|
|
16264
|
+
setCopiedVersions((prev) => ({ ...prev, [versionIndex]: false }));
|
|
16265
|
+
}, 1e3);
|
|
16266
|
+
return () => clearTimeout(timer);
|
|
16267
|
+
};
|
|
16268
|
+
const setVersionActive = async (version, index) => {
|
|
16269
|
+
setIsUpdating(true);
|
|
16270
|
+
try {
|
|
16271
|
+
const response = await fetch(`/api/agents/${agentId}/instructions`, {
|
|
16272
|
+
method: "POST",
|
|
16273
|
+
headers: {
|
|
16274
|
+
"Content-Type": "application/json",
|
|
16275
|
+
"x-mastra-dev-playground": "true"
|
|
16276
|
+
},
|
|
16277
|
+
body: JSON.stringify({
|
|
16278
|
+
instructions: version.content
|
|
16279
|
+
})
|
|
16280
|
+
});
|
|
16281
|
+
if (!response.ok) {
|
|
16282
|
+
throw new Error("Failed to update instructions");
|
|
16283
|
+
}
|
|
16284
|
+
setVersions(
|
|
16285
|
+
(prev) => prev.map((v, i) => ({
|
|
16286
|
+
...v,
|
|
16287
|
+
status: i === index ? "active" : v.status === "active" ? "published" : v.status
|
|
16288
|
+
}))
|
|
16289
|
+
);
|
|
16290
|
+
} catch (error) {
|
|
16291
|
+
console.error("Failed to set version as active:", error);
|
|
16292
|
+
} finally {
|
|
16293
|
+
setIsUpdating(false);
|
|
16294
|
+
}
|
|
16295
|
+
};
|
|
16296
|
+
const deleteVersion = (index) => {
|
|
16297
|
+
setVersions((prev) => prev.filter((_, i) => i !== index));
|
|
16298
|
+
setVersionToDelete(null);
|
|
16299
|
+
};
|
|
16300
|
+
const updateVersion = async (index, updates) => {
|
|
16301
|
+
const updatedVersion = {
|
|
16302
|
+
...versions[index],
|
|
16303
|
+
...updates
|
|
16304
|
+
};
|
|
16305
|
+
setVersions((prev) => prev.map((version, i) => i === index ? updatedVersion : version));
|
|
16306
|
+
};
|
|
16307
|
+
return {
|
|
16308
|
+
versions,
|
|
16309
|
+
copiedVersions,
|
|
16310
|
+
isUpdating,
|
|
16311
|
+
versionToDelete,
|
|
16312
|
+
setVersions,
|
|
16313
|
+
setVersionToDelete,
|
|
16314
|
+
copyToClipboard,
|
|
16315
|
+
setVersionActive,
|
|
16316
|
+
deleteVersion,
|
|
16317
|
+
updateVersion
|
|
16318
|
+
};
|
|
16319
|
+
}
|
|
16320
|
+
|
|
16321
|
+
function VersionActions({ version, index, isUpdating, onSetActive, onDelete }) {
|
|
16322
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-1", children: [
|
|
16323
|
+
version.status !== "active" && version.status !== "draft" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
16324
|
+
Button$2,
|
|
16325
|
+
{
|
|
16326
|
+
variant: "ghost",
|
|
16327
|
+
size: "sm",
|
|
16328
|
+
className: "h-6 px-2 hover:bg-mastra-bg-3 relative group",
|
|
16329
|
+
onClick: (e) => {
|
|
16330
|
+
e.stopPropagation();
|
|
16331
|
+
onSetActive(version, index);
|
|
16332
|
+
},
|
|
16333
|
+
disabled: isUpdating,
|
|
16334
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Play, { className: "h-3 w-3" })
|
|
16335
|
+
}
|
|
16336
|
+
),
|
|
16337
|
+
index !== 0 && version.status !== "active" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
16338
|
+
Button$2,
|
|
16339
|
+
{
|
|
16340
|
+
variant: "ghost",
|
|
16341
|
+
size: "sm",
|
|
16342
|
+
className: "h-6 px-2 hover:bg-mastra-bg-3 relative group",
|
|
16343
|
+
onClick: (e) => {
|
|
16344
|
+
e.stopPropagation();
|
|
16345
|
+
onDelete(index);
|
|
16346
|
+
},
|
|
16347
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "h-3 w-3 text-red-400 hover:text-red-500" })
|
|
16348
|
+
}
|
|
16349
|
+
)
|
|
16350
|
+
] });
|
|
16351
|
+
}
|
|
16352
|
+
|
|
16353
|
+
function VersionItem({
|
|
16354
|
+
version,
|
|
16355
|
+
index,
|
|
16356
|
+
isExpanded,
|
|
16357
|
+
isUpdating,
|
|
16358
|
+
onToggleExpand,
|
|
16359
|
+
onToggleAnalysis,
|
|
16360
|
+
onSetActive,
|
|
16361
|
+
onDelete
|
|
16362
|
+
}) {
|
|
16363
|
+
const [showEvals, setShowEvals] = React.useState(false);
|
|
16364
|
+
const [showInstructions, setShowInstructions] = React.useState(true);
|
|
16365
|
+
const [showAnalysis, setShowAnalysis] = React.useState(false);
|
|
16366
|
+
const { handleCopy, isCopied } = useCopyToClipboard({
|
|
16367
|
+
text: version.content
|
|
16368
|
+
});
|
|
16369
|
+
const formatText = (text) => {
|
|
16370
|
+
return text.replace(/\\n/g, "\n");
|
|
16371
|
+
};
|
|
16372
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
16373
|
+
"div",
|
|
16374
|
+
{
|
|
16375
|
+
className: `rounded-md border ${isExpanded ? "border-mastra-purple/30" : "border-mastra-bg-3"} bg-mastra-bg-2`,
|
|
16376
|
+
children: [
|
|
16377
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
16378
|
+
"div",
|
|
16379
|
+
{
|
|
16380
|
+
className: "p-2 flex items-center justify-between cursor-pointer hover:bg-mastra-bg-3/50",
|
|
16381
|
+
onClick: onToggleExpand,
|
|
16382
|
+
children: [
|
|
16383
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-2", children: [
|
|
16384
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
16385
|
+
lucideReact.ChevronRight,
|
|
16386
|
+
{
|
|
16387
|
+
className: `h-3 w-3 transition-transform ${isExpanded ? "rotate-90 text-mastra-purple" : ""}`
|
|
16388
|
+
}
|
|
16389
|
+
),
|
|
16390
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
16391
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-2", children: [
|
|
16392
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs font-medium text-mastra-el-4", children: [
|
|
16393
|
+
"Version ",
|
|
16394
|
+
index + 1
|
|
16395
|
+
] }),
|
|
16396
|
+
version.status === "active" && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] px-1.5 py-0.5 rounded-full bg-green-500/20 text-green-500", children: "Active" }),
|
|
16397
|
+
version.status === "original" && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] px-1.5 py-0.5 rounded-full bg-blue-500/20 text-blue-500", children: "Original" }),
|
|
16398
|
+
version.status === "draft" && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] px-1.5 py-0.5 rounded-full bg-yellow-500/20 text-yellow-500", children: "Draft" })
|
|
16399
|
+
] }),
|
|
16400
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[10px] text-mastra-el-3", children: version.timestamp.toLocaleString() })
|
|
16401
|
+
] })
|
|
16402
|
+
] }),
|
|
16403
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
16404
|
+
VersionActions,
|
|
16405
|
+
{
|
|
16406
|
+
version,
|
|
16407
|
+
index,
|
|
16408
|
+
isUpdating,
|
|
16409
|
+
onSetActive,
|
|
16410
|
+
onDelete
|
|
16411
|
+
}
|
|
16412
|
+
)
|
|
16413
|
+
]
|
|
16414
|
+
}
|
|
16415
|
+
),
|
|
16416
|
+
isExpanded && /* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { className: "h-[250px]", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-2 pb-2 space-y-2", children: [
|
|
16417
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
16418
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
16419
|
+
"div",
|
|
16420
|
+
{
|
|
16421
|
+
className: "flex items-center space-x-1 cursor-pointer hover:bg-mastra-bg-3/50 p-1 rounded-md mb-2",
|
|
16422
|
+
onClick: (e) => {
|
|
16423
|
+
e.stopPropagation();
|
|
16424
|
+
setShowInstructions(!showInstructions);
|
|
16425
|
+
},
|
|
16426
|
+
children: [
|
|
16427
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: `h-3 w-3 transition-transform ${showInstructions ? "rotate-90" : ""}` }),
|
|
16428
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-medium text-mastra-el-4", children: "Instructions" })
|
|
16429
|
+
]
|
|
16430
|
+
}
|
|
16431
|
+
),
|
|
16432
|
+
showInstructions && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-md border border-mastra-bg-3", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2", children: /* @__PURE__ */ jsxRuntime.jsx(CodeDisplay, { content: formatText(version.content), isCopied, onCopy: handleCopy }) }) })
|
|
16433
|
+
] }),
|
|
16434
|
+
version.analysis && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
16435
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
16436
|
+
"div",
|
|
16437
|
+
{
|
|
16438
|
+
className: "flex items-center space-x-1 cursor-pointer hover:bg-mastra-bg-3/50 p-1 rounded-md mb-2",
|
|
16439
|
+
onClick: (e) => {
|
|
16440
|
+
e.stopPropagation();
|
|
16441
|
+
setShowAnalysis(!showAnalysis);
|
|
16442
|
+
},
|
|
16443
|
+
children: [
|
|
16444
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: `h-3 w-3 transition-transform ${showAnalysis ? "rotate-90" : ""}` }),
|
|
16445
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-medium text-mastra-el-4", children: "Analysis" })
|
|
16446
|
+
]
|
|
16447
|
+
}
|
|
16448
|
+
),
|
|
16449
|
+
showAnalysis && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-md border border-mastra-bg-3", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-2", children: /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "text-[10px] text-mastra-el-4 whitespace-pre-wrap font-mono", children: formatText(version.analysis || "") }) }) })
|
|
16450
|
+
] }),
|
|
16451
|
+
version.evals && version.evals.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
|
|
16452
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
16453
|
+
"div",
|
|
16454
|
+
{
|
|
16455
|
+
className: "flex items-center space-x-1 cursor-pointer hover:bg-mastra-bg-3/50 p-1 rounded-md",
|
|
16456
|
+
onClick: (e) => {
|
|
16457
|
+
e.stopPropagation();
|
|
16458
|
+
setShowEvals(!showEvals);
|
|
16459
|
+
},
|
|
16460
|
+
children: [
|
|
16461
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: `h-3 w-3 transition-transform ${showEvals ? "rotate-90" : ""}` }),
|
|
16462
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs font-medium text-mastra-el-4", children: [
|
|
16463
|
+
"Evaluations (",
|
|
16464
|
+
version.evals.length,
|
|
16465
|
+
")"
|
|
16466
|
+
] })
|
|
16467
|
+
]
|
|
16468
|
+
}
|
|
16469
|
+
),
|
|
16470
|
+
showEvals && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pl-4", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-1 pr-4", children: version.evals.map((metric, evalIndex) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-md border border-mastra-bg-3 p-1.5 text-[10px]", children: [
|
|
16471
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-2", children: [
|
|
16472
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
16473
|
+
"span",
|
|
16474
|
+
{
|
|
16475
|
+
className: `px-1.5 py-0.5 rounded-full min-w-[32px] text-center ${metric.result.score >= 0.7 ? "bg-green-500/20 text-green-500" : metric.result.score >= 0.4 ? "bg-yellow-500/20 text-yellow-500" : "bg-red-500/20 text-red-500"}`,
|
|
16476
|
+
children: metric.result.score.toFixed(2)
|
|
16477
|
+
}
|
|
16478
|
+
),
|
|
16479
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-mastra-el-3 text-[9px]", children: new Date(metric.createdAt).toLocaleTimeString() })
|
|
16480
|
+
] }) }),
|
|
16481
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-1 space-y-1", children: [
|
|
16482
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-1.5", children: [
|
|
16483
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-mastra-el-3 shrink-0", children: "→" }),
|
|
16484
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-mastra-el-4", children: metric.input })
|
|
16485
|
+
] }),
|
|
16486
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-1.5", children: [
|
|
16487
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-mastra-el-3 shrink-0", children: "←" }),
|
|
16488
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-mastra-el-4", children: metric.output })
|
|
16489
|
+
] }),
|
|
16490
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-1.5 text-[9px] text-mastra-el-3", children: [
|
|
16491
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0", children: "⚬" }),
|
|
16492
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: metric.result.info.reason })
|
|
16493
|
+
] })
|
|
16494
|
+
] })
|
|
16495
|
+
] }, evalIndex)) }) })
|
|
16496
|
+
] })
|
|
16497
|
+
] }) })
|
|
16498
|
+
]
|
|
16499
|
+
}
|
|
16500
|
+
);
|
|
16501
|
+
}
|
|
16502
|
+
|
|
16503
|
+
function VersionHistory({
|
|
16504
|
+
versions,
|
|
16505
|
+
isUpdating,
|
|
16506
|
+
copiedVersions,
|
|
16507
|
+
onCopy,
|
|
16508
|
+
onSetActive,
|
|
16509
|
+
onDelete
|
|
16510
|
+
}) {
|
|
16511
|
+
const [expandedVersion, setExpandedVersion] = React.useState(null);
|
|
16512
|
+
const [expandedAnalysis, setExpandedAnalysis] = React.useState(null);
|
|
16513
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { className: "flex-1", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2 pr-4", children: versions.map((version, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
16514
|
+
VersionItem,
|
|
16515
|
+
{
|
|
16516
|
+
version,
|
|
16517
|
+
index,
|
|
16518
|
+
isExpanded: expandedVersion === index,
|
|
16519
|
+
isUpdating,
|
|
16520
|
+
copiedVersions,
|
|
16521
|
+
onToggleExpand: () => {
|
|
16522
|
+
if (expandedVersion === index) {
|
|
16523
|
+
return setExpandedVersion(null);
|
|
16524
|
+
}
|
|
16525
|
+
setExpandedVersion(index);
|
|
16526
|
+
},
|
|
16527
|
+
onToggleAnalysis: () => {
|
|
16528
|
+
if (expandedAnalysis === index) {
|
|
16529
|
+
return setExpandedAnalysis(null);
|
|
16530
|
+
}
|
|
16531
|
+
setExpandedAnalysis(index);
|
|
16532
|
+
},
|
|
16533
|
+
onCopy,
|
|
16534
|
+
onSetActive,
|
|
16535
|
+
onDelete
|
|
16536
|
+
},
|
|
16537
|
+
index
|
|
16538
|
+
)) }) });
|
|
16539
|
+
}
|
|
16540
|
+
|
|
16541
|
+
const VersionHistoryDialog = ({
|
|
16542
|
+
open,
|
|
16543
|
+
onOpenChange,
|
|
16544
|
+
onDelete,
|
|
16545
|
+
onSetActive,
|
|
16546
|
+
versions,
|
|
16547
|
+
isUpdating
|
|
16548
|
+
}) => {
|
|
16549
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { className: "bg-surface4", children: [
|
|
16550
|
+
/* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { children: [
|
|
16551
|
+
/* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Version History" }),
|
|
16552
|
+
/* @__PURE__ */ jsxRuntime.jsx(DialogDescription, { children: "View the history of changes to the agent's instructions." })
|
|
16553
|
+
] }),
|
|
16554
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
16555
|
+
VersionHistory,
|
|
16556
|
+
{
|
|
16557
|
+
versions,
|
|
16558
|
+
isUpdating,
|
|
16559
|
+
copiedVersions: {},
|
|
16560
|
+
onCopy: async (content, key) => {
|
|
16561
|
+
await navigator.clipboard.writeText(content);
|
|
16562
|
+
},
|
|
16563
|
+
onSetActive,
|
|
16564
|
+
onDelete
|
|
16565
|
+
}
|
|
16566
|
+
)
|
|
16567
|
+
] }) });
|
|
16568
|
+
};
|
|
16569
|
+
|
|
16570
|
+
function AgentPromptEnhancer({ agentId }) {
|
|
16571
|
+
const { data: agent } = useAgent(agentId);
|
|
16572
|
+
const [showVersionHistoryDialog, setShowVersionHistoryDialog] = React.useState(false);
|
|
16573
|
+
const formattedInstructions = extractPrompt(agent?.instructions || "");
|
|
16574
|
+
const {
|
|
16575
|
+
versions,
|
|
16576
|
+
isUpdating,
|
|
16577
|
+
versionToDelete,
|
|
16578
|
+
setVersions,
|
|
16579
|
+
setVersionToDelete,
|
|
16580
|
+
deleteVersion,
|
|
16581
|
+
updateVersion,
|
|
16582
|
+
setVersionActive
|
|
16583
|
+
} = usePromptVersions(agentId, formattedInstructions);
|
|
16584
|
+
const { enhancedPrompt, isEnhancing, userComment, enhancePrompt, setUserComment, clearEnhancement, applyChanges } = usePromptEnhancer({
|
|
16585
|
+
agentId,
|
|
16586
|
+
instructions: formattedInstructions,
|
|
16587
|
+
versions,
|
|
16588
|
+
onVersionCreate: (newVersion) => {
|
|
16589
|
+
setVersions((prev) => [...prev, newVersion]);
|
|
16590
|
+
},
|
|
16591
|
+
onVersionUpdate: updateVersion
|
|
16592
|
+
});
|
|
16593
|
+
if (!agent) return null;
|
|
16594
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
16595
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
16596
|
+
CurrentInstructions,
|
|
16597
|
+
{
|
|
16598
|
+
instructions: agent.instructions,
|
|
16599
|
+
enhancedPrompt,
|
|
16600
|
+
isEnhancing,
|
|
16601
|
+
userComment,
|
|
16602
|
+
onEnhance: enhancePrompt,
|
|
16603
|
+
onCancel: clearEnhancement,
|
|
16604
|
+
onSave: applyChanges,
|
|
16605
|
+
onCommentChange: setUserComment,
|
|
16606
|
+
agentId,
|
|
16607
|
+
onShowHistory: () => setShowVersionHistoryDialog(true)
|
|
16608
|
+
}
|
|
16609
|
+
),
|
|
16610
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
16611
|
+
VersionHistoryDialog,
|
|
16612
|
+
{
|
|
16613
|
+
versions,
|
|
16614
|
+
isUpdating,
|
|
16615
|
+
onSetActive: setVersionActive,
|
|
16616
|
+
onDelete: setVersionToDelete,
|
|
16617
|
+
open: showVersionHistoryDialog,
|
|
16618
|
+
onOpenChange: setShowVersionHistoryDialog
|
|
16619
|
+
}
|
|
16620
|
+
),
|
|
16621
|
+
/* @__PURE__ */ jsxRuntime.jsx(AlertDialog, { open: versionToDelete !== null, onOpenChange: () => setVersionToDelete(null), children: /* @__PURE__ */ jsxRuntime.jsxs(AlertDialog.Content, { children: [
|
|
16622
|
+
/* @__PURE__ */ jsxRuntime.jsxs(AlertDialog.Header, { children: [
|
|
16623
|
+
/* @__PURE__ */ jsxRuntime.jsxs(AlertDialog.Title, { children: [
|
|
16624
|
+
"Delete Version ",
|
|
16625
|
+
versionToDelete !== null ? versionToDelete + 1 : ""
|
|
16626
|
+
] }),
|
|
16627
|
+
/* @__PURE__ */ jsxRuntime.jsx(AlertDialog.Description, { children: "Are you sure you want to delete this version? This action cannot be undone." })
|
|
16628
|
+
] }),
|
|
16629
|
+
/* @__PURE__ */ jsxRuntime.jsxs(AlertDialog.Footer, { children: [
|
|
16630
|
+
/* @__PURE__ */ jsxRuntime.jsx(AlertDialog.Cancel, { children: "Cancel" }),
|
|
16631
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
16632
|
+
AlertDialog.Action,
|
|
16633
|
+
{
|
|
16634
|
+
className: "bg-red-500 hover:bg-red-600",
|
|
16635
|
+
onClick: () => {
|
|
16636
|
+
if (versionToDelete !== null) {
|
|
16637
|
+
deleteVersion(versionToDelete);
|
|
16638
|
+
}
|
|
16639
|
+
},
|
|
16640
|
+
children: "Delete"
|
|
16641
|
+
}
|
|
16642
|
+
)
|
|
16643
|
+
] })
|
|
16644
|
+
] }) })
|
|
16645
|
+
] });
|
|
16646
|
+
}
|
|
16647
|
+
|
|
16648
|
+
function AgentInformation({ agentId, threadId }) {
|
|
16649
|
+
const { data: agent, isLoading } = useAgent(agentId);
|
|
16650
|
+
const { data: modelProviders } = useModelProviders();
|
|
16651
|
+
const { mutateAsync: updateModel } = useUpdateAgentModel(agentId);
|
|
16652
|
+
const { mutate: reorderModelList } = useReorderModelList(agentId);
|
|
16653
|
+
const { mutateAsync: updateModelInModelList } = useUpdateModelInModelList(agentId);
|
|
16654
|
+
const { data: memory, isLoading: isMemoryLoading } = useMemory(agentId);
|
|
16655
|
+
const { settings, setSettings } = useAgentSettings();
|
|
16656
|
+
const STORAGE_KEY = "agent-info-selected-tab";
|
|
16657
|
+
const [selectedTab, setSelectedTab] = React.useState(() => {
|
|
16658
|
+
return sessionStorage.getItem(STORAGE_KEY) || "overview";
|
|
16659
|
+
});
|
|
16660
|
+
const handleTabChange = (value) => {
|
|
16661
|
+
setSelectedTab(value);
|
|
16662
|
+
sessionStorage.setItem(STORAGE_KEY, value);
|
|
16663
|
+
};
|
|
16664
|
+
React.useEffect(() => {
|
|
16665
|
+
if (agent?.modelId?.includes("gpt-5")) {
|
|
16666
|
+
setSettings({
|
|
16667
|
+
...settings || {},
|
|
16668
|
+
modelSettings: {
|
|
16669
|
+
...settings?.modelSettings || {},
|
|
16670
|
+
temperature: 1
|
|
16671
|
+
}
|
|
16672
|
+
});
|
|
16673
|
+
}
|
|
16674
|
+
}, [agent]);
|
|
16675
|
+
React.useEffect(() => {
|
|
16676
|
+
if (!isMemoryLoading && !memory?.result && selectedTab === "memory") {
|
|
16677
|
+
handleTabChange("overview");
|
|
16678
|
+
}
|
|
16679
|
+
}, [isMemoryLoading, memory?.result, selectedTab]);
|
|
16680
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-rows-[auto_1fr] h-full items-start overflow-y-auto border-l-sm border-border1", children: [
|
|
16681
|
+
/* @__PURE__ */ jsxRuntime.jsx(AgentEntityHeader, { agentId, isLoading: isMemoryLoading, agentName: agent?.name || "" }),
|
|
16682
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden border-t-sm border-border1 flex flex-col", children: /* @__PURE__ */ jsxRuntime.jsxs(PlaygroundTabs, { defaultTab: "overview", value: selectedTab, onValueChange: handleTabChange, children: [
|
|
16683
|
+
/* @__PURE__ */ jsxRuntime.jsxs(TabList$1, { children: [
|
|
16684
|
+
/* @__PURE__ */ jsxRuntime.jsx(Tab$1, { value: "overview", children: "Overview" }),
|
|
16685
|
+
/* @__PURE__ */ jsxRuntime.jsx(Tab$1, { value: "model-settings", children: "Model Settings" }),
|
|
16686
|
+
memory?.result && /* @__PURE__ */ jsxRuntime.jsx(Tab$1, { value: "memory", children: "Memory" })
|
|
16687
|
+
] }),
|
|
16688
|
+
/* @__PURE__ */ jsxRuntime.jsxs(TabContent$1, { value: "overview", children: [
|
|
16689
|
+
isLoading && /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-full" }),
|
|
16690
|
+
agent && /* @__PURE__ */ jsxRuntime.jsx(
|
|
16691
|
+
AgentMetadata,
|
|
16692
|
+
{
|
|
16693
|
+
agentId,
|
|
16694
|
+
agent,
|
|
16695
|
+
updateModel,
|
|
16696
|
+
updateModelInModelList,
|
|
16697
|
+
reorderModelList,
|
|
16698
|
+
modelProviders: modelProviders || [],
|
|
16699
|
+
hasMemoryEnabled: Boolean(memory?.result),
|
|
16700
|
+
promptSlot: /* @__PURE__ */ jsxRuntime.jsx(AgentPromptEnhancer, { agentId }),
|
|
16701
|
+
modelVersion: agent.modelVersion
|
|
16702
|
+
}
|
|
16703
|
+
)
|
|
16704
|
+
] }),
|
|
16705
|
+
/* @__PURE__ */ jsxRuntime.jsxs(TabContent$1, { value: "model-settings", children: [
|
|
16706
|
+
isLoading && /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-full" }),
|
|
16707
|
+
agent && /* @__PURE__ */ jsxRuntime.jsx(
|
|
16708
|
+
AgentSettings,
|
|
16709
|
+
{
|
|
16710
|
+
modelVersion: agent.modelVersion,
|
|
16711
|
+
hasMemory: Boolean(memory?.result),
|
|
16712
|
+
hasSubAgents: Boolean(Object.keys(agent.agents || {}).length > 0)
|
|
16713
|
+
}
|
|
16714
|
+
)
|
|
16715
|
+
] }),
|
|
16716
|
+
/* @__PURE__ */ jsxRuntime.jsx(TabContent$1, { value: "memory", children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-full" }) : /* @__PURE__ */ jsxRuntime.jsx(AgentMemory, { agentId, threadId }) })
|
|
16717
|
+
] }) })
|
|
16718
|
+
] });
|
|
16719
|
+
}
|
|
16720
|
+
|
|
16721
|
+
const NameCell$1 = ({ row }) => {
|
|
16722
|
+
const { Link, paths } = useLinkComponent();
|
|
16723
|
+
const tool = row.original;
|
|
16724
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
16725
|
+
EntryCell,
|
|
16726
|
+
{
|
|
16727
|
+
name: /* @__PURE__ */ jsxRuntime.jsx(Link, { className: "w-full space-y-0", href: paths.toolLink(tool.id), children: tool.id }),
|
|
16728
|
+
description: tool.description
|
|
16729
|
+
}
|
|
16730
|
+
);
|
|
16731
|
+
};
|
|
16732
|
+
const columns$1 = [
|
|
16733
|
+
{
|
|
16734
|
+
header: "Name",
|
|
16735
|
+
accessorKey: "name",
|
|
16736
|
+
cell: NameCell$1
|
|
16737
|
+
},
|
|
16738
|
+
{
|
|
16739
|
+
header: "Attached entities",
|
|
16740
|
+
accessorKey: "attachedEntities",
|
|
16741
|
+
cell: ({ row }) => {
|
|
16742
|
+
const tool = row.original;
|
|
16743
|
+
const agentsCount = tool.agents.length;
|
|
16744
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Cell, { children: /* @__PURE__ */ jsxRuntime.jsxs(Badge$1, { variant: "default", icon: /* @__PURE__ */ jsxRuntime.jsx(AgentIcon, { className: "text-accent1" }), children: [
|
|
16745
|
+
agentsCount,
|
|
16746
|
+
" agent",
|
|
16747
|
+
agentsCount > 1 ? "s" : ""
|
|
16748
|
+
] }) });
|
|
16749
|
+
}
|
|
16750
|
+
}
|
|
16751
|
+
];
|
|
16752
|
+
|
|
16753
|
+
const prepareToolsTable = (tools, agents) => {
|
|
16754
|
+
const toolsWithAgents = /* @__PURE__ */ new Map();
|
|
16755
|
+
const agentsKeys = Object.keys(agents);
|
|
16756
|
+
for (const k of agentsKeys) {
|
|
16757
|
+
const agent = agents[k];
|
|
16758
|
+
const agentToolsDict = agent.tools;
|
|
16759
|
+
const agentToolsKeys = Object.keys(agentToolsDict);
|
|
16760
|
+
for (const key of agentToolsKeys) {
|
|
16761
|
+
const tool = agentToolsDict[key];
|
|
16762
|
+
if (!toolsWithAgents.has(tool.id)) {
|
|
16763
|
+
toolsWithAgents.set(tool.id, {
|
|
16764
|
+
...tool,
|
|
16765
|
+
agents: []
|
|
16766
|
+
});
|
|
16767
|
+
}
|
|
16768
|
+
toolsWithAgents.get(tool.id).agents.push({ ...agent, id: k });
|
|
16769
|
+
}
|
|
16770
|
+
}
|
|
16771
|
+
for (const [_, tool] of Object.entries(tools)) {
|
|
16772
|
+
if (!toolsWithAgents.has(tool.id)) {
|
|
16773
|
+
toolsWithAgents.set(tool.id, {
|
|
16774
|
+
...tool,
|
|
16775
|
+
agents: []
|
|
16776
|
+
});
|
|
16777
|
+
}
|
|
16778
|
+
}
|
|
16779
|
+
return Array.from(toolsWithAgents.values());
|
|
16780
|
+
};
|
|
16781
|
+
|
|
16782
|
+
function ToolTable({ tools, agents, isLoading }) {
|
|
16783
|
+
const [search, setSearch] = React.useState("");
|
|
16784
|
+
const { navigate, paths } = useLinkComponent();
|
|
16785
|
+
const toolData = React.useMemo(() => prepareToolsTable(tools, agents), [tools, agents]);
|
|
16786
|
+
const table = reactTable.useReactTable({
|
|
16787
|
+
data: toolData,
|
|
16788
|
+
columns: columns$1,
|
|
16789
|
+
getCoreRowModel: reactTable.getCoreRowModel()
|
|
16790
|
+
});
|
|
16791
|
+
const ths = table.getHeaderGroups()[0];
|
|
16792
|
+
const rows = table.getRowModel().rows.concat();
|
|
16793
|
+
if (rows.length === 0 && !isLoading) {
|
|
16794
|
+
return /* @__PURE__ */ jsxRuntime.jsx(EmptyToolsTable, {});
|
|
16795
|
+
}
|
|
16796
|
+
const filteredRows = rows.filter((row) => row.original.id.toLowerCase().includes(search.toLowerCase()));
|
|
16797
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
16798
|
+
/* @__PURE__ */ jsxRuntime.jsx(SearchbarWrapper, { children: /* @__PURE__ */ jsxRuntime.jsx(Searchbar, { onSearch: setSearch, label: "Search tools", placeholder: "Search tools" }) }),
|
|
16799
|
+
isLoading ? /* @__PURE__ */ jsxRuntime.jsx(ToolTableSkeleton, {}) : /* @__PURE__ */ jsxRuntime.jsx(ScrollableContainer, { children: /* @__PURE__ */ jsxRuntime.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(Table$1, { children: [
|
|
16800
|
+
/* @__PURE__ */ jsxRuntime.jsx(Thead, { className: "sticky top-0", children: ths.headers.map((header) => /* @__PURE__ */ jsxRuntime.jsx(Th, { style: { width: header.column.getSize() ?? "auto" }, children: reactTable.flexRender(header.column.columnDef.header, header.getContext()) }, header.id)) }),
|
|
16801
|
+
/* @__PURE__ */ jsxRuntime.jsx(Tbody, { children: filteredRows.map((row) => {
|
|
16802
|
+
const firstAgent = row.original.agents[0];
|
|
16803
|
+
const link = firstAgent ? paths.agentToolLink(firstAgent.id, row.original.id) : paths.toolLink(row.original.id);
|
|
16804
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Row, { onClick: () => navigate(link), children: row.getVisibleCells().map((cell) => /* @__PURE__ */ jsxRuntime.jsx(React.Fragment, { children: reactTable.flexRender(cell.column.columnDef.cell, cell.getContext()) }, cell.id)) }, row.id);
|
|
16805
|
+
}) })
|
|
16806
|
+
] }) }) })
|
|
16807
|
+
] });
|
|
16808
|
+
}
|
|
16809
|
+
const ToolTableSkeleton = () => /* @__PURE__ */ jsxRuntime.jsxs(Table$1, { children: [
|
|
16810
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Thead, { children: [
|
|
16811
|
+
/* @__PURE__ */ jsxRuntime.jsx(Th, { children: "Name" }),
|
|
16812
|
+
/* @__PURE__ */ jsxRuntime.jsx(Th, { children: "Used by" })
|
|
16813
|
+
] }),
|
|
16814
|
+
/* @__PURE__ */ jsxRuntime.jsx(Tbody, { children: Array.from({ length: 3 }).map((_, index) => /* @__PURE__ */ jsxRuntime.jsxs(Row, { children: [
|
|
16815
|
+
/* @__PURE__ */ jsxRuntime.jsx(Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-4 w-1/2" }) }),
|
|
16816
|
+
/* @__PURE__ */ jsxRuntime.jsx(Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-4 w-1/2" }) })
|
|
16817
|
+
] }, index)) })
|
|
16818
|
+
] });
|
|
16819
|
+
const EmptyToolsTable = () => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-full items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
16820
|
+
EmptyState,
|
|
16821
|
+
{
|
|
16822
|
+
iconSlot: /* @__PURE__ */ jsxRuntime.jsx(ToolCoinIcon, {}),
|
|
16823
|
+
titleSlot: "Configure Tools",
|
|
16824
|
+
descriptionSlot: "Mastra tools are not configured yet. You can find more information in the documentation.",
|
|
16825
|
+
actionSlot: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
16826
|
+
Button$1,
|
|
16827
|
+
{
|
|
16828
|
+
size: "lg",
|
|
16829
|
+
className: "w-full",
|
|
16830
|
+
variant: "light",
|
|
16831
|
+
as: "a",
|
|
16832
|
+
href: "https://mastra.ai/en/docs/agents/using-tools-and-mcp",
|
|
16833
|
+
target: "_blank",
|
|
16834
|
+
children: [
|
|
16835
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icon, { children: /* @__PURE__ */ jsxRuntime.jsx(ToolsIcon, {}) }),
|
|
16836
|
+
"Docs"
|
|
16837
|
+
]
|
|
16838
|
+
}
|
|
16839
|
+
)
|
|
16840
|
+
}
|
|
16841
|
+
) });
|
|
16842
|
+
|
|
16843
|
+
const useExecuteTool = () => {
|
|
16844
|
+
const client = react$3.useMastraClient();
|
|
16845
|
+
return reactQuery.useMutation({
|
|
16846
|
+
mutationFn: async ({
|
|
16847
|
+
toolId,
|
|
16848
|
+
input,
|
|
16849
|
+
runtimeContext: playgroundRuntimeContext
|
|
16850
|
+
}) => {
|
|
16851
|
+
const runtimeContext = new di.RuntimeContext();
|
|
16852
|
+
Object.entries(playgroundRuntimeContext ?? {}).forEach(([key, value]) => {
|
|
16853
|
+
runtimeContext.set(key, value);
|
|
16854
|
+
});
|
|
16855
|
+
try {
|
|
16856
|
+
const tool = client.getTool(toolId);
|
|
16857
|
+
const response = await tool.execute({ data: input, runtimeContext });
|
|
16858
|
+
return response;
|
|
16859
|
+
} catch (error) {
|
|
16860
|
+
sonner.toast.error("Error executing dev tool");
|
|
16861
|
+
console.error("Error executing dev tool:", error);
|
|
16862
|
+
throw error;
|
|
16863
|
+
}
|
|
16864
|
+
}
|
|
16865
|
+
});
|
|
16866
|
+
};
|
|
16867
|
+
|
|
16868
|
+
const useTools = () => {
|
|
16869
|
+
const { runtimeContext } = usePlaygroundStore();
|
|
16870
|
+
const client = react$3.useMastraClient();
|
|
16871
|
+
return reactQuery.useQuery({
|
|
16872
|
+
queryKey: ["tools"],
|
|
16873
|
+
queryFn: () => client.getTools(runtimeContext)
|
|
16874
|
+
});
|
|
16875
|
+
};
|
|
16876
|
+
const useTool = (toolId) => {
|
|
16877
|
+
const client = react$3.useMastraClient();
|
|
16878
|
+
const { runtimeContext } = usePlaygroundStore();
|
|
16879
|
+
return reactQuery.useQuery({
|
|
16880
|
+
queryKey: ["tool", toolId],
|
|
16881
|
+
queryFn: () => client.getTool(toolId).details(runtimeContext)
|
|
16882
|
+
});
|
|
16883
|
+
};
|
|
16884
|
+
|
|
16885
|
+
const ToolPanel = ({ toolId }) => {
|
|
16886
|
+
const { data: tool, isLoading } = useTool(toolId);
|
|
16887
|
+
const { mutateAsync: executeTool, isPending: isExecuting, data: result } = useExecuteTool();
|
|
16888
|
+
const { runtimeContext: playgroundRuntimeContext } = usePlaygroundStore();
|
|
16889
|
+
const handleExecuteTool = async (data) => {
|
|
16890
|
+
if (!tool) return;
|
|
16891
|
+
return executeTool({
|
|
16892
|
+
toolId: tool.id,
|
|
16893
|
+
input: data,
|
|
16894
|
+
runtimeContext: playgroundRuntimeContext
|
|
16895
|
+
});
|
|
16896
|
+
};
|
|
16897
|
+
const zodInputSchema = tool?.inputSchema ? resolveSerializedZodOutput(jsonSchemaToZod(superjson.parse(tool?.inputSchema))) : z.z.object({});
|
|
16898
|
+
if (isLoading) return null;
|
|
16899
|
+
if (!tool)
|
|
16900
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-12 text-center px-6", children: /* @__PURE__ */ jsxRuntime.jsx(Txt, { variant: "header-md", className: "text-icon3", children: "Tool not found" }) });
|
|
16901
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
16902
|
+
ToolExecutor,
|
|
16903
|
+
{
|
|
16904
|
+
executionResult: result,
|
|
16905
|
+
isExecutingTool: isExecuting,
|
|
16906
|
+
zodInputSchema,
|
|
16907
|
+
handleExecuteTool,
|
|
16908
|
+
toolDescription: tool.description,
|
|
16909
|
+
toolId: tool.id
|
|
16910
|
+
}
|
|
16911
|
+
);
|
|
16912
|
+
};
|
|
16913
|
+
|
|
16914
|
+
function TemplatesTools({
|
|
16915
|
+
tagOptions,
|
|
16916
|
+
selectedTag,
|
|
16917
|
+
providerOptions,
|
|
16918
|
+
selectedProvider,
|
|
16919
|
+
onTagChange,
|
|
16920
|
+
onProviderChange,
|
|
16921
|
+
searchTerm,
|
|
16922
|
+
onSearchChange,
|
|
16923
|
+
onReset,
|
|
16924
|
+
className,
|
|
16925
|
+
isLoading
|
|
16926
|
+
}) {
|
|
16927
|
+
if (isLoading) {
|
|
16928
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
16929
|
+
"div",
|
|
16930
|
+
{
|
|
16931
|
+
className: cn(
|
|
16932
|
+
"h-[6.5rem] flex items-center gap-[2rem]",
|
|
16933
|
+
"[&>div]:bg-surface3 [&>div]:w-[12rem] [&>div]:h-[2rem] [&>div]:animate-pulse",
|
|
16934
|
+
className
|
|
16935
|
+
),
|
|
16936
|
+
children: [
|
|
16937
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", {}),
|
|
16938
|
+
" ",
|
|
16939
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", {}),
|
|
16940
|
+
" ",
|
|
16941
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", {})
|
|
16942
|
+
]
|
|
16943
|
+
}
|
|
16944
|
+
);
|
|
16945
|
+
}
|
|
16946
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-wrap mx-auto sticky top-0 gap-[2rem] bg-surface2 py-[2rem]", className), children: [
|
|
16947
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
16948
|
+
SearchField,
|
|
16949
|
+
{
|
|
16950
|
+
label: "Search templates",
|
|
16951
|
+
value: searchTerm,
|
|
16952
|
+
onChange: (e) => onSearchChange?.(e.target.value),
|
|
16953
|
+
placeholder: "Search Template"
|
|
16954
|
+
}
|
|
16955
|
+
),
|
|
16956
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Filter by tag", value: selectedTag, onValueChange: onTagChange, options: tagOptions }),
|
|
16957
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
16958
|
+
SelectField,
|
|
16959
|
+
{
|
|
16960
|
+
label: "Filter by provider",
|
|
16961
|
+
value: selectedProvider,
|
|
16962
|
+
onValueChange: onProviderChange,
|
|
16963
|
+
options: providerOptions
|
|
16964
|
+
}
|
|
16965
|
+
),
|
|
16966
|
+
onReset && /* @__PURE__ */ jsxRuntime.jsxs(Button, { onClick: onReset, children: [
|
|
16967
|
+
"Reset ",
|
|
16968
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.XIcon, {})
|
|
16969
|
+
] })
|
|
16970
|
+
] });
|
|
16971
|
+
}
|
|
16972
|
+
|
|
16973
|
+
function getRepoName(githubUrl) {
|
|
16974
|
+
return githubUrl.replace(/\/$/, "").split("/").pop();
|
|
16975
|
+
}
|
|
16976
|
+
function Container({ children, className }) {
|
|
16977
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
16978
|
+
"div",
|
|
16979
|
+
{
|
|
16980
|
+
className: cn(
|
|
16981
|
+
"border border-border1 rounded-lg mt-[3rem] py-[2rem] lg:min-h-[25rem] transition-height px-[1rem] lg:px-[3rem]",
|
|
16982
|
+
className
|
|
16983
|
+
),
|
|
16984
|
+
children
|
|
16985
|
+
}
|
|
16986
|
+
);
|
|
16987
|
+
}
|
|
16988
|
+
|
|
16989
|
+
function TemplatesList({ templates, linkComponent, className, isLoading }) {
|
|
16990
|
+
const LinkComponent = linkComponent || "a";
|
|
16991
|
+
if (isLoading) {
|
|
16992
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("grid gap-y-[1rem]", className), children: Array.from({ length: 5 }).map((_, index) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-[4rem] bg-surface3 animate-pulse rounded-lg" }, index)) });
|
|
16993
|
+
}
|
|
16994
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("grid gap-y-[1rem]", className), children: templates.map((template) => {
|
|
16995
|
+
const hasMetaInfo = template?.agents || template?.tools || template?.networks || template?.workflows || template?.mcp;
|
|
16996
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
16997
|
+
"article",
|
|
16998
|
+
{
|
|
16999
|
+
className: cn(
|
|
17000
|
+
"border border-border1 rounded-lg overflow-hidden w-full grid grid-cols-[1fr_auto] bg-surface3 transition-colors hover:bg-surface4"
|
|
17001
|
+
),
|
|
17002
|
+
children: [
|
|
17003
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
17004
|
+
LinkComponent,
|
|
17005
|
+
{
|
|
17006
|
+
to: `/templates/${template.slug}`,
|
|
17007
|
+
className: cn("grid [&:hover_p]:text-icon5", {
|
|
17008
|
+
"grid-cols-[8rem_1fr] lg:grid-cols-[12rem_1fr]": template.imageURL
|
|
17009
|
+
}),
|
|
17010
|
+
children: [
|
|
17011
|
+
template.imageURL && /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("overflow-hidden"), children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
17012
|
+
"div",
|
|
17013
|
+
{
|
|
17014
|
+
className: "w-full h-full bg-cover thumb transition-scale duration-150",
|
|
17015
|
+
style: {
|
|
17016
|
+
backgroundImage: `url(${template.imageURL})`
|
|
17017
|
+
}
|
|
17018
|
+
}
|
|
17019
|
+
) }),
|
|
17020
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
17021
|
+
"div",
|
|
17022
|
+
{
|
|
17023
|
+
className: cn(
|
|
17024
|
+
"grid py-[.75rem] px-[1.5rem] w-full gap-[0.1rem]",
|
|
17025
|
+
"[&_svg]:w-[1em] [&_svg]:h-[1em] [&_svg]:text-icon3"
|
|
17026
|
+
),
|
|
17027
|
+
children: [
|
|
17028
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-[1rem] text-icon5", children: template.title }),
|
|
17029
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[0.875rem] text-icon4 transition-colors duration-500", children: template.description }),
|
|
17030
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "hidden 2xl:flex text-icon3 text-[0.875rem] flex-wrap items-center gap-[1rem] mt-[0.75rem]", children: [
|
|
17031
|
+
hasMetaInfo && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
17032
|
+
"ul",
|
|
17033
|
+
{
|
|
17034
|
+
className: cn(
|
|
17035
|
+
"flex gap-[1rem] text-[0.875rem] text-icon3 m-0 p-0 list-none",
|
|
17036
|
+
"[&>li]:flex [&>li]:items-center [&>li]:gap-[0.1rem] text-icon4"
|
|
17037
|
+
),
|
|
17038
|
+
children: [
|
|
17039
|
+
template?.agents && template.agents.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
|
|
17040
|
+
/* @__PURE__ */ jsxRuntime.jsx(AgentIcon, {}),
|
|
17041
|
+
" ",
|
|
17042
|
+
template.agents.length
|
|
17043
|
+
] }),
|
|
17044
|
+
template?.tools && template.tools.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
|
|
17045
|
+
/* @__PURE__ */ jsxRuntime.jsx(ToolsIcon, {}),
|
|
17046
|
+
" ",
|
|
17047
|
+
template.tools.length
|
|
17048
|
+
] }),
|
|
17049
|
+
template?.networks && template.networks.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
|
|
17050
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.NetworkIcon, {}),
|
|
17051
|
+
" ",
|
|
17052
|
+
template.networks.length
|
|
17053
|
+
] }),
|
|
17054
|
+
template?.workflows && template.workflows.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
|
|
17055
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.WorkflowIcon, {}),
|
|
17056
|
+
" ",
|
|
17057
|
+
template.workflows.length
|
|
17058
|
+
] }),
|
|
17059
|
+
template?.mcp && template.mcp.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
|
|
17060
|
+
/* @__PURE__ */ jsxRuntime.jsx(McpServerIcon, {}),
|
|
17061
|
+
" ",
|
|
17062
|
+
template.mcp.length
|
|
17063
|
+
] })
|
|
17064
|
+
]
|
|
17065
|
+
}
|
|
17066
|
+
),
|
|
17067
|
+
hasMetaInfo && template.supportedProviders && /* @__PURE__ */ jsxRuntime.jsx("small", { children: "|" }),
|
|
17068
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center text-icon3 gap-[1rem]", children: template.supportedProviders.map((provider) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "", children: provider }, provider)) })
|
|
17069
|
+
] })
|
|
17070
|
+
]
|
|
17071
|
+
}
|
|
17072
|
+
)
|
|
17073
|
+
]
|
|
17074
|
+
}
|
|
17075
|
+
),
|
|
17076
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
17077
|
+
"a",
|
|
17078
|
+
{
|
|
17079
|
+
href: template.githubUrl,
|
|
17080
|
+
className: cn("group items-center gap-[0.5rem] text-[0.875rem] ml-auto pr-[1rem] hidden", "lg:flex"),
|
|
17081
|
+
target: "_blank",
|
|
15563
17082
|
rel: "noopener noreferrer",
|
|
15564
17083
|
children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-[0.5rem] px-[0.5rem] py-[0.25rem] rounded bg-surface1 group-hover:bg-surface2 text-icon3 transition-colors group-hover:text-icon5 ", children: [
|
|
15565
17084
|
/* @__PURE__ */ jsxRuntime.jsx(GithubIcon, {}),
|
|
@@ -18326,434 +19845,71 @@ function usePolling({
|
|
|
18326
19845
|
onSuccess?.(result);
|
|
18327
19846
|
if (shouldContinue(result) && refetch2) {
|
|
18328
19847
|
timeoutRef.current = setTimeout(executePoll, interval);
|
|
18329
|
-
} else {
|
|
18330
|
-
stopPolling();
|
|
18331
|
-
}
|
|
18332
|
-
} catch (err) {
|
|
18333
|
-
if (!mountedRef.current) return;
|
|
18334
|
-
setError(err);
|
|
18335
|
-
onError?.(err);
|
|
18336
|
-
stopPolling();
|
|
18337
|
-
} finally {
|
|
18338
|
-
if (mountedRef.current) {
|
|
18339
|
-
setFirstCallLoading(false);
|
|
18340
|
-
setIsLoading(false);
|
|
18341
|
-
}
|
|
18342
|
-
}
|
|
18343
|
-
},
|
|
18344
|
-
[fetchFn, interval, onSuccess, onError, shouldContinue, stopPolling]
|
|
18345
|
-
);
|
|
18346
|
-
const refetch = React.useCallback(
|
|
18347
|
-
(withPolling = false) => {
|
|
18348
|
-
console.log("refetch", { withPolling });
|
|
18349
|
-
if (withPolling) {
|
|
18350
|
-
setIsPolling(true);
|
|
18351
|
-
} else {
|
|
18352
|
-
executePoll(false);
|
|
18353
|
-
}
|
|
18354
|
-
setError(null);
|
|
18355
|
-
},
|
|
18356
|
-
[executePoll]
|
|
18357
|
-
);
|
|
18358
|
-
React.useEffect(() => {
|
|
18359
|
-
mountedRef.current = true;
|
|
18360
|
-
if (enabled && isPolling) {
|
|
18361
|
-
executePoll(true);
|
|
18362
|
-
}
|
|
18363
|
-
return () => {
|
|
18364
|
-
console.log("cleanup poll");
|
|
18365
|
-
mountedRef.current = false;
|
|
18366
|
-
cleanup();
|
|
18367
|
-
};
|
|
18368
|
-
}, [enabled, isPolling, executePoll, cleanup]);
|
|
18369
|
-
React.useEffect(() => {
|
|
18370
|
-
setRestart(restartPolling);
|
|
18371
|
-
}, [restartPolling]);
|
|
18372
|
-
React.useEffect(() => {
|
|
18373
|
-
if (restart && !isPolling) {
|
|
18374
|
-
setIsPolling(true);
|
|
18375
|
-
executePoll();
|
|
18376
|
-
setRestart(false);
|
|
18377
|
-
}
|
|
18378
|
-
}, [restart]);
|
|
18379
|
-
return {
|
|
18380
|
-
isPolling,
|
|
18381
|
-
isLoading,
|
|
18382
|
-
error,
|
|
18383
|
-
data,
|
|
18384
|
-
startPolling,
|
|
18385
|
-
stopPolling,
|
|
18386
|
-
firstCallLoading,
|
|
18387
|
-
refetch
|
|
18388
|
-
};
|
|
18389
|
-
}
|
|
18390
|
-
|
|
18391
|
-
const PlaygroundQueryClient = ({ children }) => {
|
|
18392
|
-
const queryClient = new reactQuery.QueryClient();
|
|
18393
|
-
return /* @__PURE__ */ jsxRuntime.jsx(reactQuery.QueryClientProvider, { client: queryClient, children });
|
|
18394
|
-
};
|
|
18395
|
-
|
|
18396
|
-
const useMemory = (agentId) => {
|
|
18397
|
-
const client = react$3.useMastraClient();
|
|
18398
|
-
return reactQuery.useQuery({
|
|
18399
|
-
queryKey: ["memory", agentId],
|
|
18400
|
-
queryFn: () => agentId ? client.getMemoryStatus(agentId) : null,
|
|
18401
|
-
enabled: Boolean(agentId),
|
|
18402
|
-
staleTime: 5 * 60 * 1e3,
|
|
18403
|
-
// 5 minutes
|
|
18404
|
-
gcTime: 10 * 60 * 1e3,
|
|
18405
|
-
// 10 minutes
|
|
18406
|
-
retry: false
|
|
18407
|
-
});
|
|
18408
|
-
};
|
|
18409
|
-
const useMemoryConfig = (agentId) => {
|
|
18410
|
-
const client = react$3.useMastraClient();
|
|
18411
|
-
return reactQuery.useQuery({
|
|
18412
|
-
queryKey: ["memory", "config", agentId],
|
|
18413
|
-
queryFn: () => agentId ? client.getMemoryConfig({ agentId }) : null,
|
|
18414
|
-
enabled: Boolean(agentId),
|
|
18415
|
-
staleTime: 5 * 60 * 1e3,
|
|
18416
|
-
// 5 minutes
|
|
18417
|
-
gcTime: 10 * 60 * 1e3,
|
|
18418
|
-
// 10 minutes
|
|
18419
|
-
retry: false,
|
|
18420
|
-
refetchOnWindowFocus: false
|
|
18421
|
-
});
|
|
18422
|
-
};
|
|
18423
|
-
const useThreads = ({
|
|
18424
|
-
resourceId,
|
|
18425
|
-
agentId,
|
|
18426
|
-
isMemoryEnabled
|
|
18427
|
-
}) => {
|
|
18428
|
-
const client = react$3.useMastraClient();
|
|
18429
|
-
return reactQuery.useQuery({
|
|
18430
|
-
queryKey: ["memory", "threads", resourceId, agentId],
|
|
18431
|
-
queryFn: () => isMemoryEnabled ? client.getMemoryThreads({ resourceId, agentId }) : null,
|
|
18432
|
-
enabled: Boolean(isMemoryEnabled),
|
|
18433
|
-
staleTime: 0,
|
|
18434
|
-
gcTime: 0,
|
|
18435
|
-
retry: false,
|
|
18436
|
-
refetchOnWindowFocus: false
|
|
18437
|
-
});
|
|
18438
|
-
};
|
|
18439
|
-
const useDeleteThread = () => {
|
|
18440
|
-
const client = react$3.useMastraClient();
|
|
18441
|
-
const queryClient = reactQuery.useQueryClient();
|
|
18442
|
-
return reactQuery.useMutation({
|
|
18443
|
-
mutationFn: ({ threadId, agentId, networkId }) => client.deleteThread(threadId, { agentId, networkId }),
|
|
18444
|
-
onSuccess: (_, variables) => {
|
|
18445
|
-
const { agentId, networkId } = variables;
|
|
18446
|
-
if (agentId) {
|
|
18447
|
-
queryClient.invalidateQueries({ queryKey: ["memory", "threads", agentId, agentId] });
|
|
18448
|
-
}
|
|
18449
|
-
if (networkId) {
|
|
18450
|
-
queryClient.invalidateQueries({ queryKey: ["network", "threads", networkId, networkId] });
|
|
18451
|
-
}
|
|
18452
|
-
sonner.toast.success("Chat deleted successfully");
|
|
18453
|
-
},
|
|
18454
|
-
onError: () => {
|
|
18455
|
-
sonner.toast.error("Failed to delete chat");
|
|
18456
|
-
}
|
|
18457
|
-
});
|
|
18458
|
-
};
|
|
18459
|
-
const useMemorySearch = ({
|
|
18460
|
-
agentId,
|
|
18461
|
-
resourceId,
|
|
18462
|
-
threadId
|
|
18463
|
-
}) => {
|
|
18464
|
-
const searchMemory = async (searchQuery, memoryConfig) => {
|
|
18465
|
-
if (!searchQuery.trim()) {
|
|
18466
|
-
return { results: [], count: 0, query: searchQuery };
|
|
18467
|
-
}
|
|
18468
|
-
const params = new URLSearchParams({
|
|
18469
|
-
searchQuery,
|
|
18470
|
-
resourceId,
|
|
18471
|
-
agentId
|
|
18472
|
-
});
|
|
18473
|
-
if (threadId) {
|
|
18474
|
-
params.append("threadId", threadId);
|
|
18475
|
-
}
|
|
18476
|
-
if (memoryConfig) {
|
|
18477
|
-
params.append("memoryConfig", JSON.stringify(memoryConfig));
|
|
18478
|
-
}
|
|
18479
|
-
const response = await fetch(`/api/memory/search?${params}`, {
|
|
18480
|
-
method: "GET",
|
|
18481
|
-
headers: {
|
|
18482
|
-
"Content-Type": "application/json",
|
|
18483
|
-
"x-mastra-dev-playground": "true"
|
|
18484
|
-
}
|
|
18485
|
-
});
|
|
18486
|
-
if (!response.ok) {
|
|
18487
|
-
const errorData = await response.json().catch(() => ({ message: "Unknown error" }));
|
|
18488
|
-
console.error("Search memory error:", errorData);
|
|
18489
|
-
throw new Error(errorData.message || errorData.error || "Failed to search memory");
|
|
18490
|
-
}
|
|
18491
|
-
return response.json();
|
|
18492
|
-
};
|
|
18493
|
-
return { searchMemory };
|
|
18494
|
-
};
|
|
18495
|
-
|
|
18496
|
-
const formatRelativeTime = (date) => {
|
|
18497
|
-
const now = /* @__PURE__ */ new Date();
|
|
18498
|
-
const seconds = Math.floor((now.getTime() - date.getTime()) / 1e3);
|
|
18499
|
-
if (seconds < 60) return "just now";
|
|
18500
|
-
if (seconds < 3600) return `${Math.floor(seconds / 60)}m ago`;
|
|
18501
|
-
if (seconds < 86400) return `${Math.floor(seconds / 3600)}h ago`;
|
|
18502
|
-
if (seconds < 604800) return `${Math.floor(seconds / 86400)}d ago`;
|
|
18503
|
-
return date.toLocaleDateString();
|
|
18504
|
-
};
|
|
18505
|
-
const MemorySearch = ({
|
|
18506
|
-
searchMemory,
|
|
18507
|
-
onResultClick,
|
|
18508
|
-
className,
|
|
18509
|
-
currentThreadId,
|
|
18510
|
-
chatInputValue
|
|
18511
|
-
}) => {
|
|
18512
|
-
const [query, setQuery] = React.useState("");
|
|
18513
|
-
const [results, setResults] = React.useState([]);
|
|
18514
|
-
const [isSearching, setIsSearching] = React.useState(false);
|
|
18515
|
-
const [isOpen, setIsOpen] = React.useState(false);
|
|
18516
|
-
const [error, setError] = React.useState(null);
|
|
18517
|
-
const searchTimeoutRef = React.useRef(void 0);
|
|
18518
|
-
const dropdownRef = React.useRef(null);
|
|
18519
|
-
const prevThreadIdRef = React.useRef(currentThreadId);
|
|
18520
|
-
const lastSearchTimeRef = React.useRef(0);
|
|
18521
|
-
const pendingSearchRef = React.useRef(null);
|
|
18522
|
-
const handleSearch = React.useCallback(
|
|
18523
|
-
async (searchQuery) => {
|
|
18524
|
-
if (!searchQuery.trim()) {
|
|
18525
|
-
setError(null);
|
|
18526
|
-
return;
|
|
18527
|
-
}
|
|
18528
|
-
setIsSearching(true);
|
|
18529
|
-
setError(null);
|
|
18530
|
-
try {
|
|
18531
|
-
const response = await searchMemory(searchQuery);
|
|
18532
|
-
setResults(response.results);
|
|
18533
|
-
setIsOpen((prev) => prev || response.results.length > 0);
|
|
19848
|
+
} else {
|
|
19849
|
+
stopPolling();
|
|
19850
|
+
}
|
|
18534
19851
|
} catch (err) {
|
|
18535
|
-
|
|
18536
|
-
|
|
19852
|
+
if (!mountedRef.current) return;
|
|
19853
|
+
setError(err);
|
|
19854
|
+
onError?.(err);
|
|
19855
|
+
stopPolling();
|
|
18537
19856
|
} finally {
|
|
18538
|
-
|
|
18539
|
-
|
|
18540
|
-
|
|
18541
|
-
[searchMemory]
|
|
18542
|
-
);
|
|
18543
|
-
const handleInputChange = React.useCallback(
|
|
18544
|
-
(e) => {
|
|
18545
|
-
const value = e.target.value;
|
|
18546
|
-
setQuery(value);
|
|
18547
|
-
if (searchTimeoutRef.current) {
|
|
18548
|
-
clearTimeout(searchTimeoutRef.current);
|
|
18549
|
-
}
|
|
18550
|
-
if (value.trim()) {
|
|
18551
|
-
const now = Date.now();
|
|
18552
|
-
const timeSinceLastSearch = now - lastSearchTimeRef.current;
|
|
18553
|
-
if (timeSinceLastSearch >= 500) {
|
|
18554
|
-
setIsSearching(true);
|
|
18555
|
-
handleSearch(value);
|
|
18556
|
-
lastSearchTimeRef.current = now;
|
|
18557
|
-
} else {
|
|
18558
|
-
setIsSearching(true);
|
|
18559
|
-
pendingSearchRef.current = value;
|
|
18560
|
-
const remainingTime = 500 - timeSinceLastSearch;
|
|
18561
|
-
searchTimeoutRef.current = setTimeout(() => {
|
|
18562
|
-
if (pendingSearchRef.current) {
|
|
18563
|
-
handleSearch(pendingSearchRef.current);
|
|
18564
|
-
lastSearchTimeRef.current = Date.now();
|
|
18565
|
-
pendingSearchRef.current = null;
|
|
18566
|
-
}
|
|
18567
|
-
}, remainingTime);
|
|
19857
|
+
if (mountedRef.current) {
|
|
19858
|
+
setFirstCallLoading(false);
|
|
19859
|
+
setIsLoading(false);
|
|
18568
19860
|
}
|
|
18569
|
-
} else {
|
|
18570
|
-
setResults([]);
|
|
18571
|
-
setIsOpen(false);
|
|
18572
|
-
setIsSearching(false);
|
|
18573
|
-
pendingSearchRef.current = null;
|
|
18574
19861
|
}
|
|
18575
19862
|
},
|
|
18576
|
-
[
|
|
19863
|
+
[fetchFn, interval, onSuccess, onError, shouldContinue, stopPolling]
|
|
18577
19864
|
);
|
|
18578
|
-
const
|
|
18579
|
-
(
|
|
18580
|
-
|
|
18581
|
-
|
|
18582
|
-
|
|
18583
|
-
|
|
18584
|
-
|
|
18585
|
-
handleSearch(query);
|
|
19865
|
+
const refetch = React.useCallback(
|
|
19866
|
+
(withPolling = false) => {
|
|
19867
|
+
console.log("refetch", { withPolling });
|
|
19868
|
+
if (withPolling) {
|
|
19869
|
+
setIsPolling(true);
|
|
19870
|
+
} else {
|
|
19871
|
+
executePoll(false);
|
|
18586
19872
|
}
|
|
19873
|
+
setError(null);
|
|
18587
19874
|
},
|
|
18588
|
-
[
|
|
19875
|
+
[executePoll]
|
|
18589
19876
|
);
|
|
18590
19877
|
React.useEffect(() => {
|
|
19878
|
+
mountedRef.current = true;
|
|
19879
|
+
if (enabled && isPolling) {
|
|
19880
|
+
executePoll(true);
|
|
19881
|
+
}
|
|
18591
19882
|
return () => {
|
|
18592
|
-
|
|
18593
|
-
|
|
18594
|
-
|
|
18595
|
-
};
|
|
18596
|
-
}, []);
|
|
18597
|
-
React.useEffect(() => {
|
|
18598
|
-
const handleClickOutside = (event) => {
|
|
18599
|
-
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
|
|
18600
|
-
setIsOpen(false);
|
|
18601
|
-
}
|
|
19883
|
+
console.log("cleanup poll");
|
|
19884
|
+
mountedRef.current = false;
|
|
19885
|
+
cleanup();
|
|
18602
19886
|
};
|
|
18603
|
-
|
|
18604
|
-
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
18605
|
-
}, []);
|
|
19887
|
+
}, [enabled, isPolling, executePoll, cleanup]);
|
|
18606
19888
|
React.useEffect(() => {
|
|
18607
|
-
|
|
18608
|
-
|
|
18609
|
-
}
|
|
18610
|
-
prevThreadIdRef.current = currentThreadId;
|
|
18611
|
-
}, [currentThreadId, query, handleSearch]);
|
|
19889
|
+
setRestart(restartPolling);
|
|
19890
|
+
}, [restartPolling]);
|
|
18612
19891
|
React.useEffect(() => {
|
|
18613
|
-
if (
|
|
18614
|
-
|
|
18615
|
-
|
|
18616
|
-
|
|
18617
|
-
}
|
|
18618
|
-
if (chatInputValue.trim()) {
|
|
18619
|
-
const now = Date.now();
|
|
18620
|
-
const timeSinceLastSearch = now - lastSearchTimeRef.current;
|
|
18621
|
-
if (timeSinceLastSearch >= 500) {
|
|
18622
|
-
setIsSearching(true);
|
|
18623
|
-
handleSearch(chatInputValue);
|
|
18624
|
-
lastSearchTimeRef.current = now;
|
|
18625
|
-
} else {
|
|
18626
|
-
setIsSearching(true);
|
|
18627
|
-
pendingSearchRef.current = chatInputValue;
|
|
18628
|
-
const remainingTime = 500 - timeSinceLastSearch;
|
|
18629
|
-
searchTimeoutRef.current = setTimeout(() => {
|
|
18630
|
-
if (pendingSearchRef.current) {
|
|
18631
|
-
handleSearch(pendingSearchRef.current);
|
|
18632
|
-
lastSearchTimeRef.current = Date.now();
|
|
18633
|
-
pendingSearchRef.current = null;
|
|
18634
|
-
}
|
|
18635
|
-
}, remainingTime);
|
|
18636
|
-
}
|
|
18637
|
-
} else {
|
|
18638
|
-
setResults([]);
|
|
18639
|
-
setIsOpen(false);
|
|
18640
|
-
setIsSearching(false);
|
|
18641
|
-
pendingSearchRef.current = null;
|
|
18642
|
-
}
|
|
18643
|
-
}
|
|
18644
|
-
return () => {
|
|
18645
|
-
if (searchTimeoutRef.current) {
|
|
18646
|
-
clearTimeout(searchTimeoutRef.current);
|
|
18647
|
-
}
|
|
18648
|
-
};
|
|
18649
|
-
}, [chatInputValue]);
|
|
18650
|
-
const handleResultClick = (messageId, threadId) => {
|
|
18651
|
-
onResultClick?.(messageId, threadId);
|
|
18652
|
-
};
|
|
18653
|
-
const clearSearch = () => {
|
|
18654
|
-
setQuery("");
|
|
18655
|
-
setResults([]);
|
|
18656
|
-
setIsOpen(false);
|
|
18657
|
-
setError(null);
|
|
18658
|
-
if (searchTimeoutRef.current) {
|
|
18659
|
-
clearTimeout(searchTimeoutRef.current);
|
|
19892
|
+
if (restart && !isPolling) {
|
|
19893
|
+
setIsPolling(true);
|
|
19894
|
+
executePoll();
|
|
19895
|
+
setRestart(false);
|
|
18660
19896
|
}
|
|
19897
|
+
}, [restart]);
|
|
19898
|
+
return {
|
|
19899
|
+
isPolling,
|
|
19900
|
+
isLoading,
|
|
19901
|
+
error,
|
|
19902
|
+
data,
|
|
19903
|
+
startPolling,
|
|
19904
|
+
stopPolling,
|
|
19905
|
+
firstCallLoading,
|
|
19906
|
+
refetch
|
|
18661
19907
|
};
|
|
18662
|
-
|
|
18663
|
-
|
|
18664
|
-
|
|
18665
|
-
|
|
18666
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
18667
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative shrink-0", children: [
|
|
18668
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-icon3" }),
|
|
18669
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
18670
|
-
Input,
|
|
18671
|
-
{
|
|
18672
|
-
type: "text",
|
|
18673
|
-
value: query,
|
|
18674
|
-
onChange: handleInputChange,
|
|
18675
|
-
onKeyDown: handleKeyDown,
|
|
18676
|
-
placeholder: "Search memory...",
|
|
18677
|
-
className: "pl-10 pr-10 bg-surface3 border-border1"
|
|
18678
|
-
}
|
|
18679
|
-
),
|
|
18680
|
-
query && /* @__PURE__ */ jsxRuntime.jsx(
|
|
18681
|
-
Button$2,
|
|
18682
|
-
{
|
|
18683
|
-
onClick: clearSearch,
|
|
18684
|
-
variant: "ghost",
|
|
18685
|
-
size: "sm",
|
|
18686
|
-
className: "absolute right-1 top-1/2 transform -translate-y-1/2 h-6 w-6 p-0",
|
|
18687
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-4 w-4" })
|
|
18688
|
-
}
|
|
18689
|
-
)
|
|
18690
|
-
] }),
|
|
18691
|
-
(isOpen || query && (isSearching || results.length === 0)) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2 flex-1 bg-surface3 border border-border1 rounded-lg shadow-lg overflow-y-auto", children: error ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(Txt, { variant: "ui-sm", className: "text-red-500", children: error }) }) : isSearching && results.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(Txt, { variant: "ui-sm", className: "text-icon3", children: "Searching..." }) }) : results.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 text-center", children: /* @__PURE__ */ jsxRuntime.jsxs(Txt, { variant: "ui-sm", className: "text-icon3", children: [
|
|
18692
|
-
'No results found for "',
|
|
18693
|
-
query,
|
|
18694
|
-
'"'
|
|
18695
|
-
] }) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-2", children: results.map((result) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
18696
|
-
"button",
|
|
18697
|
-
{
|
|
18698
|
-
onClick: () => handleResultClick(result.id, result.threadId),
|
|
18699
|
-
className: cn(
|
|
18700
|
-
"w-full px-4 py-3 hover:bg-surface4 transition-colors duration-150 text-left border-b border-border1 last:border-b-0",
|
|
18701
|
-
result.threadId !== currentThreadId && "border-l-2 border-l-blue-400"
|
|
18702
|
-
),
|
|
18703
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
18704
|
-
result.context?.before && result.context.before.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "opacity-50 text-xs space-y-1", children: result.context.before.map((msg, idx) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-2", children: [
|
|
18705
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-medium", children: [
|
|
18706
|
-
msg.role,
|
|
18707
|
-
":"
|
|
18708
|
-
] }),
|
|
18709
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-icon3", children: truncateContent(msg.content, 50) })
|
|
18710
|
-
] }, idx)) }),
|
|
18711
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-start justify-between gap-2", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
18712
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mb-1", children: [
|
|
18713
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
18714
|
-
"span",
|
|
18715
|
-
{
|
|
18716
|
-
className: cn(
|
|
18717
|
-
"text-xs font-medium px-2 py-0.5 rounded",
|
|
18718
|
-
result.role === "user" ? "bg-blue-500/20 text-blue-400" : "bg-green-500/20 text-green-400"
|
|
18719
|
-
),
|
|
18720
|
-
children: result.role
|
|
18721
|
-
}
|
|
18722
|
-
),
|
|
18723
|
-
/* @__PURE__ */ jsxRuntime.jsx(Txt, { variant: "ui-xs", className: "text-icon3", children: formatRelativeTime(new Date(result.createdAt)) }),
|
|
18724
|
-
result.threadTitle && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
18725
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
18726
|
-
Txt,
|
|
18727
|
-
{
|
|
18728
|
-
variant: "ui-xs",
|
|
18729
|
-
className: cn(
|
|
18730
|
-
"truncate max-w-[150px]",
|
|
18731
|
-
result.threadId !== currentThreadId ? "text-blue-400 font-medium" : "text-icon3"
|
|
18732
|
-
),
|
|
18733
|
-
title: result.threadTitle,
|
|
18734
|
-
children: [
|
|
18735
|
-
"• ",
|
|
18736
|
-
result.threadTitle
|
|
18737
|
-
]
|
|
18738
|
-
}
|
|
18739
|
-
),
|
|
18740
|
-
result.threadId !== currentThreadId && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "w-3 h-3 text-blue-400" })
|
|
18741
|
-
] })
|
|
18742
|
-
] }),
|
|
18743
|
-
/* @__PURE__ */ jsxRuntime.jsx(Txt, { variant: "ui-sm", className: "text-icon5 break-words", children: truncateContent(result.content) })
|
|
18744
|
-
] }) }),
|
|
18745
|
-
result.context?.after && result.context.after.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "opacity-50 text-xs space-y-1", children: result.context.after.map((msg, idx) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-2", children: [
|
|
18746
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-medium", children: [
|
|
18747
|
-
msg.role,
|
|
18748
|
-
":"
|
|
18749
|
-
] }),
|
|
18750
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-icon3", children: truncateContent(msg.content, 50) })
|
|
18751
|
-
] }, idx)) })
|
|
18752
|
-
] })
|
|
18753
|
-
},
|
|
18754
|
-
result.id
|
|
18755
|
-
)) }) })
|
|
18756
|
-
] });
|
|
19908
|
+
}
|
|
19909
|
+
|
|
19910
|
+
const PlaygroundQueryClient = ({ children }) => {
|
|
19911
|
+
const queryClient = new reactQuery.QueryClient();
|
|
19912
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactQuery.QueryClientProvider, { client: queryClient, children });
|
|
18757
19913
|
};
|
|
18758
19914
|
|
|
18759
19915
|
const errorFallback = "Something went wrong while fetching the data.";
|
|
@@ -19188,6 +20344,7 @@ exports.AgentCoinIcon = AgentCoinIcon;
|
|
|
19188
20344
|
exports.AgentEntityHeader = AgentEntityHeader;
|
|
19189
20345
|
exports.AgentEvals = AgentEvals;
|
|
19190
20346
|
exports.AgentIcon = AgentIcon;
|
|
20347
|
+
exports.AgentInformation = AgentInformation;
|
|
19191
20348
|
exports.AgentMetadata = AgentMetadata;
|
|
19192
20349
|
exports.AgentMetadataList = AgentMetadataList;
|
|
19193
20350
|
exports.AgentMetadataListEmpty = AgentMetadataListEmpty;
|