@mastra/playground-ui 5.1.14-alpha.0 → 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 (46) hide show
  1. package/dist/{colors-CD-k9ILs.cjs → colors-DLwJ7rFA.cjs} +12 -2
  2. package/dist/colors-DLwJ7rFA.cjs.map +1 -0
  3. package/dist/{colors-B25-HzLf.js → colors-DrbbnW3f.js} +12 -2
  4. package/dist/colors-DrbbnW3f.js.map +1 -0
  5. package/dist/index.cjs.js +2503 -1606
  6. package/dist/index.cjs.js.map +1 -1
  7. package/dist/index.es.js +2464 -1607
  8. package/dist/index.es.js.map +1 -1
  9. package/dist/src/components/assistant-ui/memory-search.d.ts +11 -0
  10. package/dist/src/components/assistant-ui/thread.d.ts +2 -1
  11. package/dist/src/components/ui/alert-dialog.d.ts +26 -0
  12. package/dist/src/components/ui/entity-header.d.ts +7 -0
  13. package/dist/src/components/ui/playground-tabs.d.ts +22 -0
  14. package/dist/src/domains/agents/components/agent-chat.d.ts +1 -1
  15. package/dist/src/domains/agents/components/agent-entity-header.d.ts +6 -0
  16. package/dist/src/domains/agents/components/agent-metadata/agent-metadata-list.d.ts +12 -0
  17. package/dist/src/domains/agents/components/agent-metadata/agent-metadata-prompt.d.ts +4 -0
  18. package/dist/src/domains/agents/components/agent-metadata/agent-metadata-section.d.ts +9 -0
  19. package/dist/src/domains/agents/components/agent-metadata/agent-metadata-wrapper.d.ts +4 -0
  20. package/dist/src/domains/agents/components/agent-metadata/agent-metadata.d.ts +24 -0
  21. package/dist/src/domains/agents/components/agent-metadata/index.d.ts +5 -0
  22. package/dist/src/domains/agents/components/chat-threads.d.ts +11 -0
  23. package/dist/src/domains/agents/index.d.ts +3 -1
  24. package/dist/src/domains/scores/components/scorer-list.d.ts +9 -0
  25. package/dist/src/domains/scores/hooks/use-scorers.d.ts +25 -0
  26. package/dist/src/domains/scores/index.d.ts +2 -0
  27. package/dist/src/domains/traces/{traces-table.d.ts → components/traces-table.d.ts} +1 -1
  28. package/dist/src/domains/traces/components/traces-view.d.ts +13 -0
  29. package/dist/src/domains/traces/index.d.ts +2 -0
  30. package/dist/src/domains/workflows/index.d.ts +0 -1
  31. package/dist/src/domains/workflows/workflow/workflow-step-action-bar.d.ts +2 -1
  32. package/dist/src/ds/tokens/colors.d.ts +10 -0
  33. package/dist/src/hooks/index.d.ts +1 -0
  34. package/dist/src/hooks/use-in-view.d.ts +9 -0
  35. package/dist/src/index.d.ts +8 -0
  36. package/dist/src/lib/tanstack-query.d.ts +4 -0
  37. package/dist/src/types/memory.d.ts +29 -0
  38. package/dist/src/types.d.ts +1 -0
  39. package/dist/tokens.cjs.js +1 -1
  40. package/dist/tokens.es.js +1 -1
  41. package/package.json +5 -5
  42. package/dist/colors-B25-HzLf.js.map +0 -1
  43. package/dist/colors-CD-k9ILs.cjs.map +0 -1
  44. package/dist/src/domains/agents/components/agent-traces.d.ts +0 -10
  45. package/dist/src/domains/workflows/workflow/workflow-traces.d.ts +0 -11
  46. 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, ChevronUp, ChevronDown, Circle, 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 } 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';
@@ -24,9 +24,8 @@ import { RuntimeContext as RuntimeContext$1 } from '@mastra/core/di';
24
24
  import { create } from 'zustand';
25
25
  import { persist } from 'zustand/middleware';
26
26
  import { format, formatDistanceToNow, isValid, formatDate } from 'date-fns';
27
- import * as TabsPrimitive from '@radix-ui/react-tabs';
28
27
  import { AnimatePresence } from 'motion/react';
29
- import { C as Colors } from './colors-B25-HzLf.js';
28
+ import * as TabsPrimitive from '@radix-ui/react-tabs';
30
29
  import * as SliderPrimitive from '@radix-ui/react-slider';
31
30
  import * as LabelPrimitive from '@radix-ui/react-label';
32
31
  import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
@@ -34,7 +33,9 @@ import * as CollapsiblePrimitive from '@radix-ui/react-collapsible';
34
33
  import prettier from 'prettier';
35
34
  import prettierPluginBabel from 'prettier/plugins/babel';
36
35
  import prettierPluginEstree from 'prettier/plugins/estree';
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';
@@ -55,8 +56,10 @@ import * as PopoverPrimitive from '@radix-ui/react-popover';
55
56
  import * as SelectPrimitive from '@radix-ui/react-select';
56
57
  import { ZodProvider, getFieldConfigInZodStack, getDefaultValueInZodStack } from '@autoform/zod';
57
58
  import { CodeBlock as CodeBlock$1 } from 'react-code-block';
59
+ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
60
+ import './index.css';export * from '@tanstack/react-query';
58
61
 
59
- import './index.css';const createMastraClient = (baseUrl, mastraClientHeaders = {}) => {
62
+ const createMastraClient = (baseUrl, mastraClientHeaders = {}) => {
60
63
  return new MastraClient({
61
64
  baseUrl: baseUrl || "",
62
65
  // only add the header if the baseUrl is not provided i.e it's a local dev environment
@@ -4369,8 +4372,9 @@ const Reasoning = ({ text }) => {
4369
4372
 
4370
4373
  const AssistantMessage = ({ ToolFallback: ToolFallbackCustom }) => {
4371
4374
  const data = useMessage();
4375
+ const messageId = data.id;
4372
4376
  const isToolCallAndOrReasoning = data.content.every(({ type }) => type === "tool-call" || type === "reasoning");
4373
- 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: [
4374
4378
  /* @__PURE__ */ jsx("div", { className: "text-icon6 text-ui-lg leading-ui-lg", children: /* @__PURE__ */ jsx(
4375
4379
  MessagePrimitive.Content,
4376
4380
  {
@@ -4570,7 +4574,9 @@ const UserMessageAttachments = () => {
4570
4574
  return /* @__PURE__ */ jsx(MessagePrimitive.Attachments, { components: { Attachment: InMessageContextWrapper } });
4571
4575
  };
4572
4576
  const UserMessage = () => {
4573
- 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: [
4574
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(
4575
4581
  MessagePrimitive.Content,
4576
4582
  {
@@ -4831,7 +4837,7 @@ const ComposerAttachments = () => {
4831
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 } }) });
4832
4838
  };
4833
4839
 
4834
- const Thread = ({ ToolFallback, agentName, hasMemory }) => {
4840
+ const Thread = ({ ToolFallback, agentName, hasMemory, onInputChange }) => {
4835
4841
  const areaRef = useRef(null);
4836
4842
  useAutoscroll(areaRef, { enabled: true });
4837
4843
  const WrappedAssistantMessage = (props) => {
@@ -4852,7 +4858,7 @@ const Thread = ({ ToolFallback, agentName, hasMemory }) => {
4852
4858
  ) }),
4853
4859
  /* @__PURE__ */ jsx(ThreadPrimitive.If, { empty: false, children: /* @__PURE__ */ jsx("div", {}) })
4854
4860
  ] }),
4855
- /* @__PURE__ */ jsx(Composer$1, { hasMemory })
4861
+ /* @__PURE__ */ jsx(Composer$1, { hasMemory, onInputChange })
4856
4862
  ] });
4857
4863
  };
4858
4864
  const ThreadWrapper$1 = ({ children }) => {
@@ -4874,7 +4880,7 @@ const ThreadWelcome$1 = ({ agentName }) => {
4874
4880
  /* @__PURE__ */ jsx("p", { className: "mt-4 font-medium", children: "How can I help you today?" })
4875
4881
  ] }) });
4876
4882
  };
4877
- const Composer$1 = ({ hasMemory }) => {
4883
+ const Composer$1 = ({ hasMemory, onInputChange }) => {
4878
4884
  return /* @__PURE__ */ jsxs("div", { className: "mx-4", children: [
4879
4885
  /* @__PURE__ */ jsxs(ComposerPrimitive.Root, { children: [
4880
4886
  /* @__PURE__ */ jsx("div", { className: "max-w-[568px] w-full mx-auto pb-2", children: /* @__PURE__ */ jsx(ComposerAttachments, {}) }),
@@ -4886,7 +4892,8 @@ const Composer$1 = ({ hasMemory }) => {
4886
4892
  autoFocus: true,
4887
4893
  placeholder: "Enter your message...",
4888
4894
  name: "",
4889
- id: ""
4895
+ id: "",
4896
+ onChange: (e) => onInputChange?.(e.target.value)
4890
4897
  }
4891
4898
  ) }),
4892
4899
  /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
@@ -5162,6 +5169,7 @@ function MastraRuntimeProvider({
5162
5169
  const [messages, setMessages] = useState([]);
5163
5170
  const [currentThreadId, setCurrentThreadId] = useState(threadId);
5164
5171
  const { refetch: refreshWorkingMemory } = useWorkingMemory();
5172
+ const abortControllerRef = useRef(null);
5165
5173
  const {
5166
5174
  frequencyPenalty,
5167
5175
  presencePenalty,
@@ -5213,8 +5221,7 @@ function MastraRuntimeProvider({
5213
5221
  }
5214
5222
  }
5215
5223
  }, [initialMessages, threadId, memory]);
5216
- const mastra = useMastraClient();
5217
- const agent = mastra.getAgent(agentId);
5224
+ const baseClient = useMastraClient();
5218
5225
  const onNew = async (message) => {
5219
5226
  if (message.content[0]?.type !== "text") throw new Error("Only text messages are supported");
5220
5227
  const attachments = await convertToAIAttachments(message.attachments);
@@ -5224,6 +5231,13 @@ function MastraRuntimeProvider({
5224
5231
  { role: "user", content: input, attachments: message.attachments }
5225
5232
  ]);
5226
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);
5227
5241
  try {
5228
5242
  if (chatWithGenerate) {
5229
5243
  const generateResponse = await agent.generate({
@@ -5248,7 +5262,7 @@ function MastraRuntimeProvider({
5248
5262
  ...memory ? { threadId, resourceId: agentId } : {},
5249
5263
  providerOptions
5250
5264
  });
5251
- if (generateResponse.response) {
5265
+ if (generateResponse.response && "messages" in generateResponse.response) {
5252
5266
  const latestMessage = generateResponse.response.messages.reduce(
5253
5267
  (acc, message2) => {
5254
5268
  const _content = Array.isArray(acc.content) ? acc.content : [];
@@ -5502,10 +5516,22 @@ function MastraRuntimeProvider({
5502
5516
  } catch (error) {
5503
5517
  console.error("Error occurred in MastraRuntimeProvider", error);
5504
5518
  setIsRunning(false);
5519
+ if (error.name === "AbortError") {
5520
+ return;
5521
+ }
5505
5522
  setMessages((currentConversation) => [
5506
5523
  ...currentConversation,
5507
5524
  { role: "assistant", content: [{ type: "text", text: `${error}` }] }
5508
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);
5509
5535
  }
5510
5536
  };
5511
5537
  const runtime = useExternalStoreRuntime({
@@ -5513,6 +5539,7 @@ function MastraRuntimeProvider({
5513
5539
  messages,
5514
5540
  convertMessage: convertMessage$2,
5515
5541
  onNew,
5542
+ onCancel,
5516
5543
  adapters: {
5517
5544
  attachments: new CompositeAttachmentAdapter([
5518
5545
  new SimpleImageAttachmentAdapter(),
@@ -5599,7 +5626,15 @@ const usePlaygroundStore = create()(
5599
5626
  )
5600
5627
  );
5601
5628
 
5602
- 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
+ }) => {
5603
5638
  const { settings } = useAgentSettings();
5604
5639
  const { runtimeContext } = usePlaygroundStore();
5605
5640
  return /* @__PURE__ */ jsx(
@@ -5613,7 +5648,7 @@ const AgentChat = ({ agentId, agentName, threadId, initialMessages, memory, refr
5613
5648
  refreshThreadList,
5614
5649
  settings,
5615
5650
  runtimeContext,
5616
- children: /* @__PURE__ */ jsx(Thread, { agentName: agentName ?? "", hasMemory: memory })
5651
+ children: /* @__PURE__ */ jsx(Thread, { agentName: agentName ?? "", hasMemory: memory, onInputChange })
5617
5652
  }
5618
5653
  );
5619
5654
  };
@@ -5767,16 +5802,33 @@ const TableCaption = React.forwardRef(
5767
5802
  TableCaption.displayName = "TableCaption";
5768
5803
 
5769
5804
  const Tabs = TabsPrimitive.Root;
5770
- const TabsList = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(TabsPrimitive.List, { ref, className: cn(className), ...props }));
5805
+ const TabsList = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
5806
+ TabsPrimitive.List,
5807
+ {
5808
+ ref,
5809
+ className: clsx("bg-muted text-muted-foreground inline-flex items-center bg-transparent", className),
5810
+ ...props
5811
+ }
5812
+ ));
5771
5813
  TabsList.displayName = TabsPrimitive.List.displayName;
5772
- const TabsTrigger = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(TabsPrimitive.Trigger, { ref, className: cn(className), ...props }));
5814
+ const TabsTrigger = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
5815
+ TabsPrimitive.Trigger,
5816
+ {
5817
+ ref,
5818
+ className: cn(
5819
+ "ring-offset-background focus-visible:ring-ring data-[state=active]:bg-background data-[state=active]:text-foreground whitespace-nowrap focus-visible:outline-none text-ui-lg text-icon3 -mb-[0.5px] inline-flex items-center justify-center border-b-2 border-transparent p-3 font-medium focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:border-b-2 data-[state=active]:border-white data-[state=active]:shadow",
5820
+ className
5821
+ ),
5822
+ ...props
5823
+ }
5824
+ ));
5773
5825
  TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
5774
5826
  const TabsContent = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
5775
5827
  TabsPrimitive.Content,
5776
5828
  {
5777
5829
  ref,
5778
5830
  className: cn(
5779
- "mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
5831
+ "ring-offset-background focus-visible:ring-ring mt-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2",
5780
5832
  className
5781
5833
  ),
5782
5834
  ...props
@@ -5784,6 +5836,43 @@ const TabsContent = React.forwardRef(({ className, ...props }, ref) => /* @__PUR
5784
5836
  ));
5785
5837
  TabsContent.displayName = TabsPrimitive.Content.displayName;
5786
5838
 
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 });
5857
+ };
5858
+ const TabList = ({ 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 }) });
5860
+ };
5861
+ const Tab = ({ children, value, onClick }) => {
5862
+ return /* @__PURE__ */ jsx(
5863
+ TabsTrigger,
5864
+ {
5865
+ value,
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",
5867
+ onClick,
5868
+ children
5869
+ }
5870
+ );
5871
+ };
5872
+ const TabContent = ({ children, value }) => {
5873
+ return /* @__PURE__ */ jsx(TabsContent, { value, className: "h-full overflow-hidden flex flex-col", children });
5874
+ };
5875
+
5787
5876
  const scrollableContentClass = cn(
5788
5877
  "relative overflow-y-auto overflow-x-hidden invisible hover:visible focus:visible",
5789
5878
  "[&::-webkit-scrollbar]:w-1",
@@ -5792,35 +5881,27 @@ const scrollableContentClass = cn(
5792
5881
  "[&::-webkit-scrollbar-thumb]:bg-mastra-border/20",
5793
5882
  "[&>*]:visible"
5794
5883
  );
5795
- const tabIndicatorClass = cn(
5884
+ cn(
5796
5885
  "px-4 py-2 text-sm transition-all border-b-2 border-transparent",
5797
5886
  "data-[state=active]:border-white data-[state=active]:text-white font-medium",
5798
5887
  "data-[state=inactive]:text-mastra-el-4 hover:data-[state=inactive]:text-mastra-el-2",
5799
5888
  "focus-visible:outline-none"
5800
5889
  );
5801
- const tabContentClass = cn("data-[state=inactive]:mt-0 min-h-0 h-full grid grid-rows-[1fr]");
5890
+ cn("data-[state=inactive]:mt-0 min-h-0 h-full grid grid-rows-[1fr]");
5802
5891
  function AgentEvals({ liveEvals, ciEvals, onRefetchLiveEvals, onRefetchCiEvals }) {
5803
5892
  const [activeTab, setActiveTab] = useState("live");
5804
5893
  function handleRefresh() {
5805
5894
  if (activeTab === "live") return onRefetchLiveEvals();
5806
5895
  return onRefetchCiEvals();
5807
5896
  }
5808
- return /* @__PURE__ */ jsxs(
5809
- Tabs,
5810
- {
5811
- value: activeTab,
5812
- onValueChange: (value) => setActiveTab(value),
5813
- className: "grid grid-rows-[auto_1fr] h-full min-h-0 pb-2",
5814
- children: [
5815
- /* @__PURE__ */ jsx("div", { className: "border-b border-mastra-border/10", children: /* @__PURE__ */ jsxs(TabsList, { className: "bg-transparent border-0 h-auto mx-4", children: [
5816
- /* @__PURE__ */ jsx(TabsTrigger, { value: "live", className: tabIndicatorClass, children: "Live" }),
5817
- /* @__PURE__ */ jsx(TabsTrigger, { value: "ci", className: tabIndicatorClass, children: "CI" })
5818
- ] }) }),
5819
- /* @__PURE__ */ jsx(TabsContent, { value: "live", className: tabContentClass, children: /* @__PURE__ */ jsx(EvalTable, { evals: liveEvals, isCIMode: false, onRefresh: handleRefresh }) }),
5820
- /* @__PURE__ */ jsx(TabsContent, { value: "ci", className: tabContentClass, children: /* @__PURE__ */ jsx(EvalTable, { evals: ciEvals, isCIMode: true, onRefresh: handleRefresh }) })
5821
- ]
5822
- }
5823
- );
5897
+ return /* @__PURE__ */ jsxs(PlaygroundTabs, { defaultTab: "live", children: [
5898
+ /* @__PURE__ */ jsxs(TabList, { children: [
5899
+ /* @__PURE__ */ jsx(Tab, { value: "live", children: "Live" }),
5900
+ /* @__PURE__ */ jsx(Tab, { value: "ci", children: "CI" })
5901
+ ] }),
5902
+ /* @__PURE__ */ jsx(TabContent, { value: "live", children: /* @__PURE__ */ jsx(EvalTable, { evals: liveEvals, isCIMode: false, onRefresh: handleRefresh }) }),
5903
+ /* @__PURE__ */ jsx(TabContent, { value: "ci", children: /* @__PURE__ */ jsx(EvalTable, { evals: ciEvals, isCIMode: true, onRefresh: handleRefresh }) })
5904
+ ] });
5824
5905
  }
5825
5906
  function EvalTable({ evals, isCIMode = false, onRefresh }) {
5826
5907
  const [expandedMetrics, setExpandedMetrics] = useState(/* @__PURE__ */ new Set());
@@ -6009,907 +6090,170 @@ function EvalTable({ evals, isCIMode = false, onRefresh }) {
6009
6090
  }
6010
6091
  }
6011
6092
 
6012
- const TraceContext = createContext({});
6013
- function TraceProvider({
6014
- children,
6015
- initialTraces: traces = []
6016
- }) {
6017
- const [open, setOpen] = useState(false);
6018
- const [trace, setTrace] = useState(null);
6019
- const [currentTraceIndex, setCurrentTraceIndex] = useState(0);
6020
- const [span, setSpan] = useState(null);
6021
- const nextTrace = () => {
6022
- if (currentTraceIndex < traces.length - 1) {
6023
- const nextIndex = currentTraceIndex + 1;
6024
- setCurrentTraceIndex(nextIndex);
6025
- const nextTrace2 = traces[nextIndex].trace;
6026
- setTrace(nextTrace2);
6027
- const parentSpan = nextTrace2.find((span2) => span2.parentSpanId === null) || nextTrace2[0];
6028
- setSpan(parentSpan);
6029
- }
6030
- };
6031
- const prevTrace = () => {
6032
- if (currentTraceIndex > 0) {
6033
- const prevIndex = currentTraceIndex - 1;
6034
- setCurrentTraceIndex(prevIndex);
6035
- const prevTrace2 = traces[prevIndex].trace;
6036
- setTrace(prevTrace2);
6037
- const parentSpan = prevTrace2.find((span2) => span2.parentSpanId === null) || prevTrace2[0];
6038
- setSpan(parentSpan);
6039
- }
6040
- };
6041
- const clearData = () => {
6042
- setOpen(false);
6043
- setTrace(null);
6044
- setSpan(null);
6045
- };
6046
- return /* @__PURE__ */ jsx(
6047
- TraceContext.Provider,
6048
- {
6049
- value: {
6050
- isOpen: open,
6051
- setIsOpen: setOpen,
6052
- trace,
6053
- setTrace,
6054
- traces,
6055
- currentTraceIndex,
6056
- setCurrentTraceIndex,
6057
- nextTrace,
6058
- prevTrace,
6059
- span,
6060
- setSpan,
6061
- clearData
6062
- },
6063
- children
6064
- }
6065
- );
6066
- }
6093
+ const Slider = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxs(
6094
+ SliderPrimitive.Root,
6095
+ {
6096
+ ref,
6097
+ className: cn("relative flex w-full touch-none select-none items-center", className),
6098
+ ...props,
6099
+ children: [
6100
+ /* @__PURE__ */ jsx(SliderPrimitive.Track, { className: "relative h-1.5 w-full grow overflow-hidden rounded-full bg-primary/20", children: /* @__PURE__ */ jsx(SliderPrimitive.Range, { className: "absolute h-full bg-primary/50" }) }),
6101
+ /* @__PURE__ */ jsx(SliderPrimitive.Thumb, { className: "block h-4 w-4 rounded-full border border-primary/50 bg-white shadow transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50" })
6102
+ ]
6103
+ }
6104
+ ));
6105
+ Slider.displayName = SliderPrimitive.Root.displayName;
6067
6106
 
6068
- const rowSize = {
6069
- default: "[&>tbody>tr]:h-table-row",
6070
- small: "[&>tbody>tr]:h-table-row-small"
6071
- };
6072
- const Table = ({ className, children, size = "default" }) => {
6073
- return /* @__PURE__ */ jsx("table", { className: clsx("w-full", rowSize[size], className), children });
6074
- };
6075
- const Thead = ({ className, children }) => {
6076
- return /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", { className: clsx("h-table-header border-b-sm border-border1", className), children }) });
6077
- };
6078
- const Th = ({ className, children, ...props }) => {
6107
+ const labelVariants = cva("text-sm leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70");
6108
+ const Label = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(LabelPrimitive.Root, { ref, className: cn(labelVariants(), className), ...props }));
6109
+ Label.displayName = LabelPrimitive.Root.displayName;
6110
+
6111
+ const RadioGroup = React.forwardRef(({ className, ...props }, ref) => {
6112
+ return /* @__PURE__ */ jsx(RadioGroupPrimitive.Root, { className: cn("grid gap-2", className), ...props, ref });
6113
+ });
6114
+ RadioGroup.displayName = RadioGroupPrimitive.Root.displayName;
6115
+ const RadioGroupItem = React.forwardRef(({ className, ...props }, ref) => {
6079
6116
  return /* @__PURE__ */ jsx(
6080
- "th",
6117
+ RadioGroupPrimitive.Item,
6081
6118
  {
6082
- className: clsx(
6083
- "text-icon3 text-ui-sm h-full text-left font-normal uppercase first:pl-5 last:pr-5 whitespace-nowrap",
6119
+ ref,
6120
+ className: cn(
6121
+ "aspect-square h-4 w-4 rounded-full border border-primary text-primary ring-offset-background focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
6084
6122
  className
6085
6123
  ),
6086
6124
  ...props,
6087
- children
6125
+ children: /* @__PURE__ */ jsx(RadioGroupPrimitive.Indicator, { className: "flex items-center justify-center", children: /* @__PURE__ */ jsx(Circle, { className: "h-2.5 w-2.5 fill-current text-current" }) })
6088
6126
  }
6089
6127
  );
6128
+ });
6129
+ RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName;
6130
+
6131
+ const Entry = ({ label, children }) => {
6132
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
6133
+ /* @__PURE__ */ jsx(Txt, { as: "p", variant: "ui-md", className: "text-icon3", children: label }),
6134
+ children
6135
+ ] });
6090
6136
  };
6091
- const Tbody = ({ className, children }) => {
6092
- return /* @__PURE__ */ jsx("tbody", { className: clsx("", className), children });
6137
+
6138
+ const sizeClasses = {
6139
+ md: "h-button-md gap-md",
6140
+ lg: "h-button-lg gap-lg"
6093
6141
  };
6094
- const Row = ({ className, children, selected = false, onClick }) => {
6142
+ const variantClasses$1 = {
6143
+ default: "bg-surface2 hover:bg-surface4 text-icon3 hover:text-icon6",
6144
+ light: "bg-surface3 hover:bg-surface5 text-icon6"
6145
+ };
6146
+ const Button = ({ className, as, size = "md", variant = "default", ...props }) => {
6147
+ const Component = as || "button";
6095
6148
  return /* @__PURE__ */ jsx(
6096
- "tr",
6149
+ Component,
6097
6150
  {
6098
6151
  className: clsx(
6099
- "border-b-sm border-border1 hover:bg-surface3",
6100
- selected && "bg-surface4",
6101
- onClick && "cursor-pointer",
6102
- className
6152
+ "bg-surface2 border-sm border-border1 px-lg text-ui-md inline-flex items-center justify-center rounded-md border",
6153
+ variantClasses$1[variant],
6154
+ sizeClasses[size],
6155
+ className,
6156
+ {
6157
+ "cursor-not-allowed": props.disabled
6158
+ }
6103
6159
  ),
6104
- onClick,
6105
- children
6160
+ ...props
6106
6161
  }
6107
6162
  );
6108
6163
  };
6109
6164
 
6110
- const formatDateCell = (date) => {
6111
- const month = new Intl.DateTimeFormat("en-US", { month: "short" }).format(date).toUpperCase();
6112
- const day = date.getDate();
6113
- const formattedDay = `${month} ${day}`;
6114
- const time = new Intl.DateTimeFormat("en-US", {
6115
- hour: "2-digit",
6116
- minute: "2-digit",
6117
- second: "2-digit",
6118
- hour12: false
6119
- // Use 24-hour format
6120
- }).format(date);
6121
- return { day: formattedDay, time };
6122
- };
6165
+ const Collapsible = CollapsiblePrimitive.Root;
6166
+ const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger;
6167
+ const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent;
6123
6168
 
6124
- const Cell = ({ className, children, ...props }) => {
6125
- return /* @__PURE__ */ jsx("td", { className: clsx("text-icon5 first:pl-5 last:pr-5", className), ...props, children: /* @__PURE__ */ jsx("div", { className: clsx("flex h-full w-full shrink-0 items-center"), children }) });
6126
- };
6127
- const TxtCell = ({ className, children }) => {
6128
- return /* @__PURE__ */ jsx(Cell, { className, children: /* @__PURE__ */ jsx(Txt, { as: "span", variant: "ui-md", className: "w-full truncate", children }) });
6129
- };
6130
- const UnitCell = ({ className, children, unit }) => {
6131
- return /* @__PURE__ */ jsx(Cell, { className, children: /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-center", children: [
6132
- /* @__PURE__ */ jsx(Txt, { as: "span", variant: "ui-md", className: "shrink-0", children }),
6133
- /* @__PURE__ */ jsx(Txt, { as: "span", variant: "ui-sm", className: "text-icon3 w-full truncate", children: unit })
6134
- ] }) });
6135
- };
6136
- const DateTimeCell = ({ dateTime, ...props }) => {
6137
- const { day, time } = formatDateCell(dateTime);
6138
- return /* @__PURE__ */ jsx(Cell, { ...props, children: /* @__PURE__ */ jsxs("div", { className: "shrink-0", children: [
6139
- /* @__PURE__ */ jsx(Txt, { as: "span", variant: "ui-sm", className: "text-icon3", children: day }),
6140
- " ",
6141
- /* @__PURE__ */ jsx(Txt, { as: "span", variant: "ui-md", children: time })
6142
- ] }) });
6169
+ const formatJSON = async (code) => {
6170
+ const formatted = await prettier.format(code, {
6171
+ semi: false,
6172
+ parser: "json",
6173
+ printWidth: 80,
6174
+ tabWidth: 2,
6175
+ plugins: [prettierPluginBabel, prettierPluginEstree]
6176
+ });
6177
+ return formatted;
6143
6178
  };
6144
- const EntryCell = ({ name, description, icon, meta, ...props }) => {
6145
- return /* @__PURE__ */ jsx(Cell, { ...props, children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-[14px]", children: [
6146
- /* @__PURE__ */ jsx(Icon, { size: "lg", className: "text-icon5", children: icon }),
6147
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-0", children: [
6148
- /* @__PURE__ */ jsx(Txt, { as: "span", variant: "ui-md", className: "text-icon6 font-medium !leading-tight", children: name }),
6149
- description && /* @__PURE__ */ jsx(Txt, { as: "span", variant: "ui-xs", className: "text-icon3 w-full max-w-[300px] truncate !leading-tight", children: description })
6150
- ] }),
6151
- meta
6152
- ] }) });
6179
+ const isValidJson = (str) => {
6180
+ try {
6181
+ const obj = JSON.parse(str);
6182
+ return !!obj && typeof obj === "object";
6183
+ } catch (e) {
6184
+ return false;
6185
+ }
6153
6186
  };
6154
6187
 
6155
- const useOpenTrace = () => {
6156
- const {
6157
- setTrace,
6158
- isOpen: open,
6159
- setIsOpen: setOpen,
6160
- trace: currentTrace,
6161
- setSpan,
6162
- setCurrentTraceIndex
6163
- } = useContext(TraceContext);
6164
- const openTrace = (trace, traceIndex) => {
6165
- setTrace(trace);
6166
- const parentSpan = trace.find((span) => span.parentSpanId === null) || trace[0];
6167
- setSpan(parentSpan);
6168
- setCurrentTraceIndex(traceIndex);
6169
- if (open && currentTrace?.[0]?.id !== trace[0].id) return;
6170
- setOpen((prev) => !prev);
6171
- };
6172
- return { openTrace };
6173
- };
6174
-
6175
- const toSigFigs = (num, sigFigs) => {
6176
- return Number(num.toPrecision(sigFigs));
6177
- };
6178
-
6179
- const TracesTableEmpty = ({ colsCount }) => {
6180
- return /* @__PURE__ */ jsx(Tbody, { children: /* @__PURE__ */ jsx(Row, { children: /* @__PURE__ */ jsx(Cell, { colSpan: colsCount, className: "text-center py-4", children: /* @__PURE__ */ jsx(Txt, { children: "No traces found" }) }) }) });
6181
- };
6182
- const TracesTableError = ({ error, colsCount }) => {
6183
- return /* @__PURE__ */ jsx(Tbody, { children: /* @__PURE__ */ jsx(Row, { children: /* @__PURE__ */ jsx(Cell, { colSpan: colsCount, className: "text-center py-4", children: /* @__PURE__ */ jsx(Txt, { children: error.message }) }) }) });
6184
- };
6185
- const TraceRow = ({ trace, index, isActive }) => {
6186
- const { openTrace } = useOpenTrace();
6187
- const hasFailure = trace.trace.some((span) => span.status.code !== 0);
6188
- return /* @__PURE__ */ jsxs(Row, { className: isActive ? "bg-surface4" : "", onClick: () => openTrace(trace.trace, index), children: [
6189
- /* @__PURE__ */ jsx(DateTimeCell, { dateTime: new Date(trace.started / 1e3) }),
6190
- /* @__PURE__ */ jsxs(TxtCell, { title: trace.traceId, children: [
6191
- trace.traceId.substring(0, 7),
6192
- "..."
6193
- ] }),
6194
- /* @__PURE__ */ jsx(UnitCell, { unit: "ms", children: toSigFigs(trace.duration / 1e3, 3) }),
6195
- /* @__PURE__ */ jsx(Cell, { children: /* @__PURE__ */ jsx("button", { onClick: () => openTrace(trace.trace, index), children: /* @__PURE__ */ jsx(Badge$1, { icon: /* @__PURE__ */ jsx(TraceIcon, {}), children: trace.trace.length }) }) }),
6196
- /* @__PURE__ */ jsx(Cell, { children: hasFailure ? /* @__PURE__ */ jsx(Badge$1, { variant: "error", icon: /* @__PURE__ */ jsx(X, {}), children: "Failed" }) : /* @__PURE__ */ jsx(Badge$1, { icon: /* @__PURE__ */ jsx(Check, {}), variant: "success", children: "Success" }) })
6197
- ] });
6188
+ const useCodemirrorTheme = () => {
6189
+ return useMemo(
6190
+ () => draculaInit({
6191
+ settings: {
6192
+ fontFamily: "var(--geist-mono)",
6193
+ fontSize: "0.8rem",
6194
+ lineHighlight: "transparent",
6195
+ gutterBackground: "transparent",
6196
+ gutterForeground: Colors.surface3,
6197
+ background: "transparent"
6198
+ },
6199
+ styles: [{ tag: [tags.className, tags.propertyName] }]
6200
+ }),
6201
+ []
6202
+ );
6198
6203
  };
6199
- const TracesTable = ({ traces, error }) => {
6200
- const hasNoTraces = !traces || traces.length === 0;
6201
- const { currentTraceIndex } = useContext(TraceContext);
6202
- const colsCount = 4;
6203
- return /* @__PURE__ */ jsxs(Table, { size: "small", children: [
6204
- /* @__PURE__ */ jsxs(Thead, { children: [
6205
- /* @__PURE__ */ jsx(Th, { width: 120, children: "Time" }),
6206
- /* @__PURE__ */ jsx(Th, { width: "auto", children: "Trace Id" }),
6207
- /* @__PURE__ */ jsx(Th, { width: 120, children: "Duration" }),
6208
- /* @__PURE__ */ jsx(Th, { width: 120, children: "Spans" }),
6209
- /* @__PURE__ */ jsx(Th, { width: 120, children: "Status" })
6210
- ] }),
6211
- error ? /* @__PURE__ */ jsx(TracesTableError, { error, colsCount }) : hasNoTraces ? /* @__PURE__ */ jsx(TracesTableEmpty, { colsCount }) : /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(Tbody, { children: traces.map((trace, index) => /* @__PURE__ */ jsx(TraceRow, { trace, index, isActive: index === currentTraceIndex }, trace.traceId)) }) })
6212
- ] });
6204
+ const SyntaxHighlighter$1 = ({ data }) => {
6205
+ const formattedCode = JSON.stringify(data, null, 2);
6206
+ const theme = useCodemirrorTheme();
6207
+ return /* @__PURE__ */ jsx("div", { className: "rounded-md bg-[#1a1a1a] p-1 font-mono", children: /* @__PURE__ */ jsx(CodeMirror, { value: formattedCode, theme, extensions: [jsonLanguage] }) });
6213
6208
  };
6214
6209
 
6215
- const useResizeColumn = ({
6216
- defaultWidth,
6217
- minimumWidth,
6218
- maximumWidth,
6219
- setCurrentWidth
6220
- }) => {
6221
- const [isDragging, setIsDragging] = useState(false);
6222
- const [sidebarWidth, setSidebarWidth] = useState(defaultWidth);
6223
- const containerRef = useRef(null);
6224
- const dragStartXRef = useRef(0);
6225
- const initialWidthRef = useRef(0);
6226
- const handleMouseDown = (e) => {
6227
- e.preventDefault();
6228
- setIsDragging(true);
6229
- dragStartXRef.current = e.clientX;
6230
- initialWidthRef.current = sidebarWidth;
6231
- };
6232
- useEffect(() => {
6233
- setSidebarWidth(defaultWidth);
6234
- setCurrentWidth?.(defaultWidth);
6235
- }, [defaultWidth]);
6210
+ const AgentAdvancedSettings = () => {
6211
+ const { settings, setSettings } = useAgentSettings();
6212
+ const [isOpen, setIsOpen] = useState(false);
6213
+ const [providerOptionsValue, setProviderOptionsValue] = useState("");
6214
+ const [saved, setSaved] = useState(false);
6215
+ const [error, setError] = useState(null);
6216
+ const theme = useCodemirrorTheme();
6217
+ const { handleCopy } = useCopyToClipboard({ text: providerOptionsValue });
6218
+ const providerOptionsStr = JSON.stringify(settings?.modelSettings?.providerOptions ?? {});
6236
6219
  useEffect(() => {
6237
- const handleMouseMove = (e) => {
6238
- if (!isDragging || !containerRef.current) return;
6239
- const containerWidth = containerRef.current.offsetWidth;
6240
- const deltaX = dragStartXRef.current - e.clientX;
6241
- const deltaPercentage = deltaX / containerWidth * 100;
6242
- const newWidth = Math.min(Math.max(initialWidthRef.current + deltaPercentage, minimumWidth), maximumWidth);
6243
- setSidebarWidth(newWidth);
6244
- setCurrentWidth?.(newWidth);
6245
- };
6246
- const handleMouseUp = () => {
6247
- setIsDragging(false);
6220
+ const run = async () => {
6221
+ if (!isValidJson(providerOptionsStr)) {
6222
+ setError("Invalid JSON");
6223
+ return;
6224
+ }
6225
+ const formatted = await formatJSON(providerOptionsStr);
6226
+ setProviderOptionsValue(formatted);
6248
6227
  };
6249
- if (isDragging) {
6250
- window.addEventListener("mousemove", handleMouseMove);
6251
- window.addEventListener("mouseup", handleMouseUp);
6228
+ run();
6229
+ }, [providerOptionsStr]);
6230
+ const formatProviderOptions = async () => {
6231
+ setError(null);
6232
+ if (!isValidJson(providerOptionsValue)) {
6233
+ setError("Invalid JSON");
6234
+ return;
6252
6235
  }
6253
- return () => {
6254
- window.removeEventListener("mousemove", handleMouseMove);
6255
- window.removeEventListener("mouseup", handleMouseUp);
6256
- };
6257
- }, [isDragging]);
6258
- return { sidebarWidth, isDragging, handleMouseDown, containerRef };
6259
- };
6260
-
6261
- const MastraResizablePanel = ({
6262
- children,
6263
- defaultWidth,
6264
- minimumWidth,
6265
- maximumWidth,
6266
- className,
6267
- disabled = false,
6268
- setCurrentWidth,
6269
- dividerPosition = "left"
6270
- }) => {
6271
- const { sidebarWidth, isDragging, handleMouseDown, containerRef } = useResizeColumn({
6272
- defaultWidth: disabled ? 100 : defaultWidth,
6273
- minimumWidth,
6274
- maximumWidth,
6275
- setCurrentWidth
6276
- });
6277
- return /* @__PURE__ */ jsxs("div", { className: cn("w-full h-full relative", className), ref: containerRef, style: { width: `${sidebarWidth}%` }, children: [
6278
- !disabled && dividerPosition === "left" ? /* @__PURE__ */ jsx(
6279
- "div",
6280
- {
6281
- className: `w-px bg-border1 h-full cursor-col-resize hover:w-1.5 hover:bg-mastra-border-2 hover:bg-[#424242] active:bg-mastra-border-3 active:bg-[#3e3e3e] transition-colors absolute inset-y-0 z-10
6282
- ${isDragging ? "bg-border2 w-1.5 cursor- col-resize" : ""}`,
6283
- onMouseDown: handleMouseDown
6284
- }
6285
- ) : null,
6286
- children,
6287
- !disabled && dividerPosition === "right" ? /* @__PURE__ */ jsx(
6288
- "div",
6289
- {
6290
- className: `w-px bg-border1 h-full cursor-col-resize hover:w-1.5 hover:bg-border2 active:bg-border3 transition-colors absolute inset-y-0 z-10
6291
- ${isDragging ? "bg-border2 w-1.5 cursor- col-resize" : ""}`,
6292
- onMouseDown: handleMouseDown
6293
- }
6294
- ) : null
6295
- ] });
6296
- };
6297
-
6298
- const sizeClasses = {
6299
- md: "h-button-md gap-md",
6300
- lg: "h-button-lg gap-lg"
6301
- };
6302
- const variantClasses$1 = {
6303
- default: "bg-surface2 hover:bg-surface4 text-icon3 hover:text-icon6",
6304
- light: "bg-surface3 hover:bg-surface5 text-icon6"
6305
- };
6306
- const Button = ({ className, as, size = "md", variant = "default", ...props }) => {
6307
- const Component = as || "button";
6308
- return /* @__PURE__ */ jsx(
6309
- Component,
6310
- {
6311
- className: clsx(
6312
- "bg-surface2 border-sm border-border1 px-lg text-ui-md inline-flex items-center justify-center rounded-md border",
6313
- variantClasses$1[variant],
6314
- sizeClasses[size],
6315
- className,
6316
- {
6317
- "cursor-not-allowed": props.disabled
6236
+ const formatted = await formatJSON(providerOptionsValue);
6237
+ setProviderOptionsValue(formatted);
6238
+ };
6239
+ const saveProviderOptions = async () => {
6240
+ try {
6241
+ setError(null);
6242
+ const parsedContext = JSON.parse(providerOptionsValue);
6243
+ setSettings({
6244
+ ...settings,
6245
+ modelSettings: {
6246
+ ...settings?.modelSettings,
6247
+ providerOptions: parsedContext
6318
6248
  }
6319
- ),
6320
- ...props
6321
- }
6322
- );
6323
- };
6324
-
6325
- const TraceTree = ({ children }) => {
6326
- return /* @__PURE__ */ jsx("ol", { children });
6327
- };
6328
-
6329
- const variantClasses = {
6330
- agent: "bg-accent1"
6331
- };
6332
- const Time = ({ durationMs, tokenCount, variant, progressPercent, offsetPercent }) => {
6333
- const variantClass = variant ? variantClasses[variant] : "bg-accent3";
6334
- const percent = Math.min(100, progressPercent);
6335
- return /* @__PURE__ */ jsxs("div", { className: "w-[80px] xl:w-[166px] shrink-0", children: [
6336
- /* @__PURE__ */ jsx("div", { className: "bg-surface4 relative h-[6px] w-full rounded-full p-px overflow-hidden", children: /* @__PURE__ */ jsx(
6337
- "div",
6338
- {
6339
- className: clsx("absolute h-1 rounded-full", variantClass),
6340
- style: { width: `${percent}%`, left: `${offsetPercent}%` }
6341
- }
6342
- ) }),
6343
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4 pt-0.5", children: [
6344
- /* @__PURE__ */ jsxs(Txt, { variant: "ui-sm", className: "text-icon2 font-medium", children: [
6345
- toSigFigs(durationMs, 3),
6346
- "ms"
6347
- ] }),
6348
- tokenCount && /* @__PURE__ */ jsxs(Txt, { variant: "ui-sm", className: "text-icon2 font-medium", children: [
6349
- tokenCount,
6350
- "t"
6351
- ] })
6352
- ] })
6353
- ] });
6354
- };
6355
-
6356
- const spanIconMap = {
6357
- tool: ToolsIcon,
6358
- agent: AgentIcon,
6359
- workflow: WorkflowIcon,
6360
- memory: MemoryIcon,
6361
- rag: TraceIcon,
6362
- storage: DbIcon,
6363
- eval: ScoreIcon,
6364
- other: TraceIcon
6365
- };
6366
- const spanVariantClasses = {
6367
- tool: "text-[#ECB047]",
6368
- agent: "text-accent1",
6369
- workflow: "text-accent3",
6370
- memory: "text-accent2",
6371
- rag: "text-accent2",
6372
- storage: "text-accent2",
6373
- eval: "text-accent4",
6374
- other: "text-icon6"
6375
- };
6376
- const Span = ({
6377
- children,
6378
- durationMs,
6379
- variant,
6380
- tokenCount,
6381
- spans,
6382
- isRoot,
6383
- onClick,
6384
- isActive,
6385
- offsetMs,
6386
- totalDurationMs
6387
- }) => {
6388
- const [isExpanded, setIsExpanded] = useState(true);
6389
- const VariantIcon = spanIconMap[variant];
6390
- const variantClass = spanVariantClasses[variant];
6391
- const progressPercent = durationMs / totalDurationMs * 100;
6392
- const offsetPercent = offsetMs / totalDurationMs * 100;
6393
- const TextEl = onClick ? "button" : "div";
6394
- return /* @__PURE__ */ jsxs("li", { children: [
6395
- /* @__PURE__ */ jsxs("div", { className: clsx("flex justify-between items-center gap-2 rounded-md pl-2", isActive && "bg-surface4"), children: [
6396
- /* @__PURE__ */ jsxs("div", { className: "flex h-8 items-center gap-1 min-w-0", children: [
6397
- spans ? /* @__PURE__ */ jsx(
6398
- "button",
6399
- {
6400
- type: "button",
6401
- "aria-label": isExpanded ? "Collapse span" : "Expand span",
6402
- "aria-expanded": isExpanded,
6403
- className: "text-icon3 flex h-4 w-4",
6404
- onClick: () => setIsExpanded(!isExpanded),
6405
- children: /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(ChevronIcon, { className: clsx("transition-transform -rotate-90", { "rotate-0": isExpanded }) }) })
6406
- }
6407
- ) : /* @__PURE__ */ jsx("div", { "aria-hidden": true, className: "h-full w-4", children: !isRoot && /* @__PURE__ */ jsx("div", { className: "ml-[7px] h-full w-px rounded-full" }) }),
6408
- /* @__PURE__ */ jsxs(TextEl, { className: "flex items-center gap-2 min-w-0", onClick, children: [
6409
- /* @__PURE__ */ jsx("div", { className: clsx("bg-surface4 flex items-center justify-center rounded-md p-[3px]", variantClass), children: /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(VariantIcon, {}) }) }),
6410
- /* @__PURE__ */ jsx(Txt, { variant: "ui-md", className: "text-icon6 truncate", children })
6411
- ] })
6412
- ] }),
6413
- /* @__PURE__ */ jsx(
6414
- Time,
6415
- {
6416
- durationMs,
6417
- tokenCount,
6418
- variant: variant === "agent" ? "agent" : void 0,
6419
- progressPercent,
6420
- offsetPercent
6421
- }
6422
- )
6423
- ] }),
6424
- isExpanded && spans && /* @__PURE__ */ jsx("div", { className: "ml-4", children: spans })
6425
- ] });
6426
- };
6427
-
6428
- const Spans = ({ children }) => {
6429
- return /* @__PURE__ */ jsx("ol", { children });
6430
- };
6431
-
6432
- const Trace = ({
6433
- name,
6434
- spans,
6435
- durationMs,
6436
- tokenCount,
6437
- onClick,
6438
- variant,
6439
- isActive,
6440
- totalDurationMs
6441
- }) => {
6442
- return /* @__PURE__ */ jsx(
6443
- Span,
6444
- {
6445
- isRoot: true,
6446
- durationMs,
6447
- variant,
6448
- spans: /* @__PURE__ */ jsx(Spans, { children: spans }),
6449
- onClick,
6450
- isActive,
6451
- offsetMs: 0,
6452
- totalDurationMs,
6453
- children: name
6454
- }
6455
- );
6456
- };
6457
-
6458
- const getSpanVariant = (span) => {
6459
- const attributes = Object.keys(span.attributes || {}).map((k) => k.toLowerCase());
6460
- const lowerCaseName = span.name.toLowerCase();
6461
- const isAiSpan = lowerCaseName.startsWith("ai.");
6462
- if (isAiSpan) {
6463
- const isAiAboutTool = lowerCaseName.includes("tool");
6464
- if (isAiAboutTool) return "tool";
6465
- return "other";
6466
- }
6467
- const hasMemoryRelatedAttributes = attributes.some((key) => key.includes("memory") || key.includes("storage"));
6468
- if (hasMemoryRelatedAttributes) return "memory";
6469
- const hasToolRelatedAttributes = attributes.some((key) => key.includes("tool"));
6470
- if (hasToolRelatedAttributes) return "tool";
6471
- const hasAgentRelatedAttributes = attributes.some((key) => key.includes("agent."));
6472
- if (hasAgentRelatedAttributes) return "agent";
6473
- if (lowerCaseName.includes(".insert")) {
6474
- const evalRelatedAttribute = attributes.find((key) => String(span.attributes?.[key])?.includes("mastra_evals"));
6475
- if (evalRelatedAttribute) return "eval";
6476
- }
6477
- return "other";
6478
- };
6479
-
6480
- function buildTree(spans, minStartTime, totalDurationMs, parentSpanId = null) {
6481
- return spans.filter((span) => span.parentSpanId === parentSpanId).map((span) => {
6482
- return {
6483
- ...span,
6484
- children: buildTree(spans, minStartTime, totalDurationMs, span.id),
6485
- offset: (span.startTime - minStartTime) / 1e3,
6486
- // ns to ms
6487
- duration: span.duration / 1e3,
6488
- totalDurationMs
6489
- };
6490
- });
6491
- }
6492
- const createSpanTree = (spans) => {
6493
- if (spans.length === 0) return [];
6494
- let minStartTime;
6495
- let maxEndTime;
6496
- const orderedTree = [];
6497
- const listSize = spans.length;
6498
- for (let i = listSize - 1; i >= 0; i--) {
6499
- const span = spans[i];
6500
- if (!minStartTime || span.startTime < minStartTime) {
6501
- minStartTime = span.startTime;
6502
- }
6503
- if (!maxEndTime || span.endTime > maxEndTime) {
6504
- maxEndTime = span.endTime;
6505
- }
6506
- if (span.name !== ".insert" && span.name !== "mastra.getStorage") {
6507
- orderedTree.push(span);
6508
- }
6509
- }
6510
- if (!minStartTime || !maxEndTime) return [];
6511
- const totalDurationMs = (maxEndTime - minStartTime) / 1e3;
6512
- return buildTree(orderedTree, minStartTime, totalDurationMs);
6513
- };
6514
-
6515
- const NestedSpans = ({ spanNodes }) => {
6516
- const { span: activeSpan, setSpan } = useContext(TraceContext);
6517
- return /* @__PURE__ */ jsx(Spans, { children: spanNodes.map((spanNode) => {
6518
- const isActive = spanNode.id === activeSpan?.id;
6519
- return /* @__PURE__ */ jsx(
6520
- Span,
6521
- {
6522
- spans: spanNode.children.length > 0 && /* @__PURE__ */ jsx(NestedSpans, { spanNodes: spanNode.children }),
6523
- durationMs: spanNode.duration,
6524
- offsetMs: spanNode.offset,
6525
- variant: getSpanVariant(spanNode),
6526
- isActive,
6527
- onClick: () => setSpan(spanNode),
6528
- totalDurationMs: spanNode.totalDurationMs,
6529
- children: spanNode.name
6530
- },
6531
- spanNode.id
6532
- );
6533
- }) });
6534
- };
6535
- function SpanView({ trace }) {
6536
- const { span: activeSpan, setSpan } = useContext(TraceContext);
6537
- const tree = createSpanTree(trace);
6538
- return /* @__PURE__ */ jsx(TraceTree, { children: tree.map((node) => /* @__PURE__ */ jsx(
6539
- Trace,
6540
- {
6541
- name: node.name,
6542
- durationMs: node.duration,
6543
- totalDurationMs: node.totalDurationMs,
6544
- spans: /* @__PURE__ */ jsx(NestedSpans, { spanNodes: node.children }),
6545
- variant: getSpanVariant(node),
6546
- isActive: node.id === activeSpan?.id,
6547
- onClick: () => setSpan(node)
6548
- }
6549
- )) });
6550
- }
6551
-
6552
- const Header = ({ children, border = true }) => {
6553
- return /* @__PURE__ */ jsx(
6554
- "header",
6555
- {
6556
- className: clsx("h-header-default z-50 flex w-full items-center gap-[18px] bg-transparent px-5", {
6557
- "border-b-sm border-border1": border
6558
- }),
6559
- children
6560
- }
6561
- );
6562
- };
6563
- const HeaderTitle = ({ children }) => {
6564
- return /* @__PURE__ */ jsx(Txt, { as: "h1", variant: "ui-lg", className: "font-medium text-white", children });
6565
- };
6566
- const HeaderAction = ({ children }) => {
6567
- return /* @__PURE__ */ jsx("div", { className: "ml-auto", children });
6568
- };
6569
- const HeaderGroup = ({ children }) => {
6570
- return /* @__PURE__ */ jsx("div", { className: "gap-lg flex items-center", children });
6571
- };
6572
-
6573
- function TraceDetails() {
6574
- const { trace, currentTraceIndex, prevTrace, nextTrace, traces } = useContext(TraceContext);
6575
- const actualTrace = traces[currentTraceIndex];
6576
- if (!actualTrace || !trace) return null;
6577
- const hasFailure = trace.some((span) => span.status.code !== 0);
6578
- return /* @__PURE__ */ jsxs("aside", { children: [
6579
- /* @__PURE__ */ jsxs(Header, { children: [
6580
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
6581
- /* @__PURE__ */ jsx(Button, { className: "bg-transparent border-none", onClick: prevTrace, disabled: currentTraceIndex === 0, children: /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(ChevronUp, {}) }) }),
6582
- /* @__PURE__ */ jsx(
6583
- Button,
6584
- {
6585
- className: "bg-transparent border-none",
6586
- onClick: nextTrace,
6587
- disabled: currentTraceIndex === traces.length - 1,
6588
- children: /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(ChevronDown, {}) })
6589
- }
6590
- )
6591
- ] }),
6592
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 justify-between w-full", children: [
6593
- /* @__PURE__ */ jsxs(Txt, { variant: "ui-lg", className: "font-medium text-icon5 shrink-0", children: [
6594
- "Trace ",
6595
- /* @__PURE__ */ jsx("span", { className: "ml-2 text-icon3", children: actualTrace.traceId.substring(0, 7) })
6596
- ] }),
6597
- hasFailure && /* @__PURE__ */ jsx(Badge$1, { variant: "error", icon: /* @__PURE__ */ jsx(X, {}), children: "Failed" })
6598
- ] })
6599
- ] }),
6600
- /* @__PURE__ */ jsx("div", { className: "p-5", children: /* @__PURE__ */ jsx(SpanView, { trace }) })
6601
- ] });
6602
- }
6603
-
6604
- const useCodemirrorTheme = () => {
6605
- return useMemo(
6606
- () => draculaInit({
6607
- settings: {
6608
- fontFamily: "var(--geist-mono)",
6609
- fontSize: "0.8rem",
6610
- lineHighlight: "transparent",
6611
- gutterBackground: "transparent",
6612
- gutterForeground: Colors.surface3,
6613
- background: "transparent"
6614
- },
6615
- styles: [{ tag: [tags.className, tags.propertyName] }]
6616
- }),
6617
- []
6618
- );
6619
- };
6620
- const SyntaxHighlighter$1 = ({ data }) => {
6621
- const formattedCode = JSON.stringify(data, null, 2);
6622
- const theme = useCodemirrorTheme();
6623
- return /* @__PURE__ */ jsx("div", { className: "rounded-md bg-[#1a1a1a] p-1 font-mono", children: /* @__PURE__ */ jsx(CodeMirror, { value: formattedCode, theme, extensions: [jsonLanguage] }) });
6624
- };
6625
-
6626
- function formatOtelTimestamp(otelTimestamp) {
6627
- const date = new Date(otelTimestamp / 1e3);
6628
- return new Intl.DateTimeFormat("en-US", {
6629
- month: "numeric",
6630
- day: "numeric",
6631
- year: "numeric",
6632
- hour: "numeric",
6633
- minute: "numeric",
6634
- second: "numeric",
6635
- hour12: true
6636
- }).format(date);
6637
- }
6638
- function formatOtelTimestamp2(otelTimestamp) {
6639
- const date = new Date(otelTimestamp / 1e6);
6640
- return new Intl.DateTimeFormat("en-US", {
6641
- month: "numeric",
6642
- day: "numeric",
6643
- year: "numeric",
6644
- hour: "numeric",
6645
- minute: "numeric",
6646
- second: "numeric",
6647
- hour12: true
6648
- }).format(date);
6649
- }
6650
- function transformKey(key) {
6651
- if (key.includes(".argument.")) {
6652
- return `Input`;
6653
- }
6654
- if (key.includes(".result")) {
6655
- return "Output";
6656
- }
6657
- const newKey = key.split(".").join(" ").split("_").join(" ").replaceAll("ai", "AI");
6658
- return newKey.substring(0, 1).toUpperCase() + newKey.substring(1);
6659
- }
6660
-
6661
- function SpanDetail() {
6662
- const { span, setSpan, trace, setIsOpen } = useContext(TraceContext);
6663
- if (!span || !trace) return null;
6664
- const prevSpan = () => {
6665
- const currentIndex = trace.findIndex((t) => t.id === span.id);
6666
- if (currentIndex !== -1 && currentIndex < trace.length - 1) {
6667
- setSpan(trace[currentIndex + 1]);
6668
- }
6669
- };
6670
- const nextSpan = () => {
6671
- const currentIndex = trace.findIndex((t) => t.id === span.id);
6672
- if (currentIndex !== -1 && currentIndex > 0) {
6673
- setSpan(trace[currentIndex - 1]);
6674
- }
6675
- };
6676
- const SpanIcon = spanIconMap[getSpanVariant(span)];
6677
- const variantClass = spanVariantClasses[getSpanVariant(span)];
6678
- return /* @__PURE__ */ jsxs("aside", { children: [
6679
- /* @__PURE__ */ jsxs(Header, { children: [
6680
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
6681
- /* @__PURE__ */ jsx(Button, { className: "bg-transparent border-none", onClick: prevSpan, children: /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(ChevronUp, {}) }) }),
6682
- /* @__PURE__ */ jsx(Button, { className: "bg-transparent border-none", onClick: nextSpan, children: /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(ChevronDown, {}) }) })
6683
- ] }),
6684
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(Txt, { variant: "ui-lg", className: "font-medium text-icon5", as: "h2", children: [
6685
- "Span ",
6686
- /* @__PURE__ */ jsx("span", { className: "ml-2 text-icon3", children: span.id.substring(0, 7) })
6687
- ] }) }),
6688
- /* @__PURE__ */ jsx("div", { className: "ml-auto flex items-center gap-2", children: /* @__PURE__ */ jsx(Button, { className: "bg-transparent border-none", onClick: () => setIsOpen(false), children: /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(X, {}) }) }) })
6689
- ] }),
6690
- /* @__PURE__ */ jsxs("div", { className: "p-5", children: [
6691
- /* @__PURE__ */ jsxs(Txt, { variant: "header-md", as: "h3", className: "text-icon-6 flex items-center gap-4 pb-3", children: [
6692
- /* @__PURE__ */ jsx(Icon, { size: "lg", className: "bg-surface4 p-1 rounded-md", children: /* @__PURE__ */ jsx(SpanIcon, { className: variantClass }) }),
6693
- span.name
6694
- ] }),
6695
- /* @__PURE__ */ jsx("div", { className: "flex flex-row gap-2 items-center", children: span.status.code === 0 ? /* @__PURE__ */ jsxs(Badge$1, { icon: /* @__PURE__ */ jsx(LatencyIcon, {}), variant: "success", children: [
6696
- toSigFigs(span.duration, 3),
6697
- "ms"
6698
- ] }) : /* @__PURE__ */ jsxs(Badge$1, { variant: "error", icon: /* @__PURE__ */ jsx(X, {}), children: [
6699
- "Failed in ",
6700
- toSigFigs(span.duration, 3),
6701
- "ms"
6702
- ] }) }),
6703
- /* @__PURE__ */ jsx("hr", { className: "border-border1 border-sm my-5" }),
6704
- /* @__PURE__ */ jsxs("dl", { className: "grid grid-cols-2 justify-between gap-2", children: [
6705
- /* @__PURE__ */ jsx("dt", { className: "font-medium text-ui-md text-icon3", children: "ID" }),
6706
- /* @__PURE__ */ jsx("dd", { className: "text-ui-md text-icon6", children: span.id }),
6707
- /* @__PURE__ */ jsx("dt", { className: "font-medium text-ui-md text-icon3", children: "Created at" }),
6708
- /* @__PURE__ */ jsx("dd", { className: "text-ui-md text-icon6", children: span.startTime ? formatOtelTimestamp(span.startTime) : "" })
6709
- ] }),
6710
- span.attributes && /* @__PURE__ */ jsx(Attributes, { attributes: span.attributes }),
6711
- span.events?.length > 0 && /* @__PURE__ */ jsx(Events, { span })
6712
- ] })
6713
- ] });
6714
- }
6715
- function Attributes({ attributes }) {
6716
- if (!attributes) return null;
6717
- const entries = Object.entries(attributes);
6718
- if (entries.length === 0) return null;
6719
- const keysToHide = ["http.request_id", "componentName"];
6720
- return /* @__PURE__ */ jsx("div", { children: entries.filter(([key]) => !keysToHide.includes(key)).map(([key, val]) => {
6721
- return /* @__PURE__ */ jsxs("div", { children: [
6722
- /* @__PURE__ */ jsx("hr", { className: "border-border1 border-sm my-5" }),
6723
- /* @__PURE__ */ jsx(Txt, { as: "h4", variant: "ui-md", className: "text-icon3 pb-2", children: transformKey(key) }),
6724
- /* @__PURE__ */ jsx(AttributeValue, { value: val })
6725
- ] }, key);
6726
- }) });
6727
- }
6728
- const AttributeValue = ({ value }) => {
6729
- if (!value)
6730
- return /* @__PURE__ */ jsx(Txt, { as: "p", variant: "ui-md", className: "text-icon6", children: "N/A" });
6731
- if (typeof value === "number" || typeof value === "boolean") {
6732
- return /* @__PURE__ */ jsx(Txt, { as: "p", variant: "ui-md", className: "text-icon6", children: String(value) });
6733
- }
6734
- if (typeof value === "object") {
6735
- return /* @__PURE__ */ jsx(SyntaxHighlighter$1, { data: value });
6736
- }
6737
- try {
6738
- return /* @__PURE__ */ jsx(SyntaxHighlighter$1, { data: JSON.parse(value) });
6739
- } catch {
6740
- return /* @__PURE__ */ jsx(Txt, { as: "p", variant: "ui-md", className: "text-icon6", children: String(value) });
6741
- }
6742
- };
6743
- function Events({ span }) {
6744
- if (!span.events) return null;
6745
- return /* @__PURE__ */ jsxs("div", { children: [
6746
- /* @__PURE__ */ jsx("hr", { className: "border-border1 border-sm my-5" }),
6747
- /* @__PURE__ */ jsx(Txt, { as: "p", variant: "ui-md", className: "text-icon6 pb-2", children: "Events" }),
6748
- span.events.map((event) => {
6749
- const isLast = event === span.events[span.events.length - 1];
6750
- return /* @__PURE__ */ jsxs(React__default.Fragment, { children: [
6751
- /* @__PURE__ */ jsxs("div", { children: [
6752
- /* @__PURE__ */ jsxs("dl", { className: "grid grid-cols-2 justify-between gap-2 pb-2", children: [
6753
- /* @__PURE__ */ jsx("dt", { className: "font-medium text-ui-md text-icon3", children: "Name" }),
6754
- /* @__PURE__ */ jsx("dd", { className: "text-ui-md text-icon6", children: event.name }),
6755
- /* @__PURE__ */ jsx("dt", { className: "font-medium text-ui-md text-icon3", children: "Time" }),
6756
- /* @__PURE__ */ jsx("dd", { className: "text-ui-md text-icon6", children: event.timeUnixNano ? formatOtelTimestamp2(Number(event.timeUnixNano)) : "N/A" })
6757
- ] }),
6758
- event.attributes?.length > 0 ? /* @__PURE__ */ jsx("ul", { className: "space-y-2", children: event.attributes.filter((attribute) => attribute !== null).map((attribute) => /* @__PURE__ */ jsxs("li", { children: [
6759
- /* @__PURE__ */ jsx(Txt, { as: "h4", variant: "ui-md", className: "text-icon3 pb-2", children: transformKey(attribute.key) }),
6760
- /* @__PURE__ */ jsx(AttributeValue, { value: attribute.value })
6761
- ] }, attribute.key)) }) : null
6762
- ] }, event.name),
6763
- !isLast && /* @__PURE__ */ jsx("hr", { className: "border-border1 border-sm my-5" })
6764
- ] }, event.name);
6765
- })
6766
- ] });
6767
- }
6768
-
6769
- const TracesSidebar = ({ onResize }) => {
6770
- return /* @__PURE__ */ jsx(
6771
- MastraResizablePanel,
6772
- {
6773
- className: "h-full absolute right-0 inset-y-0 bg-surface2",
6774
- defaultWidth: 80,
6775
- minimumWidth: 50,
6776
- maximumWidth: 80,
6777
- setCurrentWidth: onResize,
6778
- children: /* @__PURE__ */ jsxs("div", { className: "h-full grid grid-cols-2", children: [
6779
- /* @__PURE__ */ jsx("div", { className: "overflow-x-scroll w-full h-[calc(100%-40px)]", children: /* @__PURE__ */ jsx(TraceDetails, {}) }),
6780
- /* @__PURE__ */ jsx("div", { className: "h-[calc(100%-40px)] overflow-x-scroll w-full border-l border-border1", children: /* @__PURE__ */ jsx(SpanDetail, {}) })
6781
- ] })
6782
- }
6783
- );
6784
- };
6785
-
6786
- function AgentTraces({ className, traces, error }) {
6787
- return /* @__PURE__ */ jsx(TraceProvider, { initialTraces: traces || [], children: /* @__PURE__ */ jsx(AgentTracesInner, { className, traces, error }) });
6788
- }
6789
- function AgentTracesInner({ className, traces, error }) {
6790
- const [sidebarWidth, setSidebarWidth] = useState(100);
6791
- const { isOpen: open } = useContext(TraceContext);
6792
- return /* @__PURE__ */ jsxs("div", { className: clsx("h-full relative overflow-hidden flex", className), children: [
6793
- /* @__PURE__ */ jsx("div", { className: "h-full overflow-y-scroll w-full", children: /* @__PURE__ */ jsx(TracesTable, { traces, error }) }),
6794
- open && /* @__PURE__ */ jsx(TracesSidebar, { width: sidebarWidth, onResize: setSidebarWidth })
6795
- ] });
6796
- }
6797
-
6798
- const Slider = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxs(
6799
- SliderPrimitive.Root,
6800
- {
6801
- ref,
6802
- className: cn("relative flex w-full touch-none select-none items-center", className),
6803
- ...props,
6804
- children: [
6805
- /* @__PURE__ */ jsx(SliderPrimitive.Track, { className: "relative h-1.5 w-full grow overflow-hidden rounded-full bg-primary/20", children: /* @__PURE__ */ jsx(SliderPrimitive.Range, { className: "absolute h-full bg-primary/50" }) }),
6806
- /* @__PURE__ */ jsx(SliderPrimitive.Thumb, { className: "block h-4 w-4 rounded-full border border-primary/50 bg-white shadow transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50" })
6807
- ]
6808
- }
6809
- ));
6810
- Slider.displayName = SliderPrimitive.Root.displayName;
6811
-
6812
- const labelVariants = cva("text-sm leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70");
6813
- const Label = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(LabelPrimitive.Root, { ref, className: cn(labelVariants(), className), ...props }));
6814
- Label.displayName = LabelPrimitive.Root.displayName;
6815
-
6816
- const RadioGroup = React.forwardRef(({ className, ...props }, ref) => {
6817
- return /* @__PURE__ */ jsx(RadioGroupPrimitive.Root, { className: cn("grid gap-2", className), ...props, ref });
6818
- });
6819
- RadioGroup.displayName = RadioGroupPrimitive.Root.displayName;
6820
- const RadioGroupItem = React.forwardRef(({ className, ...props }, ref) => {
6821
- return /* @__PURE__ */ jsx(
6822
- RadioGroupPrimitive.Item,
6823
- {
6824
- ref,
6825
- className: cn(
6826
- "aspect-square h-4 w-4 rounded-full border border-primary text-primary ring-offset-background focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
6827
- className
6828
- ),
6829
- ...props,
6830
- children: /* @__PURE__ */ jsx(RadioGroupPrimitive.Indicator, { className: "flex items-center justify-center", children: /* @__PURE__ */ jsx(Circle, { className: "h-2.5 w-2.5 fill-current text-current" }) })
6831
- }
6832
- );
6833
- });
6834
- RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName;
6835
-
6836
- const Entry = ({ label, children }) => {
6837
- return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
6838
- /* @__PURE__ */ jsx(Txt, { as: "p", variant: "ui-md", className: "text-icon3", children: label }),
6839
- children
6840
- ] });
6841
- };
6842
-
6843
- const Collapsible = CollapsiblePrimitive.Root;
6844
- const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger;
6845
- const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent;
6846
-
6847
- const formatJSON = async (code) => {
6848
- const formatted = await prettier.format(code, {
6849
- semi: false,
6850
- parser: "json",
6851
- printWidth: 80,
6852
- tabWidth: 2,
6853
- plugins: [prettierPluginBabel, prettierPluginEstree]
6854
- });
6855
- return formatted;
6856
- };
6857
- const isValidJson = (str) => {
6858
- try {
6859
- const obj = JSON.parse(str);
6860
- return !!obj && typeof obj === "object";
6861
- } catch (e) {
6862
- return false;
6863
- }
6864
- };
6865
-
6866
- const AgentAdvancedSettings = () => {
6867
- const { settings, setSettings } = useAgentSettings();
6868
- const [isOpen, setIsOpen] = useState(false);
6869
- const [providerOptionsValue, setProviderOptionsValue] = useState("");
6870
- const [saved, setSaved] = useState(false);
6871
- const [error, setError] = useState(null);
6872
- const theme = useCodemirrorTheme();
6873
- const { handleCopy } = useCopyToClipboard({ text: providerOptionsValue });
6874
- const providerOptionsStr = JSON.stringify(settings?.modelSettings?.providerOptions ?? {});
6875
- useEffect(() => {
6876
- const run = async () => {
6877
- if (!isValidJson(providerOptionsStr)) {
6878
- setError("Invalid JSON");
6879
- return;
6880
- }
6881
- const formatted = await formatJSON(providerOptionsStr);
6882
- setProviderOptionsValue(formatted);
6883
- };
6884
- run();
6885
- }, [providerOptionsStr]);
6886
- const formatProviderOptions = async () => {
6887
- setError(null);
6888
- if (!isValidJson(providerOptionsValue)) {
6889
- setError("Invalid JSON");
6890
- return;
6891
- }
6892
- const formatted = await formatJSON(providerOptionsValue);
6893
- setProviderOptionsValue(formatted);
6894
- };
6895
- const saveProviderOptions = async () => {
6896
- try {
6897
- setError(null);
6898
- const parsedContext = JSON.parse(providerOptionsValue);
6899
- setSettings({
6900
- ...settings,
6901
- modelSettings: {
6902
- ...settings?.modelSettings,
6903
- providerOptions: parsedContext
6904
- }
6905
- });
6906
- setSaved(true);
6907
- setTimeout(() => {
6908
- setSaved(false);
6909
- }, 1e3);
6910
- } catch (error2) {
6911
- console.error("error", error2);
6912
- setError("Invalid JSON");
6249
+ });
6250
+ setSaved(true);
6251
+ setTimeout(() => {
6252
+ setSaved(false);
6253
+ }, 1e3);
6254
+ } catch (error2) {
6255
+ console.error("error", error2);
6256
+ setError("Invalid JSON");
6913
6257
  }
6914
6258
  };
6915
6259
  const collapsibleClassName = "rounded-lg border-sm border-border1 bg-surface3 overflow-clip";
@@ -7148,6 +6492,93 @@ const EmptyState = ({
7148
6492
  ] });
7149
6493
  };
7150
6494
 
6495
+ const rowSize = {
6496
+ default: "[&>tbody>tr]:h-table-row",
6497
+ small: "[&>tbody>tr]:h-table-row-small"
6498
+ };
6499
+ const Table = ({ className, children, size = "default" }) => {
6500
+ return /* @__PURE__ */ jsx("table", { className: clsx("w-full", rowSize[size], className), children });
6501
+ };
6502
+ const Thead = ({ className, children }) => {
6503
+ return /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", { className: clsx("h-table-header border-b-sm border-border1", className), children }) });
6504
+ };
6505
+ const Th = ({ className, children, ...props }) => {
6506
+ return /* @__PURE__ */ jsx(
6507
+ "th",
6508
+ {
6509
+ className: clsx(
6510
+ "text-icon3 text-ui-sm h-full text-left font-normal uppercase first:pl-5 last:pr-5 whitespace-nowrap",
6511
+ className
6512
+ ),
6513
+ ...props,
6514
+ children
6515
+ }
6516
+ );
6517
+ };
6518
+ const Tbody = ({ className, children }) => {
6519
+ return /* @__PURE__ */ jsx("tbody", { className: clsx("", className), children });
6520
+ };
6521
+ const Row = ({ className, children, selected = false, onClick }) => {
6522
+ return /* @__PURE__ */ jsx(
6523
+ "tr",
6524
+ {
6525
+ className: clsx(
6526
+ "border-b-sm border-border1 hover:bg-surface3",
6527
+ selected && "bg-surface4",
6528
+ onClick && "cursor-pointer",
6529
+ className
6530
+ ),
6531
+ onClick,
6532
+ children
6533
+ }
6534
+ );
6535
+ };
6536
+
6537
+ const formatDateCell = (date) => {
6538
+ const month = new Intl.DateTimeFormat("en-US", { month: "short" }).format(date).toUpperCase();
6539
+ const day = date.getDate();
6540
+ const formattedDay = `${month} ${day}`;
6541
+ const time = new Intl.DateTimeFormat("en-US", {
6542
+ hour: "2-digit",
6543
+ minute: "2-digit",
6544
+ second: "2-digit",
6545
+ hour12: false
6546
+ // Use 24-hour format
6547
+ }).format(date);
6548
+ return { day: formattedDay, time };
6549
+ };
6550
+
6551
+ const Cell = ({ className, children, ...props }) => {
6552
+ return /* @__PURE__ */ jsx("td", { className: clsx("text-icon5 first:pl-5 last:pr-5", className), ...props, children: /* @__PURE__ */ jsx("div", { className: clsx("flex h-full w-full shrink-0 items-center"), children }) });
6553
+ };
6554
+ const TxtCell = ({ className, children }) => {
6555
+ return /* @__PURE__ */ jsx(Cell, { className, children: /* @__PURE__ */ jsx(Txt, { as: "span", variant: "ui-md", className: "w-full truncate", children }) });
6556
+ };
6557
+ const UnitCell = ({ className, children, unit }) => {
6558
+ return /* @__PURE__ */ jsx(Cell, { className, children: /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-center", children: [
6559
+ /* @__PURE__ */ jsx(Txt, { as: "span", variant: "ui-md", className: "shrink-0", children }),
6560
+ /* @__PURE__ */ jsx(Txt, { as: "span", variant: "ui-sm", className: "text-icon3 w-full truncate", children: unit })
6561
+ ] }) });
6562
+ };
6563
+ const DateTimeCell = ({ dateTime, ...props }) => {
6564
+ const { day, time } = formatDateCell(dateTime);
6565
+ return /* @__PURE__ */ jsx(Cell, { ...props, children: /* @__PURE__ */ jsxs("div", { className: "shrink-0", children: [
6566
+ /* @__PURE__ */ jsx(Txt, { as: "span", variant: "ui-sm", className: "text-icon3", children: day }),
6567
+ " ",
6568
+ /* @__PURE__ */ jsx(Txt, { as: "span", variant: "ui-md", children: time })
6569
+ ] }) });
6570
+ };
6571
+ const EntryCell = ({ name, description, icon, meta, ...props }) => {
6572
+ return /* @__PURE__ */ jsx(Cell, { ...props, children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-[14px]", children: [
6573
+ /* @__PURE__ */ jsx(Icon, { size: "lg", className: "text-icon5", children: icon }),
6574
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-0", children: [
6575
+ /* @__PURE__ */ jsx(Txt, { as: "span", variant: "ui-md", className: "text-icon6 font-medium !leading-tight", children: name }),
6576
+ description && /* @__PURE__ */ jsx(Txt, { as: "span", variant: "ui-xs", className: "text-icon3 w-full max-w-[300px] truncate !leading-tight", children: description })
6577
+ ] }),
6578
+ meta
6579
+ ] }) });
6580
+ };
6581
+
7151
6582
  const INDICATOR_WIDTH = 40;
7152
6583
  const INDICATOR_HEIGHT = 150;
7153
6584
  const INDICATOR_SPACE = 10;
@@ -7774,6 +7205,7 @@ const columns$2 = [
7774
7205
  {
7775
7206
  variant: "default",
7776
7207
  icon: providerMapToIcon[row.original.provider] || /* @__PURE__ */ jsx(OpenAIIcon, {}),
7208
+ className: "truncate",
7777
7209
  children: row.original.modelId || "N/A"
7778
7210
  }
7779
7211
  ) });
@@ -7899,49 +7331,540 @@ const RuntimeContext = () => {
7899
7331
  toast.error("Invalid JSON");
7900
7332
  return;
7901
7333
  }
7902
- const formatted = await formatJSON(runtimeContextValue);
7903
- setRuntimeContextValue(formatted);
7904
- };
7905
- return /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs("div", { children: [
7906
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between pb-2", children: [
7907
- /* @__PURE__ */ jsx(Txt, { as: "label", variant: "ui-md", className: "text-icon3", children: "Runtime Context (JSON)" }),
7908
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
7909
- /* @__PURE__ */ jsxs(Tooltip, { children: [
7910
- /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx("button", { onClick: formatRuntimeContext, className: buttonClass, children: /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(Braces, {}) }) }) }),
7911
- /* @__PURE__ */ jsx(TooltipContent, { children: "Format the Runtime Context JSON" })
7912
- ] }),
7913
- /* @__PURE__ */ jsxs(Tooltip, { children: [
7914
- /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx("button", { onClick: handleCopy, className: buttonClass, children: /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(CopyIcon, {}) }) }) }),
7915
- /* @__PURE__ */ jsx(TooltipContent, { children: "Copy Runtime Context" })
7916
- ] })
7334
+ const formatted = await formatJSON(runtimeContextValue);
7335
+ setRuntimeContextValue(formatted);
7336
+ };
7337
+ return /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs("div", { children: [
7338
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between pb-2", children: [
7339
+ /* @__PURE__ */ jsx(Txt, { as: "label", variant: "ui-md", className: "text-icon3", children: "Runtime Context (JSON)" }),
7340
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
7341
+ /* @__PURE__ */ jsxs(Tooltip, { children: [
7342
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx("button", { onClick: formatRuntimeContext, className: buttonClass, children: /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(Braces, {}) }) }) }),
7343
+ /* @__PURE__ */ jsx(TooltipContent, { children: "Format the Runtime Context JSON" })
7344
+ ] }),
7345
+ /* @__PURE__ */ jsxs(Tooltip, { children: [
7346
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx("button", { onClick: handleCopy, className: buttonClass, children: /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(CopyIcon, {}) }) }) }),
7347
+ /* @__PURE__ */ jsx(TooltipContent, { children: "Copy Runtime Context" })
7348
+ ] })
7349
+ ] })
7350
+ ] }),
7351
+ /* @__PURE__ */ jsx(
7352
+ CodeMirror,
7353
+ {
7354
+ value: runtimeContextValue,
7355
+ onChange: setRuntimeContextValue,
7356
+ theme,
7357
+ extensions: [jsonLanguage],
7358
+ className: "h-[400px] overflow-y-scroll bg-surface3 rounded-lg overflow-hidden p-3"
7359
+ }
7360
+ ),
7361
+ /* @__PURE__ */ jsx("div", { className: "flex justify-end pt-2", children: /* @__PURE__ */ jsx(Button, { onClick: handleSaveRuntimeContext, children: "Save" }) })
7362
+ ] }) });
7363
+ };
7364
+ const RuntimeContextWrapper = ({ children }) => {
7365
+ const { Link } = useLinkComponent();
7366
+ return /* @__PURE__ */ jsxs("div", { className: "max-w-3xl p-5 overflow-y-scroll h-full", children: [
7367
+ /* @__PURE__ */ jsxs("div", { className: "rounded-lg p-4 pb-5 bg-surface4 shadow-md space-y-3 border border-border1 mb-5", children: [
7368
+ /* @__PURE__ */ jsx(Txt, { as: "p", variant: "ui-lg", className: "text-icon3", children: "Mastra provides runtime context, which is a system based on dependency injection that enables you to configure your agents and tools with runtime variables. If you find yourself creating several different agents that do very similar things, runtime context allows you to combine them into one agent." }),
7369
+ /* @__PURE__ */ jsxs(Button, { as: Link, to: "https://mastra.ai/en/docs/agents/runtime-variables", target: "_blank", children: [
7370
+ /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(ExternalLink, {}) }),
7371
+ "See documentation"
7372
+ ] })
7373
+ ] }),
7374
+ children
7375
+ ] });
7376
+ };
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 })
7917
7574
  ] })
7918
- ] }),
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" }) }),
7919
7593
  /* @__PURE__ */ jsx(
7920
- CodeMirror,
7594
+ AgentMetadataSection,
7921
7595
  {
7922
- value: runtimeContextValue,
7923
- onChange: setRuntimeContextValue,
7924
- theme,
7925
- extensions: [jsonLanguage],
7926
- className: "h-[400px] overflow-y-scroll bg-surface3 rounded-lg overflow-hidden p-3"
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" })
7927
7602
  }
7928
7603
  ),
7929
- /* @__PURE__ */ jsx("div", { className: "flex justify-end pt-2", children: /* @__PURE__ */ jsx(Button, { onClick: handleSaveRuntimeContext, children: "Save" }) })
7930
- ] }) });
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
+ ] });
7931
7629
  };
7932
- const RuntimeContextWrapper = ({ children }) => {
7630
+ const AgentMetadataToolList = ({ tools, computeToolLink }) => {
7933
7631
  const { Link } = useLinkComponent();
7934
- return /* @__PURE__ */ jsxs("div", { className: "max-w-3xl p-5 overflow-y-scroll h-full", children: [
7935
- /* @__PURE__ */ jsxs("div", { className: "rounded-lg p-4 pb-5 bg-surface4 shadow-md space-y-3 border border-border1 mb-5", children: [
7936
- /* @__PURE__ */ jsx(Txt, { as: "p", variant: "ui-lg", className: "text-icon3", children: "Mastra provides runtime context, which is a system based on dependency injection that enables you to configure your agents and tools with runtime variables. If you find yourself creating several different agents that do very similar things, runtime context allows you to combine them into one agent." }),
7937
- /* @__PURE__ */ jsxs(Button, { as: Link, to: "https://mastra.ai/en/docs/agents/runtime-variables", target: "_blank", children: [
7938
- /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(ExternalLink, {}) }),
7939
- "See documentation"
7940
- ] })
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 }) })
7941
7657
  ] }),
7942
- children
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
+ )
7943
7822
  ] });
7944
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
+ };
7945
7868
 
7946
7869
  const convertMessage$1 = (message) => {
7947
7870
  return message;
@@ -8407,6 +8330,10 @@ const useVNextNetworkChat = () => {
8407
8330
  return context;
8408
8331
  };
8409
8332
 
8333
+ const toSigFigs = (num, sigFigs) => {
8334
+ return Number(num.toPrecision(sigFigs));
8335
+ };
8336
+
8410
8337
  const Clock = ({ startedAt, endedAt }) => {
8411
8338
  const [time, setTime] = useState(startedAt);
8412
8339
  useEffect(() => {
@@ -9385,7 +9312,8 @@ const WorkflowStepActionBar = ({
9385
9312
  onShowTrace,
9386
9313
  onShowNestedGraph,
9387
9314
  onSendEvent,
9388
- runId
9315
+ runId,
9316
+ status
9389
9317
  }) => {
9390
9318
  const [isInputOpen, setIsInputOpen] = useState(false);
9391
9319
  const [isOutputOpen, setIsOutputOpen] = useState(false);
@@ -9396,71 +9324,84 @@ const WorkflowStepActionBar = ({
9396
9324
  const dialogContentClass = "bg-surface2 rounded-lg border-sm border-border1 max-w-4xl w-full px-0";
9397
9325
  const dialogTitleClass = "border-b-sm border-border1 pb-4 px-6";
9398
9326
  const showEventForm = event && onSendEvent && runId;
9399
- return /* @__PURE__ */ jsx(Fragment, { children: (input || output || error || mapConfig || resumeData || onShowNestedGraph || showEventForm) && /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center bg-surface4 border-t-sm border-border1 px-2 py-1 gap-2 rounded-b-lg", children: [
9400
- onShowNestedGraph && /* @__PURE__ */ jsx(Button, { onClick: onShowNestedGraph, children: "View nested graph" }),
9401
- mapConfig && /* @__PURE__ */ jsxs(Fragment, { children: [
9402
- /* @__PURE__ */ jsx(Button, { onClick: () => setIsMapConfigOpen(true), children: "Map config" }),
9403
- /* @__PURE__ */ jsx(Dialog, { open: isMapConfigOpen, onOpenChange: setIsMapConfigOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: dialogContentClass, children: [
9404
- /* @__PURE__ */ jsxs(DialogTitle, { className: dialogTitleClass, children: [
9405
- stepName,
9406
- " map config"
9407
- ] }),
9408
- /* @__PURE__ */ jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsx(CodeDialogContent, { data: mapConfig }) })
9409
- ] }) })
9410
- ] }),
9411
- input && /* @__PURE__ */ jsxs(Fragment, { children: [
9412
- /* @__PURE__ */ jsx(Button, { onClick: () => setIsInputOpen(true), children: "Input" }),
9413
- /* @__PURE__ */ jsx(Dialog, { open: isInputOpen, onOpenChange: setIsInputOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: dialogContentClass, children: [
9414
- /* @__PURE__ */ jsxs(DialogTitle, { className: dialogTitleClass, children: [
9415
- stepName,
9416
- " input"
9327
+ return /* @__PURE__ */ jsx(Fragment, { children: (input || output || error || mapConfig || resumeData || onShowNestedGraph || showEventForm) && /* @__PURE__ */ jsxs(
9328
+ "div",
9329
+ {
9330
+ className: cn(
9331
+ "flex flex-wrap items-center bg-surface4 border-t-sm border-border1 px-2 py-1 gap-2 rounded-b-lg",
9332
+ status === "success" && "bg-accent1Dark",
9333
+ status === "failed" && "bg-accent2Dark",
9334
+ status === "suspended" && "bg-accent3Dark",
9335
+ status === "waiting" && "bg-accent5Dark",
9336
+ status === "running" && "bg-accent6Dark"
9337
+ ),
9338
+ children: [
9339
+ onShowNestedGraph && /* @__PURE__ */ jsx(Button, { onClick: onShowNestedGraph, children: "View nested graph" }),
9340
+ mapConfig && /* @__PURE__ */ jsxs(Fragment, { children: [
9341
+ /* @__PURE__ */ jsx(Button, { onClick: () => setIsMapConfigOpen(true), children: "Map config" }),
9342
+ /* @__PURE__ */ jsx(Dialog, { open: isMapConfigOpen, onOpenChange: setIsMapConfigOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: dialogContentClass, children: [
9343
+ /* @__PURE__ */ jsxs(DialogTitle, { className: dialogTitleClass, children: [
9344
+ stepName,
9345
+ " map config"
9346
+ ] }),
9347
+ /* @__PURE__ */ jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsx(CodeDialogContent, { data: mapConfig }) })
9348
+ ] }) })
9417
9349
  ] }),
9418
- /* @__PURE__ */ jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsx(CodeDialogContent, { data: input }) })
9419
- ] }) })
9420
- ] }),
9421
- resumeData && /* @__PURE__ */ jsxs(Fragment, { children: [
9422
- /* @__PURE__ */ jsx(Button, { onClick: () => setIsResumeDataOpen(true), children: "Resume data" }),
9423
- /* @__PURE__ */ jsx(Dialog, { open: isResumeDataOpen, onOpenChange: setIsResumeDataOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: dialogContentClass, children: [
9424
- /* @__PURE__ */ jsxs(DialogTitle, { className: dialogTitleClass, children: [
9425
- stepName,
9426
- " resume data"
9350
+ input && /* @__PURE__ */ jsxs(Fragment, { children: [
9351
+ /* @__PURE__ */ jsx(Button, { onClick: () => setIsInputOpen(true), children: "Input" }),
9352
+ /* @__PURE__ */ jsx(Dialog, { open: isInputOpen, onOpenChange: setIsInputOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: dialogContentClass, children: [
9353
+ /* @__PURE__ */ jsxs(DialogTitle, { className: dialogTitleClass, children: [
9354
+ stepName,
9355
+ " input"
9356
+ ] }),
9357
+ /* @__PURE__ */ jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsx(CodeDialogContent, { data: input }) })
9358
+ ] }) })
9427
9359
  ] }),
9428
- /* @__PURE__ */ jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsx(CodeDialogContent, { data: resumeData }) })
9429
- ] }) })
9430
- ] }),
9431
- output && /* @__PURE__ */ jsxs(Fragment, { children: [
9432
- /* @__PURE__ */ jsx(Button, { onClick: () => setIsOutputOpen(true), children: "Output" }),
9433
- /* @__PURE__ */ jsx(Dialog, { open: isOutputOpen, onOpenChange: setIsOutputOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: dialogContentClass, children: [
9434
- /* @__PURE__ */ jsxs(DialogTitle, { className: dialogTitleClass, children: [
9435
- stepName,
9436
- " output"
9360
+ resumeData && /* @__PURE__ */ jsxs(Fragment, { children: [
9361
+ /* @__PURE__ */ jsx(Button, { onClick: () => setIsResumeDataOpen(true), children: "Resume data" }),
9362
+ /* @__PURE__ */ jsx(Dialog, { open: isResumeDataOpen, onOpenChange: setIsResumeDataOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: dialogContentClass, children: [
9363
+ /* @__PURE__ */ jsxs(DialogTitle, { className: dialogTitleClass, children: [
9364
+ stepName,
9365
+ " resume data"
9366
+ ] }),
9367
+ /* @__PURE__ */ jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsx(CodeDialogContent, { data: resumeData }) })
9368
+ ] }) })
9437
9369
  ] }),
9438
- /* @__PURE__ */ jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsx(CodeDialogContent, { data: output }) })
9439
- ] }) })
9440
- ] }),
9441
- error && /* @__PURE__ */ jsxs(Fragment, { children: [
9442
- /* @__PURE__ */ jsx(Button, { onClick: () => setIsErrorOpen(true), children: "Error" }),
9443
- /* @__PURE__ */ jsx(Dialog, { open: isErrorOpen, onOpenChange: setIsErrorOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: dialogContentClass, children: [
9444
- /* @__PURE__ */ jsxs(DialogTitle, { className: dialogTitleClass, children: [
9445
- stepName,
9446
- " error"
9370
+ output && /* @__PURE__ */ jsxs(Fragment, { children: [
9371
+ /* @__PURE__ */ jsx(Button, { onClick: () => setIsOutputOpen(true), children: "Output" }),
9372
+ /* @__PURE__ */ jsx(Dialog, { open: isOutputOpen, onOpenChange: setIsOutputOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: dialogContentClass, children: [
9373
+ /* @__PURE__ */ jsxs(DialogTitle, { className: dialogTitleClass, children: [
9374
+ stepName,
9375
+ " output"
9376
+ ] }),
9377
+ /* @__PURE__ */ jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsx(CodeDialogContent, { data: output }) })
9378
+ ] }) })
9447
9379
  ] }),
9448
- /* @__PURE__ */ jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsx(CodeDialogContent, { data: error }) })
9449
- ] }) })
9450
- ] }),
9451
- onShowTrace && /* @__PURE__ */ jsx(Button, { onClick: onShowTrace, children: "Show trace" }),
9452
- showEventForm && /* @__PURE__ */ jsxs(Fragment, { children: [
9453
- /* @__PURE__ */ jsx(Button, { className: "ring-1 ring-accent5 !text-accent5", onClick: () => setIsEventFormOpen(true), children: "Send event" }),
9454
- /* @__PURE__ */ jsx(Dialog, { open: isEventFormOpen, onOpenChange: setIsEventFormOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: dialogContentClass, children: [
9455
- /* @__PURE__ */ jsxs(DialogTitle, { className: dialogTitleClass, children: [
9456
- "Send ",
9457
- event,
9458
- " event"
9380
+ error && /* @__PURE__ */ jsxs(Fragment, { children: [
9381
+ /* @__PURE__ */ jsx(Button, { onClick: () => setIsErrorOpen(true), children: "Error" }),
9382
+ /* @__PURE__ */ jsx(Dialog, { open: isErrorOpen, onOpenChange: setIsErrorOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: dialogContentClass, children: [
9383
+ /* @__PURE__ */ jsxs(DialogTitle, { className: dialogTitleClass, children: [
9384
+ stepName,
9385
+ " error"
9386
+ ] }),
9387
+ /* @__PURE__ */ jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsx(CodeDialogContent, { data: error }) })
9388
+ ] }) })
9459
9389
  ] }),
9460
- /* @__PURE__ */ jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsx(WorkflowRunEventForm, { event, runId, onSendEvent }) })
9461
- ] }) })
9462
- ] })
9463
- ] }) });
9390
+ onShowTrace && /* @__PURE__ */ jsx(Button, { onClick: onShowTrace, children: "Show trace" }),
9391
+ showEventForm && /* @__PURE__ */ jsxs(Fragment, { children: [
9392
+ /* @__PURE__ */ jsx(Button, { className: "ring-1 ring-accent5 !text-accent5", onClick: () => setIsEventFormOpen(true), children: "Send event" }),
9393
+ /* @__PURE__ */ jsx(Dialog, { open: isEventFormOpen, onOpenChange: setIsEventFormOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: dialogContentClass, children: [
9394
+ /* @__PURE__ */ jsxs(DialogTitle, { className: dialogTitleClass, children: [
9395
+ "Send ",
9396
+ event,
9397
+ " event"
9398
+ ] }),
9399
+ /* @__PURE__ */ jsx("div", { className: "px-4 overflow-hidden", children: /* @__PURE__ */ jsx(WorkflowRunEventForm, { event, runId, onSendEvent }) })
9400
+ ] }) })
9401
+ ] })
9402
+ ]
9403
+ }
9404
+ ) });
9464
9405
  };
9465
9406
 
9466
9407
  function WorkflowConditionNode({ data }) {
@@ -9479,8 +9420,8 @@ function WorkflowConditionNode({ data }) {
9479
9420
  {
9480
9421
  className: cn(
9481
9422
  "bg-surface3 rounded-lg w-[300px] border-sm border-border1",
9482
- previousStep?.status === "success" && nextStep && "ring-2 ring-accent1",
9483
- previousStep?.status === "failed" && nextStep && "ring-2 ring-accent2"
9423
+ previousStep?.status === "success" && nextStep && "ring-2 ring-accent1 bg-accent1Darker",
9424
+ previousStep?.status === "failed" && nextStep && "ring-2 ring-accent2 bg-accent2Darker"
9484
9425
  ),
9485
9426
  children: [
9486
9427
  /* @__PURE__ */ jsxs(
@@ -9509,7 +9450,12 @@ function WorkflowConditionNode({ data }) {
9509
9450
  /* @__PURE__ */ jsx(Highlight, { theme: themes.oneDark, code: String(condition.fnString).trim(), language: "javascript", children: ({ className, style, tokens, getLineProps, getTokenProps }) => /* @__PURE__ */ jsx(
9510
9451
  "pre",
9511
9452
  {
9512
- className: `${className} relative font-mono p-3 w-full cursor-pointer rounded-lg text-xs !bg-surface4 overflow-scroll`,
9453
+ className: cn(
9454
+ "relative font-mono p-3 w-full cursor-pointer rounded-lg text-xs !bg-surface4 overflow-scroll",
9455
+ className,
9456
+ previousStep?.status === "success" && nextStep && "!bg-accent1Dark",
9457
+ previousStep?.status === "failed" && nextStep && "!bg-accent2Dark"
9458
+ ),
9513
9459
  onClick: () => setOpenDialog(true),
9514
9460
  style,
9515
9461
  children: tokens.map((line, i) => /* @__PURE__ */ jsxs("div", { ...getLineProps({ line }), children: [
@@ -9558,7 +9504,15 @@ function WorkflowConditionNode({ data }) {
9558
9504
  ]
9559
9505
  }
9560
9506
  ),
9561
- /* @__PURE__ */ jsx(WorkflowStepActionBar, { stepName: nextStepId, input: previousStep?.output, mapConfig: data.mapConfig })
9507
+ /* @__PURE__ */ jsx(
9508
+ WorkflowStepActionBar,
9509
+ {
9510
+ stepName: nextStepId,
9511
+ input: previousStep?.output,
9512
+ mapConfig: data.mapConfig,
9513
+ status: nextStep ? previousStep?.status : void 0
9514
+ }
9515
+ )
9562
9516
  ]
9563
9517
  }
9564
9518
  ),
@@ -9583,11 +9537,11 @@ function WorkflowDefaultNode({
9583
9537
  {
9584
9538
  className: cn(
9585
9539
  "bg-surface3 rounded-lg w-[274px] border-sm border-border1 pt-2",
9586
- step?.status === "success" && "ring-2 ring-accent1",
9587
- step?.status === "failed" && "ring-2 ring-accent2",
9588
- step?.status === "suspended" && "ring-2 ring-accent3",
9589
- step?.status === "waiting" && "ring-2 ring-accent5",
9590
- step?.status === "running" && "ring-2 ring-accent6"
9540
+ step?.status === "success" && "ring-2 ring-accent1 bg-accent1Darker",
9541
+ step?.status === "failed" && "ring-2 ring-accent2 bg-accent2Darker",
9542
+ step?.status === "suspended" && "ring-2 ring-accent3 bg-accent3Darker",
9543
+ step?.status === "waiting" && "ring-2 ring-accent5 bg-accent5Darker",
9544
+ step?.status === "running" && "ring-2 ring-accent6 bg-accent6Darker"
9591
9545
  ),
9592
9546
  children: [
9593
9547
  /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-2 px-3", !description && "pb-2"), children: [
@@ -9633,7 +9587,8 @@ function WorkflowDefaultNode({
9633
9587
  event: step?.status === "waiting" ? event : void 0,
9634
9588
  onShowTrace: runId && onShowTrace ? () => onShowTrace?.({ runId, stepName: fullLabel }) : void 0,
9635
9589
  runId,
9636
- onSendEvent
9590
+ onSendEvent,
9591
+ status: step?.status
9637
9592
  }
9638
9593
  )
9639
9594
  ]
@@ -9886,11 +9841,11 @@ function WorkflowNestedNode({
9886
9841
  {
9887
9842
  className: cn(
9888
9843
  "bg-surface3 rounded-lg w-[274px] border-sm border-border1 pt-2",
9889
- step?.status === "success" && "ring-2 ring-accent1",
9890
- step?.status === "failed" && "ring-2 ring-accent2",
9891
- step?.status === "suspended" && "ring-2 ring-accent3",
9892
- step?.status === "waiting" && "ring-2 ring-accent5",
9893
- step?.status === "running" && "ring-2 ring-accent6"
9844
+ step?.status === "success" && "ring-2 ring-accent1 bg-accent1Darker",
9845
+ step?.status === "failed" && "ring-2 ring-accent2 bg-accent2Darker",
9846
+ step?.status === "suspended" && "ring-2 ring-accent3 bg-accent3Darker",
9847
+ step?.status === "waiting" && "ring-2 ring-accent5 bg-accent5Darker",
9848
+ step?.status === "running" && "ring-2 ring-accent6 bg-accent6Darker"
9894
9849
  ),
9895
9850
  children: [
9896
9851
  /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-2 px-3", !description && "pb-2"), children: [
@@ -9922,7 +9877,8 @@ function WorkflowNestedNode({
9922
9877
  onShowNestedGraph: () => showNestedGraph({ label, fullStep: fullLabel, stepGraph }),
9923
9878
  onSendEvent,
9924
9879
  event: step?.status === "waiting" ? event : void 0,
9925
- runId
9880
+ runId,
9881
+ status: step?.status
9926
9882
  }
9927
9883
  )
9928
9884
  ]
@@ -11123,7 +11079,7 @@ const columns$1 = [
11123
11079
  {
11124
11080
  id: "model",
11125
11081
  header: "Routing Models",
11126
- cell: ({ row }) => /* @__PURE__ */ jsxs(Cell, { children: [
11082
+ cell: ({ row }) => /* @__PURE__ */ jsxs(Cell, { className: "truncate", children: [
11127
11083
  /* @__PURE__ */ jsx(Badge$1, { variant: "default", icon: /* @__PURE__ */ jsx(Brain, {}), children: row.original.routingModel }),
11128
11084
  row.original.isVNext ? /* @__PURE__ */ jsx(Badge$1, { className: "!text-accent1 ml-2", children: "vNext" }) : null
11129
11085
  ] })
@@ -11212,46 +11168,11 @@ const NetworkTableSkeleton = () => {
11212
11168
  /* @__PURE__ */ jsx(Tbody, { children: Array.from({ length: 3 }).map((_, index) => /* @__PURE__ */ jsxs(Row, { children: [
11213
11169
  /* @__PURE__ */ jsx(Cell, { children: /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-1/2" }) }),
11214
11170
  /* @__PURE__ */ jsx(Cell, { width: 160, children: /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-1/2" }) }),
11215
- /* @__PURE__ */ jsx(Cell, { width: 160, children: /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-1/2" }) }),
11216
- /* @__PURE__ */ jsx(Cell, { width: 160, children: /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-1/2" }) }),
11217
- /* @__PURE__ */ jsx(Cell, { width: 160, children: /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-1/2" }) })
11218
- ] }, index)) })
11219
- ] });
11220
- };
11221
-
11222
- const Entity = ({ children, className, onClick }) => {
11223
- return /* @__PURE__ */ jsx(
11224
- "div",
11225
- {
11226
- tabIndex: onClick ? 0 : void 0,
11227
- onKeyDown: (e) => {
11228
- if (!onClick) return;
11229
- if (e.key === "Enter" || e.key === " ") {
11230
- e.preventDefault();
11231
- onClick?.();
11232
- }
11233
- },
11234
- className: clsx(
11235
- "flex gap-3 group/entity bg-surface3 rounded-lg border-sm border-border1 py-3 px-4",
11236
- onClick && "cursor-pointer hover:bg-surface4 transition-all",
11237
- className
11238
- ),
11239
- onClick,
11240
- children
11241
- }
11242
- );
11243
- };
11244
- const EntityIcon = ({ children, className }) => {
11245
- return /* @__PURE__ */ jsx(Icon, { size: "lg", className: clsx("text-icon3 mt-1", className), children });
11246
- };
11247
- const EntityName = ({ children, className }) => {
11248
- return /* @__PURE__ */ jsx(Txt, { as: "p", variant: "ui-lg", className: clsx("text-icon6 font-medium", className), children });
11249
- };
11250
- const EntityDescription = ({ children, className }) => {
11251
- return /* @__PURE__ */ jsx(Txt, { as: "p", variant: "ui-sm", className: clsx("text-icon3", className), children });
11252
- };
11253
- const EntityContent = ({ children, className }) => {
11254
- return /* @__PURE__ */ jsx("div", { className, children });
11171
+ /* @__PURE__ */ jsx(Cell, { width: 160, children: /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-1/2" }) }),
11172
+ /* @__PURE__ */ jsx(Cell, { width: 160, children: /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-1/2" }) }),
11173
+ /* @__PURE__ */ jsx(Cell, { width: 160, children: /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-1/2" }) })
11174
+ ] }, index)) })
11175
+ ] });
11255
11176
  };
11256
11177
 
11257
11178
  const ToolList = ({ tools, agents, isLoading, computeLink, computeAgentLink }) => {
@@ -11388,31 +11309,6 @@ const prepareAgents = (tools, agents) => {
11388
11309
  return Array.from(toolsWithAgents.values());
11389
11310
  };
11390
11311
 
11391
- function WorkflowTraces({ traces, error, runId, stepName }) {
11392
- return /* @__PURE__ */ jsx(TraceProvider, { initialTraces: traces || [], children: /* @__PURE__ */ jsx(WorkflowTracesInner, { traces, error, runId, stepName }) });
11393
- }
11394
- function WorkflowTracesInner({ traces, error, runId, stepName }) {
11395
- const hasRunRef = useRef(false);
11396
- const [sidebarWidth, setSidebarWidth] = useState(100);
11397
- const { isOpen: open, setTrace, setIsOpen, setSpan } = useContext(TraceContext);
11398
- useEffect(() => {
11399
- if (hasRunRef.current) return;
11400
- if (!runId || !stepName) return;
11401
- const matchingTrace = traces.find((trace) => trace.runId === runId);
11402
- if (!matchingTrace) return;
11403
- const matchingSpan = matchingTrace.trace.find((span) => span.name.includes(stepName));
11404
- if (!matchingSpan) return;
11405
- setTrace(matchingTrace.trace);
11406
- setSpan(matchingSpan);
11407
- setIsOpen(true);
11408
- hasRunRef.current = true;
11409
- }, [runId, traces, setTrace]);
11410
- return /* @__PURE__ */ jsxs("main", { className: "h-full relative overflow-hidden flex", children: [
11411
- /* @__PURE__ */ jsx("div", { className: "h-full overflow-y-scroll w-full", children: /* @__PURE__ */ jsx(TracesTable, { traces, error }) }),
11412
- open && /* @__PURE__ */ jsx(TracesSidebar, { width: sidebarWidth, onResize: setSidebarWidth })
11413
- ] });
11414
- }
11415
-
11416
11312
  function LegacyWorkflowNestedGraph({
11417
11313
  stepGraph,
11418
11314
  stepSubscriberGraph,
@@ -11810,7 +11706,7 @@ const DatePicker = ({
11810
11706
  DatePickerOnly,
11811
11707
  {
11812
11708
  value,
11813
- setValue: (v) => setValue(v ? /* @__PURE__ */ new Date(`${v}z`) : null),
11709
+ setValue,
11814
11710
  clearable: props.clearable,
11815
11711
  setOpenPopover,
11816
11712
  ...props
@@ -12442,31 +12338,280 @@ const WorkflowResult = ({ jsonResult, sanitizedJsonResult }) => {
12442
12338
  );
12443
12339
  };
12444
12340
 
12445
- function LegacyWorkflowTrigger({
12341
+ function LegacyWorkflowTrigger({
12342
+ workflowId,
12343
+ setRunId
12344
+ }) {
12345
+ const { legacyResult: result, setLegacyResult: setResult, payload, setPayload } = useContext(WorkflowRunContext);
12346
+ const { isLoading, legacyWorkflow: workflow } = useLegacyWorkflow(workflowId);
12347
+ const { createLegacyWorkflowRun: createWorkflowRun, startLegacyWorkflowRun: startWorkflowRun } = useExecuteWorkflow();
12348
+ const {
12349
+ watchLegacyWorkflow: watchWorkflow,
12350
+ legacyWatchResult: watchResult,
12351
+ isWatchingLegacyWorkflow: isWatchingWorkflow
12352
+ } = useWatchWorkflow();
12353
+ const { resumeLegacyWorkflow: resumeWorkflow, isResumingLegacyWorkflow: isResumingWorkflow } = useResumeWorkflow();
12354
+ const [suspendedSteps, setSuspendedSteps] = useState([]);
12355
+ const [isRunning, setIsRunning] = useState(false);
12356
+ const triggerSchema = workflow?.triggerSchema;
12357
+ const handleExecuteWorkflow = async (data) => {
12358
+ try {
12359
+ if (!workflow) return;
12360
+ setIsRunning(true);
12361
+ setResult(null);
12362
+ const { runId } = await createWorkflowRun({ workflowId });
12363
+ setRunId?.(runId);
12364
+ watchWorkflow({ workflowId, runId });
12365
+ startWorkflowRun({ workflowId, runId, input: data });
12366
+ } catch (err) {
12367
+ setIsRunning(false);
12368
+ toast.error("Error executing workflow");
12369
+ }
12370
+ };
12371
+ const handleResumeWorkflow = async (step) => {
12372
+ if (!workflow) return;
12373
+ const { stepId, runId: prevRunId, context } = step;
12374
+ const { runId } = await createWorkflowRun({ workflowId, prevRunId });
12375
+ watchWorkflow({ workflowId, runId });
12376
+ await resumeWorkflow({
12377
+ stepId,
12378
+ runId,
12379
+ context,
12380
+ workflowId
12381
+ });
12382
+ };
12383
+ const watchResultToUse = result ?? watchResult;
12384
+ const workflowActivePaths = watchResultToUse?.activePaths ?? {};
12385
+ useEffect(() => {
12386
+ setIsRunning(isWatchingWorkflow);
12387
+ }, [isWatchingWorkflow]);
12388
+ useEffect(() => {
12389
+ if (!watchResultToUse?.activePaths || !result?.runId) return;
12390
+ const suspended = Object.entries(watchResultToUse.activePaths).filter(([_, { status }]) => status === "suspended").map(([stepId, { suspendPayload }]) => ({
12391
+ stepId,
12392
+ runId: result.runId,
12393
+ suspendPayload
12394
+ }));
12395
+ setSuspendedSteps(suspended);
12396
+ }, [watchResultToUse, result]);
12397
+ useEffect(() => {
12398
+ if (watchResult) {
12399
+ setResult(watchResult);
12400
+ }
12401
+ }, [watchResult]);
12402
+ if (isLoading) {
12403
+ return /* @__PURE__ */ jsx(ScrollArea, { className: "h-[calc(100vh-126px)] pt-2 px-4 pb-4 text-xs", children: /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
12404
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-10" }),
12405
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-10" })
12406
+ ] }) });
12407
+ }
12408
+ if (!workflow) return null;
12409
+ const isSuspendedSteps = suspendedSteps.length > 0;
12410
+ const zodInputSchema = triggerSchema ? resolveSerializedZodOutput(jsonSchemaToZod(parse(triggerSchema))) : null;
12411
+ const { sanitizedOutput, ...restResult } = result ?? {};
12412
+ const hasWorkflowActivePaths = Object.values(workflowActivePaths).length > 0;
12413
+ return /* @__PURE__ */ jsx("div", { className: "h-full px-5 pt-3 pb-12", children: /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
12414
+ isResumingWorkflow && /* @__PURE__ */ jsxs("div", { className: "py-2 px-5 flex items-center gap-2 bg-surface5 -mx-5 -mt-5 border-b-sm border-border1", children: [
12415
+ /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(Loader2, { className: "animate-spin text-icon6" }) }),
12416
+ /* @__PURE__ */ jsx(Txt, { children: "Resuming workflow" })
12417
+ ] }),
12418
+ !isSuspendedSteps && /* @__PURE__ */ jsx(Fragment, { children: zodInputSchema ? /* @__PURE__ */ jsx(
12419
+ DynamicForm,
12420
+ {
12421
+ schema: zodInputSchema,
12422
+ defaultValues: payload,
12423
+ isSubmitLoading: isWatchingWorkflow,
12424
+ submitButtonLabel: "Run",
12425
+ onSubmit: (data) => {
12426
+ setPayload(data);
12427
+ handleExecuteWorkflow(data);
12428
+ }
12429
+ }
12430
+ ) : /* @__PURE__ */ jsx(
12431
+ Button,
12432
+ {
12433
+ className: "w-full",
12434
+ variant: "light",
12435
+ disabled: isRunning,
12436
+ onClick: () => handleExecuteWorkflow(null),
12437
+ children: isRunning ? /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(Loader2, { className: "animate-spin" }) }) : "Trigger"
12438
+ }
12439
+ ) }),
12440
+ isSuspendedSteps && suspendedSteps?.map((step) => {
12441
+ const stepDefinition = workflow.steps[step.stepId];
12442
+ const stepSchema = stepDefinition?.inputSchema ? resolveSerializedZodOutput(jsonSchemaToZod(parse(stepDefinition.inputSchema))) : z.record(z.string(), z.any());
12443
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col px-4", children: [
12444
+ /* @__PURE__ */ jsx(Text, { variant: "secondary", className: "text-mastra-el-3", size: "xs", children: step.stepId }),
12445
+ step.suspendPayload && /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
12446
+ CodeBlockDemo,
12447
+ {
12448
+ className: "w-full overflow-x-auto p-2",
12449
+ code: JSON.stringify(step.suspendPayload, null, 2),
12450
+ language: "json"
12451
+ }
12452
+ ) }),
12453
+ /* @__PURE__ */ jsx(
12454
+ DynamicForm,
12455
+ {
12456
+ schema: stepSchema,
12457
+ isSubmitLoading: isResumingWorkflow,
12458
+ submitButtonLabel: "Resume",
12459
+ onSubmit: (data) => {
12460
+ handleResumeWorkflow({
12461
+ stepId: step.stepId,
12462
+ runId: step.runId,
12463
+ suspendPayload: step.suspendPayload,
12464
+ context: data
12465
+ });
12466
+ }
12467
+ }
12468
+ )
12469
+ ] });
12470
+ }),
12471
+ hasWorkflowActivePaths && /* @__PURE__ */ jsxs(Fragment, { children: [
12472
+ /* @__PURE__ */ jsx("hr", { className: "border-border1 border-sm my-5" }),
12473
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-4", children: Object.entries(workflowActivePaths)?.map(([stepId, { status: pathStatus, stepPath }]) => {
12474
+ return /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-1", children: stepPath?.map((path, idx) => {
12475
+ return /* @__PURE__ */ jsx(LegacyWorkflowStatus, { stepId, pathStatus, path }, idx);
12476
+ }) }, stepId);
12477
+ }) })
12478
+ ] }),
12479
+ result && /* @__PURE__ */ jsxs(Fragment, { children: [
12480
+ /* @__PURE__ */ jsx("hr", { className: "border-border1 border-sm my-5" }),
12481
+ /* @__PURE__ */ jsx(WorkflowResult, { sanitizedJsonResult: sanitizedOutput, jsonResult: JSON.stringify(restResult, null, 2) })
12482
+ ] })
12483
+ ] }) });
12484
+ }
12485
+
12486
+ const WorkflowStatus = ({ stepId, status, result }) => {
12487
+ return /* @__PURE__ */ jsx(
12488
+ WorkflowCard,
12489
+ {
12490
+ header: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
12491
+ /* @__PURE__ */ jsxs(Icon, { children: [
12492
+ status === "success" && /* @__PURE__ */ jsx(CheckIcon, { className: "text-accent1" }),
12493
+ status === "failed" && /* @__PURE__ */ jsx(CrossIcon, { className: "text-accent2" }),
12494
+ status === "suspended" && /* @__PURE__ */ jsx(CirclePause, { className: "text-accent3" }),
12495
+ status === "waiting" && /* @__PURE__ */ jsx(HourglassIcon, { className: "text-accent5" }),
12496
+ status === "running" && /* @__PURE__ */ jsx(Loader2, { className: "text-accent6 animate-spin" })
12497
+ ] }),
12498
+ /* @__PURE__ */ jsx(Txt, { as: "span", variant: "ui-lg", className: "text-icon6 font-medium", children: stepId.charAt(0).toUpperCase() + stepId.slice(1) })
12499
+ ] }),
12500
+ children: /* @__PURE__ */ jsxs("div", { className: "rounded-md bg-surface4 p-1 font-mono relative", children: [
12501
+ /* @__PURE__ */ jsx(CopyButton, { content: JSON.stringify(result, null, 2), className: "absolute top-2 right-2 z-10" }),
12502
+ /* @__PURE__ */ jsx(SyntaxHighlighter$1, { data: result })
12503
+ ] })
12504
+ }
12505
+ );
12506
+ };
12507
+
12508
+ const WorkflowInputData = ({
12509
+ schema,
12510
+ defaultValues,
12511
+ isSubmitLoading,
12512
+ submitButtonLabel,
12513
+ onSubmit
12514
+ }) => {
12515
+ const [type, setType] = useState("form");
12516
+ return /* @__PURE__ */ jsxs("div", { children: [
12517
+ /* @__PURE__ */ jsx(RadioGroup, { value: type, onValueChange: (value) => setType(value), className: "pb-4", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-row gap-4", children: [
12518
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
12519
+ /* @__PURE__ */ jsx(RadioGroupItem, { value: "form", id: "form" }),
12520
+ /* @__PURE__ */ jsx(Label, { htmlFor: "form", className: "!text-icon3 text-ui-sm", children: "Form" })
12521
+ ] }),
12522
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
12523
+ /* @__PURE__ */ jsx(RadioGroupItem, { value: "json", id: "json" }),
12524
+ /* @__PURE__ */ jsx(Label, { htmlFor: "json", className: "!text-icon3 text-ui-sm", children: "JSON" })
12525
+ ] })
12526
+ ] }) }),
12527
+ type === "form" ? /* @__PURE__ */ jsx(
12528
+ DynamicForm,
12529
+ {
12530
+ schema,
12531
+ defaultValues,
12532
+ isSubmitLoading,
12533
+ submitButtonLabel,
12534
+ onSubmit
12535
+ }
12536
+ ) : /* @__PURE__ */ jsx(
12537
+ JSONInput,
12538
+ {
12539
+ schema,
12540
+ defaultValues,
12541
+ isSubmitLoading,
12542
+ submitButtonLabel,
12543
+ onSubmit
12544
+ }
12545
+ )
12546
+ ] });
12547
+ };
12548
+ const JSONInput = ({ schema, defaultValues, isSubmitLoading, submitButtonLabel, onSubmit }) => {
12549
+ const [errors, setErrors] = useState([]);
12550
+ const [inputData, setInputData] = useState(JSON.stringify(defaultValues ?? {}, null, 2));
12551
+ const handleSubmit = () => {
12552
+ setErrors([]);
12553
+ try {
12554
+ const result = schema.safeParse(JSON.parse(inputData));
12555
+ if (!result.success) {
12556
+ setErrors(result.error.issues.map((e) => `[${e.path.join(".")}] ${e.message}`));
12557
+ } else {
12558
+ onSubmit(result.data);
12559
+ }
12560
+ } catch (e) {
12561
+ setErrors(["Invalid JSON provided"]);
12562
+ }
12563
+ };
12564
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4", children: [
12565
+ errors.length > 0 && /* @__PURE__ */ jsxs("div", { className: "border-sm border-accent2 rounded-lg p-2", children: [
12566
+ /* @__PURE__ */ jsxs(Txt, { as: "p", variant: "ui-md", className: "text-accent2 font-semibold", children: [
12567
+ errors.length,
12568
+ " errors found"
12569
+ ] }),
12570
+ /* @__PURE__ */ jsx("ul", { className: "list-disc list-inside", children: errors.map((error, idx) => /* @__PURE__ */ jsx("li", { className: "text-ui-sm text-accent2", children: error }, idx)) })
12571
+ ] }),
12572
+ /* @__PURE__ */ jsx(SyntaxHighlighter, { data: inputData, onChange: setInputData }),
12573
+ /* @__PURE__ */ jsx(Button, { variant: "light", onClick: handleSubmit, className: "w-full", size: "lg", children: isSubmitLoading ? /* @__PURE__ */ jsx(Loader2, { className: "animate-spin" }) : submitButtonLabel })
12574
+ ] });
12575
+ };
12576
+ const SyntaxHighlighter = ({ data, onChange }) => {
12577
+ const theme = useCodemirrorTheme$1();
12578
+ return /* @__PURE__ */ jsxs("div", { className: "rounded-md bg-[#1a1a1a] p-1 font-mono", children: [
12579
+ /* @__PURE__ */ jsx(CopyButton, { content: data, className: "absolute top-2 right-2 z-10" }),
12580
+ /* @__PURE__ */ jsx(CodeMirror, { value: data, theme, extensions: [jsonLanguage], onChange })
12581
+ ] });
12582
+ };
12583
+
12584
+ function WorkflowTrigger({
12446
12585
  workflowId,
12447
- setRunId
12586
+ setRunId,
12587
+ workflow,
12588
+ isLoading,
12589
+ createWorkflowRun,
12590
+ resumeWorkflow,
12591
+ streamWorkflow,
12592
+ isStreamingWorkflow,
12593
+ streamResult,
12594
+ isResumingWorkflow,
12595
+ isCancellingWorkflowRun,
12596
+ cancelWorkflowRun
12448
12597
  }) {
12449
- const { legacyResult: result, setLegacyResult: setResult, payload, setPayload } = useContext(WorkflowRunContext);
12450
- const { isLoading, legacyWorkflow: workflow } = useLegacyWorkflow(workflowId);
12451
- const { createLegacyWorkflowRun: createWorkflowRun, startLegacyWorkflowRun: startWorkflowRun } = useExecuteWorkflow();
12452
- const {
12453
- watchLegacyWorkflow: watchWorkflow,
12454
- legacyWatchResult: watchResult,
12455
- isWatchingLegacyWorkflow: isWatchingWorkflow
12456
- } = useWatchWorkflow();
12457
- const { resumeLegacyWorkflow: resumeWorkflow, isResumingLegacyWorkflow: isResumingWorkflow } = useResumeWorkflow();
12598
+ const { runtimeContext } = usePlaygroundStore();
12599
+ const { result, setResult, payload, setPayload } = useContext(WorkflowRunContext);
12458
12600
  const [suspendedSteps, setSuspendedSteps] = useState([]);
12459
12601
  const [isRunning, setIsRunning] = useState(false);
12460
- const triggerSchema = workflow?.triggerSchema;
12602
+ const [innerRunId, setInnerRunId] = useState("");
12603
+ const [cancelResponse, setCancelResponse] = useState(null);
12604
+ const triggerSchema = workflow?.inputSchema;
12461
12605
  const handleExecuteWorkflow = async (data) => {
12462
12606
  try {
12463
12607
  if (!workflow) return;
12464
12608
  setIsRunning(true);
12609
+ setCancelResponse(null);
12465
12610
  setResult(null);
12466
12611
  const { runId } = await createWorkflowRun({ workflowId });
12467
12612
  setRunId?.(runId);
12468
- watchWorkflow({ workflowId, runId });
12469
- startWorkflowRun({ workflowId, runId, input: data });
12613
+ setInnerRunId(runId);
12614
+ streamWorkflow({ workflowId, runId, inputData: data, runtimeContext });
12470
12615
  } catch (err) {
12471
12616
  setIsRunning(false);
12472
12617
  toast.error("Error executing workflow");
@@ -12474,533 +12619,1004 @@ function LegacyWorkflowTrigger({
12474
12619
  };
12475
12620
  const handleResumeWorkflow = async (step) => {
12476
12621
  if (!workflow) return;
12477
- const { stepId, runId: prevRunId, context } = step;
12622
+ setCancelResponse(null);
12623
+ const { stepId, runId: prevRunId, resumeData } = step;
12478
12624
  const { runId } = await createWorkflowRun({ workflowId, prevRunId });
12479
- watchWorkflow({ workflowId, runId });
12480
12625
  await resumeWorkflow({
12481
- stepId,
12626
+ step: stepId,
12482
12627
  runId,
12483
- context,
12484
- workflowId
12628
+ resumeData,
12629
+ workflowId,
12630
+ runtimeContext
12485
12631
  });
12486
12632
  };
12487
- const watchResultToUse = result ?? watchResult;
12488
- const workflowActivePaths = watchResultToUse?.activePaths ?? {};
12633
+ const handleCancelWorkflowRun = async () => {
12634
+ const response = await cancelWorkflowRun({ workflowId, runId: innerRunId });
12635
+ setCancelResponse(response);
12636
+ };
12637
+ const streamResultToUse = result ?? streamResult;
12489
12638
  useEffect(() => {
12490
- setIsRunning(isWatchingWorkflow);
12491
- }, [isWatchingWorkflow]);
12639
+ setIsRunning(isStreamingWorkflow);
12640
+ }, [isStreamingWorkflow]);
12492
12641
  useEffect(() => {
12493
- if (!watchResultToUse?.activePaths || !result?.runId) return;
12494
- const suspended = Object.entries(watchResultToUse.activePaths).filter(([_, { status }]) => status === "suspended").map(([stepId, { suspendPayload }]) => ({
12642
+ if (!streamResultToUse?.payload?.workflowState?.steps || !result?.runId) return;
12643
+ const suspended = Object.entries(streamResultToUse.payload.workflowState.steps).filter(([_, { status }]) => status === "suspended").map(([stepId, { payload: payload2 }]) => ({
12495
12644
  stepId,
12496
12645
  runId: result.runId,
12497
- suspendPayload
12646
+ suspendPayload: payload2,
12647
+ isLoading: false
12498
12648
  }));
12499
12649
  setSuspendedSteps(suspended);
12500
- }, [watchResultToUse, result]);
12650
+ }, [streamResultToUse, result]);
12501
12651
  useEffect(() => {
12502
- if (watchResult) {
12503
- setResult(watchResult);
12652
+ if (streamResult) {
12653
+ setResult(streamResult);
12504
12654
  }
12505
- }, [watchResult]);
12655
+ }, [streamResult]);
12506
12656
  if (isLoading) {
12507
12657
  return /* @__PURE__ */ jsx(ScrollArea, { className: "h-[calc(100vh-126px)] pt-2 px-4 pb-4 text-xs", children: /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
12508
12658
  /* @__PURE__ */ jsx(Skeleton, { className: "h-10" }),
12509
12659
  /* @__PURE__ */ jsx(Skeleton, { className: "h-10" })
12510
12660
  ] }) });
12511
12661
  }
12512
- if (!workflow) return null;
12513
- const isSuspendedSteps = suspendedSteps.length > 0;
12514
- const zodInputSchema = triggerSchema ? resolveSerializedZodOutput(jsonSchemaToZod(parse(triggerSchema))) : null;
12515
- const { sanitizedOutput, ...restResult } = result ?? {};
12516
- const hasWorkflowActivePaths = Object.values(workflowActivePaths).length > 0;
12517
- return /* @__PURE__ */ jsx("div", { className: "h-full px-5 pt-3 pb-12", children: /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
12518
- isResumingWorkflow && /* @__PURE__ */ jsxs("div", { className: "py-2 px-5 flex items-center gap-2 bg-surface5 -mx-5 -mt-5 border-b-sm border-border1", children: [
12519
- /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(Loader2, { className: "animate-spin text-icon6" }) }),
12520
- /* @__PURE__ */ jsx(Txt, { children: "Resuming workflow" })
12521
- ] }),
12522
- !isSuspendedSteps && /* @__PURE__ */ jsx(Fragment, { children: zodInputSchema ? /* @__PURE__ */ jsx(
12523
- DynamicForm,
12524
- {
12525
- schema: zodInputSchema,
12526
- defaultValues: payload,
12527
- isSubmitLoading: isWatchingWorkflow,
12528
- submitButtonLabel: "Run",
12529
- onSubmit: (data) => {
12530
- setPayload(data);
12531
- handleExecuteWorkflow(data);
12532
- }
12533
- }
12534
- ) : /* @__PURE__ */ jsx(
12662
+ if (!workflow) return null;
12663
+ const isSuspendedSteps = suspendedSteps.length > 0;
12664
+ const zodInputSchema = triggerSchema ? resolveSerializedZodOutput(jsonSchemaToZod(parse(triggerSchema))) : null;
12665
+ const workflowActivePaths = streamResultToUse?.payload?.workflowState?.steps ?? {};
12666
+ const hasWorkflowActivePaths = Object.values(workflowActivePaths).length > 0;
12667
+ const doneStatuses = ["success", "failed", "canceled"];
12668
+ return /* @__PURE__ */ jsxs("div", { className: "h-full pt-3 pb-12", children: [
12669
+ /* @__PURE__ */ jsxs("div", { className: "space-y-4 px-5 pb-5 border-b-sm border-border1", children: [
12670
+ (isResumingWorkflow || isSuspendedSteps && isStreamingWorkflow) && /* @__PURE__ */ jsxs("div", { className: "py-2 px-5 flex items-center gap-2 bg-surface5 -mx-5 -mt-5 border-b-sm border-border1", children: [
12671
+ /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(Loader2, { className: "animate-spin text-icon6" }) }),
12672
+ /* @__PURE__ */ jsx(Txt, { children: "Resuming workflow" })
12673
+ ] }),
12674
+ !isSuspendedSteps && /* @__PURE__ */ jsx(Fragment, { children: zodInputSchema ? /* @__PURE__ */ jsx(
12675
+ WorkflowInputData,
12676
+ {
12677
+ schema: zodInputSchema,
12678
+ defaultValues: payload,
12679
+ isSubmitLoading: isStreamingWorkflow,
12680
+ submitButtonLabel: "Run",
12681
+ onSubmit: (data) => {
12682
+ setPayload(data);
12683
+ handleExecuteWorkflow(data);
12684
+ }
12685
+ }
12686
+ ) : /* @__PURE__ */ jsx(
12687
+ Button,
12688
+ {
12689
+ className: "w-full",
12690
+ variant: "light",
12691
+ disabled: isRunning,
12692
+ onClick: () => handleExecuteWorkflow(null),
12693
+ children: isRunning ? /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(Loader2, { className: "animate-spin" }) }) : "Trigger"
12694
+ }
12695
+ ) }),
12696
+ !isStreamingWorkflow && isSuspendedSteps && suspendedSteps?.map((step) => {
12697
+ const stepDefinition = workflow.allSteps[step.stepId];
12698
+ if (!stepDefinition || stepDefinition.isWorkflow) return null;
12699
+ const stepSchema = stepDefinition?.resumeSchema ? resolveSerializedZodOutput(jsonSchemaToZod(parse(stepDefinition.resumeSchema))) : z.record(z.string(), z.any());
12700
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col px-4", children: [
12701
+ /* @__PURE__ */ jsx(Text, { variant: "secondary", className: "text-mastra-el-3", size: "xs", children: step.stepId }),
12702
+ step.suspendPayload && /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
12703
+ CodeBlockDemo,
12704
+ {
12705
+ className: "w-full overflow-x-auto p-2",
12706
+ code: JSON.stringify(step.suspendPayload, null, 2),
12707
+ language: "json"
12708
+ }
12709
+ ) }),
12710
+ /* @__PURE__ */ jsx(
12711
+ WorkflowInputData,
12712
+ {
12713
+ schema: stepSchema,
12714
+ isSubmitLoading: isResumingWorkflow,
12715
+ submitButtonLabel: "Resume",
12716
+ onSubmit: (data) => {
12717
+ const stepIds = step.stepId?.split(".");
12718
+ handleResumeWorkflow({
12719
+ stepId: stepIds,
12720
+ runId: step.runId,
12721
+ suspendPayload: step.suspendPayload,
12722
+ resumeData: data});
12723
+ }
12724
+ }
12725
+ )
12726
+ ] }, step.stepId);
12727
+ }),
12728
+ result?.runId && /* @__PURE__ */ jsxs(
12729
+ Button,
12730
+ {
12731
+ variant: "light",
12732
+ className: "w-full",
12733
+ size: "lg",
12734
+ onClick: handleCancelWorkflowRun,
12735
+ disabled: !!cancelResponse?.message || isCancellingWorkflowRun || result?.payload?.workflowState?.status && doneStatuses.includes(result?.payload?.workflowState?.status),
12736
+ children: [
12737
+ isCancellingWorkflowRun ? /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(Loader2, { className: "animate-spin" }) }) : /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(StopCircle, {}) }),
12738
+ cancelResponse?.message || "Cancel Workflow Run"
12739
+ ]
12740
+ }
12741
+ ),
12742
+ hasWorkflowActivePaths && /* @__PURE__ */ jsxs(Fragment, { children: [
12743
+ /* @__PURE__ */ jsx("hr", { className: "border-border1 border-sm my-5" }),
12744
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
12745
+ /* @__PURE__ */ jsx(Text, { variant: "secondary", className: "px-4 text-mastra-el-3", size: "xs", children: "Status" }),
12746
+ /* @__PURE__ */ jsx("div", { className: "px-4 flex flex-col gap-4", children: Object.entries(workflowActivePaths).filter(([key, _]) => key !== "input" && !key.endsWith(".input")).map(([stepId, { status, output }]) => {
12747
+ return /* @__PURE__ */ jsx(WorkflowStatus, { stepId, status, result: output ?? {} }, stepId);
12748
+ }) })
12749
+ ] })
12750
+ ] })
12751
+ ] }),
12752
+ result && /* @__PURE__ */ jsx("div", { className: "p-5 border-b-sm border-border1", children: /* @__PURE__ */ jsx(WorkflowJsonDialog, { result }) })
12753
+ ] });
12754
+ }
12755
+ const WorkflowJsonDialog = ({ result }) => {
12756
+ const [open, setOpen] = useState(false);
12757
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
12758
+ /* @__PURE__ */ jsxs(Button, { variant: "light", onClick: () => setOpen(true), className: "w-full", size: "lg", children: [
12759
+ /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(Braces, { className: "text-icon3" }) }),
12760
+ "Open Workflow Execution (JSON)"
12761
+ ] }),
12762
+ /* @__PURE__ */ jsx(Dialog, { open, onOpenChange: setOpen, children: /* @__PURE__ */ jsx(DialogPortal, { children: /* @__PURE__ */ jsxs(DialogContent, { className: "max-w-6xl max-h-[90vh] overflow-y-auto overflow-x-hidden bg-surface2", children: [
12763
+ /* @__PURE__ */ jsx(DialogTitle, { children: "Workflow Execution (JSON)" }),
12764
+ /* @__PURE__ */ jsx("div", { className: "w-full h-full overflow-x-scroll", children: /* @__PURE__ */ jsx(SyntaxHighlighter$2, { data: result, className: "p-4" }) })
12765
+ ] }) }) })
12766
+ ] });
12767
+ };
12768
+
12769
+ const WorkflowRuns = ({ workflowId, runId, isLoading, runs, onPressRun }) => {
12770
+ if (isLoading) {
12771
+ return /* @__PURE__ */ jsx("div", { className: "p-4", children: /* @__PURE__ */ jsx(Skeleton, { className: "h-[600px]" }) });
12772
+ }
12773
+ if (runs.length === 0) {
12774
+ return /* @__PURE__ */ jsx("div", { className: "p-4", children: /* @__PURE__ */ jsx(Txt, { variant: "ui-md", className: "text-icon6 text-center", children: "No previous run" }) });
12775
+ }
12776
+ return /* @__PURE__ */ jsx("ol", { className: "pb-10", children: runs.map((run) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(
12777
+ "button",
12778
+ {
12779
+ onClick: () => onPressRun({ workflowId, runId: run.runId }),
12780
+ className: clsx("px-3 py-2 border-b-sm border-border1 block w-full hover:bg-surface4 text-left", {
12781
+ "bg-surface4": run.runId === runId
12782
+ }),
12783
+ children: [
12784
+ /* @__PURE__ */ jsx(Txt, { variant: "ui-lg", className: "font-medium text-icon6 truncate", as: "p", children: run.runId }),
12785
+ /* @__PURE__ */ jsx(Txt, { variant: "ui-sm", className: "font-medium text-icon3 truncate", as: "p", children: typeof run?.snapshot === "string" ? "" : run?.snapshot?.timestamp ? formatDate(run?.snapshot?.timestamp, "MMM d, yyyy h:mm a") : "" })
12786
+ ]
12787
+ }
12788
+ ) }, run.runId)) });
12789
+ };
12790
+
12791
+ const columns = [
12792
+ {
12793
+ id: "name",
12794
+ header: "Name",
12795
+ cell: ({ row }) => {
12796
+ const { Link } = useLinkComponent();
12797
+ return /* @__PURE__ */ jsx(
12798
+ EntryCell,
12799
+ {
12800
+ icon: /* @__PURE__ */ jsx(WorkflowIcon, {}),
12801
+ name: /* @__PURE__ */ jsx(Link, { href: row.original.link, children: row.original.name }),
12802
+ description: void 0,
12803
+ meta: void 0
12804
+ }
12805
+ );
12806
+ },
12807
+ meta: {
12808
+ width: "auto"
12809
+ }
12810
+ },
12811
+ {
12812
+ id: "stepsCount",
12813
+ header: "Steps",
12814
+ size: 300,
12815
+ cell: ({ row }) => /* @__PURE__ */ jsx(Cell, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end items-center gap-2", children: [
12816
+ /* @__PURE__ */ jsxs(Badge$1, { icon: /* @__PURE__ */ jsx(Footprints, {}), className: "!h-button-md", children: [
12817
+ row.original.stepsCount,
12818
+ " step",
12819
+ row.original.stepsCount > 1 ? "s" : ""
12820
+ ] }),
12821
+ row.original.isLegacy ? /* @__PURE__ */ jsx(Badge$1, { className: "!text-foreground/80 !h-button-md", children: "Legacy" }) : null
12822
+ ] }) })
12823
+ }
12824
+ ];
12825
+
12826
+ function WorkflowTable({ workflows, legacyWorkflows, isLoading, computeLink }) {
12827
+ const { navigate } = useLinkComponent();
12828
+ const workflowData = useMemo(() => {
12829
+ const _workflowsData = Object.keys(workflows ?? {}).map((key) => {
12830
+ const workflow = workflows?.[key];
12831
+ return {
12832
+ id: key,
12833
+ name: workflow?.name || "N/A",
12834
+ stepsCount: Object.keys(workflow?.steps ?? {})?.length,
12835
+ isLegacy: false,
12836
+ link: computeLink(key)
12837
+ };
12838
+ });
12839
+ const legacyWorkflowsData = Object.keys(legacyWorkflows ?? {}).map((key) => {
12840
+ const workflow = legacyWorkflows?.[key];
12841
+ return {
12842
+ id: key,
12843
+ name: workflow?.name || "N/A",
12844
+ stepsCount: Object.keys(workflow?.steps ?? {})?.length,
12845
+ isLegacy: true,
12846
+ link: computeLink(key)
12847
+ };
12848
+ });
12849
+ return [..._workflowsData, ...legacyWorkflowsData];
12850
+ }, [workflows, legacyWorkflows]);
12851
+ const table = useReactTable({
12852
+ data: workflowData,
12853
+ columns,
12854
+ getCoreRowModel: getCoreRowModel()
12855
+ });
12856
+ if (isLoading) return /* @__PURE__ */ jsx(WorkflowTableSkeleton, {});
12857
+ const ths = table.getHeaderGroups()[0];
12858
+ const rows = table.getRowModel().rows.concat();
12859
+ if (rows.length === 0) {
12860
+ return /* @__PURE__ */ jsx(EmptyWorkflowsTable, {});
12861
+ }
12862
+ return /* @__PURE__ */ jsx(ScrollableContainer, { children: /* @__PURE__ */ jsxs(Table, { children: [
12863
+ /* @__PURE__ */ jsx(Thead, { className: "sticky top-0", children: ths.headers.map((header) => /* @__PURE__ */ jsx(Th, { style: { width: header.index === 0 ? "auto" : header.column.getSize() }, children: flexRender(header.column.columnDef.header, header.getContext()) }, header.id)) }),
12864
+ /* @__PURE__ */ jsx(Tbody, { children: rows.map((row) => /* @__PURE__ */ jsx(Row, { onClick: () => navigate(row.original.link), children: row.getVisibleCells().map((cell) => /* @__PURE__ */ jsx(React__default.Fragment, { children: flexRender(cell.column.columnDef.cell, cell.getContext()) }, cell.id)) }, row.id)) })
12865
+ ] }) });
12866
+ }
12867
+ const WorkflowTableSkeleton = () => /* @__PURE__ */ jsxs(Table, { children: [
12868
+ /* @__PURE__ */ jsxs(Thead, { children: [
12869
+ /* @__PURE__ */ jsx(Th, { children: "Name" }),
12870
+ /* @__PURE__ */ jsx(Th, { width: 300, children: "Steps" })
12871
+ ] }),
12872
+ /* @__PURE__ */ jsx(Tbody, { children: Array.from({ length: 3 }).map((_, index) => /* @__PURE__ */ jsxs(Row, { children: [
12873
+ /* @__PURE__ */ jsx(Cell, { children: /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-1/2" }) }),
12874
+ /* @__PURE__ */ jsx(Cell, { width: 300, children: /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-1/2" }) })
12875
+ ] }, index)) })
12876
+ ] });
12877
+ const EmptyWorkflowsTable = () => /* @__PURE__ */ jsx("div", { className: "flex h-full items-center justify-center", children: /* @__PURE__ */ jsx(
12878
+ EmptyState,
12879
+ {
12880
+ iconSlot: /* @__PURE__ */ jsx(WorkflowCoinIcon, {}),
12881
+ titleSlot: "Configure Workflows",
12882
+ descriptionSlot: "Mastra workflows are not configured yet. You can find more information in the documentation.",
12883
+ actionSlot: /* @__PURE__ */ jsxs(
12535
12884
  Button,
12536
12885
  {
12886
+ size: "lg",
12537
12887
  className: "w-full",
12538
12888
  variant: "light",
12539
- disabled: isRunning,
12540
- onClick: () => handleExecuteWorkflow(null),
12541
- children: isRunning ? /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(Loader2, { className: "animate-spin" }) }) : "Trigger"
12889
+ as: "a",
12890
+ href: "https://mastra.ai/en/docs/workflows/overview",
12891
+ target: "_blank",
12892
+ children: [
12893
+ /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(WorkflowIcon, {}) }),
12894
+ "Docs"
12895
+ ]
12542
12896
  }
12543
- ) }),
12544
- isSuspendedSteps && suspendedSteps?.map((step) => {
12545
- const stepDefinition = workflow.steps[step.stepId];
12546
- const stepSchema = stepDefinition?.inputSchema ? resolveSerializedZodOutput(jsonSchemaToZod(parse(stepDefinition.inputSchema))) : z.record(z.string(), z.any());
12547
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-col px-4", children: [
12548
- /* @__PURE__ */ jsx(Text, { variant: "secondary", className: "text-mastra-el-3", size: "xs", children: step.stepId }),
12549
- step.suspendPayload && /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
12550
- CodeBlockDemo,
12551
- {
12552
- className: "w-full overflow-x-auto p-2",
12553
- code: JSON.stringify(step.suspendPayload, null, 2),
12554
- language: "json"
12555
- }
12556
- ) }),
12557
- /* @__PURE__ */ jsx(
12558
- DynamicForm,
12559
- {
12560
- schema: stepSchema,
12561
- isSubmitLoading: isResumingWorkflow,
12562
- submitButtonLabel: "Resume",
12563
- onSubmit: (data) => {
12564
- handleResumeWorkflow({
12565
- stepId: step.stepId,
12566
- runId: step.runId,
12567
- suspendPayload: step.suspendPayload,
12568
- context: data
12569
- });
12570
- }
12571
- }
12572
- )
12573
- ] });
12574
- }),
12575
- hasWorkflowActivePaths && /* @__PURE__ */ jsxs(Fragment, { children: [
12576
- /* @__PURE__ */ jsx("hr", { className: "border-border1 border-sm my-5" }),
12577
- /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-4", children: Object.entries(workflowActivePaths)?.map(([stepId, { status: pathStatus, stepPath }]) => {
12578
- return /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-1", children: stepPath?.map((path, idx) => {
12579
- return /* @__PURE__ */ jsx(LegacyWorkflowStatus, { stepId, pathStatus, path }, idx);
12580
- }) }, stepId);
12581
- }) })
12582
- ] }),
12583
- result && /* @__PURE__ */ jsxs(Fragment, { children: [
12584
- /* @__PURE__ */ jsx("hr", { className: "border-border1 border-sm my-5" }),
12585
- /* @__PURE__ */ jsx(WorkflowResult, { sanitizedJsonResult: sanitizedOutput, jsonResult: JSON.stringify(restResult, null, 2) })
12586
- ] })
12587
- ] }) });
12588
- }
12897
+ )
12898
+ }
12899
+ ) });
12589
12900
 
12590
- const WorkflowStatus = ({ stepId, status, result }) => {
12901
+ const TraceContext = createContext({});
12902
+ function TraceProvider({
12903
+ children,
12904
+ initialTraces: traces = []
12905
+ }) {
12906
+ const [open, setOpen] = useState(false);
12907
+ const [trace, setTrace] = useState(null);
12908
+ const [currentTraceIndex, setCurrentTraceIndex] = useState(0);
12909
+ const [span, setSpan] = useState(null);
12910
+ const nextTrace = () => {
12911
+ if (currentTraceIndex < traces.length - 1) {
12912
+ const nextIndex = currentTraceIndex + 1;
12913
+ setCurrentTraceIndex(nextIndex);
12914
+ const nextTrace2 = traces[nextIndex].trace;
12915
+ setTrace(nextTrace2);
12916
+ const parentSpan = nextTrace2.find((span2) => span2.parentSpanId === null) || nextTrace2[0];
12917
+ setSpan(parentSpan);
12918
+ }
12919
+ };
12920
+ const prevTrace = () => {
12921
+ if (currentTraceIndex > 0) {
12922
+ const prevIndex = currentTraceIndex - 1;
12923
+ setCurrentTraceIndex(prevIndex);
12924
+ const prevTrace2 = traces[prevIndex].trace;
12925
+ setTrace(prevTrace2);
12926
+ const parentSpan = prevTrace2.find((span2) => span2.parentSpanId === null) || prevTrace2[0];
12927
+ setSpan(parentSpan);
12928
+ }
12929
+ };
12930
+ const clearData = () => {
12931
+ setOpen(false);
12932
+ setTrace(null);
12933
+ setSpan(null);
12934
+ };
12591
12935
  return /* @__PURE__ */ jsx(
12592
- WorkflowCard,
12936
+ TraceContext.Provider,
12593
12937
  {
12594
- header: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
12595
- /* @__PURE__ */ jsxs(Icon, { children: [
12596
- status === "success" && /* @__PURE__ */ jsx(CheckIcon, { className: "text-accent1" }),
12597
- status === "failed" && /* @__PURE__ */ jsx(CrossIcon, { className: "text-accent2" }),
12598
- status === "suspended" && /* @__PURE__ */ jsx(CirclePause, { className: "text-accent3" }),
12599
- status === "waiting" && /* @__PURE__ */ jsx(HourglassIcon, { className: "text-accent5" }),
12600
- status === "running" && /* @__PURE__ */ jsx(Loader2, { className: "text-accent6 animate-spin" })
12601
- ] }),
12602
- /* @__PURE__ */ jsx(Txt, { as: "span", variant: "ui-lg", className: "text-icon6 font-medium", children: stepId.charAt(0).toUpperCase() + stepId.slice(1) })
12603
- ] }),
12604
- children: /* @__PURE__ */ jsxs("div", { className: "rounded-md bg-surface4 p-1 font-mono relative", children: [
12605
- /* @__PURE__ */ jsx(CopyButton, { content: JSON.stringify(result, null, 2), className: "absolute top-2 right-2 z-10" }),
12606
- /* @__PURE__ */ jsx(SyntaxHighlighter$1, { data: result })
12607
- ] })
12938
+ value: {
12939
+ isOpen: open,
12940
+ setIsOpen: setOpen,
12941
+ trace,
12942
+ setTrace,
12943
+ traces,
12944
+ currentTraceIndex,
12945
+ setCurrentTraceIndex,
12946
+ nextTrace,
12947
+ prevTrace,
12948
+ span,
12949
+ setSpan,
12950
+ clearData
12951
+ },
12952
+ children
12953
+ }
12954
+ );
12955
+ }
12956
+
12957
+ const useOpenTrace = () => {
12958
+ const {
12959
+ setTrace,
12960
+ isOpen: open,
12961
+ setIsOpen: setOpen,
12962
+ trace: currentTrace,
12963
+ setSpan,
12964
+ setCurrentTraceIndex
12965
+ } = useContext(TraceContext);
12966
+ const openTrace = (trace, traceIndex) => {
12967
+ setTrace(trace);
12968
+ const parentSpan = trace.find((span) => span.parentSpanId === null) || trace[0];
12969
+ setSpan(parentSpan);
12970
+ setCurrentTraceIndex(traceIndex);
12971
+ if (open && currentTrace?.[0]?.id !== trace[0].id) return;
12972
+ setOpen((prev) => !prev);
12973
+ };
12974
+ return { openTrace };
12975
+ };
12976
+
12977
+ const TracesTableEmpty = ({ colsCount }) => {
12978
+ return /* @__PURE__ */ jsx(Tbody, { children: /* @__PURE__ */ jsx(Row, { children: /* @__PURE__ */ jsx(Cell, { colSpan: colsCount, className: "text-center py-4", children: /* @__PURE__ */ jsx(Txt, { children: "No traces found" }) }) }) });
12979
+ };
12980
+ const TracesTableError = ({ error, colsCount }) => {
12981
+ return /* @__PURE__ */ jsx(Tbody, { children: /* @__PURE__ */ jsx(Row, { children: /* @__PURE__ */ jsx(Cell, { colSpan: colsCount, className: "text-center py-4", children: /* @__PURE__ */ jsx(Txt, { children: error.message }) }) }) });
12982
+ };
12983
+ const TraceRow = ({ trace, index, isActive }) => {
12984
+ const { openTrace } = useOpenTrace();
12985
+ const hasFailure = trace.trace.some((span) => span.status.code !== 0);
12986
+ return /* @__PURE__ */ jsxs(Row, { className: isActive ? "bg-surface4" : "", onClick: () => openTrace(trace.trace, index), children: [
12987
+ /* @__PURE__ */ jsx(DateTimeCell, { dateTime: new Date(trace.started / 1e3) }),
12988
+ /* @__PURE__ */ jsxs(TxtCell, { title: trace.traceId, children: [
12989
+ trace.traceId.substring(0, 7),
12990
+ "..."
12991
+ ] }),
12992
+ /* @__PURE__ */ jsx(UnitCell, { unit: "ms", children: toSigFigs(trace.duration / 1e3, 3) }),
12993
+ /* @__PURE__ */ jsx(Cell, { children: /* @__PURE__ */ jsx("button", { onClick: () => openTrace(trace.trace, index), children: /* @__PURE__ */ jsx(Badge$1, { icon: /* @__PURE__ */ jsx(TraceIcon, {}), children: trace.trace.length }) }) }),
12994
+ /* @__PURE__ */ jsx(Cell, { children: hasFailure ? /* @__PURE__ */ jsx(Badge$1, { variant: "error", icon: /* @__PURE__ */ jsx(X, {}), children: "Failed" }) : /* @__PURE__ */ jsx(Badge$1, { icon: /* @__PURE__ */ jsx(Check, {}), variant: "success", children: "Success" }) })
12995
+ ] });
12996
+ };
12997
+ const TracesTable = ({ traces, error }) => {
12998
+ const hasNoTraces = !traces || traces.length === 0;
12999
+ const { currentTraceIndex } = useContext(TraceContext);
13000
+ const colsCount = 4;
13001
+ return /* @__PURE__ */ jsxs(Table, { size: "small", children: [
13002
+ /* @__PURE__ */ jsxs(Thead, { children: [
13003
+ /* @__PURE__ */ jsx(Th, { width: 120, children: "Time" }),
13004
+ /* @__PURE__ */ jsx(Th, { width: "auto", children: "Trace Id" }),
13005
+ /* @__PURE__ */ jsx(Th, { width: 120, children: "Duration" }),
13006
+ /* @__PURE__ */ jsx(Th, { width: 120, children: "Spans" }),
13007
+ /* @__PURE__ */ jsx(Th, { width: 120, children: "Status" })
13008
+ ] }),
13009
+ error ? /* @__PURE__ */ jsx(TracesTableError, { error, colsCount }) : hasNoTraces ? /* @__PURE__ */ jsx(TracesTableEmpty, { colsCount }) : /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(Tbody, { children: traces.map((trace, index) => /* @__PURE__ */ jsx(
13010
+ TraceRow,
13011
+ {
13012
+ trace,
13013
+ index,
13014
+ isActive: index === currentTraceIndex
13015
+ },
13016
+ trace.traceId + index
13017
+ )) }) })
13018
+ ] });
13019
+ };
13020
+
13021
+ const useResizeColumn = ({
13022
+ defaultWidth,
13023
+ minimumWidth,
13024
+ maximumWidth,
13025
+ setCurrentWidth
13026
+ }) => {
13027
+ const [isDragging, setIsDragging] = useState(false);
13028
+ const [sidebarWidth, setSidebarWidth] = useState(defaultWidth);
13029
+ const containerRef = useRef(null);
13030
+ const dragStartXRef = useRef(0);
13031
+ const initialWidthRef = useRef(0);
13032
+ const handleMouseDown = (e) => {
13033
+ e.preventDefault();
13034
+ setIsDragging(true);
13035
+ dragStartXRef.current = e.clientX;
13036
+ initialWidthRef.current = sidebarWidth;
13037
+ };
13038
+ useEffect(() => {
13039
+ setSidebarWidth(defaultWidth);
13040
+ setCurrentWidth?.(defaultWidth);
13041
+ }, [defaultWidth]);
13042
+ useEffect(() => {
13043
+ const handleMouseMove = (e) => {
13044
+ if (!isDragging || !containerRef.current) return;
13045
+ const containerWidth = containerRef.current.offsetWidth;
13046
+ const deltaX = dragStartXRef.current - e.clientX;
13047
+ const deltaPercentage = deltaX / containerWidth * 100;
13048
+ const newWidth = Math.min(Math.max(initialWidthRef.current + deltaPercentage, minimumWidth), maximumWidth);
13049
+ setSidebarWidth(newWidth);
13050
+ setCurrentWidth?.(newWidth);
13051
+ };
13052
+ const handleMouseUp = () => {
13053
+ setIsDragging(false);
13054
+ };
13055
+ if (isDragging) {
13056
+ window.addEventListener("mousemove", handleMouseMove);
13057
+ window.addEventListener("mouseup", handleMouseUp);
12608
13058
  }
12609
- );
13059
+ return () => {
13060
+ window.removeEventListener("mousemove", handleMouseMove);
13061
+ window.removeEventListener("mouseup", handleMouseUp);
13062
+ };
13063
+ }, [isDragging]);
13064
+ return { sidebarWidth, isDragging, handleMouseDown, containerRef };
12610
13065
  };
12611
13066
 
12612
- const WorkflowInputData = ({
12613
- schema,
12614
- defaultValues,
12615
- isSubmitLoading,
12616
- submitButtonLabel,
12617
- onSubmit
13067
+ const MastraResizablePanel = ({
13068
+ children,
13069
+ defaultWidth,
13070
+ minimumWidth,
13071
+ maximumWidth,
13072
+ className,
13073
+ disabled = false,
13074
+ setCurrentWidth,
13075
+ dividerPosition = "left"
12618
13076
  }) => {
12619
- const [type, setType] = useState("form");
12620
- return /* @__PURE__ */ jsxs("div", { children: [
12621
- /* @__PURE__ */ jsx(RadioGroup, { value: type, onValueChange: (value) => setType(value), className: "pb-4", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-row gap-4", children: [
12622
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
12623
- /* @__PURE__ */ jsx(RadioGroupItem, { value: "form", id: "form" }),
12624
- /* @__PURE__ */ jsx(Label, { htmlFor: "form", className: "!text-icon3 text-ui-sm", children: "Form" })
12625
- ] }),
12626
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
12627
- /* @__PURE__ */ jsx(RadioGroupItem, { value: "json", id: "json" }),
12628
- /* @__PURE__ */ jsx(Label, { htmlFor: "json", className: "!text-icon3 text-ui-sm", children: "JSON" })
12629
- ] })
12630
- ] }) }),
12631
- type === "form" ? /* @__PURE__ */ jsx(
12632
- DynamicForm,
13077
+ const { sidebarWidth, isDragging, handleMouseDown, containerRef } = useResizeColumn({
13078
+ defaultWidth: disabled ? 100 : defaultWidth,
13079
+ minimumWidth,
13080
+ maximumWidth,
13081
+ setCurrentWidth
13082
+ });
13083
+ return /* @__PURE__ */ jsxs("div", { className: cn("w-full h-full relative", className), ref: containerRef, style: { width: `${sidebarWidth}%` }, children: [
13084
+ !disabled && dividerPosition === "left" ? /* @__PURE__ */ jsx(
13085
+ "div",
12633
13086
  {
12634
- schema,
12635
- defaultValues,
12636
- isSubmitLoading,
12637
- submitButtonLabel,
12638
- onSubmit
13087
+ className: `w-px bg-border1 h-full cursor-col-resize hover:w-1.5 hover:bg-mastra-border-2 hover:bg-[#424242] active:bg-mastra-border-3 active:bg-[#3e3e3e] transition-colors absolute inset-y-0 z-10
13088
+ ${isDragging ? "bg-border2 w-1.5 cursor- col-resize" : ""}`,
13089
+ onMouseDown: handleMouseDown
12639
13090
  }
12640
- ) : /* @__PURE__ */ jsx(
12641
- JSONInput,
13091
+ ) : null,
13092
+ children,
13093
+ !disabled && dividerPosition === "right" ? /* @__PURE__ */ jsx(
13094
+ "div",
12642
13095
  {
12643
- schema,
12644
- defaultValues,
12645
- isSubmitLoading,
12646
- submitButtonLabel,
12647
- onSubmit
13096
+ className: `w-px bg-border1 h-full cursor-col-resize hover:w-1.5 hover:bg-border2 active:bg-border3 transition-colors absolute inset-y-0 z-10
13097
+ ${isDragging ? "bg-border2 w-1.5 cursor- col-resize" : ""}`,
13098
+ onMouseDown: handleMouseDown
12648
13099
  }
12649
- )
13100
+ ) : null
12650
13101
  ] });
12651
13102
  };
12652
- const JSONInput = ({ schema, defaultValues, isSubmitLoading, submitButtonLabel, onSubmit }) => {
12653
- const [errors, setErrors] = useState([]);
12654
- const [inputData, setInputData] = useState(JSON.stringify(defaultValues ?? {}, null, 2));
12655
- const handleSubmit = () => {
12656
- setErrors([]);
12657
- try {
12658
- const result = schema.safeParse(JSON.parse(inputData));
12659
- if (!result.success) {
12660
- setErrors(result.error.issues.map((e) => `[${e.path.join(".")}] ${e.message}`));
12661
- } else {
12662
- onSubmit(result.data);
13103
+
13104
+ const TraceTree = ({ children }) => {
13105
+ return /* @__PURE__ */ jsx("ol", { children });
13106
+ };
13107
+
13108
+ const variantClasses = {
13109
+ agent: "bg-accent1"
13110
+ };
13111
+ const Time = ({ durationMs, tokenCount, variant, progressPercent, offsetPercent }) => {
13112
+ const variantClass = variant ? variantClasses[variant] : "bg-accent3";
13113
+ const percent = Math.min(100, progressPercent);
13114
+ return /* @__PURE__ */ jsxs("div", { className: "w-[80px] xl:w-[166px] shrink-0", children: [
13115
+ /* @__PURE__ */ jsx("div", { className: "bg-surface4 relative h-[6px] w-full rounded-full p-px overflow-hidden", children: /* @__PURE__ */ jsx(
13116
+ "div",
13117
+ {
13118
+ className: clsx("absolute h-1 rounded-full", variantClass),
13119
+ style: { width: `${percent}%`, left: `${offsetPercent}%` }
12663
13120
  }
12664
- } catch (e) {
12665
- setErrors(["Invalid JSON provided"]);
12666
- }
12667
- };
12668
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4", children: [
12669
- errors.length > 0 && /* @__PURE__ */ jsxs("div", { className: "border-sm border-accent2 rounded-lg p-2", children: [
12670
- /* @__PURE__ */ jsxs(Txt, { as: "p", variant: "ui-md", className: "text-accent2 font-semibold", children: [
12671
- errors.length,
12672
- " errors found"
13121
+ ) }),
13122
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4 pt-0.5", children: [
13123
+ /* @__PURE__ */ jsxs(Txt, { variant: "ui-sm", className: "text-icon2 font-medium", children: [
13124
+ toSigFigs(durationMs, 3),
13125
+ "ms"
12673
13126
  ] }),
12674
- /* @__PURE__ */ jsx("ul", { className: "list-disc list-inside", children: errors.map((error, idx) => /* @__PURE__ */ jsx("li", { className: "text-ui-sm text-accent2", children: error }, idx)) })
13127
+ tokenCount && /* @__PURE__ */ jsxs(Txt, { variant: "ui-sm", className: "text-icon2 font-medium", children: [
13128
+ tokenCount,
13129
+ "t"
13130
+ ] })
13131
+ ] })
13132
+ ] });
13133
+ };
13134
+
13135
+ const spanIconMap = {
13136
+ tool: ToolsIcon,
13137
+ agent: AgentIcon,
13138
+ workflow: WorkflowIcon,
13139
+ memory: MemoryIcon,
13140
+ rag: TraceIcon,
13141
+ storage: DbIcon,
13142
+ eval: ScoreIcon,
13143
+ other: TraceIcon
13144
+ };
13145
+ const spanVariantClasses = {
13146
+ tool: "text-[#ECB047]",
13147
+ agent: "text-accent1",
13148
+ workflow: "text-accent3",
13149
+ memory: "text-accent2",
13150
+ rag: "text-accent2",
13151
+ storage: "text-accent2",
13152
+ eval: "text-accent4",
13153
+ other: "text-icon6"
13154
+ };
13155
+ const Span = ({
13156
+ children,
13157
+ durationMs,
13158
+ variant,
13159
+ tokenCount,
13160
+ spans,
13161
+ isRoot,
13162
+ onClick,
13163
+ isActive,
13164
+ offsetMs,
13165
+ totalDurationMs
13166
+ }) => {
13167
+ const [isExpanded, setIsExpanded] = useState(true);
13168
+ const VariantIcon = spanIconMap[variant];
13169
+ const variantClass = spanVariantClasses[variant];
13170
+ const progressPercent = durationMs / totalDurationMs * 100;
13171
+ const offsetPercent = offsetMs / totalDurationMs * 100;
13172
+ const TextEl = onClick ? "button" : "div";
13173
+ return /* @__PURE__ */ jsxs("li", { children: [
13174
+ /* @__PURE__ */ jsxs("div", { className: clsx("flex justify-between items-center gap-2 rounded-md pl-2", isActive && "bg-surface4"), children: [
13175
+ /* @__PURE__ */ jsxs("div", { className: "flex h-8 items-center gap-1 min-w-0", children: [
13176
+ spans ? /* @__PURE__ */ jsx(
13177
+ "button",
13178
+ {
13179
+ type: "button",
13180
+ "aria-label": isExpanded ? "Collapse span" : "Expand span",
13181
+ "aria-expanded": isExpanded,
13182
+ className: "text-icon3 flex h-4 w-4",
13183
+ onClick: () => setIsExpanded(!isExpanded),
13184
+ children: /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(ChevronIcon, { className: clsx("transition-transform -rotate-90", { "rotate-0": isExpanded }) }) })
13185
+ }
13186
+ ) : /* @__PURE__ */ jsx("div", { "aria-hidden": true, className: "h-full w-4", children: !isRoot && /* @__PURE__ */ jsx("div", { className: "ml-[7px] h-full w-px rounded-full" }) }),
13187
+ /* @__PURE__ */ jsxs(TextEl, { className: "flex items-center gap-2 min-w-0", onClick, children: [
13188
+ /* @__PURE__ */ jsx("div", { className: clsx("bg-surface4 flex items-center justify-center rounded-md p-[3px]", variantClass), children: /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(VariantIcon, {}) }) }),
13189
+ /* @__PURE__ */ jsx(Txt, { variant: "ui-md", className: "text-icon6 truncate", children })
13190
+ ] })
13191
+ ] }),
13192
+ /* @__PURE__ */ jsx(
13193
+ Time,
13194
+ {
13195
+ durationMs,
13196
+ tokenCount,
13197
+ variant: variant === "agent" ? "agent" : void 0,
13198
+ progressPercent,
13199
+ offsetPercent
13200
+ }
13201
+ )
12675
13202
  ] }),
12676
- /* @__PURE__ */ jsx(SyntaxHighlighter, { data: inputData, onChange: setInputData }),
12677
- /* @__PURE__ */ jsx(Button, { variant: "light", onClick: handleSubmit, className: "w-full", size: "lg", children: isSubmitLoading ? /* @__PURE__ */ jsx(Loader2, { className: "animate-spin" }) : submitButtonLabel })
13203
+ isExpanded && spans && /* @__PURE__ */ jsx("div", { className: "ml-4", children: spans })
12678
13204
  ] });
12679
13205
  };
12680
- const SyntaxHighlighter = ({ data, onChange }) => {
12681
- const theme = useCodemirrorTheme$1();
12682
- return /* @__PURE__ */ jsxs("div", { className: "rounded-md bg-[#1a1a1a] p-1 font-mono", children: [
12683
- /* @__PURE__ */ jsx(CopyButton, { content: data, className: "absolute top-2 right-2 z-10" }),
12684
- /* @__PURE__ */ jsx(CodeMirror, { value: data, theme, extensions: [jsonLanguage], onChange })
12685
- ] });
13206
+
13207
+ const Spans = ({ children }) => {
13208
+ return /* @__PURE__ */ jsx("ol", { children });
13209
+ };
13210
+
13211
+ const Trace = ({
13212
+ name,
13213
+ spans,
13214
+ durationMs,
13215
+ tokenCount,
13216
+ onClick,
13217
+ variant,
13218
+ isActive,
13219
+ totalDurationMs
13220
+ }) => {
13221
+ return /* @__PURE__ */ jsx(
13222
+ Span,
13223
+ {
13224
+ isRoot: true,
13225
+ durationMs,
13226
+ variant,
13227
+ spans: /* @__PURE__ */ jsx(Spans, { children: spans }),
13228
+ onClick,
13229
+ isActive,
13230
+ offsetMs: 0,
13231
+ totalDurationMs,
13232
+ children: name
13233
+ }
13234
+ );
13235
+ };
13236
+
13237
+ const getSpanVariant = (span) => {
13238
+ const attributes = Object.keys(span.attributes || {}).map((k) => k.toLowerCase());
13239
+ const lowerCaseName = span.name.toLowerCase();
13240
+ const isAiSpan = lowerCaseName.startsWith("ai.");
13241
+ if (isAiSpan) {
13242
+ const isAiAboutTool = lowerCaseName.includes("tool");
13243
+ if (isAiAboutTool) return "tool";
13244
+ return "other";
13245
+ }
13246
+ const hasMemoryRelatedAttributes = attributes.some((key) => key.includes("memory") || key.includes("storage"));
13247
+ if (hasMemoryRelatedAttributes) return "memory";
13248
+ const hasToolRelatedAttributes = attributes.some((key) => key.includes("tool"));
13249
+ if (hasToolRelatedAttributes) return "tool";
13250
+ const hasAgentRelatedAttributes = attributes.some((key) => key.includes("agent."));
13251
+ if (hasAgentRelatedAttributes) return "agent";
13252
+ if (lowerCaseName.includes(".insert")) {
13253
+ const evalRelatedAttribute = attributes.find((key) => String(span.attributes?.[key])?.includes("mastra_evals"));
13254
+ if (evalRelatedAttribute) return "eval";
13255
+ }
13256
+ return "other";
12686
13257
  };
12687
13258
 
12688
- function WorkflowTrigger({
12689
- workflowId,
12690
- setRunId,
12691
- workflow,
12692
- isLoading,
12693
- createWorkflowRun,
12694
- resumeWorkflow,
12695
- streamWorkflow,
12696
- isStreamingWorkflow,
12697
- streamResult,
12698
- isResumingWorkflow,
12699
- isCancellingWorkflowRun,
12700
- cancelWorkflowRun
12701
- }) {
12702
- const { runtimeContext } = usePlaygroundStore();
12703
- const { result, setResult, payload, setPayload } = useContext(WorkflowRunContext);
12704
- const [suspendedSteps, setSuspendedSteps] = useState([]);
12705
- const [isRunning, setIsRunning] = useState(false);
12706
- const [innerRunId, setInnerRunId] = useState("");
12707
- const [cancelResponse, setCancelResponse] = useState(null);
12708
- const triggerSchema = workflow?.inputSchema;
12709
- const handleExecuteWorkflow = async (data) => {
12710
- try {
12711
- if (!workflow) return;
12712
- setIsRunning(true);
12713
- setCancelResponse(null);
12714
- setResult(null);
12715
- const { runId } = await createWorkflowRun({ workflowId });
12716
- setRunId?.(runId);
12717
- setInnerRunId(runId);
12718
- streamWorkflow({ workflowId, runId, inputData: data, runtimeContext });
12719
- } catch (err) {
12720
- setIsRunning(false);
12721
- toast.error("Error executing workflow");
13259
+ function buildTree(spans, minStartTime, totalDurationMs, parentSpanId = null) {
13260
+ return spans.filter((span) => span.parentSpanId === parentSpanId).map((span) => {
13261
+ return {
13262
+ ...span,
13263
+ children: buildTree(spans, minStartTime, totalDurationMs, span.id),
13264
+ offset: (span.startTime - minStartTime) / 1e3,
13265
+ // ns to ms
13266
+ duration: span.duration / 1e3,
13267
+ totalDurationMs
13268
+ };
13269
+ });
13270
+ }
13271
+ const createSpanTree = (spans) => {
13272
+ if (spans.length === 0) return [];
13273
+ let minStartTime;
13274
+ let maxEndTime;
13275
+ const orderedTree = [];
13276
+ const listSize = spans.length;
13277
+ for (let i = listSize - 1; i >= 0; i--) {
13278
+ const span = spans[i];
13279
+ if (!minStartTime || span.startTime < minStartTime) {
13280
+ minStartTime = span.startTime;
12722
13281
  }
12723
- };
12724
- const handleResumeWorkflow = async (step) => {
12725
- if (!workflow) return;
12726
- setCancelResponse(null);
12727
- const { stepId, runId: prevRunId, resumeData } = step;
12728
- const { runId } = await createWorkflowRun({ workflowId, prevRunId });
12729
- await resumeWorkflow({
12730
- step: stepId,
12731
- runId,
12732
- resumeData,
12733
- workflowId,
12734
- runtimeContext
12735
- });
12736
- };
12737
- const handleCancelWorkflowRun = async () => {
12738
- const response = await cancelWorkflowRun({ workflowId, runId: innerRunId });
12739
- setCancelResponse(response);
12740
- };
12741
- const streamResultToUse = result ?? streamResult;
12742
- useEffect(() => {
12743
- setIsRunning(isStreamingWorkflow);
12744
- }, [isStreamingWorkflow]);
12745
- useEffect(() => {
12746
- if (!streamResultToUse?.payload?.workflowState?.steps || !result?.runId) return;
12747
- const suspended = Object.entries(streamResultToUse.payload.workflowState.steps).filter(([_, { status }]) => status === "suspended").map(([stepId, { payload: payload2 }]) => ({
12748
- stepId,
12749
- runId: result.runId,
12750
- suspendPayload: payload2,
12751
- isLoading: false
12752
- }));
12753
- setSuspendedSteps(suspended);
12754
- }, [streamResultToUse, result]);
12755
- useEffect(() => {
12756
- if (streamResult) {
12757
- setResult(streamResult);
13282
+ if (!maxEndTime || span.endTime > maxEndTime) {
13283
+ maxEndTime = span.endTime;
13284
+ }
13285
+ if (span.name !== ".insert" && span.name !== "mastra.getStorage") {
13286
+ orderedTree.push(span);
12758
13287
  }
12759
- }, [streamResult]);
12760
- if (isLoading) {
12761
- return /* @__PURE__ */ jsx(ScrollArea, { className: "h-[calc(100vh-126px)] pt-2 px-4 pb-4 text-xs", children: /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
12762
- /* @__PURE__ */ jsx(Skeleton, { className: "h-10" }),
12763
- /* @__PURE__ */ jsx(Skeleton, { className: "h-10" })
12764
- ] }) });
12765
13288
  }
12766
- if (!workflow) return null;
12767
- const isSuspendedSteps = suspendedSteps.length > 0;
12768
- const zodInputSchema = triggerSchema ? resolveSerializedZodOutput(jsonSchemaToZod(parse(triggerSchema))) : null;
12769
- const workflowActivePaths = streamResultToUse?.payload?.workflowState?.steps ?? {};
12770
- const hasWorkflowActivePaths = Object.values(workflowActivePaths).length > 0;
12771
- const doneStatuses = ["success", "failed", "canceled"];
12772
- return /* @__PURE__ */ jsxs("div", { className: "h-full pt-3 pb-12", children: [
12773
- /* @__PURE__ */ jsxs("div", { className: "space-y-4 px-5 pb-5 border-b-sm border-border1", children: [
12774
- (isResumingWorkflow || isSuspendedSteps && isStreamingWorkflow) && /* @__PURE__ */ jsxs("div", { className: "py-2 px-5 flex items-center gap-2 bg-surface5 -mx-5 -mt-5 border-b-sm border-border1", children: [
12775
- /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(Loader2, { className: "animate-spin text-icon6" }) }),
12776
- /* @__PURE__ */ jsx(Txt, { children: "Resuming workflow" })
12777
- ] }),
12778
- !isSuspendedSteps && /* @__PURE__ */ jsx(Fragment, { children: zodInputSchema ? /* @__PURE__ */ jsx(
12779
- WorkflowInputData,
12780
- {
12781
- schema: zodInputSchema,
12782
- defaultValues: payload,
12783
- isSubmitLoading: isStreamingWorkflow,
12784
- submitButtonLabel: "Run",
12785
- onSubmit: (data) => {
12786
- setPayload(data);
12787
- handleExecuteWorkflow(data);
12788
- }
12789
- }
12790
- ) : /* @__PURE__ */ jsx(
12791
- Button,
12792
- {
12793
- className: "w-full",
12794
- variant: "light",
12795
- disabled: isRunning,
12796
- onClick: () => handleExecuteWorkflow(null),
12797
- children: isRunning ? /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(Loader2, { className: "animate-spin" }) }) : "Trigger"
12798
- }
12799
- ) }),
12800
- !isStreamingWorkflow && isSuspendedSteps && suspendedSteps?.map((step) => {
12801
- const stepDefinition = workflow.allSteps[step.stepId];
12802
- if (!stepDefinition || stepDefinition.isWorkflow) return null;
12803
- const stepSchema = stepDefinition?.resumeSchema ? resolveSerializedZodOutput(jsonSchemaToZod(parse(stepDefinition.resumeSchema))) : z.record(z.string(), z.any());
12804
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-col px-4", children: [
12805
- /* @__PURE__ */ jsx(Text, { variant: "secondary", className: "text-mastra-el-3", size: "xs", children: step.stepId }),
12806
- step.suspendPayload && /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
12807
- CodeBlockDemo,
12808
- {
12809
- className: "w-full overflow-x-auto p-2",
12810
- code: JSON.stringify(step.suspendPayload, null, 2),
12811
- language: "json"
12812
- }
12813
- ) }),
12814
- /* @__PURE__ */ jsx(
12815
- WorkflowInputData,
12816
- {
12817
- schema: stepSchema,
12818
- isSubmitLoading: isResumingWorkflow,
12819
- submitButtonLabel: "Resume",
12820
- onSubmit: (data) => {
12821
- const stepIds = step.stepId?.split(".");
12822
- handleResumeWorkflow({
12823
- stepId: stepIds,
12824
- runId: step.runId,
12825
- suspendPayload: step.suspendPayload,
12826
- resumeData: data});
12827
- }
12828
- }
12829
- )
12830
- ] }, step.stepId);
12831
- }),
12832
- result?.runId && /* @__PURE__ */ jsxs(
12833
- Button,
12834
- {
12835
- variant: "light",
12836
- className: "w-full",
12837
- size: "lg",
12838
- onClick: handleCancelWorkflowRun,
12839
- disabled: !!cancelResponse?.message || isCancellingWorkflowRun || result?.payload?.workflowState?.status && doneStatuses.includes(result?.payload?.workflowState?.status),
12840
- children: [
12841
- isCancellingWorkflowRun ? /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(Loader2, { className: "animate-spin" }) }) : /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(StopCircle, {}) }),
12842
- cancelResponse?.message || "Cancel Workflow Run"
12843
- ]
12844
- }
12845
- ),
12846
- hasWorkflowActivePaths && /* @__PURE__ */ jsxs(Fragment, { children: [
12847
- /* @__PURE__ */ jsx("hr", { className: "border-border1 border-sm my-5" }),
12848
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
12849
- /* @__PURE__ */ jsx(Text, { variant: "secondary", className: "px-4 text-mastra-el-3", size: "xs", children: "Status" }),
12850
- /* @__PURE__ */ jsx("div", { className: "px-4 flex flex-col gap-4", children: Object.entries(workflowActivePaths).filter(([key, _]) => key !== "input" && !key.endsWith(".input")).map(([stepId, { status, output }]) => {
12851
- return /* @__PURE__ */ jsx(WorkflowStatus, { stepId, status, result: output ?? {} }, stepId);
12852
- }) })
12853
- ] })
13289
+ if (!minStartTime || !maxEndTime) return [];
13290
+ const totalDurationMs = (maxEndTime - minStartTime) / 1e3;
13291
+ return buildTree(orderedTree, minStartTime, totalDurationMs);
13292
+ };
13293
+
13294
+ const NestedSpans = ({ spanNodes }) => {
13295
+ const { span: activeSpan, setSpan } = useContext(TraceContext);
13296
+ return /* @__PURE__ */ jsx(Spans, { children: spanNodes.map((spanNode) => {
13297
+ const isActive = spanNode.id === activeSpan?.id;
13298
+ return /* @__PURE__ */ jsx(
13299
+ Span,
13300
+ {
13301
+ spans: spanNode.children.length > 0 && /* @__PURE__ */ jsx(NestedSpans, { spanNodes: spanNode.children }),
13302
+ durationMs: spanNode.duration,
13303
+ offsetMs: spanNode.offset,
13304
+ variant: getSpanVariant(spanNode),
13305
+ isActive,
13306
+ onClick: () => setSpan(spanNode),
13307
+ totalDurationMs: spanNode.totalDurationMs,
13308
+ children: spanNode.name
13309
+ },
13310
+ spanNode.id
13311
+ );
13312
+ }) });
13313
+ };
13314
+ function SpanView({ trace }) {
13315
+ const { span: activeSpan, setSpan } = useContext(TraceContext);
13316
+ const tree = createSpanTree(trace);
13317
+ return /* @__PURE__ */ jsx(TraceTree, { children: tree.map((node) => /* @__PURE__ */ jsx(
13318
+ Trace,
13319
+ {
13320
+ name: node.name,
13321
+ durationMs: node.duration,
13322
+ totalDurationMs: node.totalDurationMs,
13323
+ spans: /* @__PURE__ */ jsx(NestedSpans, { spanNodes: node.children }),
13324
+ variant: getSpanVariant(node),
13325
+ isActive: node.id === activeSpan?.id,
13326
+ onClick: () => setSpan(node)
13327
+ }
13328
+ )) });
13329
+ }
13330
+
13331
+ const Header = ({ children, border = true }) => {
13332
+ return /* @__PURE__ */ jsx(
13333
+ "header",
13334
+ {
13335
+ className: clsx("h-header-default z-50 flex w-full items-center gap-[18px] bg-transparent px-5", {
13336
+ "border-b-sm border-border1": border
13337
+ }),
13338
+ children
13339
+ }
13340
+ );
13341
+ };
13342
+ const HeaderTitle = ({ children }) => {
13343
+ return /* @__PURE__ */ jsx(Txt, { as: "h1", variant: "ui-lg", className: "font-medium text-white", children });
13344
+ };
13345
+ const HeaderAction = ({ children }) => {
13346
+ return /* @__PURE__ */ jsx("div", { className: "ml-auto", children });
13347
+ };
13348
+ const HeaderGroup = ({ children }) => {
13349
+ return /* @__PURE__ */ jsx("div", { className: "gap-lg flex items-center", children });
13350
+ };
13351
+
13352
+ function TraceDetails() {
13353
+ const { trace, currentTraceIndex, prevTrace, nextTrace, traces } = useContext(TraceContext);
13354
+ const actualTrace = traces[currentTraceIndex];
13355
+ if (!actualTrace || !trace) return null;
13356
+ const hasFailure = trace.some((span) => span.status.code !== 0);
13357
+ return /* @__PURE__ */ jsxs("aside", { children: [
13358
+ /* @__PURE__ */ jsxs(Header, { children: [
13359
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
13360
+ /* @__PURE__ */ jsx(Button, { className: "bg-transparent border-none", onClick: prevTrace, disabled: currentTraceIndex === 0, children: /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(ChevronUp, {}) }) }),
13361
+ /* @__PURE__ */ jsx(
13362
+ Button,
13363
+ {
13364
+ className: "bg-transparent border-none",
13365
+ onClick: nextTrace,
13366
+ disabled: currentTraceIndex === traces.length - 1,
13367
+ children: /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(ChevronDown, {}) })
13368
+ }
13369
+ )
13370
+ ] }),
13371
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 justify-between w-full", children: [
13372
+ /* @__PURE__ */ jsxs(Txt, { variant: "ui-lg", className: "font-medium text-icon5 shrink-0", children: [
13373
+ "Trace ",
13374
+ /* @__PURE__ */ jsx("span", { className: "ml-2 text-icon3", children: actualTrace.traceId.substring(0, 7) })
13375
+ ] }),
13376
+ hasFailure && /* @__PURE__ */ jsx(Badge$1, { variant: "error", icon: /* @__PURE__ */ jsx(X, {}), children: "Failed" })
12854
13377
  ] })
12855
13378
  ] }),
12856
- result && /* @__PURE__ */ jsx("div", { className: "p-5 border-b-sm border-border1", children: /* @__PURE__ */ jsx(WorkflowJsonDialog, { result }) })
13379
+ /* @__PURE__ */ jsx("div", { className: "p-5", children: /* @__PURE__ */ jsx(SpanView, { trace }) })
12857
13380
  ] });
12858
13381
  }
12859
- const WorkflowJsonDialog = ({ result }) => {
12860
- const [open, setOpen] = useState(false);
12861
- return /* @__PURE__ */ jsxs(Fragment, { children: [
12862
- /* @__PURE__ */ jsxs(Button, { variant: "light", onClick: () => setOpen(true), className: "w-full", size: "lg", children: [
12863
- /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(Braces, { className: "text-icon3" }) }),
12864
- "Open Workflow Execution (JSON)"
12865
- ] }),
12866
- /* @__PURE__ */ jsx(Dialog, { open, onOpenChange: setOpen, children: /* @__PURE__ */ jsx(DialogPortal, { children: /* @__PURE__ */ jsxs(DialogContent, { className: "max-w-6xl max-h-[90vh] overflow-y-auto overflow-x-hidden bg-surface2", children: [
12867
- /* @__PURE__ */ jsx(DialogTitle, { children: "Workflow Execution (JSON)" }),
12868
- /* @__PURE__ */ jsx("div", { className: "w-full h-full overflow-x-scroll", children: /* @__PURE__ */ jsx(SyntaxHighlighter$2, { data: result, className: "p-4" }) })
12869
- ] }) }) })
12870
- ] });
12871
- };
12872
13382
 
12873
- const WorkflowRuns = ({ workflowId, runId, isLoading, runs, onPressRun }) => {
12874
- if (isLoading) {
12875
- return /* @__PURE__ */ jsx("div", { className: "p-4", children: /* @__PURE__ */ jsx(Skeleton, { className: "h-[600px]" }) });
13383
+ function formatDuration(duration, fixedPoint = 2) {
13384
+ const durationInSecs = duration / 1e3;
13385
+ return durationInSecs.toFixed(fixedPoint);
13386
+ }
13387
+ function formatOtelTimestamp(otelTimestamp) {
13388
+ const date = new Date(otelTimestamp / 1e3);
13389
+ return new Intl.DateTimeFormat("en-US", {
13390
+ month: "numeric",
13391
+ day: "numeric",
13392
+ year: "numeric",
13393
+ hour: "numeric",
13394
+ minute: "numeric",
13395
+ second: "numeric",
13396
+ hour12: true
13397
+ }).format(date);
13398
+ }
13399
+ function formatOtelTimestamp2(otelTimestamp) {
13400
+ const date = new Date(otelTimestamp / 1e6);
13401
+ return new Intl.DateTimeFormat("en-US", {
13402
+ month: "numeric",
13403
+ day: "numeric",
13404
+ year: "numeric",
13405
+ hour: "numeric",
13406
+ minute: "numeric",
13407
+ second: "numeric",
13408
+ hour12: true
13409
+ }).format(date);
13410
+ }
13411
+ function transformKey(key) {
13412
+ if (key.includes(".argument.")) {
13413
+ return `Input`;
12876
13414
  }
12877
- if (runs.length === 0) {
12878
- return /* @__PURE__ */ jsx("div", { className: "p-4", children: /* @__PURE__ */ jsx(Txt, { variant: "ui-md", className: "text-icon6 text-center", children: "No previous run" }) });
13415
+ if (key.includes(".result")) {
13416
+ return "Output";
12879
13417
  }
12880
- return /* @__PURE__ */ jsx("ol", { className: "pb-10", children: runs.map((run) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(
12881
- "button",
12882
- {
12883
- onClick: () => onPressRun({ workflowId, runId: run.runId }),
12884
- className: clsx("px-3 py-2 border-b-sm border-border1 block w-full hover:bg-surface4 text-left", {
12885
- "bg-surface4": run.runId === runId
12886
- }),
12887
- children: [
12888
- /* @__PURE__ */ jsx(Txt, { variant: "ui-lg", className: "font-medium text-icon6 truncate", as: "p", children: run.runId }),
12889
- /* @__PURE__ */ jsx(Txt, { variant: "ui-sm", className: "font-medium text-icon3 truncate", as: "p", children: typeof run?.snapshot === "string" ? "" : run?.snapshot?.timestamp ? formatDate(run?.snapshot?.timestamp, "MMM d, yyyy h:mm a") : "" })
12890
- ]
13418
+ const newKey = key.split(".").join(" ").split("_").join(" ").replaceAll("ai", "AI");
13419
+ return newKey.substring(0, 1).toUpperCase() + newKey.substring(1);
13420
+ }
13421
+ function cleanString(string) {
13422
+ return string.replace(/\\n/g, "").replace(/\n/g, "").replace(/\s+/g, " ").trim();
13423
+ }
13424
+ const allowedAiSpanAttributes = [
13425
+ "operation.name",
13426
+ "ai.operationId",
13427
+ "ai.model.provider",
13428
+ "ai.model.id",
13429
+ "ai.prompt.format",
13430
+ "ai.prompt.messages",
13431
+ "ai.prompt.tools",
13432
+ "ai.prompt.toolChoice",
13433
+ "ai.settings.toolChoice",
13434
+ "ai.schema",
13435
+ "ai.settings.output",
13436
+ "ai.response.object",
13437
+ "ai.response.text",
13438
+ "ai.response.timestamp",
13439
+ "componentName",
13440
+ "ai.usage.promptTokens",
13441
+ "ai.usage.completionTokens"
13442
+ ];
13443
+
13444
+ function SpanDetail() {
13445
+ const { span, setSpan, trace, setIsOpen } = useContext(TraceContext);
13446
+ if (!span || !trace) return null;
13447
+ const prevSpan = () => {
13448
+ const currentIndex = trace.findIndex((t) => t.id === span.id);
13449
+ if (currentIndex !== -1 && currentIndex < trace.length - 1) {
13450
+ setSpan(trace[currentIndex + 1]);
12891
13451
  }
12892
- ) }, run.runId)) });
13452
+ };
13453
+ const nextSpan = () => {
13454
+ const currentIndex = trace.findIndex((t) => t.id === span.id);
13455
+ if (currentIndex !== -1 && currentIndex > 0) {
13456
+ setSpan(trace[currentIndex - 1]);
13457
+ }
13458
+ };
13459
+ const SpanIcon = spanIconMap[getSpanVariant(span)];
13460
+ const variantClass = spanVariantClasses[getSpanVariant(span)];
13461
+ return /* @__PURE__ */ jsxs("aside", { children: [
13462
+ /* @__PURE__ */ jsxs(Header, { children: [
13463
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
13464
+ /* @__PURE__ */ jsx(Button, { className: "bg-transparent border-none", onClick: prevSpan, children: /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(ChevronUp, {}) }) }),
13465
+ /* @__PURE__ */ jsx(Button, { className: "bg-transparent border-none", onClick: nextSpan, children: /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(ChevronDown, {}) }) })
13466
+ ] }),
13467
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(Txt, { variant: "ui-lg", className: "font-medium text-icon5", as: "h2", children: [
13468
+ "Span ",
13469
+ /* @__PURE__ */ jsx("span", { className: "ml-2 text-icon3", children: span.id.substring(0, 7) })
13470
+ ] }) }),
13471
+ /* @__PURE__ */ jsx("div", { className: "ml-auto flex items-center gap-2", children: /* @__PURE__ */ jsx(Button, { className: "bg-transparent border-none", onClick: () => setIsOpen(false), children: /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(X, {}) }) }) })
13472
+ ] }),
13473
+ /* @__PURE__ */ jsxs("div", { className: "p-5", children: [
13474
+ /* @__PURE__ */ jsxs(Txt, { variant: "header-md", as: "h3", className: "text-icon-6 flex items-center gap-4 pb-3", children: [
13475
+ /* @__PURE__ */ jsx(Icon, { size: "lg", className: "bg-surface4 p-1 rounded-md", children: /* @__PURE__ */ jsx(SpanIcon, { className: variantClass }) }),
13476
+ span.name
13477
+ ] }),
13478
+ /* @__PURE__ */ jsx("div", { className: "flex flex-row gap-2 items-center", children: span.status.code === 0 ? /* @__PURE__ */ jsxs(Badge$1, { icon: /* @__PURE__ */ jsx(LatencyIcon, {}), variant: "success", children: [
13479
+ toSigFigs(span.duration, 3),
13480
+ "ms"
13481
+ ] }) : /* @__PURE__ */ jsxs(Badge$1, { variant: "error", icon: /* @__PURE__ */ jsx(X, {}), children: [
13482
+ "Failed in ",
13483
+ toSigFigs(span.duration, 3),
13484
+ "ms"
13485
+ ] }) }),
13486
+ /* @__PURE__ */ jsx("hr", { className: "border-border1 border-sm my-5" }),
13487
+ /* @__PURE__ */ jsxs("dl", { className: "grid grid-cols-2 justify-between gap-2", children: [
13488
+ /* @__PURE__ */ jsx("dt", { className: "font-medium text-ui-md text-icon3", children: "ID" }),
13489
+ /* @__PURE__ */ jsx("dd", { className: "text-ui-md text-icon6", children: span.id }),
13490
+ /* @__PURE__ */ jsx("dt", { className: "font-medium text-ui-md text-icon3", children: "Created at" }),
13491
+ /* @__PURE__ */ jsx("dd", { className: "text-ui-md text-icon6", children: span.startTime ? formatOtelTimestamp(span.startTime) : "" })
13492
+ ] }),
13493
+ span.attributes && /* @__PURE__ */ jsx(Attributes, { attributes: span.attributes }),
13494
+ span.events?.length > 0 && /* @__PURE__ */ jsx(Events, { span })
13495
+ ] })
13496
+ ] });
13497
+ }
13498
+ function Attributes({ attributes }) {
13499
+ if (!attributes) return null;
13500
+ const entries = Object.entries(attributes);
13501
+ if (entries.length === 0) return null;
13502
+ const keysToHide = ["http.request_id", "componentName"];
13503
+ return /* @__PURE__ */ jsx("div", { children: entries.filter(([key]) => !keysToHide.includes(key)).map(([key, val]) => {
13504
+ return /* @__PURE__ */ jsxs("div", { children: [
13505
+ /* @__PURE__ */ jsx("hr", { className: "border-border1 border-sm my-5" }),
13506
+ /* @__PURE__ */ jsx(Txt, { as: "h4", variant: "ui-md", className: "text-icon3 pb-2", children: transformKey(key) }),
13507
+ /* @__PURE__ */ jsx(AttributeValue, { value: val })
13508
+ ] }, key);
13509
+ }) });
13510
+ }
13511
+ const AttributeValue = ({ value }) => {
13512
+ if (!value)
13513
+ return /* @__PURE__ */ jsx(Txt, { as: "p", variant: "ui-md", className: "text-icon6", children: "N/A" });
13514
+ if (typeof value === "number" || typeof value === "boolean") {
13515
+ return /* @__PURE__ */ jsx(Txt, { as: "p", variant: "ui-md", className: "text-icon6", children: String(value) });
13516
+ }
13517
+ if (typeof value === "object") {
13518
+ return /* @__PURE__ */ jsx(SyntaxHighlighter$1, { data: value });
13519
+ }
13520
+ try {
13521
+ return /* @__PURE__ */ jsx(SyntaxHighlighter$1, { data: JSON.parse(value) });
13522
+ } catch {
13523
+ return /* @__PURE__ */ jsx(Txt, { as: "p", variant: "ui-md", className: "text-icon6", children: String(value) });
13524
+ }
12893
13525
  };
13526
+ function Events({ span }) {
13527
+ if (!span.events) return null;
13528
+ return /* @__PURE__ */ jsxs("div", { children: [
13529
+ /* @__PURE__ */ jsx("hr", { className: "border-border1 border-sm my-5" }),
13530
+ /* @__PURE__ */ jsx(Txt, { as: "p", variant: "ui-md", className: "text-icon6 pb-2", children: "Events" }),
13531
+ span.events.map((event) => {
13532
+ const isLast = event === span.events[span.events.length - 1];
13533
+ return /* @__PURE__ */ jsxs(React__default.Fragment, { children: [
13534
+ /* @__PURE__ */ jsxs("div", { children: [
13535
+ /* @__PURE__ */ jsxs("dl", { className: "grid grid-cols-2 justify-between gap-2 pb-2", children: [
13536
+ /* @__PURE__ */ jsx("dt", { className: "font-medium text-ui-md text-icon3", children: "Name" }),
13537
+ /* @__PURE__ */ jsx("dd", { className: "text-ui-md text-icon6", children: event.name }),
13538
+ /* @__PURE__ */ jsx("dt", { className: "font-medium text-ui-md text-icon3", children: "Time" }),
13539
+ /* @__PURE__ */ jsx("dd", { className: "text-ui-md text-icon6", children: event.timeUnixNano ? formatOtelTimestamp2(Number(event.timeUnixNano)) : "N/A" })
13540
+ ] }),
13541
+ event.attributes?.length > 0 ? /* @__PURE__ */ jsx("ul", { className: "space-y-2", children: event.attributes.filter((attribute) => attribute !== null).map((attribute) => /* @__PURE__ */ jsxs("li", { children: [
13542
+ /* @__PURE__ */ jsx(Txt, { as: "h4", variant: "ui-md", className: "text-icon3 pb-2", children: transformKey(attribute.key) }),
13543
+ /* @__PURE__ */ jsx(AttributeValue, { value: attribute.value })
13544
+ ] }, attribute.key)) }) : null
13545
+ ] }, event.name),
13546
+ !isLast && /* @__PURE__ */ jsx("hr", { className: "border-border1 border-sm my-5" })
13547
+ ] }, event.name);
13548
+ })
13549
+ ] });
13550
+ }
12894
13551
 
12895
- const columns = [
12896
- {
12897
- id: "name",
12898
- header: "Name",
12899
- cell: ({ row }) => {
12900
- const { Link } = useLinkComponent();
12901
- return /* @__PURE__ */ jsx(
12902
- EntryCell,
12903
- {
12904
- icon: /* @__PURE__ */ jsx(WorkflowIcon, {}),
12905
- name: /* @__PURE__ */ jsx(Link, { href: row.original.link, children: row.original.name }),
12906
- description: void 0,
12907
- meta: void 0
12908
- }
12909
- );
12910
- },
12911
- meta: {
12912
- width: "auto"
13552
+ const TracesSidebar = ({ onResize }) => {
13553
+ return /* @__PURE__ */ jsx(
13554
+ MastraResizablePanel,
13555
+ {
13556
+ className: "h-full absolute right-0 inset-y-0 bg-surface2",
13557
+ defaultWidth: 80,
13558
+ minimumWidth: 50,
13559
+ maximumWidth: 80,
13560
+ setCurrentWidth: onResize,
13561
+ children: /* @__PURE__ */ jsxs("div", { className: "h-full grid grid-cols-2", children: [
13562
+ /* @__PURE__ */ jsx("div", { className: "overflow-x-scroll w-full h-[calc(100%-40px)]", children: /* @__PURE__ */ jsx(TraceDetails, {}) }),
13563
+ /* @__PURE__ */ jsx("div", { className: "h-[calc(100%-40px)] overflow-x-scroll w-full border-l border-border1", children: /* @__PURE__ */ jsx(SpanDetail, {}) })
13564
+ ] })
12913
13565
  }
12914
- },
12915
- {
12916
- id: "stepsCount",
12917
- header: "Steps",
12918
- size: 300,
12919
- cell: ({ row }) => /* @__PURE__ */ jsx(Cell, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end items-center gap-2", children: [
12920
- /* @__PURE__ */ jsxs(Badge$1, { icon: /* @__PURE__ */ jsx(Footprints, {}), className: "!h-button-md", children: [
12921
- row.original.stepsCount,
12922
- " step",
12923
- row.original.stepsCount > 1 ? "s" : ""
12924
- ] }),
12925
- row.original.isLegacy ? /* @__PURE__ */ jsx(Badge$1, { className: "!text-foreground/80 !h-button-md", children: "Legacy" }) : null
12926
- ] }) })
12927
- }
12928
- ];
13566
+ );
13567
+ };
12929
13568
 
12930
- function WorkflowTable({ workflows, legacyWorkflows, isLoading, computeLink }) {
12931
- const { navigate } = useLinkComponent();
12932
- const workflowData = useMemo(() => {
12933
- const _workflowsData = Object.keys(workflows ?? {}).map((key) => {
12934
- const workflow = workflows?.[key];
12935
- return {
12936
- id: key,
12937
- name: workflow?.name || "N/A",
12938
- stepsCount: Object.keys(workflow?.steps ?? {})?.length,
12939
- isLegacy: false,
12940
- link: computeLink(key)
12941
- };
12942
- });
12943
- const legacyWorkflowsData = Object.keys(legacyWorkflows ?? {}).map((key) => {
12944
- const workflow = legacyWorkflows?.[key];
12945
- return {
12946
- id: key,
12947
- name: workflow?.name || "N/A",
12948
- stepsCount: Object.keys(workflow?.steps ?? {})?.length,
12949
- isLegacy: true,
12950
- link: computeLink(key)
12951
- };
12952
- });
12953
- return [..._workflowsData, ...legacyWorkflowsData];
12954
- }, [workflows, legacyWorkflows]);
12955
- const table = useReactTable({
12956
- data: workflowData,
12957
- columns,
12958
- getCoreRowModel: getCoreRowModel()
12959
- });
12960
- if (isLoading) return /* @__PURE__ */ jsx(WorkflowTableSkeleton, {});
12961
- const ths = table.getHeaderGroups()[0];
12962
- const rows = table.getRowModel().rows.concat();
12963
- if (rows.length === 0) {
12964
- return /* @__PURE__ */ jsx(EmptyWorkflowsTable, {});
13569
+ function TracesView({
13570
+ isLoading,
13571
+ error,
13572
+ traces,
13573
+ runId,
13574
+ stepName,
13575
+ className,
13576
+ setEndOfListElement
13577
+ }) {
13578
+ if (isLoading) {
13579
+ return /* @__PURE__ */ jsx(TracesViewSkeleton, {});
12965
13580
  }
12966
- return /* @__PURE__ */ jsx(ScrollableContainer, { children: /* @__PURE__ */ jsxs(Table, { children: [
12967
- /* @__PURE__ */ jsx(Thead, { className: "sticky top-0", children: ths.headers.map((header) => /* @__PURE__ */ jsx(Th, { style: { width: header.index === 0 ? "auto" : header.column.getSize() }, children: flexRender(header.column.columnDef.header, header.getContext()) }, header.id)) }),
12968
- /* @__PURE__ */ jsx(Tbody, { children: rows.map((row) => /* @__PURE__ */ jsx(Row, { onClick: () => navigate(row.original.link), children: row.getVisibleCells().map((cell) => /* @__PURE__ */ jsx(React__default.Fragment, { children: flexRender(cell.column.columnDef.cell, cell.getContext()) }, cell.id)) }, row.id)) })
12969
- ] }) });
13581
+ return /* @__PURE__ */ jsx(TraceProvider, { initialTraces: traces || [], children: /* @__PURE__ */ jsx(
13582
+ TracesViewInner,
13583
+ {
13584
+ traces,
13585
+ error,
13586
+ runId,
13587
+ stepName,
13588
+ className,
13589
+ setEndOfListElement
13590
+ }
13591
+ ) });
12970
13592
  }
12971
- const WorkflowTableSkeleton = () => /* @__PURE__ */ jsxs(Table, { children: [
12972
- /* @__PURE__ */ jsxs(Thead, { children: [
12973
- /* @__PURE__ */ jsx(Th, { children: "Name" }),
12974
- /* @__PURE__ */ jsx(Th, { width: 300, children: "Steps" })
12975
- ] }),
12976
- /* @__PURE__ */ jsx(Tbody, { children: Array.from({ length: 3 }).map((_, index) => /* @__PURE__ */ jsxs(Row, { children: [
12977
- /* @__PURE__ */ jsx(Cell, { children: /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-1/2" }) }),
12978
- /* @__PURE__ */ jsx(Cell, { width: 300, children: /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-1/2" }) })
12979
- ] }, index)) })
12980
- ] });
12981
- const EmptyWorkflowsTable = () => /* @__PURE__ */ jsx("div", { className: "flex h-full items-center justify-center", children: /* @__PURE__ */ jsx(
12982
- EmptyState,
12983
- {
12984
- iconSlot: /* @__PURE__ */ jsx(WorkflowCoinIcon, {}),
12985
- titleSlot: "Configure Workflows",
12986
- descriptionSlot: "Mastra workflows are not configured yet. You can find more information in the documentation.",
12987
- actionSlot: /* @__PURE__ */ jsxs(
12988
- Button,
12989
- {
12990
- size: "lg",
12991
- className: "w-full",
12992
- variant: "light",
12993
- as: "a",
12994
- href: "https://mastra.ai/en/docs/workflows/overview",
12995
- target: "_blank",
12996
- children: [
12997
- /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(WorkflowIcon, {}) }),
12998
- "Docs"
12999
- ]
13000
- }
13001
- )
13002
- }
13003
- ) });
13593
+ function TracesViewInner({ traces, error, runId, stepName, className, setEndOfListElement }) {
13594
+ const hasRunRef = useRef(false);
13595
+ const [sidebarWidth, setSidebarWidth] = useState(100);
13596
+ const { isOpen: open, setTrace, setIsOpen, setSpan } = useContext(TraceContext);
13597
+ useEffect(() => {
13598
+ if (hasRunRef.current) return;
13599
+ if (!runId || !stepName) return;
13600
+ const matchingTrace = traces.find((trace) => trace.runId === runId);
13601
+ if (!matchingTrace) return;
13602
+ const matchingSpan = matchingTrace.trace.find((span) => span.name.includes(stepName));
13603
+ if (!matchingSpan) return;
13604
+ setTrace(matchingTrace.trace);
13605
+ setSpan(matchingSpan);
13606
+ setIsOpen(true);
13607
+ hasRunRef.current = true;
13608
+ }, [runId, traces, setTrace]);
13609
+ return /* @__PURE__ */ jsxs("div", { className: clsx("h-full relative overflow-hidden flex", className), children: [
13610
+ /* @__PURE__ */ jsxs("div", { className: "h-full overflow-y-scroll w-full", children: [
13611
+ /* @__PURE__ */ jsx(TracesTable, { traces, error }),
13612
+ /* @__PURE__ */ jsx("div", { "aria-hidden": true, ref: setEndOfListElement })
13613
+ ] }),
13614
+ open && /* @__PURE__ */ jsx(TracesSidebar, { width: sidebarWidth, onResize: setSidebarWidth })
13615
+ ] });
13616
+ }
13617
+ const TracesViewSkeleton = () => {
13618
+ return /* @__PURE__ */ jsx("div", { className: "h-full relative overflow-hidden flex", children: /* @__PURE__ */ jsx("div", { className: "h-full overflow-y-scroll w-full", children: /* @__PURE__ */ jsx(Skeleton, { className: "h-10" }) }) });
13619
+ };
13004
13620
 
13005
13621
  const DataTable = ({
13006
13622
  columns,
@@ -13140,47 +13756,6 @@ function devUIStyleRequested(name) {
13140
13756
  }
13141
13757
  }
13142
13758
 
13143
- const Threads = ({ children }) => {
13144
- return /* @__PURE__ */ jsx("nav", { className: "bg-surface2 border-r-sm border-border1 min-h-full overflow-hidden", children });
13145
- };
13146
- const ThreadLink = ({ children, as: Component = "a", href, className, prefetch, to }) => {
13147
- return /* @__PURE__ */ jsx(
13148
- Component,
13149
- {
13150
- href,
13151
- prefetch,
13152
- to,
13153
- className: clsx("text-ui-sm flex h-full w-full flex-col justify-center font-medium", className),
13154
- children
13155
- }
13156
- );
13157
- };
13158
- const ThreadList = ({ children }) => {
13159
- return /* @__PURE__ */ jsx("ol", { children });
13160
- };
13161
- const ThreadItem = ({ children, isActive }) => {
13162
- return /* @__PURE__ */ jsx(
13163
- "li",
13164
- {
13165
- className: clsx(
13166
- "border-b-sm border-border1 hover:bg-surface3 group flex h-[54px] items-center justify-between gap-2 pl-5 py-2",
13167
- isActive && "bg-surface4"
13168
- ),
13169
- children
13170
- }
13171
- );
13172
- };
13173
- const ThreadDeleteButton = ({ onClick }) => {
13174
- return /* @__PURE__ */ jsx(
13175
- Button,
13176
- {
13177
- className: "shrink-0 border-none bg-transparent opacity-0 transition-all group-focus-within:opacity-100 group-hover:opacity-100",
13178
- onClick,
13179
- children: /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(X, { "aria-label": "delete thread", className: "text-icon3" }) })
13180
- }
13181
- );
13182
- };
13183
-
13184
13759
  const Breadcrumb = ({ children, label }) => {
13185
13760
  return /* @__PURE__ */ jsx("nav", { "aria-label": label, children: /* @__PURE__ */ jsx("ol", { className: "gap-sm flex items-center", children }) });
13186
13761
  };
@@ -13363,5 +13938,287 @@ function usePolling({
13363
13938
  };
13364
13939
  }
13365
13940
 
13366
- export { AgentChat, AgentCoinIcon, AgentEvals, AgentIcon, AgentNetworkCoinIcon, AgentSettings, AgentSettingsContext, AgentSettingsProvider, AgentTraces, 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, 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, PromptIcon, RadioGroup, RadioGroupItem, RepoIcon, Row, RuntimeContext, RuntimeContextWrapper, ScoreIcon, SettingsIcon, SlashIcon, Table, Tbody, Th, Thead, ThreadDeleteButton, ThreadItem, ThreadLink, ThreadList, Threads, ToolCoinIcon, ToolList, ToolListEmpty, ToolListSkeleton, ToolsIcon, TraceIcon, TsIcon, Txt, TxtCell, UnitCell, VNextNetworkChat, VariablesIcon, WorkflowCoinIcon, WorkflowGraph, WorkflowIcon, WorkflowRunContext, WorkflowRunProvider, WorkflowRuns, WorkflowTable, WorkflowTableSkeleton, WorkflowTraces, WorkflowTrigger, WorkingMemoryContext, WorkingMemoryProvider, providerMapToIcon, useAgentSettings, useCurrentRun, useLinkComponent, useMastraClient, usePlaygroundStore, usePolling, useSpeechRecognition, useWorkingMemory };
13941
+ const useInView = () => {
13942
+ const [inView, setInView] = useState(false);
13943
+ const setRef = useCallback((node) => {
13944
+ if (node) {
13945
+ const observer = new IntersectionObserver(([entry]) => {
13946
+ setInView(entry.isIntersecting);
13947
+ });
13948
+ observer.observe(node);
13949
+ return () => observer.disconnect();
13950
+ }
13951
+ }, []);
13952
+ return { inView, setRef };
13953
+ };
13954
+
13955
+ const PlaygroundQueryClient = ({ children }) => {
13956
+ const queryClient = new QueryClient();
13957
+ return /* @__PURE__ */ jsx(QueryClientProvider, { client: queryClient, children });
13958
+ };
13959
+
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 };
13367
14224
  //# sourceMappingURL=index.es.js.map