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