@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.cjs.js CHANGED
@@ -37,6 +37,7 @@ const prettierPluginBabel = require('prettier/plugins/babel');
37
37
  const prettierPluginEstree = require('prettier/plugins/estree');
38
38
  const colors = require('./colors-DLwJ7rFA.cjs');
39
39
  const reactTable = require('@tanstack/react-table');
40
+ const AlertDialogPrimitive = require('@radix-ui/react-alert-dialog');
40
41
  const uiUtils = require('@ai-sdk/ui-utils');
41
42
  const Markdown = require('react-markdown');
42
43
  const react$2 = require('@xyflow/react');
@@ -85,6 +86,7 @@ const SliderPrimitive__namespace = /*#__PURE__*/_interopNamespaceDefault(SliderP
85
86
  const LabelPrimitive__namespace = /*#__PURE__*/_interopNamespaceDefault(LabelPrimitive);
86
87
  const RadioGroupPrimitive__namespace = /*#__PURE__*/_interopNamespaceDefault(RadioGroupPrimitive);
87
88
  const CollapsiblePrimitive__namespace = /*#__PURE__*/_interopNamespaceDefault(CollapsiblePrimitive);
89
+ const AlertDialogPrimitive__namespace = /*#__PURE__*/_interopNamespaceDefault(AlertDialogPrimitive);
88
90
  const ScrollAreaPrimitive__namespace = /*#__PURE__*/_interopNamespaceDefault(ScrollAreaPrimitive);
89
91
  const CheckboxPrimitive__namespace = /*#__PURE__*/_interopNamespaceDefault(CheckboxPrimitive);
90
92
  const PopoverPrimitive__namespace = /*#__PURE__*/_interopNamespaceDefault(PopoverPrimitive);
@@ -4403,8 +4405,9 @@ const Reasoning = ({ text }) => {
4403
4405
 
4404
4406
  const AssistantMessage = ({ ToolFallback: ToolFallbackCustom }) => {
4405
4407
  const data = react.useMessage();
4408
+ const messageId = data.id;
4406
4409
  const isToolCallAndOrReasoning = data.content.every(({ type }) => type === "tool-call" || type === "reasoning");
4407
- return /* @__PURE__ */ jsxRuntime.jsxs(react.MessagePrimitive.Root, { className: "max-w-full", children: [
4410
+ return /* @__PURE__ */ jsxRuntime.jsxs(react.MessagePrimitive.Root, { className: "max-w-full", "data-message-id": messageId, children: [
4408
4411
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-icon6 text-ui-lg leading-ui-lg", children: /* @__PURE__ */ jsxRuntime.jsx(
4409
4412
  react.MessagePrimitive.Content,
4410
4413
  {
@@ -4604,7 +4607,9 @@ const UserMessageAttachments = () => {
4604
4607
  return /* @__PURE__ */ jsxRuntime.jsx(react.MessagePrimitive.Attachments, { components: { Attachment: InMessageContextWrapper } });
4605
4608
  };
4606
4609
  const UserMessage = () => {
4607
- return /* @__PURE__ */ jsxRuntime.jsxs(react.MessagePrimitive.Root, { className: "w-full flex items-end pb-4 flex-col", children: [
4610
+ const message = react.useMessage();
4611
+ const messageId = message?.id;
4612
+ return /* @__PURE__ */ jsxRuntime.jsxs(react.MessagePrimitive.Root, { className: "w-full flex items-end pb-4 flex-col", "data-message-id": messageId, children: [
4608
4613
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-[366px] px-5 py-3 text-icon6 text-ui-lg leading-ui-lg rounded-lg bg-surface3", children: /* @__PURE__ */ jsxRuntime.jsx(
4609
4614
  react.MessagePrimitive.Content,
4610
4615
  {
@@ -4865,7 +4870,7 @@ const ComposerAttachments = () => {
4865
4870
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex w-full flex-row items-center gap-4 pb-2", children: /* @__PURE__ */ jsxRuntime.jsx(react.ComposerPrimitive.Attachments, { components: { Attachment: AttachmentThumbnail } }) });
4866
4871
  };
4867
4872
 
4868
- const Thread = ({ ToolFallback, agentName, hasMemory }) => {
4873
+ const Thread = ({ ToolFallback, agentName, hasMemory, onInputChange }) => {
4869
4874
  const areaRef = React.useRef(null);
4870
4875
  useAutoscroll(areaRef, { enabled: true });
4871
4876
  const WrappedAssistantMessage = (props) => {
@@ -4886,7 +4891,7 @@ const Thread = ({ ToolFallback, agentName, hasMemory }) => {
4886
4891
  ) }),
4887
4892
  /* @__PURE__ */ jsxRuntime.jsx(react.ThreadPrimitive.If, { empty: false, children: /* @__PURE__ */ jsxRuntime.jsx("div", {}) })
4888
4893
  ] }),
4889
- /* @__PURE__ */ jsxRuntime.jsx(Composer$1, { hasMemory })
4894
+ /* @__PURE__ */ jsxRuntime.jsx(Composer$1, { hasMemory, onInputChange })
4890
4895
  ] });
4891
4896
  };
4892
4897
  const ThreadWrapper$1 = ({ children }) => {
@@ -4908,7 +4913,7 @@ const ThreadWelcome$1 = ({ agentName }) => {
4908
4913
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-4 font-medium", children: "How can I help you today?" })
4909
4914
  ] }) });
4910
4915
  };
4911
- const Composer$1 = ({ hasMemory }) => {
4916
+ const Composer$1 = ({ hasMemory, onInputChange }) => {
4912
4917
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-4", children: [
4913
4918
  /* @__PURE__ */ jsxRuntime.jsxs(react.ComposerPrimitive.Root, { children: [
4914
4919
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-[568px] w-full mx-auto pb-2", children: /* @__PURE__ */ jsxRuntime.jsx(ComposerAttachments, {}) }),
@@ -4920,7 +4925,8 @@ const Composer$1 = ({ hasMemory }) => {
4920
4925
  autoFocus: true,
4921
4926
  placeholder: "Enter your message...",
4922
4927
  name: "",
4923
- id: ""
4928
+ id: "",
4929
+ onChange: (e) => onInputChange?.(e.target.value)
4924
4930
  }
4925
4931
  ) }),
4926
4932
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
@@ -5196,6 +5202,7 @@ function MastraRuntimeProvider({
5196
5202
  const [messages, setMessages] = React.useState([]);
5197
5203
  const [currentThreadId, setCurrentThreadId] = React.useState(threadId);
5198
5204
  const { refetch: refreshWorkingMemory } = useWorkingMemory();
5205
+ const abortControllerRef = React.useRef(null);
5199
5206
  const {
5200
5207
  frequencyPenalty,
5201
5208
  presencePenalty,
@@ -5247,8 +5254,7 @@ function MastraRuntimeProvider({
5247
5254
  }
5248
5255
  }
5249
5256
  }, [initialMessages, threadId, memory]);
5250
- const mastra = useMastraClient();
5251
- const agent = mastra.getAgent(agentId);
5257
+ const baseClient = useMastraClient();
5252
5258
  const onNew = async (message) => {
5253
5259
  if (message.content[0]?.type !== "text") throw new Error("Only text messages are supported");
5254
5260
  const attachments = await convertToAIAttachments(message.attachments);
@@ -5258,6 +5264,13 @@ function MastraRuntimeProvider({
5258
5264
  { role: "user", content: input, attachments: message.attachments }
5259
5265
  ]);
5260
5266
  setIsRunning(true);
5267
+ const controller = new AbortController();
5268
+ abortControllerRef.current = controller;
5269
+ const clientWithAbort = new clientJs.MastraClient({
5270
+ ...baseClient.options,
5271
+ abortSignal: controller.signal
5272
+ });
5273
+ const agent = clientWithAbort.getAgent(agentId);
5261
5274
  try {
5262
5275
  if (chatWithGenerate) {
5263
5276
  const generateResponse = await agent.generate({
@@ -5282,7 +5295,7 @@ function MastraRuntimeProvider({
5282
5295
  ...memory ? { threadId, resourceId: agentId } : {},
5283
5296
  providerOptions
5284
5297
  });
5285
- if (generateResponse.response) {
5298
+ if (generateResponse.response && "messages" in generateResponse.response) {
5286
5299
  const latestMessage = generateResponse.response.messages.reduce(
5287
5300
  (acc, message2) => {
5288
5301
  const _content = Array.isArray(acc.content) ? acc.content : [];
@@ -5536,10 +5549,22 @@ function MastraRuntimeProvider({
5536
5549
  } catch (error) {
5537
5550
  console.error("Error occurred in MastraRuntimeProvider", error);
5538
5551
  setIsRunning(false);
5552
+ if (error.name === "AbortError") {
5553
+ return;
5554
+ }
5539
5555
  setMessages((currentConversation) => [
5540
5556
  ...currentConversation,
5541
5557
  { role: "assistant", content: [{ type: "text", text: `${error}` }] }
5542
5558
  ]);
5559
+ } finally {
5560
+ abortControllerRef.current = null;
5561
+ }
5562
+ };
5563
+ const onCancel = async () => {
5564
+ if (abortControllerRef.current) {
5565
+ abortControllerRef.current.abort();
5566
+ abortControllerRef.current = null;
5567
+ setIsRunning(false);
5543
5568
  }
5544
5569
  };
5545
5570
  const runtime = react.useExternalStoreRuntime({
@@ -5547,6 +5572,7 @@ function MastraRuntimeProvider({
5547
5572
  messages,
5548
5573
  convertMessage: convertMessage$2,
5549
5574
  onNew,
5575
+ onCancel,
5550
5576
  adapters: {
5551
5577
  attachments: new react.CompositeAttachmentAdapter([
5552
5578
  new react.SimpleImageAttachmentAdapter(),
@@ -5633,7 +5659,15 @@ const usePlaygroundStore = zustand.create()(
5633
5659
  )
5634
5660
  );
5635
5661
 
5636
- const AgentChat = ({ agentId, agentName, threadId, initialMessages, memory, refreshThreadList }) => {
5662
+ const AgentChat = ({
5663
+ agentId,
5664
+ agentName,
5665
+ threadId,
5666
+ initialMessages,
5667
+ memory,
5668
+ refreshThreadList,
5669
+ onInputChange
5670
+ }) => {
5637
5671
  const { settings } = useAgentSettings();
5638
5672
  const { runtimeContext } = usePlaygroundStore();
5639
5673
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -5647,7 +5681,7 @@ const AgentChat = ({ agentId, agentName, threadId, initialMessages, memory, refr
5647
5681
  refreshThreadList,
5648
5682
  settings,
5649
5683
  runtimeContext,
5650
- children: /* @__PURE__ */ jsxRuntime.jsx(Thread, { agentName: agentName ?? "", hasMemory: memory })
5684
+ children: /* @__PURE__ */ jsxRuntime.jsx(Thread, { agentName: agentName ?? "", hasMemory: memory, onInputChange })
5651
5685
  }
5652
5686
  );
5653
5687
  };
@@ -5835,26 +5869,41 @@ const TabsContent = React__namespace.forwardRef(({ className, ...props }, ref) =
5835
5869
  ));
5836
5870
  TabsContent.displayName = TabsPrimitive__namespace.Content.displayName;
5837
5871
 
5838
- const PlaygroundTabs = ({ children, defaultTab }) => {
5839
- const [tab, setTab] = React.useState(defaultTab);
5840
- return /* @__PURE__ */ jsxRuntime.jsx(Tabs, { value: tab, onValueChange: (value) => setTab(value), className: "h-full", children });
5872
+ const PlaygroundTabs = ({
5873
+ children,
5874
+ defaultTab,
5875
+ value,
5876
+ onValueChange
5877
+ }) => {
5878
+ const [internalTab, setInternalTab] = React.useState(defaultTab);
5879
+ const isControlled = value !== void 0 && onValueChange !== void 0;
5880
+ const currentTab = isControlled ? value : internalTab;
5881
+ const handleTabChange = (newValue) => {
5882
+ const typedValue = newValue;
5883
+ if (isControlled) {
5884
+ onValueChange(typedValue);
5885
+ } else {
5886
+ setInternalTab(typedValue);
5887
+ }
5888
+ };
5889
+ return /* @__PURE__ */ jsxRuntime.jsx(Tabs, { value: currentTab, onValueChange: handleTabChange, className: "h-full", children });
5841
5890
  };
5842
5891
  const TabList = ({ children }) => {
5843
- return /* @__PURE__ */ jsxRuntime.jsx(TabsList, { className: "border-b-sm border-border1 flex w-full shrink-0", children });
5892
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full overflow-x-auto", children: /* @__PURE__ */ jsxRuntime.jsx(TabsList, { className: "border-b-sm border-border1 flex min-w-full shrink-0", children }) });
5844
5893
  };
5845
5894
  const Tab = ({ children, value, onClick }) => {
5846
5895
  return /* @__PURE__ */ jsxRuntime.jsx(
5847
5896
  TabsTrigger,
5848
5897
  {
5849
5898
  value,
5850
- className: "text-xs p-3 text-mastra-el-3 data-[state=active]:text-mastra-el-5 data-[state=active]:border-b-2",
5899
+ 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",
5851
5900
  onClick,
5852
5901
  children
5853
5902
  }
5854
5903
  );
5855
5904
  };
5856
5905
  const TabContent = ({ children, value }) => {
5857
- return /* @__PURE__ */ jsxRuntime.jsx(TabsContent, { value, className: "h-full pb-5", children });
5906
+ return /* @__PURE__ */ jsxRuntime.jsx(TabsContent, { value, className: "h-full overflow-hidden flex flex-col", children });
5858
5907
  };
5859
5908
 
5860
5909
  const scrollableContentClass = cn(
@@ -7189,6 +7238,7 @@ const columns$2 = [
7189
7238
  {
7190
7239
  variant: "default",
7191
7240
  icon: providerMapToIcon[row.original.provider] || /* @__PURE__ */ jsxRuntime.jsx(OpenAIIcon, {}),
7241
+ className: "truncate",
7192
7242
  children: row.original.modelId || "N/A"
7193
7243
  }
7194
7244
  ) });
@@ -7358,6 +7408,497 @@ const RuntimeContextWrapper = ({ children }) => {
7358
7408
  ] });
7359
7409
  };
7360
7410
 
7411
+ const AgentMetadataSection = ({ title, children, hint }) => {
7412
+ const { Link } = useLinkComponent();
7413
+ return /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-2 pb-7 last:pb-0", children: [
7414
+ /* @__PURE__ */ jsxRuntime.jsxs(Txt, { as: "h3", variant: "ui-md", className: "text-icon3 flex items-center gap-1", children: [
7415
+ title,
7416
+ hint && /* @__PURE__ */ jsxRuntime.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
7417
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { children: /* @__PURE__ */ jsxRuntime.jsx(Link, { href: hint.link, target: "_blank", rel: "noopener noreferrer", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "text-icon3", size: "sm", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.InfoIcon, {}) }) }) }),
7418
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { children: hint.title })
7419
+ ] }) })
7420
+ ] }),
7421
+ children
7422
+ ] });
7423
+ };
7424
+
7425
+ const AgentMetadataList = ({ children }) => {
7426
+ return /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "flex flex-wrap gap-2", children });
7427
+ };
7428
+ const AgentMetadataListItem = ({ children }) => {
7429
+ return /* @__PURE__ */ jsxRuntime.jsx("li", { className: "shrink-0 font-medium", children });
7430
+ };
7431
+ const AgentMetadataListEmpty = ({ children }) => {
7432
+ return /* @__PURE__ */ jsxRuntime.jsx(Txt, { variant: "ui-sm", className: "text-icon6", children });
7433
+ };
7434
+
7435
+ const AgentMetadataWrapper = ({ children }) => {
7436
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-2 overflow-y-auto h-full px-5", children });
7437
+ };
7438
+
7439
+ const useScoresByEntityId = (entityId, entityType, page = 0) => {
7440
+ const client = useMastraClient();
7441
+ const [scores, setScores] = React.useState(null);
7442
+ const [isLoading, setIsLoading] = React.useState(true);
7443
+ React.useEffect(() => {
7444
+ const fetchScores = async () => {
7445
+ setIsLoading(true);
7446
+ try {
7447
+ const res = await client.getScoresByEntityId({
7448
+ entityId,
7449
+ entityType,
7450
+ page: page || 0,
7451
+ perPage: 10
7452
+ });
7453
+ setScores(res);
7454
+ setIsLoading(false);
7455
+ } catch (error) {
7456
+ setScores(null);
7457
+ setIsLoading(false);
7458
+ }
7459
+ };
7460
+ fetchScores();
7461
+ }, [entityId, entityType, page]);
7462
+ return { scores, isLoading };
7463
+ };
7464
+ const useScoresByScorerId = ({ scorerId, page = 0, entityId, entityType }) => {
7465
+ const client = useMastraClient();
7466
+ const [scores, setScores] = React.useState(null);
7467
+ const [isLoading, setIsLoading] = React.useState(true);
7468
+ React.useEffect(() => {
7469
+ const fetchScores = async () => {
7470
+ setIsLoading(true);
7471
+ try {
7472
+ const res = await client.getScoresByScorerId({
7473
+ scorerId,
7474
+ page: page || 0,
7475
+ entityId: entityId || void 0,
7476
+ entityType: entityType || void 0,
7477
+ perPage: 10
7478
+ });
7479
+ setScores(res);
7480
+ setIsLoading(false);
7481
+ } catch (error) {
7482
+ setScores(null);
7483
+ setIsLoading(false);
7484
+ }
7485
+ };
7486
+ fetchScores();
7487
+ }, [scorerId, page, entityId, entityType]);
7488
+ return { scores, isLoading };
7489
+ };
7490
+ const useScorer = (scorerId) => {
7491
+ const client = useMastraClient();
7492
+ const [scorer, setScorer] = React.useState(null);
7493
+ const [isLoading, setIsLoading] = React.useState(true);
7494
+ React.useEffect(() => {
7495
+ const fetchScorer = async () => {
7496
+ setIsLoading(true);
7497
+ try {
7498
+ const res = await client.getScorer(scorerId);
7499
+ setScorer(res);
7500
+ } catch (error) {
7501
+ setScorer(null);
7502
+ console.error("Error fetching scorer", error);
7503
+ sonner.toast.error("Error fetching scorer");
7504
+ } finally {
7505
+ setIsLoading(false);
7506
+ }
7507
+ };
7508
+ fetchScorer();
7509
+ }, [scorerId]);
7510
+ return { scorer, isLoading };
7511
+ };
7512
+ const useScorers = () => {
7513
+ const client = useMastraClient();
7514
+ const [scorers, setScorers] = React.useState({});
7515
+ const [isLoading, setIsLoading] = React.useState(true);
7516
+ React.useEffect(() => {
7517
+ const fetchScorers = async () => {
7518
+ setIsLoading(true);
7519
+ try {
7520
+ const res = await client.getScorers();
7521
+ setScorers(res);
7522
+ } catch (error) {
7523
+ setScorers({});
7524
+ console.error("Error fetching agents", error);
7525
+ sonner.toast.error("Error fetching agents");
7526
+ } finally {
7527
+ setIsLoading(false);
7528
+ }
7529
+ };
7530
+ fetchScorers();
7531
+ }, []);
7532
+ return { scorers, isLoading };
7533
+ };
7534
+
7535
+ const Entity = ({ children, className, onClick }) => {
7536
+ return /* @__PURE__ */ jsxRuntime.jsx(
7537
+ "div",
7538
+ {
7539
+ tabIndex: onClick ? 0 : void 0,
7540
+ onKeyDown: (e) => {
7541
+ if (!onClick) return;
7542
+ if (e.key === "Enter" || e.key === " ") {
7543
+ e.preventDefault();
7544
+ onClick?.();
7545
+ }
7546
+ },
7547
+ className: clsx(
7548
+ "flex gap-3 group/entity bg-surface3 rounded-lg border-sm border-border1 py-3 px-4",
7549
+ onClick && "cursor-pointer hover:bg-surface4 transition-all",
7550
+ className
7551
+ ),
7552
+ onClick,
7553
+ children
7554
+ }
7555
+ );
7556
+ };
7557
+ const EntityIcon = ({ children, className }) => {
7558
+ return /* @__PURE__ */ jsxRuntime.jsx(Icon, { size: "lg", className: clsx("text-icon3 mt-1", className), children });
7559
+ };
7560
+ const EntityName = ({ children, className }) => {
7561
+ return /* @__PURE__ */ jsxRuntime.jsx(Txt, { as: "p", variant: "ui-lg", className: clsx("text-icon6 font-medium", className), children });
7562
+ };
7563
+ const EntityDescription = ({ children, className }) => {
7564
+ return /* @__PURE__ */ jsxRuntime.jsx(Txt, { as: "p", variant: "ui-sm", className: clsx("text-icon3", className), children });
7565
+ };
7566
+ const EntityContent = ({ children, className }) => {
7567
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className, children });
7568
+ };
7569
+
7570
+ const ScorerList = ({ entityId, entityType }) => {
7571
+ const { scorers, isLoading } = useScorers();
7572
+ if (isLoading) {
7573
+ return /* @__PURE__ */ jsxRuntime.jsx(ScorerSkeleton, {});
7574
+ }
7575
+ const scorerList = Object.keys(scorers).filter((scorerKey) => {
7576
+ const scorer = scorers[scorerKey];
7577
+ if (entityType === "AGENT") {
7578
+ return scorer.agentIds.includes(entityId);
7579
+ }
7580
+ return scorer.workflowIds.includes(entityId);
7581
+ }).map((scorerKey) => ({ ...scorers[scorerKey], id: scorerKey }));
7582
+ if (scorerList.length === 0) {
7583
+ return /* @__PURE__ */ jsxRuntime.jsx(EmptyScorerList, {});
7584
+ }
7585
+ return /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "space-y-2", children: scorerList.map((scorer) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsx(ScorerEntity, { scorer }) }, scorer.id)) });
7586
+ };
7587
+ const EmptyScorerList = () => {
7588
+ return /* @__PURE__ */ jsxRuntime.jsx(Txt, { as: "p", variant: "ui-lg", className: "text-icon6", children: "No scorers were attached to this agent." });
7589
+ };
7590
+ const ScorerSkeleton = () => {
7591
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
7592
+ /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-4 w-24" }),
7593
+ /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-4 w-24" })
7594
+ ] });
7595
+ };
7596
+ const ScorerEntity = ({ scorer }) => {
7597
+ const { Link } = useLinkComponent();
7598
+ const linkRef = React.useRef(null);
7599
+ return /* @__PURE__ */ jsxRuntime.jsxs(Entity, { onClick: () => linkRef.current?.click(), children: [
7600
+ /* @__PURE__ */ jsxRuntime.jsx(EntityIcon, { children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.GaugeIcon, { className: "group-hover/entity:text-accent3" }) }),
7601
+ /* @__PURE__ */ jsxRuntime.jsxs(EntityContent, { children: [
7602
+ /* @__PURE__ */ jsxRuntime.jsx(EntityName, { children: /* @__PURE__ */ jsxRuntime.jsx(Link, { ref: linkRef, href: `/scorers/${scorer.id}`, children: scorer.scorer.name }) }),
7603
+ /* @__PURE__ */ jsxRuntime.jsx(EntityDescription, { children: scorer.scorer.description }),
7604
+ scorer.sampling?.type === "ratio" && /* @__PURE__ */ jsxRuntime.jsxs(Badge$1, { children: [
7605
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-icon3", children: "Sample rate:" }),
7606
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-icon6", children: scorer.sampling.rate })
7607
+ ] })
7608
+ ] })
7609
+ ] });
7610
+ };
7611
+
7612
+ const AgentMetadata = ({
7613
+ agent,
7614
+ promptSlot,
7615
+ hasMemoryEnabled,
7616
+ computeToolLink,
7617
+ computeWorkflowLink
7618
+ }) => {
7619
+ const providerIcon = providerMapToIcon[agent.provider || "openai.chat"];
7620
+ const agentTools = agent.tools ?? {};
7621
+ const tools = Object.keys(agentTools).map((key) => agentTools[key]);
7622
+ const agentWorkflows = agent.workflows ?? {};
7623
+ const workflows = Object.keys(agentWorkflows).map((key) => agentWorkflows[key]);
7624
+ return /* @__PURE__ */ jsxRuntime.jsxs(AgentMetadataWrapper, { children: [
7625
+ /* @__PURE__ */ jsxRuntime.jsx(AgentMetadataSection, { title: "Model", children: /* @__PURE__ */ jsxRuntime.jsx(Badge$1, { icon: providerIcon, className: "font-medium", children: agent.modelId || "N/A" }) }),
7626
+ /* @__PURE__ */ jsxRuntime.jsx(
7627
+ AgentMetadataSection,
7628
+ {
7629
+ title: "Memory",
7630
+ hint: {
7631
+ link: "https://mastra.ai/en/docs/agents/agent-memory",
7632
+ title: "Agent Memory documentation"
7633
+ },
7634
+ children: /* @__PURE__ */ jsxRuntime.jsx(Badge$1, { icon: /* @__PURE__ */ jsxRuntime.jsx(MemoryIcon, {}), variant: hasMemoryEnabled ? "success" : "error", className: "font-medium", children: hasMemoryEnabled ? "On" : "Off" })
7635
+ }
7636
+ ),
7637
+ /* @__PURE__ */ jsxRuntime.jsx(
7638
+ AgentMetadataSection,
7639
+ {
7640
+ title: "Tools",
7641
+ hint: {
7642
+ link: "https://mastra.ai/en/docs/agents/using-tools-and-mcp",
7643
+ title: "Using Tools and MCP documentation"
7644
+ },
7645
+ children: /* @__PURE__ */ jsxRuntime.jsx(AgentMetadataToolList, { tools, computeToolLink })
7646
+ }
7647
+ ),
7648
+ /* @__PURE__ */ jsxRuntime.jsx(
7649
+ AgentMetadataSection,
7650
+ {
7651
+ title: "Workflows",
7652
+ hint: {
7653
+ link: "https://mastra.ai/en/docs/workflows/overview",
7654
+ title: "Workflows documentation"
7655
+ },
7656
+ children: /* @__PURE__ */ jsxRuntime.jsx(AgentMetadataWorkflowList, { workflows, computeWorkflowLink })
7657
+ }
7658
+ ),
7659
+ /* @__PURE__ */ jsxRuntime.jsx(AgentMetadataSection, { title: "Scorers", children: /* @__PURE__ */ jsxRuntime.jsx(AgentMetadataScorerList, { entityId: agent.name }) }),
7660
+ /* @__PURE__ */ jsxRuntime.jsx(AgentMetadataSection, { title: "System Prompt", children: promptSlot })
7661
+ ] });
7662
+ };
7663
+ const AgentMetadataToolList = ({ tools, computeToolLink }) => {
7664
+ const { Link } = useLinkComponent();
7665
+ if (tools.length === 0) {
7666
+ return /* @__PURE__ */ jsxRuntime.jsx(AgentMetadataListEmpty, { children: "No tools" });
7667
+ }
7668
+ return /* @__PURE__ */ jsxRuntime.jsx(AgentMetadataList, { children: tools.map((tool) => /* @__PURE__ */ jsxRuntime.jsx(AgentMetadataListItem, { children: /* @__PURE__ */ jsxRuntime.jsx(Link, { href: computeToolLink(tool), children: /* @__PURE__ */ jsxRuntime.jsx(Badge$1, { icon: /* @__PURE__ */ jsxRuntime.jsx(ToolsIcon, { className: "text-[#ECB047]" }), children: tool.id }) }) }, tool.id)) });
7669
+ };
7670
+ const AgentMetadataScorerList = ({ entityId }) => {
7671
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-5 pb-5", children: /* @__PURE__ */ jsxRuntime.jsx(ScorerList, { entityId, entityType: "AGENT" }) });
7672
+ };
7673
+ const AgentMetadataWorkflowList = ({ workflows, computeWorkflowLink }) => {
7674
+ const { Link } = useLinkComponent();
7675
+ if (workflows.length === 0) {
7676
+ return /* @__PURE__ */ jsxRuntime.jsx(AgentMetadataListEmpty, { children: "No workflows" });
7677
+ }
7678
+ return /* @__PURE__ */ jsxRuntime.jsx(AgentMetadataList, { children: workflows.map((workflow) => /* @__PURE__ */ jsxRuntime.jsx(AgentMetadataListItem, { children: /* @__PURE__ */ jsxRuntime.jsx(Link, { href: computeWorkflowLink(workflow), children: /* @__PURE__ */ jsxRuntime.jsx(Badge$1, { icon: /* @__PURE__ */ jsxRuntime.jsx(WorkflowIcon, { className: "text-accent3" }), children: workflow.name }) }) }, workflow.name)) });
7679
+ };
7680
+
7681
+ const AgentMetadataPrompt = ({ prompt }) => {
7682
+ return /* @__PURE__ */ jsxRuntime.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 });
7683
+ };
7684
+
7685
+ const EntityHeader = ({ icon, title, isLoading, children }) => {
7686
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-5", children: [
7687
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-icon6 flex items-center gap-2", children: [
7688
+ /* @__PURE__ */ jsxRuntime.jsx(Icon, { size: "lg", className: "bg-surface4 rounded-md p-1", children: icon }),
7689
+ isLoading ? /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-3 w-1/3" }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex min-w-0 items-center gap-4", children: /* @__PURE__ */ jsxRuntime.jsx(Txt, { variant: "header-md", as: "h2", className: "truncate font-medium", children: title }) })
7690
+ ] }),
7691
+ children && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pt-2", children })
7692
+ ] });
7693
+ };
7694
+
7695
+ const AgentEntityHeader = ({ agentId, isLoading, agentName }) => {
7696
+ const { handleCopy } = useCopyToClipboard({ text: agentId });
7697
+ return /* @__PURE__ */ jsxRuntime.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(EntityHeader, { icon: /* @__PURE__ */ jsxRuntime.jsx(AgentIcon, {}), title: agentName, isLoading, children: /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
7698
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: handleCopy, className: "h-badge-default shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(Badge$1, { icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CopyIcon, {}), variant: "default", children: agentId }) }) }),
7699
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { children: "Copy Agent ID for use in code" })
7700
+ ] }) }) });
7701
+ };
7702
+
7703
+ const Threads = ({ children }) => {
7704
+ return /* @__PURE__ */ jsxRuntime.jsx("nav", { className: "bg-surface2 border-r-sm border-border1 min-h-full overflow-hidden", children });
7705
+ };
7706
+ const ThreadLink = ({ children, as: Component = "a", href, className, prefetch, to }) => {
7707
+ return /* @__PURE__ */ jsxRuntime.jsx(
7708
+ Component,
7709
+ {
7710
+ href,
7711
+ prefetch,
7712
+ to,
7713
+ className: clsx("text-ui-sm flex h-full w-full flex-col justify-center font-medium", className),
7714
+ children
7715
+ }
7716
+ );
7717
+ };
7718
+ const ThreadList = ({ children }) => {
7719
+ return /* @__PURE__ */ jsxRuntime.jsx("ol", { children });
7720
+ };
7721
+ const ThreadItem = ({ children, isActive }) => {
7722
+ return /* @__PURE__ */ jsxRuntime.jsx(
7723
+ "li",
7724
+ {
7725
+ className: clsx(
7726
+ "border-b-sm border-border1 hover:bg-surface3 group flex h-[54px] items-center justify-between gap-2 pl-5 py-2",
7727
+ isActive && "bg-surface4"
7728
+ ),
7729
+ children
7730
+ }
7731
+ );
7732
+ };
7733
+ const ThreadDeleteButton = ({ onClick }) => {
7734
+ return /* @__PURE__ */ jsxRuntime.jsx(
7735
+ Button,
7736
+ {
7737
+ className: "shrink-0 border-none bg-transparent opacity-0 transition-all group-focus-within:opacity-100 group-hover:opacity-100",
7738
+ onClick,
7739
+ children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { "aria-label": "delete thread", className: "text-icon3" }) })
7740
+ }
7741
+ );
7742
+ };
7743
+
7744
+ const AlertDialogRoot = AlertDialogPrimitive__namespace.Root;
7745
+ const AlertDialogTrigger = AlertDialogPrimitive__namespace.Trigger;
7746
+ const AlertDialogPortal = AlertDialogPrimitive__namespace.Portal;
7747
+ function AlertDialog({
7748
+ open,
7749
+ onOpenChange,
7750
+ children
7751
+ }) {
7752
+ return /* @__PURE__ */ jsxRuntime.jsx(AlertDialogRoot, { open, onOpenChange, children });
7753
+ }
7754
+ const AlertDialogOverlay = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
7755
+ AlertDialogPrimitive__namespace.Overlay,
7756
+ {
7757
+ className: cn(
7758
+ "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",
7759
+ className
7760
+ ),
7761
+ ...props,
7762
+ ref
7763
+ }
7764
+ ));
7765
+ AlertDialogOverlay.displayName = AlertDialogPrimitive__namespace.Overlay.displayName;
7766
+ const AlertDialogContent = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(AlertDialogPortal, { children: [
7767
+ /* @__PURE__ */ jsxRuntime.jsx(AlertDialogOverlay, {}),
7768
+ /* @__PURE__ */ jsxRuntime.jsx(
7769
+ AlertDialogPrimitive__namespace.Content,
7770
+ {
7771
+ ref,
7772
+ className: cn(
7773
+ "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",
7774
+ className
7775
+ ),
7776
+ ...props
7777
+ }
7778
+ )
7779
+ ] }));
7780
+ AlertDialogContent.displayName = AlertDialogPrimitive__namespace.Content.displayName;
7781
+ const AlertDialogHeader = ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex flex-col space-y-2 text-center sm:text-left", className), ...props });
7782
+ AlertDialogHeader.displayName = "AlertDialogHeader";
7783
+ const AlertDialogFooter = ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className), ...props });
7784
+ AlertDialogFooter.displayName = "AlertDialogFooter";
7785
+ const AlertDialogTitle = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(AlertDialogPrimitive__namespace.Title, { ref, className: cn("text-lg font-semibold", className), ...props }));
7786
+ AlertDialogTitle.displayName = AlertDialogPrimitive__namespace.Title.displayName;
7787
+ const AlertDialogDescription = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(AlertDialogPrimitive__namespace.Description, { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
7788
+ AlertDialogDescription.displayName = AlertDialogPrimitive__namespace.Description.displayName;
7789
+ const AlertDialogAction = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(AlertDialogPrimitive__namespace.Action, { ref, className: cn(buttonVariants(), className), ...props }));
7790
+ AlertDialogAction.displayName = AlertDialogPrimitive__namespace.Action.displayName;
7791
+ const AlertDialogCancel = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
7792
+ AlertDialogPrimitive__namespace.Cancel,
7793
+ {
7794
+ ref,
7795
+ className: cn(buttonVariants({ variant: "outline" }), "mt-2 sm:mt-0", className),
7796
+ ...props
7797
+ }
7798
+ ));
7799
+ AlertDialogCancel.displayName = AlertDialogPrimitive__namespace.Cancel.displayName;
7800
+ AlertDialog.Trigger = AlertDialogTrigger;
7801
+ AlertDialog.Portal = AlertDialogPortal;
7802
+ AlertDialog.Overlay = AlertDialogOverlay;
7803
+ AlertDialog.Content = AlertDialogContent;
7804
+ AlertDialog.Header = AlertDialogHeader;
7805
+ AlertDialog.Footer = AlertDialogFooter;
7806
+ AlertDialog.Title = AlertDialogTitle;
7807
+ AlertDialog.Description = AlertDialogDescription;
7808
+ AlertDialog.Action = AlertDialogAction;
7809
+ AlertDialog.Cancel = AlertDialogCancel;
7810
+
7811
+ const ChatThreads = ({
7812
+ computeNewThreadLink,
7813
+ computeThreadLink,
7814
+ threads,
7815
+ isLoading,
7816
+ threadId,
7817
+ onDelete
7818
+ }) => {
7819
+ const { Link } = useLinkComponent();
7820
+ const [deleteId, setDeleteId] = React.useState(null);
7821
+ if (isLoading) {
7822
+ return /* @__PURE__ */ jsxRuntime.jsx(ChatThreadSkeleton, {});
7823
+ }
7824
+ const reverseThreads = [...threads].reverse();
7825
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "overflow-y-auto h-full w-full", children: [
7826
+ /* @__PURE__ */ jsxRuntime.jsx(Threads, { children: /* @__PURE__ */ jsxRuntime.jsxs(ThreadList, { children: [
7827
+ /* @__PURE__ */ jsxRuntime.jsx(ThreadItem, { children: /* @__PURE__ */ jsxRuntime.jsx(ThreadLink, { as: Link, to: computeNewThreadLink(), children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-accent1 flex items-center gap-4", children: [
7828
+ /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "bg-surface4 rounded-lg", size: "lg", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, {}) }),
7829
+ "New Chat"
7830
+ ] }) }) }),
7831
+ reverseThreads.length === 0 && /* @__PURE__ */ jsxRuntime.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!" }),
7832
+ reverseThreads.map((thread) => {
7833
+ const isActive = thread.id === threadId;
7834
+ return /* @__PURE__ */ jsxRuntime.jsxs(ThreadItem, { isActive, children: [
7835
+ /* @__PURE__ */ jsxRuntime.jsxs(ThreadLink, { as: Link, to: computeThreadLink(thread.id), children: [
7836
+ /* @__PURE__ */ jsxRuntime.jsx(ThreadTitle, { title: thread.title }),
7837
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: formatDay(thread.createdAt) })
7838
+ ] }),
7839
+ /* @__PURE__ */ jsxRuntime.jsx(ThreadDeleteButton, { onClick: () => setDeleteId(thread.id) })
7840
+ ] }, thread.id);
7841
+ })
7842
+ ] }) }),
7843
+ /* @__PURE__ */ jsxRuntime.jsx(
7844
+ DeleteThreadDialog,
7845
+ {
7846
+ open: !!deleteId,
7847
+ onOpenChange: () => setDeleteId(null),
7848
+ onDelete: () => {
7849
+ if (deleteId) {
7850
+ onDelete(deleteId);
7851
+ }
7852
+ }
7853
+ }
7854
+ )
7855
+ ] });
7856
+ };
7857
+ const DeleteThreadDialog = ({ open, onOpenChange, onDelete }) => {
7858
+ return /* @__PURE__ */ jsxRuntime.jsx(AlertDialog, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsxs(AlertDialog.Content, { children: [
7859
+ /* @__PURE__ */ jsxRuntime.jsxs(AlertDialog.Header, { children: [
7860
+ /* @__PURE__ */ jsxRuntime.jsx(AlertDialog.Title, { children: "Are you absolutely sure?" }),
7861
+ /* @__PURE__ */ jsxRuntime.jsx(AlertDialog.Description, { children: "This action cannot be undone. This will permanently delete your chat and remove it from our servers." })
7862
+ ] }),
7863
+ /* @__PURE__ */ jsxRuntime.jsxs(AlertDialog.Footer, { children: [
7864
+ /* @__PURE__ */ jsxRuntime.jsx(AlertDialog.Cancel, { children: "Cancel" }),
7865
+ /* @__PURE__ */ jsxRuntime.jsx(AlertDialog.Action, { onClick: onDelete, children: "Continue" })
7866
+ ] })
7867
+ ] }) });
7868
+ };
7869
+ const ChatThreadSkeleton = () => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4 w-full h-full space-y-2", children: [
7870
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-9 w-9" }) }),
7871
+ /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-4" }),
7872
+ /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-4" }),
7873
+ /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-4" }),
7874
+ /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-4" }),
7875
+ /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-4" })
7876
+ ] });
7877
+ function isDefaultThreadName(name) {
7878
+ const defaultPattern = /^New Thread \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z$/;
7879
+ return defaultPattern.test(name);
7880
+ }
7881
+ function ThreadTitle({ title }) {
7882
+ if (!title) {
7883
+ return null;
7884
+ }
7885
+ if (isDefaultThreadName(title)) {
7886
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Chat from" });
7887
+ }
7888
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate max-w-[14rem]", children: title });
7889
+ }
7890
+ const formatDay = (date) => {
7891
+ const options = {
7892
+ month: "short",
7893
+ day: "numeric",
7894
+ hour: "numeric",
7895
+ minute: "numeric",
7896
+ second: "numeric",
7897
+ hour12: true
7898
+ };
7899
+ return new Date(date).toLocaleString("en-us", options).replace(",", " at");
7900
+ };
7901
+
7361
7902
  const convertMessage$1 = (message) => {
7362
7903
  return message;
7363
7904
  };
@@ -10667,41 +11208,6 @@ const NetworkTableSkeleton = () => {
10667
11208
  ] });
10668
11209
  };
10669
11210
 
10670
- const Entity = ({ children, className, onClick }) => {
10671
- return /* @__PURE__ */ jsxRuntime.jsx(
10672
- "div",
10673
- {
10674
- tabIndex: onClick ? 0 : void 0,
10675
- onKeyDown: (e) => {
10676
- if (!onClick) return;
10677
- if (e.key === "Enter" || e.key === " ") {
10678
- e.preventDefault();
10679
- onClick?.();
10680
- }
10681
- },
10682
- className: clsx(
10683
- "flex gap-3 group/entity bg-surface3 rounded-lg border-sm border-border1 py-3 px-4",
10684
- onClick && "cursor-pointer hover:bg-surface4 transition-all",
10685
- className
10686
- ),
10687
- onClick,
10688
- children
10689
- }
10690
- );
10691
- };
10692
- const EntityIcon = ({ children, className }) => {
10693
- return /* @__PURE__ */ jsxRuntime.jsx(Icon, { size: "lg", className: clsx("text-icon3 mt-1", className), children });
10694
- };
10695
- const EntityName = ({ children, className }) => {
10696
- return /* @__PURE__ */ jsxRuntime.jsx(Txt, { as: "p", variant: "ui-lg", className: clsx("text-icon6 font-medium", className), children });
10697
- };
10698
- const EntityDescription = ({ children, className }) => {
10699
- return /* @__PURE__ */ jsxRuntime.jsx(Txt, { as: "p", variant: "ui-sm", className: clsx("text-icon3", className), children });
10700
- };
10701
- const EntityContent = ({ children, className }) => {
10702
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className, children });
10703
- };
10704
-
10705
11211
  const ToolList = ({ tools, agents, isLoading, computeLink, computeAgentLink }) => {
10706
11212
  const toolsWithAgents = React.useMemo(() => prepareAgents(tools, agents), [tools, agents]);
10707
11213
  if (isLoading)
@@ -11233,7 +11739,7 @@ const DatePicker = ({
11233
11739
  DatePickerOnly,
11234
11740
  {
11235
11741
  value,
11236
- setValue: (v) => setValue(v ? /* @__PURE__ */ new Date(`${v}z`) : null),
11742
+ setValue,
11237
11743
  clearable: props.clearable,
11238
11744
  setOpenPopover,
11239
11745
  ...props
@@ -13283,57 +13789,6 @@ function devUIStyleRequested(name) {
13283
13789
  }
13284
13790
  }
13285
13791
 
13286
- const Threads = ({ children }) => {
13287
- return /* @__PURE__ */ jsxRuntime.jsx("nav", { className: "bg-surface2 border-r-sm border-border1 min-h-full overflow-hidden", children });
13288
- };
13289
- const ThreadLink = ({ children, as: Component = "a", href, className, prefetch, to }) => {
13290
- return /* @__PURE__ */ jsxRuntime.jsx(
13291
- Component,
13292
- {
13293
- href,
13294
- prefetch,
13295
- to,
13296
- className: clsx("text-ui-sm flex h-full w-full flex-col justify-center font-medium", className),
13297
- children
13298
- }
13299
- );
13300
- };
13301
- const ThreadList = ({ children }) => {
13302
- return /* @__PURE__ */ jsxRuntime.jsx("ol", { children });
13303
- };
13304
- const ThreadItem = ({ children, isActive }) => {
13305
- return /* @__PURE__ */ jsxRuntime.jsx(
13306
- "li",
13307
- {
13308
- className: clsx(
13309
- "border-b-sm border-border1 hover:bg-surface3 group flex h-[54px] items-center justify-between gap-2 pl-5 py-2",
13310
- isActive && "bg-surface4"
13311
- ),
13312
- children
13313
- }
13314
- );
13315
- };
13316
- const ThreadDeleteButton = ({ onClick }) => {
13317
- return /* @__PURE__ */ jsxRuntime.jsx(
13318
- Button,
13319
- {
13320
- className: "shrink-0 border-none bg-transparent opacity-0 transition-all group-focus-within:opacity-100 group-hover:opacity-100",
13321
- onClick,
13322
- children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { "aria-label": "delete thread", className: "text-icon3" }) })
13323
- }
13324
- );
13325
- };
13326
-
13327
- const EntityHeader = ({ icon, title, isLoading, children }) => {
13328
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-5", children: [
13329
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-icon6 flex items-center gap-2", children: [
13330
- /* @__PURE__ */ jsxRuntime.jsx(Icon, { size: "lg", className: "bg-surface4 rounded-md p-1", children: icon }),
13331
- isLoading ? /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-3 w-1/3" }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex min-w-0 items-center gap-4", children: /* @__PURE__ */ jsxRuntime.jsx(Txt, { variant: "header-md", as: "h2", className: "truncate font-medium", children: title }) })
13332
- ] }),
13333
- children
13334
- ] });
13335
- };
13336
-
13337
13792
  const Breadcrumb = ({ children, label }) => {
13338
13793
  return /* @__PURE__ */ jsxRuntime.jsx("nav", { "aria-label": label, children: /* @__PURE__ */ jsxRuntime.jsx("ol", { className: "gap-sm flex items-center", children }) });
13339
13794
  };
@@ -13535,10 +13990,284 @@ const PlaygroundQueryClient = ({ children }) => {
13535
13990
  return /* @__PURE__ */ jsxRuntime.jsx(reactQuery.QueryClientProvider, { client: queryClient, children });
13536
13991
  };
13537
13992
 
13993
+ const formatRelativeTime = (date) => {
13994
+ const now = /* @__PURE__ */ new Date();
13995
+ const seconds = Math.floor((now.getTime() - date.getTime()) / 1e3);
13996
+ if (seconds < 60) return "just now";
13997
+ if (seconds < 3600) return `${Math.floor(seconds / 60)}m ago`;
13998
+ if (seconds < 86400) return `${Math.floor(seconds / 3600)}h ago`;
13999
+ if (seconds < 604800) return `${Math.floor(seconds / 86400)}d ago`;
14000
+ return date.toLocaleDateString();
14001
+ };
14002
+ const MemorySearch = ({
14003
+ searchMemory,
14004
+ onResultClick,
14005
+ className,
14006
+ currentThreadId,
14007
+ chatInputValue
14008
+ }) => {
14009
+ const [query, setQuery] = React.useState("");
14010
+ const [results, setResults] = React.useState([]);
14011
+ const [isSearching, setIsSearching] = React.useState(false);
14012
+ const [isOpen, setIsOpen] = React.useState(false);
14013
+ const [error, setError] = React.useState(null);
14014
+ const searchTimeoutRef = React.useRef(void 0);
14015
+ const dropdownRef = React.useRef(null);
14016
+ const prevThreadIdRef = React.useRef(currentThreadId);
14017
+ const lastSearchTimeRef = React.useRef(0);
14018
+ const pendingSearchRef = React.useRef(null);
14019
+ const handleSearch = React.useCallback(
14020
+ async (searchQuery) => {
14021
+ if (!searchQuery.trim()) {
14022
+ setError(null);
14023
+ return;
14024
+ }
14025
+ setIsSearching(true);
14026
+ setError(null);
14027
+ try {
14028
+ const response = await searchMemory(searchQuery);
14029
+ setResults(response.results);
14030
+ setIsOpen((prev) => prev || response.results.length > 0);
14031
+ } catch (err) {
14032
+ setError("Failed to search memory");
14033
+ console.error("Memory search error:", err);
14034
+ } finally {
14035
+ setIsSearching(false);
14036
+ }
14037
+ },
14038
+ [searchMemory]
14039
+ );
14040
+ const handleInputChange = React.useCallback(
14041
+ (e) => {
14042
+ const value = e.target.value;
14043
+ setQuery(value);
14044
+ if (searchTimeoutRef.current) {
14045
+ clearTimeout(searchTimeoutRef.current);
14046
+ }
14047
+ if (value.trim()) {
14048
+ const now = Date.now();
14049
+ const timeSinceLastSearch = now - lastSearchTimeRef.current;
14050
+ if (timeSinceLastSearch >= 500) {
14051
+ setIsSearching(true);
14052
+ handleSearch(value);
14053
+ lastSearchTimeRef.current = now;
14054
+ } else {
14055
+ setIsSearching(true);
14056
+ pendingSearchRef.current = value;
14057
+ const remainingTime = 500 - timeSinceLastSearch;
14058
+ searchTimeoutRef.current = setTimeout(() => {
14059
+ if (pendingSearchRef.current) {
14060
+ handleSearch(pendingSearchRef.current);
14061
+ lastSearchTimeRef.current = Date.now();
14062
+ pendingSearchRef.current = null;
14063
+ }
14064
+ }, remainingTime);
14065
+ }
14066
+ } else {
14067
+ setResults([]);
14068
+ setIsOpen(false);
14069
+ setIsSearching(false);
14070
+ pendingSearchRef.current = null;
14071
+ }
14072
+ },
14073
+ [handleSearch]
14074
+ );
14075
+ const handleKeyDown = React.useCallback(
14076
+ (e) => {
14077
+ if (e.key === "Enter") {
14078
+ e.preventDefault();
14079
+ if (searchTimeoutRef.current) {
14080
+ clearTimeout(searchTimeoutRef.current);
14081
+ }
14082
+ handleSearch(query);
14083
+ }
14084
+ },
14085
+ [query, handleSearch]
14086
+ );
14087
+ React.useEffect(() => {
14088
+ return () => {
14089
+ if (searchTimeoutRef.current) {
14090
+ clearTimeout(searchTimeoutRef.current);
14091
+ }
14092
+ };
14093
+ }, []);
14094
+ React.useEffect(() => {
14095
+ const handleClickOutside = (event) => {
14096
+ if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
14097
+ setIsOpen(false);
14098
+ }
14099
+ };
14100
+ document.addEventListener("mousedown", handleClickOutside);
14101
+ return () => document.removeEventListener("mousedown", handleClickOutside);
14102
+ }, []);
14103
+ React.useEffect(() => {
14104
+ if (prevThreadIdRef.current !== currentThreadId && query.trim()) {
14105
+ handleSearch(query);
14106
+ }
14107
+ prevThreadIdRef.current = currentThreadId;
14108
+ }, [currentThreadId, query, handleSearch]);
14109
+ React.useEffect(() => {
14110
+ if (chatInputValue !== void 0 && chatInputValue !== query) {
14111
+ setQuery(chatInputValue);
14112
+ if (searchTimeoutRef.current) {
14113
+ clearTimeout(searchTimeoutRef.current);
14114
+ }
14115
+ if (chatInputValue.trim()) {
14116
+ const now = Date.now();
14117
+ const timeSinceLastSearch = now - lastSearchTimeRef.current;
14118
+ if (timeSinceLastSearch >= 500) {
14119
+ setIsSearching(true);
14120
+ handleSearch(chatInputValue);
14121
+ lastSearchTimeRef.current = now;
14122
+ } else {
14123
+ setIsSearching(true);
14124
+ pendingSearchRef.current = chatInputValue;
14125
+ const remainingTime = 500 - timeSinceLastSearch;
14126
+ searchTimeoutRef.current = setTimeout(() => {
14127
+ if (pendingSearchRef.current) {
14128
+ handleSearch(pendingSearchRef.current);
14129
+ lastSearchTimeRef.current = Date.now();
14130
+ pendingSearchRef.current = null;
14131
+ }
14132
+ }, remainingTime);
14133
+ }
14134
+ } else {
14135
+ setResults([]);
14136
+ setIsOpen(false);
14137
+ setIsSearching(false);
14138
+ pendingSearchRef.current = null;
14139
+ }
14140
+ }
14141
+ return () => {
14142
+ if (searchTimeoutRef.current) {
14143
+ clearTimeout(searchTimeoutRef.current);
14144
+ }
14145
+ };
14146
+ }, [chatInputValue]);
14147
+ const handleResultClick = (messageId, threadId) => {
14148
+ onResultClick?.(messageId, threadId);
14149
+ };
14150
+ const clearSearch = () => {
14151
+ setQuery("");
14152
+ setResults([]);
14153
+ setIsOpen(false);
14154
+ setError(null);
14155
+ if (searchTimeoutRef.current) {
14156
+ clearTimeout(searchTimeoutRef.current);
14157
+ }
14158
+ };
14159
+ const truncateContent = (content, maxLength = 100) => {
14160
+ if (content.length <= maxLength) return content;
14161
+ return content.substring(0, maxLength) + "...";
14162
+ };
14163
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col h-full", className), ref: dropdownRef, children: [
14164
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative shrink-0", children: [
14165
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-icon3" }),
14166
+ /* @__PURE__ */ jsxRuntime.jsx(
14167
+ Input,
14168
+ {
14169
+ type: "text",
14170
+ value: query,
14171
+ onChange: handleInputChange,
14172
+ onKeyDown: handleKeyDown,
14173
+ placeholder: "Search memory...",
14174
+ className: "pl-10 pr-10 bg-surface3 border-border1"
14175
+ }
14176
+ ),
14177
+ query && /* @__PURE__ */ jsxRuntime.jsx(
14178
+ Button$1,
14179
+ {
14180
+ onClick: clearSearch,
14181
+ variant: "ghost",
14182
+ size: "sm",
14183
+ className: "absolute right-1 top-1/2 transform -translate-y-1/2 h-6 w-6 p-0",
14184
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-4 w-4" })
14185
+ }
14186
+ )
14187
+ ] }),
14188
+ (isOpen || query && (isSearching || results.length === 0)) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2 flex-1 bg-surface3 border border-border1 rounded-lg shadow-lg overflow-y-auto", children: error ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(Txt, { variant: "ui-sm", className: "text-red-500", children: error }) }) : isSearching && results.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(Txt, { variant: "ui-sm", className: "text-icon3", children: "Searching..." }) }) : results.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 text-center", children: /* @__PURE__ */ jsxRuntime.jsxs(Txt, { variant: "ui-sm", className: "text-icon3", children: [
14189
+ 'No results found for "',
14190
+ query,
14191
+ '"'
14192
+ ] }) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-2", children: results.map((result) => /* @__PURE__ */ jsxRuntime.jsx(
14193
+ "button",
14194
+ {
14195
+ onClick: () => handleResultClick(result.id, result.threadId),
14196
+ className: cn(
14197
+ "w-full px-4 py-3 hover:bg-surface4 transition-colors duration-150 text-left border-b border-border1 last:border-b-0",
14198
+ result.threadId !== currentThreadId && "border-l-2 border-l-blue-400"
14199
+ ),
14200
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
14201
+ result.context?.before && result.context.before.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "opacity-50 text-xs space-y-1", children: result.context.before.map((msg, idx) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-2", children: [
14202
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-medium", children: [
14203
+ msg.role,
14204
+ ":"
14205
+ ] }),
14206
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-icon3", children: truncateContent(msg.content, 50) })
14207
+ ] }, idx)) }),
14208
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-start justify-between gap-2", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
14209
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mb-1", children: [
14210
+ /* @__PURE__ */ jsxRuntime.jsx(
14211
+ "span",
14212
+ {
14213
+ className: cn(
14214
+ "text-xs font-medium px-2 py-0.5 rounded",
14215
+ result.role === "user" ? "bg-blue-500/20 text-blue-400" : "bg-green-500/20 text-green-400"
14216
+ ),
14217
+ children: result.role
14218
+ }
14219
+ ),
14220
+ /* @__PURE__ */ jsxRuntime.jsx(Txt, { variant: "ui-xs", className: "text-icon3", children: formatRelativeTime(new Date(result.createdAt)) }),
14221
+ result.threadTitle && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
14222
+ /* @__PURE__ */ jsxRuntime.jsxs(
14223
+ Txt,
14224
+ {
14225
+ variant: "ui-xs",
14226
+ className: cn(
14227
+ "truncate max-w-[150px]",
14228
+ result.threadId !== currentThreadId ? "text-blue-400 font-medium" : "text-icon3"
14229
+ ),
14230
+ title: result.threadTitle,
14231
+ children: [
14232
+ "• ",
14233
+ result.threadTitle
14234
+ ]
14235
+ }
14236
+ ),
14237
+ result.threadId !== currentThreadId && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "w-3 h-3 text-blue-400" })
14238
+ ] })
14239
+ ] }),
14240
+ /* @__PURE__ */ jsxRuntime.jsx(Txt, { variant: "ui-sm", className: "text-icon5 break-words", children: truncateContent(result.content) })
14241
+ ] }) }),
14242
+ result.context?.after && result.context.after.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "opacity-50 text-xs space-y-1", children: result.context.after.map((msg, idx) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-2", children: [
14243
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-medium", children: [
14244
+ msg.role,
14245
+ ":"
14246
+ ] }),
14247
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-icon3", children: truncateContent(msg.content, 50) })
14248
+ ] }, idx)) })
14249
+ ] })
14250
+ },
14251
+ result.id
14252
+ )) }) })
14253
+ ] });
14254
+ };
14255
+
13538
14256
  exports.AgentChat = AgentChat;
13539
14257
  exports.AgentCoinIcon = AgentCoinIcon;
14258
+ exports.AgentEntityHeader = AgentEntityHeader;
13540
14259
  exports.AgentEvals = AgentEvals;
13541
14260
  exports.AgentIcon = AgentIcon;
14261
+ exports.AgentMetadata = AgentMetadata;
14262
+ exports.AgentMetadataList = AgentMetadataList;
14263
+ exports.AgentMetadataListEmpty = AgentMetadataListEmpty;
14264
+ exports.AgentMetadataListItem = AgentMetadataListItem;
14265
+ exports.AgentMetadataPrompt = AgentMetadataPrompt;
14266
+ exports.AgentMetadataScorerList = AgentMetadataScorerList;
14267
+ exports.AgentMetadataSection = AgentMetadataSection;
14268
+ exports.AgentMetadataToolList = AgentMetadataToolList;
14269
+ exports.AgentMetadataWorkflowList = AgentMetadataWorkflowList;
14270
+ exports.AgentMetadataWrapper = AgentMetadataWrapper;
13542
14271
  exports.AgentNetworkCoinIcon = AgentNetworkCoinIcon;
13543
14272
  exports.AgentSettings = AgentSettings;
13544
14273
  exports.AgentSettingsContext = AgentSettingsContext;
@@ -13546,12 +14275,14 @@ exports.AgentSettingsProvider = AgentSettingsProvider;
13546
14275
  exports.AgentsTable = AgentsTable;
13547
14276
  exports.AgentsTableSkeleton = AgentsTableSkeleton;
13548
14277
  exports.AiIcon = AiIcon;
14278
+ exports.AlertDialog = AlertDialog;
13549
14279
  exports.ApiIcon = ApiIcon;
13550
14280
  exports.Badge = Badge$1;
13551
14281
  exports.BranchIcon = BranchIcon;
13552
14282
  exports.Breadcrumb = Breadcrumb;
13553
14283
  exports.Button = Button;
13554
14284
  exports.Cell = Cell;
14285
+ exports.ChatThreads = ChatThreads;
13555
14286
  exports.CheckIcon = CheckIcon;
13556
14287
  exports.ChevronIcon = ChevronIcon;
13557
14288
  exports.CommitIcon = CommitIcon;
@@ -13567,6 +14298,7 @@ exports.DividerIcon = DividerIcon;
13567
14298
  exports.DocsIcon = DocsIcon;
13568
14299
  exports.DynamicForm = DynamicForm;
13569
14300
  exports.EmptyAgentsTable = EmptyAgentsTable;
14301
+ exports.EmptyScorerList = EmptyScorerList;
13570
14302
  exports.EmptyState = EmptyState;
13571
14303
  exports.EmptyWorkflowsTable = EmptyWorkflowsTable;
13572
14304
  exports.Entity = Entity;
@@ -13604,6 +14336,7 @@ exports.MastraResizablePanel = MastraResizablePanel;
13604
14336
  exports.McpCoinIcon = McpCoinIcon;
13605
14337
  exports.McpServerIcon = McpServerIcon;
13606
14338
  exports.MemoryIcon = MemoryIcon;
14339
+ exports.MemorySearch = MemorySearch;
13607
14340
  exports.NetworkChat = NetworkChat;
13608
14341
  exports.NetworkContext = NetworkContext;
13609
14342
  exports.NetworkProvider = NetworkProvider;
@@ -13621,6 +14354,8 @@ exports.Row = Row;
13621
14354
  exports.RuntimeContext = RuntimeContext;
13622
14355
  exports.RuntimeContextWrapper = RuntimeContextWrapper;
13623
14356
  exports.ScoreIcon = ScoreIcon;
14357
+ exports.ScorerList = ScorerList;
14358
+ exports.ScorerSkeleton = ScorerSkeleton;
13624
14359
  exports.SettingsIcon = SettingsIcon;
13625
14360
  exports.SlashIcon = SlashIcon;
13626
14361
  exports.Tab = Tab;
@@ -13674,6 +14409,10 @@ exports.useLinkComponent = useLinkComponent;
13674
14409
  exports.useMastraClient = useMastraClient;
13675
14410
  exports.usePlaygroundStore = usePlaygroundStore;
13676
14411
  exports.usePolling = usePolling;
14412
+ exports.useScorer = useScorer;
14413
+ exports.useScorers = useScorers;
14414
+ exports.useScoresByEntityId = useScoresByEntityId;
14415
+ exports.useScoresByScorerId = useScoresByScorerId;
13677
14416
  exports.useSpeechRecognition = useSpeechRecognition;
13678
14417
  exports.useWorkingMemory = useWorkingMemory;
13679
14418
  Object.keys(reactQuery).forEach(k => {