@mastra/playground-ui 5.1.14-alpha.1 → 5.1.14-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. package/dist/index.cjs.js +843 -104
  2. package/dist/index.cjs.js.map +1 -1
  3. package/dist/index.es.js +823 -106
  4. package/dist/index.es.js.map +1 -1
  5. package/dist/src/components/assistant-ui/memory-search.d.ts +11 -0
  6. package/dist/src/components/assistant-ui/thread.d.ts +2 -1
  7. package/dist/src/components/ui/alert-dialog.d.ts +26 -0
  8. package/dist/src/components/ui/playground-tabs.d.ts +3 -1
  9. package/dist/src/domains/agents/components/agent-chat.d.ts +1 -1
  10. package/dist/src/domains/agents/components/agent-entity-header.d.ts +6 -0
  11. package/dist/src/domains/agents/components/agent-metadata/agent-metadata-list.d.ts +12 -0
  12. package/dist/src/domains/agents/components/agent-metadata/agent-metadata-prompt.d.ts +4 -0
  13. package/dist/src/domains/agents/components/agent-metadata/agent-metadata-section.d.ts +9 -0
  14. package/dist/src/domains/agents/components/agent-metadata/agent-metadata-wrapper.d.ts +4 -0
  15. package/dist/src/domains/agents/components/agent-metadata/agent-metadata.d.ts +24 -0
  16. package/dist/src/domains/agents/components/agent-metadata/index.d.ts +5 -0
  17. package/dist/src/domains/agents/components/chat-threads.d.ts +11 -0
  18. package/dist/src/domains/agents/index.d.ts +3 -0
  19. package/dist/src/domains/scores/components/scorer-list.d.ts +9 -0
  20. package/dist/src/domains/scores/hooks/use-scorers.d.ts +25 -0
  21. package/dist/src/domains/scores/index.d.ts +2 -0
  22. package/dist/src/index.d.ts +3 -0
  23. package/dist/src/types/memory.d.ts +29 -0
  24. package/dist/src/types.d.ts +1 -0
  25. package/package.json +5 -5
  26. package/dist/src/main.d.ts +0 -1
package/dist/index.es.js CHANGED
@@ -3,7 +3,7 @@ import * as React from 'react';
3
3
  import React__default, { createContext, useContext, forwardRef, memo, useState, useEffect, useRef, useCallback, useMemo, Suspense, Fragment as Fragment$1, startTransition } from 'react';
4
4
  import { MastraClient } from '@mastra/client-js';
5
5
  import { useMessage, MessagePrimitive, ActionBarPrimitive, useAttachment, AttachmentPrimitive, useComposerRuntime, ComposerPrimitive, ThreadPrimitive, useExternalStoreRuntime, CompositeAttachmentAdapter, SimpleImageAttachmentAdapter, SimpleTextAttachmentAdapter, AssistantRuntimeProvider } from '@assistant-ui/react';
6
- import { CheckIcon as CheckIcon$1, CopyIcon, Check, Copy, ChevronUpIcon, BrainIcon, X, FileText, CircleXIcon, Mic, PlusIcon, ArrowUp, Search, RefreshCcwIcon, ChevronRight, SortAsc, SortDesc, Circle, ChevronDown, Braces, SaveIcon, RefreshCw, ExternalLink, LoaderCircle, ChevronDownIcon, ExternalLinkIcon, Loader2, Network, PauseIcon, HourglassIcon, CircleDashed, Footprints, CircleCheck, CircleX, Minus, Plus, Maximize, Workflow, AlertCircleIcon, Users, Brain, NetworkIcon, SearchIcon, AlertCircle, CalendarIcon, Brackets, TrashIcon, CirclePause, StopCircle, ChevronUp } from 'lucide-react';
6
+ import { CheckIcon as CheckIcon$1, CopyIcon, Check, Copy, ChevronUpIcon, BrainIcon, X, FileText, CircleXIcon, Mic, PlusIcon, ArrowUp, Search, RefreshCcwIcon, ChevronRight, SortAsc, SortDesc, Circle, ChevronDown, Braces, SaveIcon, RefreshCw, ExternalLink, InfoIcon as InfoIcon$1, GaugeIcon, Plus, LoaderCircle, ChevronDownIcon, ExternalLinkIcon, Loader2, Network, PauseIcon, HourglassIcon, CircleDashed, Footprints, CircleCheck, CircleX, Minus, Maximize, Workflow, AlertCircleIcon, Users, Brain, NetworkIcon, SearchIcon, AlertCircle, CalendarIcon, Brackets, TrashIcon, CirclePause, StopCircle, ChevronUp } from 'lucide-react';
7
7
  import { Slot } from '@radix-ui/react-slot';
8
8
  import * as TooltipPrimitive from '@radix-ui/react-tooltip';
9
9
  import { TooltipProvider as TooltipProvider$1 } from '@radix-ui/react-tooltip';
@@ -35,6 +35,7 @@ import prettierPluginBabel from 'prettier/plugins/babel';
35
35
  import prettierPluginEstree from 'prettier/plugins/estree';
36
36
  import { C as Colors } from './colors-DrbbnW3f.js';
37
37
  import { useReactTable, getCoreRowModel, flexRender } from '@tanstack/react-table';
38
+ import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog';
38
39
  import { processDataStream } from '@ai-sdk/ui-utils';
39
40
  import Markdown from 'react-markdown';
40
41
  import { MarkerType, Handle, Position, useViewport, useReactFlow, Panel, useNodesState, useEdgesState, ReactFlow, MiniMap, Background, BackgroundVariant, ReactFlowProvider, Controls } from '@xyflow/react';
@@ -4371,8 +4372,9 @@ const Reasoning = ({ text }) => {
4371
4372
 
4372
4373
  const AssistantMessage = ({ ToolFallback: ToolFallbackCustom }) => {
4373
4374
  const data = useMessage();
4375
+ const messageId = data.id;
4374
4376
  const isToolCallAndOrReasoning = data.content.every(({ type }) => type === "tool-call" || type === "reasoning");
4375
- return /* @__PURE__ */ jsxs(MessagePrimitive.Root, { className: "max-w-full", children: [
4377
+ return /* @__PURE__ */ jsxs(MessagePrimitive.Root, { className: "max-w-full", "data-message-id": messageId, children: [
4376
4378
  /* @__PURE__ */ jsx("div", { className: "text-icon6 text-ui-lg leading-ui-lg", children: /* @__PURE__ */ jsx(
4377
4379
  MessagePrimitive.Content,
4378
4380
  {
@@ -4572,7 +4574,9 @@ const UserMessageAttachments = () => {
4572
4574
  return /* @__PURE__ */ jsx(MessagePrimitive.Attachments, { components: { Attachment: InMessageContextWrapper } });
4573
4575
  };
4574
4576
  const UserMessage = () => {
4575
- return /* @__PURE__ */ jsxs(MessagePrimitive.Root, { className: "w-full flex items-end pb-4 flex-col", children: [
4577
+ const message = useMessage();
4578
+ const messageId = message?.id;
4579
+ return /* @__PURE__ */ jsxs(MessagePrimitive.Root, { className: "w-full flex items-end pb-4 flex-col", "data-message-id": messageId, children: [
4576
4580
  /* @__PURE__ */ jsx("div", { className: "max-w-[366px] px-5 py-3 text-icon6 text-ui-lg leading-ui-lg rounded-lg bg-surface3", children: /* @__PURE__ */ jsx(
4577
4581
  MessagePrimitive.Content,
4578
4582
  {
@@ -4833,7 +4837,7 @@ const ComposerAttachments = () => {
4833
4837
  return /* @__PURE__ */ jsx("div", { className: "flex w-full flex-row items-center gap-4 pb-2", children: /* @__PURE__ */ jsx(ComposerPrimitive.Attachments, { components: { Attachment: AttachmentThumbnail } }) });
4834
4838
  };
4835
4839
 
4836
- const Thread = ({ ToolFallback, agentName, hasMemory }) => {
4840
+ const Thread = ({ ToolFallback, agentName, hasMemory, onInputChange }) => {
4837
4841
  const areaRef = useRef(null);
4838
4842
  useAutoscroll(areaRef, { enabled: true });
4839
4843
  const WrappedAssistantMessage = (props) => {
@@ -4854,7 +4858,7 @@ const Thread = ({ ToolFallback, agentName, hasMemory }) => {
4854
4858
  ) }),
4855
4859
  /* @__PURE__ */ jsx(ThreadPrimitive.If, { empty: false, children: /* @__PURE__ */ jsx("div", {}) })
4856
4860
  ] }),
4857
- /* @__PURE__ */ jsx(Composer$1, { hasMemory })
4861
+ /* @__PURE__ */ jsx(Composer$1, { hasMemory, onInputChange })
4858
4862
  ] });
4859
4863
  };
4860
4864
  const ThreadWrapper$1 = ({ children }) => {
@@ -4876,7 +4880,7 @@ const ThreadWelcome$1 = ({ agentName }) => {
4876
4880
  /* @__PURE__ */ jsx("p", { className: "mt-4 font-medium", children: "How can I help you today?" })
4877
4881
  ] }) });
4878
4882
  };
4879
- const Composer$1 = ({ hasMemory }) => {
4883
+ const Composer$1 = ({ hasMemory, onInputChange }) => {
4880
4884
  return /* @__PURE__ */ jsxs("div", { className: "mx-4", children: [
4881
4885
  /* @__PURE__ */ jsxs(ComposerPrimitive.Root, { children: [
4882
4886
  /* @__PURE__ */ jsx("div", { className: "max-w-[568px] w-full mx-auto pb-2", children: /* @__PURE__ */ jsx(ComposerAttachments, {}) }),
@@ -4888,7 +4892,8 @@ const Composer$1 = ({ hasMemory }) => {
4888
4892
  autoFocus: true,
4889
4893
  placeholder: "Enter your message...",
4890
4894
  name: "",
4891
- id: ""
4895
+ id: "",
4896
+ onChange: (e) => onInputChange?.(e.target.value)
4892
4897
  }
4893
4898
  ) }),
4894
4899
  /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
@@ -5164,6 +5169,7 @@ function MastraRuntimeProvider({
5164
5169
  const [messages, setMessages] = useState([]);
5165
5170
  const [currentThreadId, setCurrentThreadId] = useState(threadId);
5166
5171
  const { refetch: refreshWorkingMemory } = useWorkingMemory();
5172
+ const abortControllerRef = useRef(null);
5167
5173
  const {
5168
5174
  frequencyPenalty,
5169
5175
  presencePenalty,
@@ -5215,8 +5221,7 @@ function MastraRuntimeProvider({
5215
5221
  }
5216
5222
  }
5217
5223
  }, [initialMessages, threadId, memory]);
5218
- const mastra = useMastraClient();
5219
- const agent = mastra.getAgent(agentId);
5224
+ const baseClient = useMastraClient();
5220
5225
  const onNew = async (message) => {
5221
5226
  if (message.content[0]?.type !== "text") throw new Error("Only text messages are supported");
5222
5227
  const attachments = await convertToAIAttachments(message.attachments);
@@ -5226,6 +5231,13 @@ function MastraRuntimeProvider({
5226
5231
  { role: "user", content: input, attachments: message.attachments }
5227
5232
  ]);
5228
5233
  setIsRunning(true);
5234
+ const controller = new AbortController();
5235
+ abortControllerRef.current = controller;
5236
+ const clientWithAbort = new MastraClient({
5237
+ ...baseClient.options,
5238
+ abortSignal: controller.signal
5239
+ });
5240
+ const agent = clientWithAbort.getAgent(agentId);
5229
5241
  try {
5230
5242
  if (chatWithGenerate) {
5231
5243
  const generateResponse = await agent.generate({
@@ -5250,7 +5262,7 @@ function MastraRuntimeProvider({
5250
5262
  ...memory ? { threadId, resourceId: agentId } : {},
5251
5263
  providerOptions
5252
5264
  });
5253
- if (generateResponse.response) {
5265
+ if (generateResponse.response && "messages" in generateResponse.response) {
5254
5266
  const latestMessage = generateResponse.response.messages.reduce(
5255
5267
  (acc, message2) => {
5256
5268
  const _content = Array.isArray(acc.content) ? acc.content : [];
@@ -5504,10 +5516,22 @@ function MastraRuntimeProvider({
5504
5516
  } catch (error) {
5505
5517
  console.error("Error occurred in MastraRuntimeProvider", error);
5506
5518
  setIsRunning(false);
5519
+ if (error.name === "AbortError") {
5520
+ return;
5521
+ }
5507
5522
  setMessages((currentConversation) => [
5508
5523
  ...currentConversation,
5509
5524
  { role: "assistant", content: [{ type: "text", text: `${error}` }] }
5510
5525
  ]);
5526
+ } finally {
5527
+ abortControllerRef.current = null;
5528
+ }
5529
+ };
5530
+ const onCancel = async () => {
5531
+ if (abortControllerRef.current) {
5532
+ abortControllerRef.current.abort();
5533
+ abortControllerRef.current = null;
5534
+ setIsRunning(false);
5511
5535
  }
5512
5536
  };
5513
5537
  const runtime = useExternalStoreRuntime({
@@ -5515,6 +5539,7 @@ function MastraRuntimeProvider({
5515
5539
  messages,
5516
5540
  convertMessage: convertMessage$2,
5517
5541
  onNew,
5542
+ onCancel,
5518
5543
  adapters: {
5519
5544
  attachments: new CompositeAttachmentAdapter([
5520
5545
  new SimpleImageAttachmentAdapter(),
@@ -5601,7 +5626,15 @@ const usePlaygroundStore = create()(
5601
5626
  )
5602
5627
  );
5603
5628
 
5604
- const AgentChat = ({ agentId, agentName, threadId, initialMessages, memory, refreshThreadList }) => {
5629
+ const AgentChat = ({
5630
+ agentId,
5631
+ agentName,
5632
+ threadId,
5633
+ initialMessages,
5634
+ memory,
5635
+ refreshThreadList,
5636
+ onInputChange
5637
+ }) => {
5605
5638
  const { settings } = useAgentSettings();
5606
5639
  const { runtimeContext } = usePlaygroundStore();
5607
5640
  return /* @__PURE__ */ jsx(
@@ -5615,7 +5648,7 @@ const AgentChat = ({ agentId, agentName, threadId, initialMessages, memory, refr
5615
5648
  refreshThreadList,
5616
5649
  settings,
5617
5650
  runtimeContext,
5618
- children: /* @__PURE__ */ jsx(Thread, { agentName: agentName ?? "", hasMemory: memory })
5651
+ children: /* @__PURE__ */ jsx(Thread, { agentName: agentName ?? "", hasMemory: memory, onInputChange })
5619
5652
  }
5620
5653
  );
5621
5654
  };
@@ -5803,26 +5836,41 @@ const TabsContent = React.forwardRef(({ className, ...props }, ref) => /* @__PUR
5803
5836
  ));
5804
5837
  TabsContent.displayName = TabsPrimitive.Content.displayName;
5805
5838
 
5806
- const PlaygroundTabs = ({ children, defaultTab }) => {
5807
- const [tab, setTab] = useState(defaultTab);
5808
- return /* @__PURE__ */ jsx(Tabs, { value: tab, onValueChange: (value) => setTab(value), className: "h-full", children });
5839
+ const PlaygroundTabs = ({
5840
+ children,
5841
+ defaultTab,
5842
+ value,
5843
+ onValueChange
5844
+ }) => {
5845
+ const [internalTab, setInternalTab] = useState(defaultTab);
5846
+ const isControlled = value !== void 0 && onValueChange !== void 0;
5847
+ const currentTab = isControlled ? value : internalTab;
5848
+ const handleTabChange = (newValue) => {
5849
+ const typedValue = newValue;
5850
+ if (isControlled) {
5851
+ onValueChange(typedValue);
5852
+ } else {
5853
+ setInternalTab(typedValue);
5854
+ }
5855
+ };
5856
+ return /* @__PURE__ */ jsx(Tabs, { value: currentTab, onValueChange: handleTabChange, className: "h-full", children });
5809
5857
  };
5810
5858
  const TabList = ({ children }) => {
5811
- return /* @__PURE__ */ jsx(TabsList, { className: "border-b-sm border-border1 flex w-full shrink-0", children });
5859
+ return /* @__PURE__ */ jsx("div", { className: "w-full overflow-x-auto", children: /* @__PURE__ */ jsx(TabsList, { className: "border-b-sm border-border1 flex min-w-full shrink-0", children }) });
5812
5860
  };
5813
5861
  const Tab = ({ children, value, onClick }) => {
5814
5862
  return /* @__PURE__ */ jsx(
5815
5863
  TabsTrigger,
5816
5864
  {
5817
5865
  value,
5818
- className: "text-xs p-3 text-mastra-el-3 data-[state=active]:text-mastra-el-5 data-[state=active]:border-b-2",
5866
+ className: "text-xs p-3 text-mastra-el-3 data-[state=active]:text-mastra-el-5 data-[state=active]:border-b-2 whitespace-nowrap flex-shrink-0",
5819
5867
  onClick,
5820
5868
  children
5821
5869
  }
5822
5870
  );
5823
5871
  };
5824
5872
  const TabContent = ({ children, value }) => {
5825
- return /* @__PURE__ */ jsx(TabsContent, { value, className: "h-full pb-5", children });
5873
+ return /* @__PURE__ */ jsx(TabsContent, { value, className: "h-full overflow-hidden flex flex-col", children });
5826
5874
  };
5827
5875
 
5828
5876
  const scrollableContentClass = cn(
@@ -7157,6 +7205,7 @@ const columns$2 = [
7157
7205
  {
7158
7206
  variant: "default",
7159
7207
  icon: providerMapToIcon[row.original.provider] || /* @__PURE__ */ jsx(OpenAIIcon, {}),
7208
+ className: "truncate",
7160
7209
  children: row.original.modelId || "N/A"
7161
7210
  }
7162
7211
  ) });
@@ -7326,6 +7375,497 @@ const RuntimeContextWrapper = ({ children }) => {
7326
7375
  ] });
7327
7376
  };
7328
7377
 
7378
+ const AgentMetadataSection = ({ title, children, hint }) => {
7379
+ const { Link } = useLinkComponent();
7380
+ return /* @__PURE__ */ jsxs("section", { className: "space-y-2 pb-7 last:pb-0", children: [
7381
+ /* @__PURE__ */ jsxs(Txt, { as: "h3", variant: "ui-md", className: "text-icon3 flex items-center gap-1", children: [
7382
+ title,
7383
+ hint && /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs(Tooltip, { children: [
7384
+ /* @__PURE__ */ jsx(TooltipTrigger, { children: /* @__PURE__ */ jsx(Link, { href: hint.link, target: "_blank", rel: "noopener noreferrer", children: /* @__PURE__ */ jsx(Icon, { className: "text-icon3", size: "sm", children: /* @__PURE__ */ jsx(InfoIcon$1, {}) }) }) }),
7385
+ /* @__PURE__ */ jsx(TooltipContent, { children: hint.title })
7386
+ ] }) })
7387
+ ] }),
7388
+ children
7389
+ ] });
7390
+ };
7391
+
7392
+ const AgentMetadataList = ({ children }) => {
7393
+ return /* @__PURE__ */ jsx("ul", { className: "flex flex-wrap gap-2", children });
7394
+ };
7395
+ const AgentMetadataListItem = ({ children }) => {
7396
+ return /* @__PURE__ */ jsx("li", { className: "shrink-0 font-medium", children });
7397
+ };
7398
+ const AgentMetadataListEmpty = ({ children }) => {
7399
+ return /* @__PURE__ */ jsx(Txt, { variant: "ui-sm", className: "text-icon6", children });
7400
+ };
7401
+
7402
+ const AgentMetadataWrapper = ({ children }) => {
7403
+ return /* @__PURE__ */ jsx("div", { className: "py-2 overflow-y-auto h-full px-5", children });
7404
+ };
7405
+
7406
+ const useScoresByEntityId = (entityId, entityType, page = 0) => {
7407
+ const client = useMastraClient();
7408
+ const [scores, setScores] = useState(null);
7409
+ const [isLoading, setIsLoading] = useState(true);
7410
+ useEffect(() => {
7411
+ const fetchScores = async () => {
7412
+ setIsLoading(true);
7413
+ try {
7414
+ const res = await client.getScoresByEntityId({
7415
+ entityId,
7416
+ entityType,
7417
+ page: page || 0,
7418
+ perPage: 10
7419
+ });
7420
+ setScores(res);
7421
+ setIsLoading(false);
7422
+ } catch (error) {
7423
+ setScores(null);
7424
+ setIsLoading(false);
7425
+ }
7426
+ };
7427
+ fetchScores();
7428
+ }, [entityId, entityType, page]);
7429
+ return { scores, isLoading };
7430
+ };
7431
+ const useScoresByScorerId = ({ scorerId, page = 0, entityId, entityType }) => {
7432
+ const client = useMastraClient();
7433
+ const [scores, setScores] = useState(null);
7434
+ const [isLoading, setIsLoading] = useState(true);
7435
+ useEffect(() => {
7436
+ const fetchScores = async () => {
7437
+ setIsLoading(true);
7438
+ try {
7439
+ const res = await client.getScoresByScorerId({
7440
+ scorerId,
7441
+ page: page || 0,
7442
+ entityId: entityId || void 0,
7443
+ entityType: entityType || void 0,
7444
+ perPage: 10
7445
+ });
7446
+ setScores(res);
7447
+ setIsLoading(false);
7448
+ } catch (error) {
7449
+ setScores(null);
7450
+ setIsLoading(false);
7451
+ }
7452
+ };
7453
+ fetchScores();
7454
+ }, [scorerId, page, entityId, entityType]);
7455
+ return { scores, isLoading };
7456
+ };
7457
+ const useScorer = (scorerId) => {
7458
+ const client = useMastraClient();
7459
+ const [scorer, setScorer] = useState(null);
7460
+ const [isLoading, setIsLoading] = useState(true);
7461
+ useEffect(() => {
7462
+ const fetchScorer = async () => {
7463
+ setIsLoading(true);
7464
+ try {
7465
+ const res = await client.getScorer(scorerId);
7466
+ setScorer(res);
7467
+ } catch (error) {
7468
+ setScorer(null);
7469
+ console.error("Error fetching scorer", error);
7470
+ toast.error("Error fetching scorer");
7471
+ } finally {
7472
+ setIsLoading(false);
7473
+ }
7474
+ };
7475
+ fetchScorer();
7476
+ }, [scorerId]);
7477
+ return { scorer, isLoading };
7478
+ };
7479
+ const useScorers = () => {
7480
+ const client = useMastraClient();
7481
+ const [scorers, setScorers] = useState({});
7482
+ const [isLoading, setIsLoading] = useState(true);
7483
+ useEffect(() => {
7484
+ const fetchScorers = async () => {
7485
+ setIsLoading(true);
7486
+ try {
7487
+ const res = await client.getScorers();
7488
+ setScorers(res);
7489
+ } catch (error) {
7490
+ setScorers({});
7491
+ console.error("Error fetching agents", error);
7492
+ toast.error("Error fetching agents");
7493
+ } finally {
7494
+ setIsLoading(false);
7495
+ }
7496
+ };
7497
+ fetchScorers();
7498
+ }, []);
7499
+ return { scorers, isLoading };
7500
+ };
7501
+
7502
+ const Entity = ({ children, className, onClick }) => {
7503
+ return /* @__PURE__ */ jsx(
7504
+ "div",
7505
+ {
7506
+ tabIndex: onClick ? 0 : void 0,
7507
+ onKeyDown: (e) => {
7508
+ if (!onClick) return;
7509
+ if (e.key === "Enter" || e.key === " ") {
7510
+ e.preventDefault();
7511
+ onClick?.();
7512
+ }
7513
+ },
7514
+ className: clsx(
7515
+ "flex gap-3 group/entity bg-surface3 rounded-lg border-sm border-border1 py-3 px-4",
7516
+ onClick && "cursor-pointer hover:bg-surface4 transition-all",
7517
+ className
7518
+ ),
7519
+ onClick,
7520
+ children
7521
+ }
7522
+ );
7523
+ };
7524
+ const EntityIcon = ({ children, className }) => {
7525
+ return /* @__PURE__ */ jsx(Icon, { size: "lg", className: clsx("text-icon3 mt-1", className), children });
7526
+ };
7527
+ const EntityName = ({ children, className }) => {
7528
+ return /* @__PURE__ */ jsx(Txt, { as: "p", variant: "ui-lg", className: clsx("text-icon6 font-medium", className), children });
7529
+ };
7530
+ const EntityDescription = ({ children, className }) => {
7531
+ return /* @__PURE__ */ jsx(Txt, { as: "p", variant: "ui-sm", className: clsx("text-icon3", className), children });
7532
+ };
7533
+ const EntityContent = ({ children, className }) => {
7534
+ return /* @__PURE__ */ jsx("div", { className, children });
7535
+ };
7536
+
7537
+ const ScorerList = ({ entityId, entityType }) => {
7538
+ const { scorers, isLoading } = useScorers();
7539
+ if (isLoading) {
7540
+ return /* @__PURE__ */ jsx(ScorerSkeleton, {});
7541
+ }
7542
+ const scorerList = Object.keys(scorers).filter((scorerKey) => {
7543
+ const scorer = scorers[scorerKey];
7544
+ if (entityType === "AGENT") {
7545
+ return scorer.agentIds.includes(entityId);
7546
+ }
7547
+ return scorer.workflowIds.includes(entityId);
7548
+ }).map((scorerKey) => ({ ...scorers[scorerKey], id: scorerKey }));
7549
+ if (scorerList.length === 0) {
7550
+ return /* @__PURE__ */ jsx(EmptyScorerList, {});
7551
+ }
7552
+ return /* @__PURE__ */ jsx("ul", { className: "space-y-2", children: scorerList.map((scorer) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(ScorerEntity, { scorer }) }, scorer.id)) });
7553
+ };
7554
+ const EmptyScorerList = () => {
7555
+ return /* @__PURE__ */ jsx(Txt, { as: "p", variant: "ui-lg", className: "text-icon6", children: "No scorers were attached to this agent." });
7556
+ };
7557
+ const ScorerSkeleton = () => {
7558
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
7559
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-24" }),
7560
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-24" })
7561
+ ] });
7562
+ };
7563
+ const ScorerEntity = ({ scorer }) => {
7564
+ const { Link } = useLinkComponent();
7565
+ const linkRef = useRef(null);
7566
+ return /* @__PURE__ */ jsxs(Entity, { onClick: () => linkRef.current?.click(), children: [
7567
+ /* @__PURE__ */ jsx(EntityIcon, { children: /* @__PURE__ */ jsx(GaugeIcon, { className: "group-hover/entity:text-accent3" }) }),
7568
+ /* @__PURE__ */ jsxs(EntityContent, { children: [
7569
+ /* @__PURE__ */ jsx(EntityName, { children: /* @__PURE__ */ jsx(Link, { ref: linkRef, href: `/scorers/${scorer.id}`, children: scorer.scorer.name }) }),
7570
+ /* @__PURE__ */ jsx(EntityDescription, { children: scorer.scorer.description }),
7571
+ scorer.sampling?.type === "ratio" && /* @__PURE__ */ jsxs(Badge$1, { children: [
7572
+ /* @__PURE__ */ jsx("span", { className: "text-icon3", children: "Sample rate:" }),
7573
+ /* @__PURE__ */ jsx("span", { className: "text-icon6", children: scorer.sampling.rate })
7574
+ ] })
7575
+ ] })
7576
+ ] });
7577
+ };
7578
+
7579
+ const AgentMetadata = ({
7580
+ agent,
7581
+ promptSlot,
7582
+ hasMemoryEnabled,
7583
+ computeToolLink,
7584
+ computeWorkflowLink
7585
+ }) => {
7586
+ const providerIcon = providerMapToIcon[agent.provider || "openai.chat"];
7587
+ const agentTools = agent.tools ?? {};
7588
+ const tools = Object.keys(agentTools).map((key) => agentTools[key]);
7589
+ const agentWorkflows = agent.workflows ?? {};
7590
+ const workflows = Object.keys(agentWorkflows).map((key) => agentWorkflows[key]);
7591
+ return /* @__PURE__ */ jsxs(AgentMetadataWrapper, { children: [
7592
+ /* @__PURE__ */ jsx(AgentMetadataSection, { title: "Model", children: /* @__PURE__ */ jsx(Badge$1, { icon: providerIcon, className: "font-medium", children: agent.modelId || "N/A" }) }),
7593
+ /* @__PURE__ */ jsx(
7594
+ AgentMetadataSection,
7595
+ {
7596
+ title: "Memory",
7597
+ hint: {
7598
+ link: "https://mastra.ai/en/docs/agents/agent-memory",
7599
+ title: "Agent Memory documentation"
7600
+ },
7601
+ children: /* @__PURE__ */ jsx(Badge$1, { icon: /* @__PURE__ */ jsx(MemoryIcon, {}), variant: hasMemoryEnabled ? "success" : "error", className: "font-medium", children: hasMemoryEnabled ? "On" : "Off" })
7602
+ }
7603
+ ),
7604
+ /* @__PURE__ */ jsx(
7605
+ AgentMetadataSection,
7606
+ {
7607
+ title: "Tools",
7608
+ hint: {
7609
+ link: "https://mastra.ai/en/docs/agents/using-tools-and-mcp",
7610
+ title: "Using Tools and MCP documentation"
7611
+ },
7612
+ children: /* @__PURE__ */ jsx(AgentMetadataToolList, { tools, computeToolLink })
7613
+ }
7614
+ ),
7615
+ /* @__PURE__ */ jsx(
7616
+ AgentMetadataSection,
7617
+ {
7618
+ title: "Workflows",
7619
+ hint: {
7620
+ link: "https://mastra.ai/en/docs/workflows/overview",
7621
+ title: "Workflows documentation"
7622
+ },
7623
+ children: /* @__PURE__ */ jsx(AgentMetadataWorkflowList, { workflows, computeWorkflowLink })
7624
+ }
7625
+ ),
7626
+ /* @__PURE__ */ jsx(AgentMetadataSection, { title: "Scorers", children: /* @__PURE__ */ jsx(AgentMetadataScorerList, { entityId: agent.name }) }),
7627
+ /* @__PURE__ */ jsx(AgentMetadataSection, { title: "System Prompt", children: promptSlot })
7628
+ ] });
7629
+ };
7630
+ const AgentMetadataToolList = ({ tools, computeToolLink }) => {
7631
+ const { Link } = useLinkComponent();
7632
+ if (tools.length === 0) {
7633
+ return /* @__PURE__ */ jsx(AgentMetadataListEmpty, { children: "No tools" });
7634
+ }
7635
+ return /* @__PURE__ */ jsx(AgentMetadataList, { children: tools.map((tool) => /* @__PURE__ */ jsx(AgentMetadataListItem, { children: /* @__PURE__ */ jsx(Link, { href: computeToolLink(tool), children: /* @__PURE__ */ jsx(Badge$1, { icon: /* @__PURE__ */ jsx(ToolsIcon, { className: "text-[#ECB047]" }), children: tool.id }) }) }, tool.id)) });
7636
+ };
7637
+ const AgentMetadataScorerList = ({ entityId }) => {
7638
+ return /* @__PURE__ */ jsx("div", { className: "px-5 pb-5", children: /* @__PURE__ */ jsx(ScorerList, { entityId, entityType: "AGENT" }) });
7639
+ };
7640
+ const AgentMetadataWorkflowList = ({ workflows, computeWorkflowLink }) => {
7641
+ const { Link } = useLinkComponent();
7642
+ if (workflows.length === 0) {
7643
+ return /* @__PURE__ */ jsx(AgentMetadataListEmpty, { children: "No workflows" });
7644
+ }
7645
+ return /* @__PURE__ */ jsx(AgentMetadataList, { children: workflows.map((workflow) => /* @__PURE__ */ jsx(AgentMetadataListItem, { children: /* @__PURE__ */ jsx(Link, { href: computeWorkflowLink(workflow), children: /* @__PURE__ */ jsx(Badge$1, { icon: /* @__PURE__ */ jsx(WorkflowIcon, { className: "text-accent3" }), children: workflow.name }) }) }, workflow.name)) });
7646
+ };
7647
+
7648
+ const AgentMetadataPrompt = ({ prompt }) => {
7649
+ return /* @__PURE__ */ jsx(Txt, { as: "p", variant: "ui-md", className: "bg-surface4 text-icon6 whitespace-pre-wrap rounded-lg px-2 py-1.5 text-sm", children: prompt });
7650
+ };
7651
+
7652
+ const EntityHeader = ({ icon, title, isLoading, children }) => {
7653
+ return /* @__PURE__ */ jsxs("div", { className: "p-5", children: [
7654
+ /* @__PURE__ */ jsxs("div", { className: "text-icon6 flex items-center gap-2", children: [
7655
+ /* @__PURE__ */ jsx(Icon, { size: "lg", className: "bg-surface4 rounded-md p-1", children: icon }),
7656
+ isLoading ? /* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-1/3" }) : /* @__PURE__ */ jsx("div", { className: "flex min-w-0 items-center gap-4", children: /* @__PURE__ */ jsx(Txt, { variant: "header-md", as: "h2", className: "truncate font-medium", children: title }) })
7657
+ ] }),
7658
+ children && /* @__PURE__ */ jsx("div", { className: "pt-2", children })
7659
+ ] });
7660
+ };
7661
+
7662
+ const AgentEntityHeader = ({ agentId, isLoading, agentName }) => {
7663
+ const { handleCopy } = useCopyToClipboard({ text: agentId });
7664
+ return /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsx(EntityHeader, { icon: /* @__PURE__ */ jsx(AgentIcon, {}), title: agentName, isLoading, children: /* @__PURE__ */ jsxs(Tooltip, { children: [
7665
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx("button", { onClick: handleCopy, className: "h-badge-default shrink-0", children: /* @__PURE__ */ jsx(Badge$1, { icon: /* @__PURE__ */ jsx(CopyIcon, {}), variant: "default", children: agentId }) }) }),
7666
+ /* @__PURE__ */ jsx(TooltipContent, { children: "Copy Agent ID for use in code" })
7667
+ ] }) }) });
7668
+ };
7669
+
7670
+ const Threads = ({ children }) => {
7671
+ return /* @__PURE__ */ jsx("nav", { className: "bg-surface2 border-r-sm border-border1 min-h-full overflow-hidden", children });
7672
+ };
7673
+ const ThreadLink = ({ children, as: Component = "a", href, className, prefetch, to }) => {
7674
+ return /* @__PURE__ */ jsx(
7675
+ Component,
7676
+ {
7677
+ href,
7678
+ prefetch,
7679
+ to,
7680
+ className: clsx("text-ui-sm flex h-full w-full flex-col justify-center font-medium", className),
7681
+ children
7682
+ }
7683
+ );
7684
+ };
7685
+ const ThreadList = ({ children }) => {
7686
+ return /* @__PURE__ */ jsx("ol", { children });
7687
+ };
7688
+ const ThreadItem = ({ children, isActive }) => {
7689
+ return /* @__PURE__ */ jsx(
7690
+ "li",
7691
+ {
7692
+ className: clsx(
7693
+ "border-b-sm border-border1 hover:bg-surface3 group flex h-[54px] items-center justify-between gap-2 pl-5 py-2",
7694
+ isActive && "bg-surface4"
7695
+ ),
7696
+ children
7697
+ }
7698
+ );
7699
+ };
7700
+ const ThreadDeleteButton = ({ onClick }) => {
7701
+ return /* @__PURE__ */ jsx(
7702
+ Button,
7703
+ {
7704
+ className: "shrink-0 border-none bg-transparent opacity-0 transition-all group-focus-within:opacity-100 group-hover:opacity-100",
7705
+ onClick,
7706
+ children: /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(X, { "aria-label": "delete thread", className: "text-icon3" }) })
7707
+ }
7708
+ );
7709
+ };
7710
+
7711
+ const AlertDialogRoot = AlertDialogPrimitive.Root;
7712
+ const AlertDialogTrigger = AlertDialogPrimitive.Trigger;
7713
+ const AlertDialogPortal = AlertDialogPrimitive.Portal;
7714
+ function AlertDialog({
7715
+ open,
7716
+ onOpenChange,
7717
+ children
7718
+ }) {
7719
+ return /* @__PURE__ */ jsx(AlertDialogRoot, { open, onOpenChange, children });
7720
+ }
7721
+ const AlertDialogOverlay = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
7722
+ AlertDialogPrimitive.Overlay,
7723
+ {
7724
+ className: cn(
7725
+ "fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
7726
+ className
7727
+ ),
7728
+ ...props,
7729
+ ref
7730
+ }
7731
+ ));
7732
+ AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName;
7733
+ const AlertDialogContent = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxs(AlertDialogPortal, { children: [
7734
+ /* @__PURE__ */ jsx(AlertDialogOverlay, {}),
7735
+ /* @__PURE__ */ jsx(
7736
+ AlertDialogPrimitive.Content,
7737
+ {
7738
+ ref,
7739
+ className: cn(
7740
+ "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-[#141414] p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
7741
+ className
7742
+ ),
7743
+ ...props
7744
+ }
7745
+ )
7746
+ ] }));
7747
+ AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName;
7748
+ const AlertDialogHeader = ({ className, ...props }) => /* @__PURE__ */ jsx("div", { className: cn("flex flex-col space-y-2 text-center sm:text-left", className), ...props });
7749
+ AlertDialogHeader.displayName = "AlertDialogHeader";
7750
+ const AlertDialogFooter = ({ className, ...props }) => /* @__PURE__ */ jsx("div", { className: cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className), ...props });
7751
+ AlertDialogFooter.displayName = "AlertDialogFooter";
7752
+ const AlertDialogTitle = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(AlertDialogPrimitive.Title, { ref, className: cn("text-lg font-semibold", className), ...props }));
7753
+ AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName;
7754
+ const AlertDialogDescription = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(AlertDialogPrimitive.Description, { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
7755
+ AlertDialogDescription.displayName = AlertDialogPrimitive.Description.displayName;
7756
+ const AlertDialogAction = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(AlertDialogPrimitive.Action, { ref, className: cn(buttonVariants(), className), ...props }));
7757
+ AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName;
7758
+ const AlertDialogCancel = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
7759
+ AlertDialogPrimitive.Cancel,
7760
+ {
7761
+ ref,
7762
+ className: cn(buttonVariants({ variant: "outline" }), "mt-2 sm:mt-0", className),
7763
+ ...props
7764
+ }
7765
+ ));
7766
+ AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName;
7767
+ AlertDialog.Trigger = AlertDialogTrigger;
7768
+ AlertDialog.Portal = AlertDialogPortal;
7769
+ AlertDialog.Overlay = AlertDialogOverlay;
7770
+ AlertDialog.Content = AlertDialogContent;
7771
+ AlertDialog.Header = AlertDialogHeader;
7772
+ AlertDialog.Footer = AlertDialogFooter;
7773
+ AlertDialog.Title = AlertDialogTitle;
7774
+ AlertDialog.Description = AlertDialogDescription;
7775
+ AlertDialog.Action = AlertDialogAction;
7776
+ AlertDialog.Cancel = AlertDialogCancel;
7777
+
7778
+ const ChatThreads = ({
7779
+ computeNewThreadLink,
7780
+ computeThreadLink,
7781
+ threads,
7782
+ isLoading,
7783
+ threadId,
7784
+ onDelete
7785
+ }) => {
7786
+ const { Link } = useLinkComponent();
7787
+ const [deleteId, setDeleteId] = useState(null);
7788
+ if (isLoading) {
7789
+ return /* @__PURE__ */ jsx(ChatThreadSkeleton, {});
7790
+ }
7791
+ const reverseThreads = [...threads].reverse();
7792
+ return /* @__PURE__ */ jsxs("div", { className: "overflow-y-auto h-full w-full", children: [
7793
+ /* @__PURE__ */ jsx(Threads, { children: /* @__PURE__ */ jsxs(ThreadList, { children: [
7794
+ /* @__PURE__ */ jsx(ThreadItem, { children: /* @__PURE__ */ jsx(ThreadLink, { as: Link, to: computeNewThreadLink(), children: /* @__PURE__ */ jsxs("span", { className: "text-accent1 flex items-center gap-4", children: [
7795
+ /* @__PURE__ */ jsx(Icon, { className: "bg-surface4 rounded-lg", size: "lg", children: /* @__PURE__ */ jsx(Plus, {}) }),
7796
+ "New Chat"
7797
+ ] }) }) }),
7798
+ reverseThreads.length === 0 && /* @__PURE__ */ jsx(Txt, { as: "p", variant: "ui-sm", className: "text-icon3 py-3 px-5 max-w-[12rem]", children: "Your conversations will appear here once you start chatting!" }),
7799
+ reverseThreads.map((thread) => {
7800
+ const isActive = thread.id === threadId;
7801
+ return /* @__PURE__ */ jsxs(ThreadItem, { isActive, children: [
7802
+ /* @__PURE__ */ jsxs(ThreadLink, { as: Link, to: computeThreadLink(thread.id), children: [
7803
+ /* @__PURE__ */ jsx(ThreadTitle, { title: thread.title }),
7804
+ /* @__PURE__ */ jsx("span", { children: formatDay(thread.createdAt) })
7805
+ ] }),
7806
+ /* @__PURE__ */ jsx(ThreadDeleteButton, { onClick: () => setDeleteId(thread.id) })
7807
+ ] }, thread.id);
7808
+ })
7809
+ ] }) }),
7810
+ /* @__PURE__ */ jsx(
7811
+ DeleteThreadDialog,
7812
+ {
7813
+ open: !!deleteId,
7814
+ onOpenChange: () => setDeleteId(null),
7815
+ onDelete: () => {
7816
+ if (deleteId) {
7817
+ onDelete(deleteId);
7818
+ }
7819
+ }
7820
+ }
7821
+ )
7822
+ ] });
7823
+ };
7824
+ const DeleteThreadDialog = ({ open, onOpenChange, onDelete }) => {
7825
+ return /* @__PURE__ */ jsx(AlertDialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs(AlertDialog.Content, { children: [
7826
+ /* @__PURE__ */ jsxs(AlertDialog.Header, { children: [
7827
+ /* @__PURE__ */ jsx(AlertDialog.Title, { children: "Are you absolutely sure?" }),
7828
+ /* @__PURE__ */ jsx(AlertDialog.Description, { children: "This action cannot be undone. This will permanently delete your chat and remove it from our servers." })
7829
+ ] }),
7830
+ /* @__PURE__ */ jsxs(AlertDialog.Footer, { children: [
7831
+ /* @__PURE__ */ jsx(AlertDialog.Cancel, { children: "Cancel" }),
7832
+ /* @__PURE__ */ jsx(AlertDialog.Action, { onClick: onDelete, children: "Continue" })
7833
+ ] })
7834
+ ] }) });
7835
+ };
7836
+ const ChatThreadSkeleton = () => /* @__PURE__ */ jsxs("div", { className: "p-4 w-full h-full space-y-2", children: [
7837
+ /* @__PURE__ */ jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsx(Skeleton, { className: "h-9 w-9" }) }),
7838
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-4" }),
7839
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-4" }),
7840
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-4" }),
7841
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-4" }),
7842
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-4" })
7843
+ ] });
7844
+ function isDefaultThreadName(name) {
7845
+ const defaultPattern = /^New Thread \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z$/;
7846
+ return defaultPattern.test(name);
7847
+ }
7848
+ function ThreadTitle({ title }) {
7849
+ if (!title) {
7850
+ return null;
7851
+ }
7852
+ if (isDefaultThreadName(title)) {
7853
+ return /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "Chat from" });
7854
+ }
7855
+ return /* @__PURE__ */ jsx("span", { className: "truncate max-w-[14rem]", children: title });
7856
+ }
7857
+ const formatDay = (date) => {
7858
+ const options = {
7859
+ month: "short",
7860
+ day: "numeric",
7861
+ hour: "numeric",
7862
+ minute: "numeric",
7863
+ second: "numeric",
7864
+ hour12: true
7865
+ };
7866
+ return new Date(date).toLocaleString("en-us", options).replace(",", " at");
7867
+ };
7868
+
7329
7869
  const convertMessage$1 = (message) => {
7330
7870
  return message;
7331
7871
  };
@@ -10635,41 +11175,6 @@ const NetworkTableSkeleton = () => {
10635
11175
  ] });
10636
11176
  };
10637
11177
 
10638
- const Entity = ({ children, className, onClick }) => {
10639
- return /* @__PURE__ */ jsx(
10640
- "div",
10641
- {
10642
- tabIndex: onClick ? 0 : void 0,
10643
- onKeyDown: (e) => {
10644
- if (!onClick) return;
10645
- if (e.key === "Enter" || e.key === " ") {
10646
- e.preventDefault();
10647
- onClick?.();
10648
- }
10649
- },
10650
- className: clsx(
10651
- "flex gap-3 group/entity bg-surface3 rounded-lg border-sm border-border1 py-3 px-4",
10652
- onClick && "cursor-pointer hover:bg-surface4 transition-all",
10653
- className
10654
- ),
10655
- onClick,
10656
- children
10657
- }
10658
- );
10659
- };
10660
- const EntityIcon = ({ children, className }) => {
10661
- return /* @__PURE__ */ jsx(Icon, { size: "lg", className: clsx("text-icon3 mt-1", className), children });
10662
- };
10663
- const EntityName = ({ children, className }) => {
10664
- return /* @__PURE__ */ jsx(Txt, { as: "p", variant: "ui-lg", className: clsx("text-icon6 font-medium", className), children });
10665
- };
10666
- const EntityDescription = ({ children, className }) => {
10667
- return /* @__PURE__ */ jsx(Txt, { as: "p", variant: "ui-sm", className: clsx("text-icon3", className), children });
10668
- };
10669
- const EntityContent = ({ children, className }) => {
10670
- return /* @__PURE__ */ jsx("div", { className, children });
10671
- };
10672
-
10673
11178
  const ToolList = ({ tools, agents, isLoading, computeLink, computeAgentLink }) => {
10674
11179
  const toolsWithAgents = useMemo(() => prepareAgents(tools, agents), [tools, agents]);
10675
11180
  if (isLoading)
@@ -11201,7 +11706,7 @@ const DatePicker = ({
11201
11706
  DatePickerOnly,
11202
11707
  {
11203
11708
  value,
11204
- setValue: (v) => setValue(v ? /* @__PURE__ */ new Date(`${v}z`) : null),
11709
+ setValue,
11205
11710
  clearable: props.clearable,
11206
11711
  setOpenPopover,
11207
11712
  ...props
@@ -13251,57 +13756,6 @@ function devUIStyleRequested(name) {
13251
13756
  }
13252
13757
  }
13253
13758
 
13254
- const Threads = ({ children }) => {
13255
- return /* @__PURE__ */ jsx("nav", { className: "bg-surface2 border-r-sm border-border1 min-h-full overflow-hidden", children });
13256
- };
13257
- const ThreadLink = ({ children, as: Component = "a", href, className, prefetch, to }) => {
13258
- return /* @__PURE__ */ jsx(
13259
- Component,
13260
- {
13261
- href,
13262
- prefetch,
13263
- to,
13264
- className: clsx("text-ui-sm flex h-full w-full flex-col justify-center font-medium", className),
13265
- children
13266
- }
13267
- );
13268
- };
13269
- const ThreadList = ({ children }) => {
13270
- return /* @__PURE__ */ jsx("ol", { children });
13271
- };
13272
- const ThreadItem = ({ children, isActive }) => {
13273
- return /* @__PURE__ */ jsx(
13274
- "li",
13275
- {
13276
- className: clsx(
13277
- "border-b-sm border-border1 hover:bg-surface3 group flex h-[54px] items-center justify-between gap-2 pl-5 py-2",
13278
- isActive && "bg-surface4"
13279
- ),
13280
- children
13281
- }
13282
- );
13283
- };
13284
- const ThreadDeleteButton = ({ onClick }) => {
13285
- return /* @__PURE__ */ jsx(
13286
- Button,
13287
- {
13288
- className: "shrink-0 border-none bg-transparent opacity-0 transition-all group-focus-within:opacity-100 group-hover:opacity-100",
13289
- onClick,
13290
- children: /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(X, { "aria-label": "delete thread", className: "text-icon3" }) })
13291
- }
13292
- );
13293
- };
13294
-
13295
- const EntityHeader = ({ icon, title, isLoading, children }) => {
13296
- return /* @__PURE__ */ jsxs("div", { className: "p-5", children: [
13297
- /* @__PURE__ */ jsxs("div", { className: "text-icon6 flex items-center gap-2", children: [
13298
- /* @__PURE__ */ jsx(Icon, { size: "lg", className: "bg-surface4 rounded-md p-1", children: icon }),
13299
- isLoading ? /* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-1/3" }) : /* @__PURE__ */ jsx("div", { className: "flex min-w-0 items-center gap-4", children: /* @__PURE__ */ jsx(Txt, { variant: "header-md", as: "h2", className: "truncate font-medium", children: title }) })
13300
- ] }),
13301
- children
13302
- ] });
13303
- };
13304
-
13305
13759
  const Breadcrumb = ({ children, label }) => {
13306
13760
  return /* @__PURE__ */ jsx("nav", { "aria-label": label, children: /* @__PURE__ */ jsx("ol", { className: "gap-sm flex items-center", children }) });
13307
13761
  };
@@ -13503,5 +13957,268 @@ const PlaygroundQueryClient = ({ children }) => {
13503
13957
  return /* @__PURE__ */ jsx(QueryClientProvider, { client: queryClient, children });
13504
13958
  };
13505
13959
 
13506
- export { AgentChat, AgentCoinIcon, AgentEvals, AgentIcon, AgentNetworkCoinIcon, AgentSettings, AgentSettingsContext, AgentSettingsProvider, AgentsTable, AgentsTableSkeleton, AiIcon, ApiIcon, Badge$1 as Badge, BranchIcon, Breadcrumb, Button, Cell, CheckIcon, ChevronIcon, CommitIcon, CrossIcon, Crumb, DarkLogo, DataTable, DateTimeCell, DbIcon, DebugIcon, DeploymentIcon, DividerIcon, DocsIcon, DynamicForm, EmptyAgentsTable, EmptyState, EmptyWorkflowsTable, Entity, EntityContent, EntityDescription, EntityHeader, EntityIcon, EntityName, Entry, EntryCell, EnvIcon, EvaluatorCoinIcon, FiltersIcon, FolderIcon, GithubCoinIcon, GithubIcon, GoogleIcon, Header, HeaderAction, HeaderGroup, HeaderTitle, HomeIcon, Icon, InfoIcon, JudgeIcon, LatencyIcon, LegacyWorkflowGraph, LegacyWorkflowTrigger, LinkComponentProvider, LogsIcon, MainContentContent, MainContentLayout, MastraClientProvider, MastraResizablePanel, McpCoinIcon, McpServerIcon, MemoryIcon, NetworkChat, NetworkContext, NetworkProvider, NetworkTable, NetworkTableEmpty, NetworkTableSkeleton, OpenAIIcon, PlaygroundQueryClient, PlaygroundTabs, PromptIcon, RadioGroup, RadioGroupItem, RepoIcon, Row, RuntimeContext, RuntimeContextWrapper, ScoreIcon, SettingsIcon, SlashIcon, Tab, TabContent, TabList, Table, Tbody, Th, Thead, ThreadDeleteButton, ThreadItem, ThreadLink, ThreadList, Threads, ToolCoinIcon, ToolList, ToolListEmpty, ToolListSkeleton, ToolsIcon, TraceIcon, TracesView, TracesViewSkeleton, TsIcon, Txt, TxtCell, UnitCell, VNextNetworkChat, VariablesIcon, WorkflowCoinIcon, WorkflowGraph, WorkflowIcon, WorkflowRunContext, WorkflowRunProvider, WorkflowRuns, WorkflowTable, WorkflowTableSkeleton, WorkflowTrigger, WorkingMemoryContext, WorkingMemoryProvider, allowedAiSpanAttributes, cleanString, formatDuration, formatOtelTimestamp, formatOtelTimestamp2, providerMapToIcon, transformKey, useAgentSettings, useCurrentRun, useInView, useLinkComponent, useMastraClient, usePlaygroundStore, usePolling, useSpeechRecognition, useWorkingMemory };
13960
+ const formatRelativeTime = (date) => {
13961
+ const now = /* @__PURE__ */ new Date();
13962
+ const seconds = Math.floor((now.getTime() - date.getTime()) / 1e3);
13963
+ if (seconds < 60) return "just now";
13964
+ if (seconds < 3600) return `${Math.floor(seconds / 60)}m ago`;
13965
+ if (seconds < 86400) return `${Math.floor(seconds / 3600)}h ago`;
13966
+ if (seconds < 604800) return `${Math.floor(seconds / 86400)}d ago`;
13967
+ return date.toLocaleDateString();
13968
+ };
13969
+ const MemorySearch = ({
13970
+ searchMemory,
13971
+ onResultClick,
13972
+ className,
13973
+ currentThreadId,
13974
+ chatInputValue
13975
+ }) => {
13976
+ const [query, setQuery] = useState("");
13977
+ const [results, setResults] = useState([]);
13978
+ const [isSearching, setIsSearching] = useState(false);
13979
+ const [isOpen, setIsOpen] = useState(false);
13980
+ const [error, setError] = useState(null);
13981
+ const searchTimeoutRef = useRef(void 0);
13982
+ const dropdownRef = useRef(null);
13983
+ const prevThreadIdRef = useRef(currentThreadId);
13984
+ const lastSearchTimeRef = useRef(0);
13985
+ const pendingSearchRef = useRef(null);
13986
+ const handleSearch = useCallback(
13987
+ async (searchQuery) => {
13988
+ if (!searchQuery.trim()) {
13989
+ setError(null);
13990
+ return;
13991
+ }
13992
+ setIsSearching(true);
13993
+ setError(null);
13994
+ try {
13995
+ const response = await searchMemory(searchQuery);
13996
+ setResults(response.results);
13997
+ setIsOpen((prev) => prev || response.results.length > 0);
13998
+ } catch (err) {
13999
+ setError("Failed to search memory");
14000
+ console.error("Memory search error:", err);
14001
+ } finally {
14002
+ setIsSearching(false);
14003
+ }
14004
+ },
14005
+ [searchMemory]
14006
+ );
14007
+ const handleInputChange = useCallback(
14008
+ (e) => {
14009
+ const value = e.target.value;
14010
+ setQuery(value);
14011
+ if (searchTimeoutRef.current) {
14012
+ clearTimeout(searchTimeoutRef.current);
14013
+ }
14014
+ if (value.trim()) {
14015
+ const now = Date.now();
14016
+ const timeSinceLastSearch = now - lastSearchTimeRef.current;
14017
+ if (timeSinceLastSearch >= 500) {
14018
+ setIsSearching(true);
14019
+ handleSearch(value);
14020
+ lastSearchTimeRef.current = now;
14021
+ } else {
14022
+ setIsSearching(true);
14023
+ pendingSearchRef.current = value;
14024
+ const remainingTime = 500 - timeSinceLastSearch;
14025
+ searchTimeoutRef.current = setTimeout(() => {
14026
+ if (pendingSearchRef.current) {
14027
+ handleSearch(pendingSearchRef.current);
14028
+ lastSearchTimeRef.current = Date.now();
14029
+ pendingSearchRef.current = null;
14030
+ }
14031
+ }, remainingTime);
14032
+ }
14033
+ } else {
14034
+ setResults([]);
14035
+ setIsOpen(false);
14036
+ setIsSearching(false);
14037
+ pendingSearchRef.current = null;
14038
+ }
14039
+ },
14040
+ [handleSearch]
14041
+ );
14042
+ const handleKeyDown = useCallback(
14043
+ (e) => {
14044
+ if (e.key === "Enter") {
14045
+ e.preventDefault();
14046
+ if (searchTimeoutRef.current) {
14047
+ clearTimeout(searchTimeoutRef.current);
14048
+ }
14049
+ handleSearch(query);
14050
+ }
14051
+ },
14052
+ [query, handleSearch]
14053
+ );
14054
+ useEffect(() => {
14055
+ return () => {
14056
+ if (searchTimeoutRef.current) {
14057
+ clearTimeout(searchTimeoutRef.current);
14058
+ }
14059
+ };
14060
+ }, []);
14061
+ useEffect(() => {
14062
+ const handleClickOutside = (event) => {
14063
+ if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
14064
+ setIsOpen(false);
14065
+ }
14066
+ };
14067
+ document.addEventListener("mousedown", handleClickOutside);
14068
+ return () => document.removeEventListener("mousedown", handleClickOutside);
14069
+ }, []);
14070
+ useEffect(() => {
14071
+ if (prevThreadIdRef.current !== currentThreadId && query.trim()) {
14072
+ handleSearch(query);
14073
+ }
14074
+ prevThreadIdRef.current = currentThreadId;
14075
+ }, [currentThreadId, query, handleSearch]);
14076
+ useEffect(() => {
14077
+ if (chatInputValue !== void 0 && chatInputValue !== query) {
14078
+ setQuery(chatInputValue);
14079
+ if (searchTimeoutRef.current) {
14080
+ clearTimeout(searchTimeoutRef.current);
14081
+ }
14082
+ if (chatInputValue.trim()) {
14083
+ const now = Date.now();
14084
+ const timeSinceLastSearch = now - lastSearchTimeRef.current;
14085
+ if (timeSinceLastSearch >= 500) {
14086
+ setIsSearching(true);
14087
+ handleSearch(chatInputValue);
14088
+ lastSearchTimeRef.current = now;
14089
+ } else {
14090
+ setIsSearching(true);
14091
+ pendingSearchRef.current = chatInputValue;
14092
+ const remainingTime = 500 - timeSinceLastSearch;
14093
+ searchTimeoutRef.current = setTimeout(() => {
14094
+ if (pendingSearchRef.current) {
14095
+ handleSearch(pendingSearchRef.current);
14096
+ lastSearchTimeRef.current = Date.now();
14097
+ pendingSearchRef.current = null;
14098
+ }
14099
+ }, remainingTime);
14100
+ }
14101
+ } else {
14102
+ setResults([]);
14103
+ setIsOpen(false);
14104
+ setIsSearching(false);
14105
+ pendingSearchRef.current = null;
14106
+ }
14107
+ }
14108
+ return () => {
14109
+ if (searchTimeoutRef.current) {
14110
+ clearTimeout(searchTimeoutRef.current);
14111
+ }
14112
+ };
14113
+ }, [chatInputValue]);
14114
+ const handleResultClick = (messageId, threadId) => {
14115
+ onResultClick?.(messageId, threadId);
14116
+ };
14117
+ const clearSearch = () => {
14118
+ setQuery("");
14119
+ setResults([]);
14120
+ setIsOpen(false);
14121
+ setError(null);
14122
+ if (searchTimeoutRef.current) {
14123
+ clearTimeout(searchTimeoutRef.current);
14124
+ }
14125
+ };
14126
+ const truncateContent = (content, maxLength = 100) => {
14127
+ if (content.length <= maxLength) return content;
14128
+ return content.substring(0, maxLength) + "...";
14129
+ };
14130
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col h-full", className), ref: dropdownRef, children: [
14131
+ /* @__PURE__ */ jsxs("div", { className: "relative shrink-0", children: [
14132
+ /* @__PURE__ */ jsx(Search, { className: "absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-icon3" }),
14133
+ /* @__PURE__ */ jsx(
14134
+ Input,
14135
+ {
14136
+ type: "text",
14137
+ value: query,
14138
+ onChange: handleInputChange,
14139
+ onKeyDown: handleKeyDown,
14140
+ placeholder: "Search memory...",
14141
+ className: "pl-10 pr-10 bg-surface3 border-border1"
14142
+ }
14143
+ ),
14144
+ query && /* @__PURE__ */ jsx(
14145
+ Button$1,
14146
+ {
14147
+ onClick: clearSearch,
14148
+ variant: "ghost",
14149
+ size: "sm",
14150
+ className: "absolute right-1 top-1/2 transform -translate-y-1/2 h-6 w-6 p-0",
14151
+ children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" })
14152
+ }
14153
+ )
14154
+ ] }),
14155
+ (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: [
14156
+ 'No results found for "',
14157
+ query,
14158
+ '"'
14159
+ ] }) }) : /* @__PURE__ */ jsx("div", { className: "py-2", children: results.map((result) => /* @__PURE__ */ jsx(
14160
+ "button",
14161
+ {
14162
+ onClick: () => handleResultClick(result.id, result.threadId),
14163
+ className: cn(
14164
+ "w-full px-4 py-3 hover:bg-surface4 transition-colors duration-150 text-left border-b border-border1 last:border-b-0",
14165
+ result.threadId !== currentThreadId && "border-l-2 border-l-blue-400"
14166
+ ),
14167
+ children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
14168
+ 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: [
14169
+ /* @__PURE__ */ jsxs("span", { className: "font-medium", children: [
14170
+ msg.role,
14171
+ ":"
14172
+ ] }),
14173
+ /* @__PURE__ */ jsx("span", { className: "text-icon3", children: truncateContent(msg.content, 50) })
14174
+ ] }, idx)) }),
14175
+ /* @__PURE__ */ jsx("div", { className: "flex items-start justify-between gap-2", children: /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
14176
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-1", children: [
14177
+ /* @__PURE__ */ jsx(
14178
+ "span",
14179
+ {
14180
+ className: cn(
14181
+ "text-xs font-medium px-2 py-0.5 rounded",
14182
+ result.role === "user" ? "bg-blue-500/20 text-blue-400" : "bg-green-500/20 text-green-400"
14183
+ ),
14184
+ children: result.role
14185
+ }
14186
+ ),
14187
+ /* @__PURE__ */ jsx(Txt, { variant: "ui-xs", className: "text-icon3", children: formatRelativeTime(new Date(result.createdAt)) }),
14188
+ result.threadTitle && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
14189
+ /* @__PURE__ */ jsxs(
14190
+ Txt,
14191
+ {
14192
+ variant: "ui-xs",
14193
+ className: cn(
14194
+ "truncate max-w-[150px]",
14195
+ result.threadId !== currentThreadId ? "text-blue-400 font-medium" : "text-icon3"
14196
+ ),
14197
+ title: result.threadTitle,
14198
+ children: [
14199
+ "• ",
14200
+ result.threadTitle
14201
+ ]
14202
+ }
14203
+ ),
14204
+ result.threadId !== currentThreadId && /* @__PURE__ */ jsx(ExternalLink, { className: "w-3 h-3 text-blue-400" })
14205
+ ] })
14206
+ ] }),
14207
+ /* @__PURE__ */ jsx(Txt, { variant: "ui-sm", className: "text-icon5 break-words", children: truncateContent(result.content) })
14208
+ ] }) }),
14209
+ 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: [
14210
+ /* @__PURE__ */ jsxs("span", { className: "font-medium", children: [
14211
+ msg.role,
14212
+ ":"
14213
+ ] }),
14214
+ /* @__PURE__ */ jsx("span", { className: "text-icon3", children: truncateContent(msg.content, 50) })
14215
+ ] }, idx)) })
14216
+ ] })
14217
+ },
14218
+ result.id
14219
+ )) }) })
14220
+ ] });
14221
+ };
14222
+
14223
+ export { AgentChat, AgentCoinIcon, AgentEntityHeader, AgentEvals, AgentIcon, AgentMetadata, AgentMetadataList, AgentMetadataListEmpty, AgentMetadataListItem, AgentMetadataPrompt, AgentMetadataScorerList, AgentMetadataSection, AgentMetadataToolList, AgentMetadataWorkflowList, AgentMetadataWrapper, AgentNetworkCoinIcon, AgentSettings, AgentSettingsContext, AgentSettingsProvider, AgentsTable, AgentsTableSkeleton, AiIcon, AlertDialog, ApiIcon, Badge$1 as Badge, BranchIcon, Breadcrumb, Button, Cell, ChatThreads, CheckIcon, ChevronIcon, CommitIcon, CrossIcon, Crumb, DarkLogo, DataTable, DateTimeCell, DbIcon, DebugIcon, DeploymentIcon, DividerIcon, DocsIcon, DynamicForm, EmptyAgentsTable, EmptyScorerList, EmptyState, EmptyWorkflowsTable, Entity, EntityContent, EntityDescription, EntityHeader, EntityIcon, EntityName, Entry, EntryCell, EnvIcon, EvaluatorCoinIcon, FiltersIcon, FolderIcon, GithubCoinIcon, GithubIcon, GoogleIcon, Header, HeaderAction, HeaderGroup, HeaderTitle, HomeIcon, Icon, InfoIcon, JudgeIcon, LatencyIcon, LegacyWorkflowGraph, LegacyWorkflowTrigger, LinkComponentProvider, LogsIcon, MainContentContent, MainContentLayout, MastraClientProvider, MastraResizablePanel, McpCoinIcon, McpServerIcon, MemoryIcon, MemorySearch, NetworkChat, NetworkContext, NetworkProvider, NetworkTable, NetworkTableEmpty, NetworkTableSkeleton, OpenAIIcon, PlaygroundQueryClient, PlaygroundTabs, PromptIcon, RadioGroup, RadioGroupItem, RepoIcon, Row, RuntimeContext, RuntimeContextWrapper, ScoreIcon, ScorerList, ScorerSkeleton, SettingsIcon, SlashIcon, Tab, TabContent, TabList, Table, Tbody, Th, Thead, ThreadDeleteButton, ThreadItem, ThreadLink, ThreadList, Threads, ToolCoinIcon, ToolList, ToolListEmpty, ToolListSkeleton, ToolsIcon, TraceIcon, TracesView, TracesViewSkeleton, TsIcon, Txt, TxtCell, UnitCell, VNextNetworkChat, VariablesIcon, WorkflowCoinIcon, WorkflowGraph, WorkflowIcon, WorkflowRunContext, WorkflowRunProvider, WorkflowRuns, WorkflowTable, WorkflowTableSkeleton, WorkflowTrigger, WorkingMemoryContext, WorkingMemoryProvider, allowedAiSpanAttributes, cleanString, formatDuration, formatOtelTimestamp, formatOtelTimestamp2, providerMapToIcon, transformKey, useAgentSettings, useCurrentRun, useInView, useLinkComponent, useMastraClient, usePlaygroundStore, usePolling, useScorer, useScorers, useScoresByEntityId, useScoresByScorerId, useSpeechRecognition, useWorkingMemory };
13507
14224
  //# sourceMappingURL=index.es.js.map