@mastra/playground-ui 6.1.0 → 6.1.1-alpha.0

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 (42) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/index.cjs.js +2950 -1185
  3. package/dist/index.cjs.js.map +1 -1
  4. package/dist/index.css +1477 -0
  5. package/dist/index.es.js +2923 -1190
  6. package/dist/index.es.js.map +1 -1
  7. package/dist/src/components/ui/elements/buttons/button.d.ts +1 -6
  8. package/dist/src/components/ui/elements/date-time-picker/date-picker.d.ts +4 -0
  9. package/dist/src/components/ui/elements/date-time-picker/date-time-picker.d.ts +31 -0
  10. package/dist/src/components/ui/elements/date-time-picker/index.d.ts +1 -0
  11. package/dist/src/components/ui/elements/date-time-picker/time-picker.d.ts +7 -0
  12. package/dist/src/components/ui/elements/entry-list/entry-list-cell.d.ts +5 -1
  13. package/dist/src/components/ui/elements/entry-list/entry-list-item.d.ts +4 -3
  14. package/dist/src/components/ui/elements/entry-list/entry-list.d.ts +5 -3
  15. package/dist/src/components/ui/elements/headers/index.d.ts +1 -0
  16. package/dist/src/components/ui/elements/headers/page-header.d.ts +8 -0
  17. package/dist/src/components/ui/elements/index.d.ts +5 -0
  18. package/dist/src/components/ui/elements/side-dialog/index.d.ts +2 -0
  19. package/dist/src/components/ui/elements/side-dialog/side-dialog-code-section.d.ts +5 -0
  20. package/dist/src/components/ui/elements/side-dialog/side-dialog-heading.d.ts +6 -0
  21. package/dist/src/components/ui/elements/side-dialog/side-dialog-top.d.ts +2 -1
  22. package/dist/src/components/ui/elements/side-dialog/side-dialog.d.ts +3 -1
  23. package/dist/src/components/ui/elements/text/formatters/get-short-id.d.ts +1 -0
  24. package/dist/src/components/ui/elements/text/index.d.ts +2 -0
  25. package/dist/src/components/ui/elements/text/text-and-icon.d.ts +6 -0
  26. package/dist/src/domains/observability/components/helpers.d.ts +17 -0
  27. package/dist/src/domains/observability/components/index.d.ts +6 -0
  28. package/dist/src/domains/observability/components/shared.d.ts +6 -0
  29. package/dist/src/domains/observability/components/span-details.d.ts +4 -0
  30. package/dist/src/domains/observability/components/span-dialog.d.ts +13 -0
  31. package/dist/src/domains/observability/components/trace-dialog.d.ts +13 -0
  32. package/dist/src/domains/observability/components/trace-span-usage.d.ts +12 -0
  33. package/dist/src/domains/observability/components/trace-timeline-legend.d.ts +6 -0
  34. package/dist/src/domains/observability/components/trace-timeline-span.d.ts +12 -0
  35. package/dist/src/domains/observability/components/trace-timeline.d.ts +12 -0
  36. package/dist/src/domains/observability/components/traces-tools.d.ts +17 -0
  37. package/dist/src/domains/observability/index.d.ts +3 -0
  38. package/dist/src/domains/observability/types.d.ts +9 -0
  39. package/dist/src/domains/observability/utils/format-hierarchical-spans.d.ts +3 -0
  40. package/dist/src/index.d.ts +2 -0
  41. package/package.json +4 -4
  42. package/dist/src/components/ui/elements/buttons/button.stories.d.ts +0 -13
package/dist/index.es.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
- import React__default, { createContext, useContext, forwardRef, memo, useState, useEffect, useRef, useCallback, useMemo, Fragment as Fragment$1, Suspense, useId, startTransition } from 'react';
3
+ import React__default, { createContext, useContext, forwardRef, memo, useState, useEffect, useRef, useCallback, useMemo, Fragment as Fragment$1, Suspense, useId, startTransition, isValidElement } from 'react';
4
4
  import { MastraClient } from '@mastra/client-js';
5
5
  import { useMessage, MessagePrimitive, ActionBarPrimitive, useAttachment, AttachmentPrimitive, useComposerRuntime, ComposerPrimitive, useComposer, ThreadPrimitive, CompositeAttachmentAdapter, SimpleImageAttachmentAdapter, SimpleTextAttachmentAdapter, WebSpeechSynthesisAdapter, useExternalStoreRuntime, AssistantRuntimeProvider } from '@assistant-ui/react';
6
- import { CheckIcon as CheckIcon$1, CopyIcon, Check, Copy, ChevronUpIcon, X, Braces, Loader2, Network, ChevronDown, PauseIcon, HourglassIcon, CircleDashed, Footprints, CircleCheck, CircleX, Workflow, AlertCircleIcon, AlertCircle, CalendarIcon, Brackets, PlusIcon, TrashIcon, Plus, ChevronDownIcon, Minus, Maximize, CirclePause, Circle, StopCircle, BrainIcon, AudioLinesIcon, StopCircleIcon, FileText, CircleXIcon, Link, CloudUpload, Mic, ArrowUp, Search, RefreshCcwIcon, ChevronRight, SortAsc, SortDesc, SaveIcon, RefreshCw, ExternalLink, InfoIcon as InfoIcon$1, GaugeIcon, EditIcon, LoaderCircle, ExternalLinkIcon, Users, Brain, NetworkIcon, SearchIcon, TriangleAlertIcon, XIcon, WorkflowIcon as WorkflowIcon$1, PackageIcon, GitBranchIcon, PackageOpenIcon, ArrowRightIcon, OctagonXIcon, AlertTriangleIcon, FrownIcon, ChevronUp } from 'lucide-react';
6
+ import { CheckIcon as CheckIcon$1, CopyIcon, Check, Copy, ChevronUpIcon, X, Braces, Loader2, Network, ChevronDown, PauseIcon, HourglassIcon, CircleDashed, Footprints, CircleCheck, CircleX, Workflow, AlertCircleIcon, AlertCircle, CalendarIcon, Brackets, PlusIcon, TrashIcon, Plus, ChevronDownIcon, Minus, Maximize, CirclePause, Circle, StopCircle, BrainIcon, AudioLinesIcon, StopCircleIcon, FileText, CircleXIcon, Link, CloudUpload, Mic, ArrowUp, Search, RefreshCcwIcon, ChevronRight, SortAsc, SortDesc, SaveIcon, RefreshCw, ExternalLink, InfoIcon as InfoIcon$1, GaugeIcon, EditIcon, LoaderCircle, ExternalLinkIcon, Users, Brain, NetworkIcon, SearchIcon, TriangleAlertIcon, ChevronRightIcon, ArrowLeftIcon, ArrowRightIcon, XIcon, ChevronsRightIcon, ArrowUpIcon, ArrowDownIcon, AlignLeftIcon, AlignJustifyIcon, CircleAlertIcon, WorkflowIcon as WorkflowIcon$1, PackageIcon, GitBranchIcon, PackageOpenIcon, OctagonXIcon, AlertTriangleIcon, FrownIcon, ChevronUp, ChevronsLeftRight, TimerIcon, ChevronsLeftRightIcon, ChevronFirstIcon, ChevronLastIcon, ListTreeIcon, ArrowRightToLineIcon, CoinsIcon, EyeIcon, ChevronsLeftRightEllipsisIcon, PanelTopIcon, HashIcon, PanelLeftIcon } 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';
@@ -13,10 +13,10 @@ import '@assistant-ui/react-markdown/styles/dot.css';
13
13
  import remarkGfm from 'remark-gfm';
14
14
  import { makePrismAsyncLightSyntaxHighlighter } from '@assistant-ui/react-syntax-highlighter';
15
15
  import { coldarkDark } from 'react-syntax-highlighter/dist/cjs/styles/prism';
16
- import { jsonLanguage } from '@codemirror/lang-json';
16
+ import { jsonLanguage, json } from '@codemirror/lang-json';
17
17
  import { tags } from '@lezer/highlight';
18
18
  import { draculaInit } from '@uiw/codemirror-theme-dracula';
19
- import CodeMirror from '@uiw/react-codemirror';
19
+ import CodeMirror, { EditorView } from '@uiw/react-codemirror';
20
20
  import { toast } from 'sonner';
21
21
  import { useDebouncedCallback } from 'use-debounce';
22
22
  import { MarkerType, Handle, Position, useNodesState, useEdgesState, ReactFlow, Controls, MiniMap, Background, BackgroundVariant, ReactFlowProvider, useViewport, useReactFlow, Panel } from '@xyflow/react';
@@ -57,8 +57,10 @@ import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog';
57
57
  import { processDataStream } from '@ai-sdk/ui-utils';
58
58
  import Markdown from 'react-markdown';
59
59
  import { RuntimeContext as RuntimeContext$2 } from '@mastra/core/runtime-context';
60
- import { VisuallyHidden } from '@radix-ui/react-visually-hidden';
60
+ import * as VisuallyHidden from '@radix-ui/react-visually-hidden';
61
+ import { VisuallyHidden as VisuallyHidden$1 } from '@radix-ui/react-visually-hidden';
61
62
  import * as HoverCard from '@radix-ui/react-hover-card';
63
+ import { format as format$1 } from 'date-fns/format';
62
64
  import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
63
65
  import './index.css';export * from '@tanstack/react-query';
64
66
 
@@ -4308,7 +4310,7 @@ function CopyButton({ content, copyMessage, className }) {
4308
4310
  );
4309
4311
  }
4310
4312
 
4311
- const useCodemirrorTheme$1 = () => {
4313
+ const useCodemirrorTheme$2 = () => {
4312
4314
  return useMemo(
4313
4315
  () => draculaInit({
4314
4316
  settings: {
@@ -4326,7 +4328,7 @@ const useCodemirrorTheme$1 = () => {
4326
4328
  };
4327
4329
  const SyntaxHighlighter$2 = ({ data, className }) => {
4328
4330
  const formattedCode = JSON.stringify(data, null, 2);
4329
- const theme = useCodemirrorTheme$1();
4331
+ const theme = useCodemirrorTheme$2();
4330
4332
  return /* @__PURE__ */ jsxs("div", { className: clsx("rounded-md bg-surface4 p-1 font-mono relative", className), children: [
4331
4333
  /* @__PURE__ */ jsx(CopyButton, { content: formattedCode, className: "absolute top-2 right-2" }),
4332
4334
  /* @__PURE__ */ jsx(CodeMirror, { value: formattedCode, theme, extensions: [jsonLanguage] })
@@ -5577,7 +5579,7 @@ const Button$1 = ({ className, as, size = "md", variant = "default", ...props })
5577
5579
  );
5578
5580
  };
5579
5581
 
5580
- const useCodemirrorTheme = () => {
5582
+ const useCodemirrorTheme$1 = () => {
5581
5583
  return useMemo(
5582
5584
  () => draculaInit({
5583
5585
  settings: {
@@ -5595,12 +5597,12 @@ const useCodemirrorTheme = () => {
5595
5597
  };
5596
5598
  const SyntaxHighlighter$1 = ({ data }) => {
5597
5599
  const formattedCode = JSON.stringify(data, null, 2);
5598
- const theme = useCodemirrorTheme();
5600
+ const theme = useCodemirrorTheme$1();
5599
5601
  return /* @__PURE__ */ jsx("div", { className: "rounded-md bg-[#1a1a1a] p-1 font-mono", children: /* @__PURE__ */ jsx(CodeMirror, { value: formattedCode, theme, extensions: [jsonLanguage] }) });
5600
5602
  };
5601
5603
 
5602
5604
  const CodeDialogContent = ({ data }) => {
5603
- const theme = useCodemirrorTheme();
5605
+ const theme = useCodemirrorTheme$1();
5604
5606
  if (typeof data !== "string") {
5605
5607
  return /* @__PURE__ */ jsxs("div", { className: "max-h-[500px] overflow-auto relative p-4", children: [
5606
5608
  /* @__PURE__ */ jsx("div", { className: "absolute right-2 top-2 bg-surface4 rounded-full z-10", children: /* @__PURE__ */ jsx(CopyButton, { content: JSON.stringify(data, null, 2) }) }),
@@ -5658,7 +5660,7 @@ const WorkflowRunEventForm = ({ event, runId, onSendEvent }) => {
5658
5660
  const [eventData, setEventData] = useState("");
5659
5661
  const [isLoading, setIsLoading] = useState(false);
5660
5662
  const [error, setError] = useState(null);
5661
- const theme = useCodemirrorTheme();
5663
+ const theme = useCodemirrorTheme$1();
5662
5664
  const { handleCopy } = useCopyToClipboard({ text: eventData });
5663
5665
  const handleSendEvent = async () => {
5664
5666
  let data;
@@ -6522,7 +6524,7 @@ const PopoverContent = React.forwardRef(({ className, align = "center", sideOffs
6522
6524
  ) }));
6523
6525
  PopoverContent.displayName = PopoverPrimitive.Content.displayName;
6524
6526
 
6525
- const DatePicker = ({
6527
+ const DatePicker$1 = ({
6526
6528
  value,
6527
6529
  setValue,
6528
6530
  children,
@@ -6688,7 +6690,7 @@ const DateField = ({ inputProps, field, error, id }) => {
6688
6690
  }
6689
6691
  }, [field]);
6690
6692
  return /* @__PURE__ */ jsx(
6691
- DatePicker,
6693
+ DatePicker$1,
6692
6694
  {
6693
6695
  id,
6694
6696
  className: error ? "border-destructive" : "",
@@ -6707,7 +6709,7 @@ const DateField = ({ inputProps, field, error, id }) => {
6707
6709
  );
6708
6710
  };
6709
6711
 
6710
- const Select = SelectPrimitive.Root;
6712
+ const Select$1 = SelectPrimitive.Root;
6711
6713
  const SelectValue = SelectPrimitive.Value;
6712
6714
  const SelectTrigger = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
6713
6715
  SelectPrimitive.Trigger,
@@ -6769,7 +6771,7 @@ SelectItem.displayName = SelectPrimitive.Item.displayName;
6769
6771
  const SelectField$1 = ({ field, inputProps, error, id, value }) => {
6770
6772
  const { key, ...props } = inputProps;
6771
6773
  return /* @__PURE__ */ jsxs(
6772
- Select,
6774
+ Select$1,
6773
6775
  {
6774
6776
  ...props,
6775
6777
  onValueChange: (value2) => {
@@ -7807,7 +7809,7 @@ const JSONInput = ({ schema, defaultValues, isSubmitLoading, submitButtonLabel,
7807
7809
  ] });
7808
7810
  };
7809
7811
  const SyntaxHighlighter = ({ data, onChange }) => {
7810
- const theme = useCodemirrorTheme$1();
7812
+ const theme = useCodemirrorTheme$2();
7811
7813
  return /* @__PURE__ */ jsxs("div", { className: "rounded-md bg-[#1a1a1a] p-1 font-mono", children: [
7812
7814
  /* @__PURE__ */ jsx(CopyButton, { content: data, className: "absolute top-2 right-2 z-10" }),
7813
7815
  /* @__PURE__ */ jsx(CodeMirror, { value: data, theme, extensions: [jsonLanguage], onChange })
@@ -10690,7 +10692,7 @@ const AgentAdvancedSettings = () => {
10690
10692
  const [providerOptionsValue, setProviderOptionsValue] = useState("");
10691
10693
  const [saved, setSaved] = useState(false);
10692
10694
  const [error, setError] = useState(null);
10693
- const theme = useCodemirrorTheme();
10695
+ const theme = useCodemirrorTheme$1();
10694
10696
  const { handleCopy } = useCopyToClipboard({ text: providerOptionsValue });
10695
10697
  const providerOptionsStr = JSON.stringify(settings?.modelSettings?.providerOptions ?? {});
10696
10698
  useEffect(() => {
@@ -11530,7 +11532,7 @@ const EmptyAgentsTable = () => /* @__PURE__ */ jsx("div", { className: "flex h-f
11530
11532
  const RuntimeContext = () => {
11531
11533
  const { runtimeContext, setRuntimeContext } = usePlaygroundStore();
11532
11534
  const [runtimeContextValue, setRuntimeContextValue] = useState("");
11533
- const theme = useCodemirrorTheme();
11535
+ const theme = useCodemirrorTheme$1();
11534
11536
  const { handleCopy } = useCopyToClipboard({ text: runtimeContextValue });
11535
11537
  const runtimeContextStr = JSON.stringify(runtimeContext);
11536
11538
  useEffect(() => {
@@ -11999,7 +12001,7 @@ const AgentMetadataModelSwitcher = ({
11999
12001
  const filteredModels = allModels.filter((model2) => model2.model.includes(selectedModel));
12000
12002
  return /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
12001
12003
  /* @__PURE__ */ jsxs(
12002
- Select,
12004
+ Select$1,
12003
12005
  {
12004
12006
  value: model?.provider ?? selectedProvider,
12005
12007
  onValueChange: setSelectedProvider,
@@ -14034,7 +14036,7 @@ function InputField({
14034
14036
  ...props
14035
14037
  }) {
14036
14038
  const LabelWrapper = ({ children }) => {
14037
- return labelIsHidden ? /* @__PURE__ */ jsx(VisuallyHidden, { children }) : children;
14039
+ return labelIsHidden ? /* @__PURE__ */ jsx(VisuallyHidden$1, { children }) : children;
14038
14040
  };
14039
14041
  return /* @__PURE__ */ jsxs(
14040
14042
  "div",
@@ -14067,10 +14069,11 @@ function InputField({
14067
14069
  value,
14068
14070
  className: cn(
14069
14071
  "flex grow items-center cursor-pointer text-[0.875rem] text-[rgba(255,255,255,0.8)] border border-[rgba(255,255,255,0.15)] leading-none rounded-lg bg-transparent min-h-[2.5rem] px-[0.75rem] py-[0.5rem] w-full",
14072
+ "focus:outline-none focus:shadow-[inset_0_0_0_1px_#18fb6f]",
14070
14073
  "placeholder:text-icon3 placeholder:text-[.8125rem]",
14071
14074
  {
14072
14075
  "cursor-not-allowed opacity-50": disabled,
14073
- "border-red-800": error || errorMsg
14076
+ "border-red-800 focus:border-[rgba(255,255,255,0.15)]": error || errorMsg
14074
14077
  }
14075
14078
  ),
14076
14079
  "data-testid": testId,
@@ -14124,6 +14127,7 @@ function TextareaField({
14124
14127
  {
14125
14128
  className: cn(
14126
14129
  "flex w-full items-center leading-[1.6] text-[0.875rem] text-[rgba(255,255,255,0.7)] border border-[rgba(255,255,255,0.15)] rounded-lg bg-transparent py-[0.5rem] px-[0.75rem] min-h-[6rem]",
14130
+ "focus:outline-none focus:shadow-[inset_0_0_0_1px_#18fb6f]",
14127
14131
  { "cursor-not-allowed opacity-50": disabled }
14128
14132
  ),
14129
14133
  "data-testid": testId,
@@ -14137,28 +14141,32 @@ function TextareaField({
14137
14141
  );
14138
14142
  }
14139
14143
 
14140
- const Button = ({ className, as, variant = "outline", ...props }) => {
14141
- const Component = as || "button";
14142
- return /* @__PURE__ */ jsx(
14143
- Component,
14144
- {
14145
- className: cn(
14146
- "text-[.875rem] inline-flex items-center justify-center rounded-lg px-[1rem] gap-[.75rem] leading-0 border bg-transparent text-[rgba(255,255,255,0.7)]",
14147
- "[&:not(:disabled):hover]:border-[rgba(255,255,255,0.25)] [&:not(:disabled):hover]:text-[rgba(255,255,255,0.9)]",
14148
- "[&>svg]:w-[1em] [&>svg]:h-[1em] [&>svg]:mx-[-0.3em] [&>svg]:opacity-70",
14149
- className,
14150
- {
14151
- "cursor-not-allowed opacity-50": props.disabled,
14152
- "bg-ui-primaryBtnBg text-ui-primaryBtnText hover:bg-surface6 leading-[0] font-semibold": variant === "primary",
14153
- "min-h-[2rem]": variant === "ghost",
14154
- "min-h-[2.5rem]": variant !== "ghost",
14155
- "border-[rgba(255,255,255,0.15)]": variant === "outline"
14156
- }
14157
- ),
14158
- ...props
14159
- }
14160
- );
14161
- };
14144
+ const Button = React__default.forwardRef(
14145
+ ({ className, variant = "outline", ...props }, ref) => {
14146
+ return /* @__PURE__ */ jsx(
14147
+ "button",
14148
+ {
14149
+ ref,
14150
+ className: cn(
14151
+ "text-[.875rem] inline-flex items-center justify-center rounded-lg px-[1rem] gap-[.75rem] leading-0 border bg-transparent text-[rgba(255,255,255,0.7)] whitespace-nowrap",
14152
+ "[&:not(:disabled):hover]:border-[rgba(255,255,255,0.25)] [&:not(:disabled):hover]:text-[rgba(255,255,255,0.9)]",
14153
+ "[&>svg]:w-[1em] [&>svg]:h-[1em] [&>svg]:mx-[-0.3em] [&>svg]:opacity-70 [&>svg]:shrink-0",
14154
+ "focus:outline-none focus:shadow-[inset_0_0_0_1px_rgba(24,251,111,0.75)]",
14155
+ className,
14156
+ {
14157
+ "cursor-not-allowed opacity-50": props.disabled,
14158
+ "bg-ui-primaryBtnBg text-ui-primaryBtnText hover:bg-surface6 leading-[0] font-semibold": variant === "primary",
14159
+ "min-h-[2rem]": variant === "ghost",
14160
+ "min-h-[2.5rem]": variant !== "ghost",
14161
+ "border-[rgba(255,255,255,0.15)]": variant === "outline"
14162
+ }
14163
+ ),
14164
+ ...props
14165
+ }
14166
+ );
14167
+ }
14168
+ );
14169
+ Button.displayName = "Button";
14162
14170
 
14163
14171
  function FormActions({
14164
14172
  children,
@@ -14206,7 +14214,7 @@ function SelectField({
14206
14214
  "div",
14207
14215
  {
14208
14216
  className: cn(
14209
- "flex gap-[.5rem]",
14217
+ "flex gap-[.5rem] items-center",
14210
14218
  {
14211
14219
  "grid-rows-[auto_1fr]": label,
14212
14220
  "grid-rows-[auto_1fr_auto]": helpMsg
@@ -14218,18 +14226,19 @@ function SelectField({
14218
14226
  label,
14219
14227
  required && /* @__PURE__ */ jsx("i", { className: "text-icon2", children: "(required)" })
14220
14228
  ] }),
14221
- /* @__PURE__ */ jsxs(Select, { name, value, onValueChange, disabled, children: [
14229
+ /* @__PURE__ */ jsxs(Select$1, { name, value, onValueChange, disabled, children: [
14222
14230
  /* @__PURE__ */ jsx(
14223
14231
  SelectTrigger,
14224
14232
  {
14225
14233
  id: "select-dataset",
14226
14234
  className: cn(
14227
- "w-full border border-[rgba(255,255,255,0.15)] rounded-lg min-h-[2.5rem] min-w-[5rem] gap-[0.5rem]"
14235
+ "w-full border border-[rgba(255,255,255,0.15)] rounded-lg min-h-[2.5rem] min-w-[5rem] gap-[0.5rem]",
14236
+ "focus:outline-none focus:shadow-[inset_0_0_0_1px_rgba(24,251,111,0.75)]"
14228
14237
  ),
14229
14238
  children: /* @__PURE__ */ jsx(SelectValue, { placeholder })
14230
14239
  }
14231
14240
  ),
14232
- /* @__PURE__ */ jsx(SelectContent, { children: options.map((option) => /* @__PURE__ */ jsx(SelectItem, { value: option.value, children: option.label }, option.label)) })
14241
+ /* @__PURE__ */ jsx(SelectContent, { children: options.map((option) => /* @__PURE__ */ jsx(SelectItem, { value: option.value, children: /* @__PURE__ */ jsx("span", { className: "whitespace-nowrap truncate block", children: option.label }) }, option.label)) })
14233
14242
  ] }),
14234
14243
  helpMsg && /* @__PURE__ */ jsx("p", { className: "text-icon3 text-[0.75rem]", children: helpMsg })
14235
14244
  ]
@@ -14276,7 +14285,7 @@ function SliderField({
14276
14285
  ...props,
14277
14286
  children: [
14278
14287
  /* @__PURE__ */ jsx(SliderPrimitive.Track, { className: "relative h-[4px] w-full grow overflow-hidden rounded-full bg-gray-600", children: /* @__PURE__ */ jsx(SliderPrimitive.Range, { className: "absolute h-full bg-gray-400" }) }),
14279
- /* @__PURE__ */ jsx(SliderPrimitive.Thumb, { className: "block h-4 w-4 rounded-full bg-gray-400 shadow transition-colors disabled:pointer-events-none disabled:opacity-50" })
14288
+ /* @__PURE__ */ jsx(SliderPrimitive.Thumb, { className: "block h-4 w-4 rounded-full bg-gray-400 shadow transition-colors focus:outline-none focus:bg-[#18fb6f] disabled:pointer-events-none disabled:opacity-50" })
14280
14289
  ]
14281
14290
  }
14282
14291
  ),
@@ -14356,7 +14365,7 @@ function RadioGroupField({
14356
14365
  /* @__PURE__ */ jsx(
14357
14366
  RadioGroupPrimitive.Item,
14358
14367
  {
14359
- className: "aspect-square h-4 w-4 rounded-full border border-primary text-primary disabled:cursor-not-allowed disabled:opacity-50 ",
14368
+ className: "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 ",
14360
14369
  value: option.value,
14361
14370
  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" }) })
14362
14371
  }
@@ -14392,7 +14401,7 @@ function RadioGroupField({
14392
14401
  function KeyValueList({ data, LinkComponent, className, labelsAreHidden, isLoading }) {
14393
14402
  const { Link } = useLinkComponent();
14394
14403
  const LabelWrapper = ({ children }) => {
14395
- return labelsAreHidden ? /* @__PURE__ */ jsx(VisuallyHidden, { children }) : children;
14404
+ return labelsAreHidden ? /* @__PURE__ */ jsx(VisuallyHidden$1, { children }) : children;
14396
14405
  };
14397
14406
  if (!data || data.length === 0) {
14398
14407
  return null;
@@ -14433,7 +14442,8 @@ function KeyValueList({ data, LinkComponent, className, labelsAreHidden, isLoadi
14433
14442
  className: cn(
14434
14443
  "flex flex-wrap gap-[.5rem] py-[0.25rem] min-h-[2.25rem] text-[0.875rem] items-center text-icon5 text-wrap",
14435
14444
  "[&>a]:text-icon5 [&>a]:max-w-full [&>a]:w-auto truncate [&>a]:bg-[#222] [&>a]:transition-colors [&>a]:flex [&>a]:items-center [&>a]:gap-[0.5rem] [&>a]:pt-[0.15rem] [&>a]:pb-[0.2rem] [&>a]:px-[.5rem] [&>a]:rounded-md [&>a]:text-[0.875rem] [&>a]:min-h-[1.75rem] [&>a]:leading-0 ",
14436
- "[&>a:hover]:text-icon6 [&>a:hover]:bg-surface6"
14445
+ "[&>a:hover]:text-icon6 [&>a:hover]:bg-surface6",
14446
+ "[&>a>svg]:w-[1em] [&>a>svg]:h-[1em] [&>a>svg]:text-icon3 [&>a>svg]:ml-[-0.5em]"
14437
14447
  ),
14438
14448
  children: isLoading ? /* @__PURE__ */ jsx(
14439
14449
  "span",
@@ -14443,7 +14453,11 @@ function KeyValueList({ data, LinkComponent, className, labelsAreHidden, isLoadi
14443
14453
  children: " "
14444
14454
  }
14445
14455
  ) : /* @__PURE__ */ jsx(Fragment, { children: isValueItemArray ? value?.map((item) => {
14446
- return item.path ? /* @__PURE__ */ jsx(RelationWrapper, { description: item.description, children: /* @__PURE__ */ jsx(Link, { href: item.path, children: item?.name }) }, item.id) : /* @__PURE__ */ jsx("span", { children: item?.name }, item.id);
14456
+ return item.path ? /* @__PURE__ */ jsx(RelationWrapper, { description: item.description, children: /* @__PURE__ */ jsxs(Link, { href: item.path, children: [
14457
+ item?.name,
14458
+ " ",
14459
+ /* @__PURE__ */ jsx(ChevronRightIcon, {})
14460
+ ] }) }, item.id) : /* @__PURE__ */ jsx("span", { children: item?.name }, item.id);
14447
14461
  }) : /* @__PURE__ */ jsx(Fragment, { children: value ? value : /* @__PURE__ */ jsx("span", { className: "text-icon3 text-[0.75rem]", children: "n/a" }) }) })
14448
14462
  }
14449
14463
  )
@@ -14468,784 +14482,1659 @@ function RelationWrapper({ description, children }) {
14468
14482
  ] }) : children;
14469
14483
  }
14470
14484
 
14471
- function TemplatesTools({
14472
- tagOptions,
14473
- selectedTag,
14474
- providerOptions,
14475
- selectedProvider,
14476
- onTagChange,
14477
- onProviderChange,
14478
- searchTerm,
14479
- onSearchChange,
14480
- onReset,
14481
- className,
14482
- isLoading
14483
- }) {
14484
- if (isLoading) {
14485
- return /* @__PURE__ */ jsxs(
14485
+ function EntryListTextCell({ children, isLoading }) {
14486
+ const randomWidth = useMemo(() => {
14487
+ return Math.floor(Math.random() * (90 - 50 + 1)) + 50;
14488
+ }, []);
14489
+ return /* @__PURE__ */ jsx("div", { className: "text-icon4 text-[0.875rem] truncate ", children: isLoading ? /* @__PURE__ */ jsx(
14490
+ "div",
14491
+ {
14492
+ className: "bg-surface4 rounded-md animate-pulse text-transparent h-[1rem] select-none",
14493
+ style: { width: `${randomWidth}%` }
14494
+ }
14495
+ ) : children });
14496
+ }
14497
+ function EntryListStatusCell({ status }) {
14498
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex justify-center items-center w-full relative"), children: [
14499
+ status ? /* @__PURE__ */ jsx(
14486
14500
  "div",
14487
14501
  {
14488
- className: cn(
14489
- "h-[6.5rem] flex items-center gap-[2rem]",
14490
- "[&>div]:bg-surface3 [&>div]:w-[12rem] [&>div]:h-[2rem] [&>div]:animate-pulse",
14491
- className
14492
- ),
14493
- children: [
14494
- /* @__PURE__ */ jsx("div", {}),
14495
- " ",
14496
- /* @__PURE__ */ jsx("div", {}),
14497
- " ",
14498
- /* @__PURE__ */ jsx("div", {})
14499
- ]
14502
+ className: cn("w-[0.6rem] h-[0.6rem] rounded-full", {
14503
+ "bg-green-600": status === "success",
14504
+ "bg-red-700": status === "failed"
14505
+ })
14500
14506
  }
14501
- );
14507
+ ) : /* @__PURE__ */ jsx("div", { className: "text-icon2 text-[0.75rem] leading-none", children: "-" }),
14508
+ /* @__PURE__ */ jsxs(VisuallyHidden$1, { children: [
14509
+ "Status: ",
14510
+ status ? status : "not provided"
14511
+ ] })
14512
+ ] });
14513
+ }
14514
+
14515
+ function getColumnTemplate(columns) {
14516
+ if (!columns || columns.length === 0) {
14517
+ return "";
14502
14518
  }
14503
- return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-wrap mx-auto sticky top-0 gap-[2rem] bg-surface2 py-[2rem]", className), children: [
14504
- /* @__PURE__ */ jsx(
14505
- SearchField,
14506
- {
14507
- label: "Search templates",
14508
- value: searchTerm,
14509
- onChange: (e) => onSearchChange?.(e.target.value),
14510
- placeholder: "Search Template"
14511
- }
14512
- ),
14513
- /* @__PURE__ */ jsx(SelectField, { label: "Filter by tag", value: selectedTag, onValueChange: onTagChange, options: tagOptions }),
14514
- /* @__PURE__ */ jsx(
14515
- SelectField,
14519
+ return columns?.map((column) => {
14520
+ return column.size;
14521
+ }).join(" ");
14522
+ }
14523
+
14524
+ function EntryListItem({
14525
+ item,
14526
+ selectedItemId,
14527
+ onClick,
14528
+ children,
14529
+ columns,
14530
+ isLoading
14531
+ }) {
14532
+ const isSelected = selectedItemId === item.id;
14533
+ const handleClick = () => {
14534
+ return onClick && onClick(item?.id);
14535
+ };
14536
+ return /* @__PURE__ */ jsx(
14537
+ "li",
14538
+ {
14539
+ className: cn("border-b text-[#ccc] border-border1 last:border-b-0 text-[0.875rem]", {
14540
+ "bg-surface5": isSelected
14541
+ }),
14542
+ children: /* @__PURE__ */ jsx(
14543
+ "button",
14544
+ {
14545
+ onClick: handleClick,
14546
+ className: cn("grid w-full px-[1.5rem] gap-[2rem] text-left items-center min-h-[3rem]", {
14547
+ "hover:bg-surface5": !isLoading
14548
+ }),
14549
+ style: { gridTemplateColumns: getColumnTemplate(columns) },
14550
+ disabled: isLoading,
14551
+ children
14552
+ }
14553
+ )
14554
+ }
14555
+ );
14556
+ }
14557
+
14558
+ function EntryList({
14559
+ items: dataItems,
14560
+ selectedItemId,
14561
+ onItemClick,
14562
+ isLoading,
14563
+ isLoadingNextPage,
14564
+ total,
14565
+ page,
14566
+ hasMore,
14567
+ onNextPage,
14568
+ onPrevPage,
14569
+ perPage,
14570
+ columns,
14571
+ searchTerm,
14572
+ setEndOfListElement
14573
+ }) {
14574
+ const loadingItems = Array.from({ length: 3 }).map((_, index) => {
14575
+ return {
14576
+ id: `loading-${index + 1}`,
14577
+ ...(columns || []).reduce(
14578
+ (acc, col) => {
14579
+ acc[col.name] = `...`;
14580
+ return acc;
14581
+ },
14582
+ {}
14583
+ )
14584
+ };
14585
+ });
14586
+ const items = isLoading ? loadingItems : dataItems;
14587
+ return /* @__PURE__ */ jsxs("div", { className: "grid mb-[3rem]", children: [
14588
+ /* @__PURE__ */ jsx("div", { className: cn("sticky top-0 bg-surface4 z-[1] rounded-t-lg border border-border1 px-[1.5rem]"), children: /* @__PURE__ */ jsx(
14589
+ "div",
14516
14590
  {
14517
- label: "Filter by provider",
14518
- value: selectedProvider,
14519
- onValueChange: onProviderChange,
14520
- options: providerOptions
14591
+ className: cn("grid gap-[2rem] text-left uppercase py-[.75rem] text-icon3 text-[0.75rem]"),
14592
+ style: { gridTemplateColumns: getColumnTemplate(columns) },
14593
+ children: columns?.map((col) => /* @__PURE__ */ jsx("span", { children: col.label || col.name }, col.name))
14521
14594
  }
14522
- ),
14523
- onReset && /* @__PURE__ */ jsxs(Button, { onClick: onReset, children: [
14524
- "Reset ",
14525
- /* @__PURE__ */ jsx(XIcon, {})
14595
+ ) }),
14596
+ !isLoading && items?.length === 0 && /* @__PURE__ */ jsx("div", { className: "grid border border-border1 border-t-0 bg-surface3 rounded-xl rounded-t-none", children: /* @__PURE__ */ jsx("p", { className: "text-icon3 text-[0.875rem] text-center h-[3.5rem] items-center flex justify-center", children: searchTerm ? `No results found for "${searchTerm}"` : "No entries found" }) }),
14597
+ items?.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
14598
+ /* @__PURE__ */ jsx("ul", { className: "grid border border-border1 border-t-0 bg-surface3 rounded-xl rounded-t-none overflow-y-auto", children: items.map((item) => {
14599
+ return /* @__PURE__ */ jsx(
14600
+ EntryListItem,
14601
+ {
14602
+ item,
14603
+ selectedItemId,
14604
+ onClick: isLoading ? void 0 : onItemClick,
14605
+ columns,
14606
+ isLoading,
14607
+ children: (columns || []).map((col) => {
14608
+ const isValidReactElement = isValidElement(item?.[col.name]);
14609
+ return isValidReactElement ? item?.[col.name] : /* @__PURE__ */ jsx(EntryListTextCell, { isLoading, children: item?.[col.name] }, col.name);
14610
+ })
14611
+ },
14612
+ item.id
14613
+ );
14614
+ }) }),
14615
+ setEndOfListElement && /* @__PURE__ */ jsxs(
14616
+ "div",
14617
+ {
14618
+ ref: setEndOfListElement,
14619
+ className: "text-[0.875rem] text-icon3 opacity-50 flex mt-[2rem] justify-center",
14620
+ children: [
14621
+ isLoadingNextPage && "Loading...",
14622
+ !hasMore && !isLoadingNextPage && !isLoading && "No more data to load"
14623
+ ]
14624
+ }
14625
+ ),
14626
+ typeof page === "number" && typeof perPage === "number" && typeof total === "number" && /* @__PURE__ */ jsxs("div", { className: cn("flex items-center justify-center text-icon3 text-[0.875rem] gap-[2rem]"), children: [
14627
+ /* @__PURE__ */ jsxs("span", { children: [
14628
+ "Page ",
14629
+ page ? page + 1 : "1"
14630
+ ] }),
14631
+ /* @__PURE__ */ jsxs(
14632
+ "div",
14633
+ {
14634
+ className: cn(
14635
+ "flex gap-[1rem]",
14636
+ "[&>button]:flex [&>button]:items-center [&>button]:gap-[0.5rem] [&>button]:text-icon4 [&>button:hover]:text-icon5 [&>button]:transition-colors [&>button]:border [&>button]:border-border1 [&>button]:p-[0.25rem] [&>button]:px-[0.5rem] [&>button]:rounded-md",
14637
+ " [&_svg]:w-[1em] [&_svg]:h-[1em] [&_svg]:text-icon3"
14638
+ ),
14639
+ children: [
14640
+ typeof page === "number" && page > 0 && /* @__PURE__ */ jsxs("button", { onClick: onPrevPage, disabled: page === 0, children: [
14641
+ /* @__PURE__ */ jsx(ArrowLeftIcon, {}),
14642
+ "Previous"
14643
+ ] }),
14644
+ hasMore && /* @__PURE__ */ jsxs("button", { onClick: onNextPage, disabled: !hasMore, children: [
14645
+ "Next",
14646
+ /* @__PURE__ */ jsx(ArrowRightIcon, {})
14647
+ ] })
14648
+ ]
14649
+ }
14650
+ )
14651
+ ] })
14526
14652
  ] })
14527
14653
  ] });
14528
14654
  }
14529
14655
 
14530
- function getRepoName(githubUrl) {
14531
- return githubUrl.replace(/\/$/, "").split("/").pop();
14532
- }
14533
- function Container({ children, className }) {
14656
+ function EntryListToolbar({ children, className }) {
14534
14657
  return /* @__PURE__ */ jsx(
14658
+ "div",
14659
+ {
14660
+ className: cn("flex justify-between bg-surface4 z-[1] mt-[1rem] mb-[1rem] rounded-lg px-[1.5rem] ", className),
14661
+ children
14662
+ }
14663
+ );
14664
+ }
14665
+
14666
+ function EntryListPageHeader({ title, description, icon, children }) {
14667
+ return /* @__PURE__ */ jsxs(
14535
14668
  "div",
14536
14669
  {
14537
14670
  className: cn(
14538
- "border border-border1 rounded-lg mt-[3rem] py-[2rem] lg:min-h-[25rem] transition-height px-[1rem] lg:px-[3rem]",
14539
- className
14671
+ "grid z-[1] top-0 gap-y-[0.5rem] text-icon4 bg-surface2 py-[3rem]",
14672
+ "3xl:h-full 3xl:content-start 3xl:grid-rows-[auto_1fr] h-full 3xl:overflow-y-auto"
14540
14673
  ),
14541
- children
14674
+ children: [
14675
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-[1rem] w", children: [
14676
+ /* @__PURE__ */ jsxs("div", { className: cn("flex gap-[.75em] items-center", "[&>svg]:w-[1.1em] [&>svg]:h-[1.1em] [&>svg]:text-icon4"), children: [
14677
+ icon,
14678
+ /* @__PURE__ */ jsx("h1", { className: "text-icon6 text-[1.25rem]", children: title })
14679
+ ] }),
14680
+ /* @__PURE__ */ jsx("p", { className: "m-0 text-[0.875rem]", children: description })
14681
+ ] }),
14682
+ children
14683
+ ]
14542
14684
  }
14543
14685
  );
14544
14686
  }
14545
14687
 
14546
- function TemplatesList({ templates, linkComponent, className, isLoading }) {
14547
- const LinkComponent = linkComponent || "a";
14548
- if (isLoading) {
14549
- return /* @__PURE__ */ jsx("div", { className: cn("grid gap-y-[1rem]", className), children: Array.from({ length: 5 }).map((_, index) => /* @__PURE__ */ jsx("div", { className: "h-[4rem] bg-surface3 animate-pulse rounded-lg" }, index)) });
14550
- }
14551
- return /* @__PURE__ */ jsx("div", { className: cn("grid gap-y-[1rem]", className), children: templates.map((template) => {
14552
- const hasMetaInfo = template?.agents || template?.tools || template?.networks || template?.workflows || template?.mcp;
14553
- return /* @__PURE__ */ jsxs(
14554
- "article",
14688
+ function SideDialog({
14689
+ dialogTitle,
14690
+ dialogDescription,
14691
+ isOpen,
14692
+ onClose,
14693
+ children,
14694
+ variant = "default",
14695
+ hasCloseButton = true,
14696
+ className
14697
+ }) {
14698
+ const isConfirmation = variant === "confirmation";
14699
+ return /* @__PURE__ */ jsx(DialogPrimitive.Root, { open: isOpen, onOpenChange: onClose, children: /* @__PURE__ */ jsxs(DialogPrimitive.Portal, { children: [
14700
+ !isConfirmation && /* @__PURE__ */ jsx(DialogPrimitive.Overlay, { className: cn("bg-black top-0 bottom-0 right-0 left-0 fixed z-50 opacity-[0.25]") }),
14701
+ /* @__PURE__ */ jsxs(
14702
+ DialogPrimitive.Content,
14555
14703
  {
14556
14704
  className: cn(
14557
- "border border-border1 rounded-lg overflow-hidden w-full grid grid-cols-[1fr_auto] bg-surface3 transition-colors hover:bg-surface4"
14705
+ "fixed top-0 bottom-0 right-0 border-l border-border1 z-50 bg-surface4",
14706
+ "w-[calc(100vw-20rem)] max-w-[50rem]",
14707
+ "3xl:max-w-[60rem]",
14708
+ "4xl:max-w-[50%]",
14709
+ "data-[state=closed]:animate-out data-[state=closed]:fade-out-0",
14710
+ {
14711
+ "data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:slide-in-from-right-1/4": !isConfirmation,
14712
+ "bg-surface2/70": isConfirmation
14713
+ },
14714
+ className
14558
14715
  ),
14559
14716
  children: [
14560
- /* @__PURE__ */ jsxs(
14561
- LinkComponent,
14717
+ /* @__PURE__ */ jsxs(VisuallyHidden.Root, { children: [
14718
+ /* @__PURE__ */ jsx(DialogPrimitive.Title, { children: dialogTitle }),
14719
+ /* @__PURE__ */ jsx(DialogPrimitive.Description, { children: dialogDescription })
14720
+ ] }),
14721
+ !isConfirmation && hasCloseButton && /* @__PURE__ */ jsx(DialogPrimitive.Close, { asChild: true, children: /* @__PURE__ */ jsx(
14722
+ "button",
14562
14723
  {
14563
- to: `/templates/${template.slug}`,
14564
- className: cn("grid [&:hover_p]:text-icon5", {
14565
- "grid-cols-[8rem_1fr] lg:grid-cols-[12rem_1fr]": template.imageURL
14724
+ className: cn(
14725
+ "flex appearance-none items-center justify-center rounded-bl-lg h-[3.5rem] w-[3.5rem] absolute too-0 left-[-3.5rem] bg-surface4 text-icon4 border-l border-b border-border1",
14726
+ "hover:surface5 hover:text-icon5"
14727
+ ),
14728
+ "aria-label": "Close",
14729
+ children: isConfirmation ? /* @__PURE__ */ jsx(XIcon, {}) : /* @__PURE__ */ jsx(ChevronsRightIcon, {})
14730
+ }
14731
+ ) }),
14732
+ /* @__PURE__ */ jsx(
14733
+ "div",
14734
+ {
14735
+ className: cn("grid h-full", {
14736
+ "grid-rows-[auto_1fr]": !isConfirmation
14566
14737
  }),
14567
- children: [
14568
- template.imageURL && /* @__PURE__ */ jsx("div", { className: cn("relative overflow-hidden"), children: /* @__PURE__ */ jsx(
14569
- "div",
14570
- {
14571
- className: "w-full h-full bg-cover thumb transition-scale duration-150",
14572
- style: {
14573
- backgroundImage: `url(${template.imageURL})`
14574
- }
14575
- }
14576
- ) }),
14577
- /* @__PURE__ */ jsxs(
14578
- "div",
14579
- {
14580
- className: cn(
14581
- "grid py-[.75rem] px-[1.5rem] w-full gap-[0.1rem]",
14582
- "[&_svg]:w-[1em] [&_svg]:h-[1em] [&_svg]:text-icon3"
14583
- ),
14584
- children: [
14585
- /* @__PURE__ */ jsx("h2", { className: "text-[1rem] text-icon5", children: template.title }),
14586
- /* @__PURE__ */ jsx("p", { className: "text-[0.875rem] text-icon4 transition-colors duration-500", children: template.description }),
14587
- /* @__PURE__ */ jsxs("div", { className: "hidden 2xl:flex text-icon3 text-[0.875rem] flex-wrap items-center gap-[1rem] mt-[0.75rem]", children: [
14588
- hasMetaInfo && /* @__PURE__ */ jsxs(
14589
- "ul",
14590
- {
14591
- className: cn(
14592
- "flex gap-[1rem] text-[0.875rem] text-icon3 m-0 p-0 list-none",
14593
- "[&>li]:flex [&>li]:items-center [&>li]:gap-[0.1rem] text-icon4"
14594
- ),
14595
- children: [
14596
- template?.agents && template.agents.length > 0 && /* @__PURE__ */ jsxs("li", { children: [
14597
- /* @__PURE__ */ jsx(AgentIcon, {}),
14598
- " ",
14599
- template.agents.length
14600
- ] }),
14601
- template?.tools && template.tools.length > 0 && /* @__PURE__ */ jsxs("li", { children: [
14602
- /* @__PURE__ */ jsx(ToolsIcon, {}),
14603
- " ",
14604
- template.tools.length
14605
- ] }),
14606
- template?.networks && template.networks.length > 0 && /* @__PURE__ */ jsxs("li", { children: [
14607
- /* @__PURE__ */ jsx(NetworkIcon, {}),
14608
- " ",
14609
- template.networks.length
14610
- ] }),
14611
- template?.workflows && template.workflows.length > 0 && /* @__PURE__ */ jsxs("li", { children: [
14612
- /* @__PURE__ */ jsx(WorkflowIcon$1, {}),
14613
- " ",
14614
- template.workflows.length
14615
- ] }),
14616
- template?.mcp && template.mcp.length > 0 && /* @__PURE__ */ jsxs("li", { children: [
14617
- /* @__PURE__ */ jsx(McpServerIcon, {}),
14618
- " ",
14619
- template.mcp.length
14620
- ] })
14621
- ]
14622
- }
14623
- ),
14624
- hasMetaInfo && template.supportedProviders && /* @__PURE__ */ jsx("small", { children: "|" }),
14625
- /* @__PURE__ */ jsx("div", { className: "flex items-center text-icon3 gap-[1rem]", children: template.supportedProviders.map((provider) => /* @__PURE__ */ jsx("span", { className: "", children: provider }, provider)) })
14626
- ] })
14627
- ]
14628
- }
14629
- )
14630
- ]
14631
- }
14632
- ),
14633
- /* @__PURE__ */ jsx(
14634
- "a",
14635
- {
14636
- href: template.githubUrl,
14637
- className: cn("group items-center gap-[0.5rem] text-[0.875rem] ml-auto pr-[1rem] hidden", "lg:flex"),
14638
- target: "_blank",
14639
- rel: "noopener noreferrer",
14640
- children: /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-[0.5rem] px-[0.5rem] py-[0.25rem] rounded bg-surface1 group-hover:bg-surface2 text-icon3 transition-colors group-hover:text-icon5 ", children: [
14641
- /* @__PURE__ */ jsx(GithubIcon, {}),
14642
- " ",
14643
- getRepoName(template.githubUrl)
14644
- ] })
14738
+ children
14645
14739
  }
14646
14740
  )
14647
14741
  ]
14648
- },
14649
- template.slug
14650
- );
14651
- }) });
14742
+ }
14743
+ )
14744
+ ] }) });
14652
14745
  }
14653
14746
 
14654
- function TemplateInfo({
14655
- title,
14656
- description,
14657
- imageURL,
14658
- githubUrl,
14659
- isLoading,
14660
- infoData,
14661
- templateSlug
14662
- }) {
14663
- const branchName = templateSlug ? `feat/install-template-${templateSlug}` : "feat/install-template-[slug]";
14664
- return /* @__PURE__ */ jsxs(Fragment, { children: [
14665
- /* @__PURE__ */ jsxs("div", { className: cn("grid lg:grid-cols-[1fr_1fr] gap-x-[6rem] mt-[2rem] lg:min-h-[4rem] items-center "), children: [
14666
- /* @__PURE__ */ jsxs(
14667
- "div",
14747
+ function SideDialogHeader({ children, className }) {
14748
+ return /* @__PURE__ */ jsx("div", { className: cn("flex justify-between items-center pb-[1rem]", className), children });
14749
+ }
14750
+
14751
+ function SideDialogFooter({ children, onNext, onPrevious, showInnerNav }) {
14752
+ const handleOnNext = () => {
14753
+ onNext?.();
14754
+ };
14755
+ const handleOnPrevious = () => {
14756
+ onPrevious?.();
14757
+ };
14758
+ return /* @__PURE__ */ jsxs(
14759
+ "div",
14760
+ {
14761
+ className: cn(
14762
+ "flex items-center justify-end gap-[1rem] px-[1.5rem] py-[1rem] min-h-[4rem] border-t border-border1",
14668
14763
  {
14669
- className: cn(
14670
- "text-[1.5rem] flex items-center gap-[0.75rem] ",
14671
- "[&>svg]:w-[1.2em] [&>svg]:h-[1.2em] [&>svg]:opacity-50",
14672
- {
14673
- "[&>svg]:opacity-20": isLoading
14674
- }
14675
- ),
14676
- children: [
14677
- /* @__PURE__ */ jsx(PackageIcon, {}),
14678
- /* @__PURE__ */ jsx(
14679
- "h2",
14680
- {
14681
- className: cn({
14682
- "bg-surface4 flex rounded-lg min-w-[50%]": isLoading
14683
- }),
14684
- children: isLoading ? /* @__PURE__ */ jsx(Fragment, { children: " " }) : title
14685
- }
14686
- )
14687
- ]
14764
+ "justify-between": showInnerNav
14688
14765
  }
14689
14766
  ),
14690
- /* @__PURE__ */ jsx(
14691
- "div",
14692
- {
14693
- className: "w-full h-full bg-cover bg-center transition-scale duration-150 rounded-lg overflow-hidden min-h-[2rem] mt-[2rem] lg:mt-0",
14694
- style: {
14695
- backgroundImage: `url(${imageURL})`
14696
- }
14697
- }
14698
- )
14767
+ children: [
14768
+ (onNext || onPrevious) && showInnerNav && /* @__PURE__ */ jsxs("div", { className: cn("flex gap-[1rem]"), children: [
14769
+ /* @__PURE__ */ jsx(DialogPrimitive.Close, { asChild: true, children: /* @__PURE__ */ jsxs(Button, { onClick: handleOnNext, disabled: !onNext, variant: "ghost", children: [
14770
+ /* @__PURE__ */ jsx(XIcon, {}),
14771
+ "Close"
14772
+ ] }) }),
14773
+ /* @__PURE__ */ jsxs(Button, { onClick: handleOnNext, disabled: !onNext, variant: "ghost", children: [
14774
+ "Next",
14775
+ /* @__PURE__ */ jsx(ArrowUpIcon, {})
14776
+ ] }),
14777
+ /* @__PURE__ */ jsxs(Button, { onClick: handleOnPrevious, disabled: !onPrevious, variant: "ghost", children: [
14778
+ /* @__PURE__ */ jsx(ArrowDownIcon, {}),
14779
+ "Previous"
14780
+ ] })
14781
+ ] }),
14782
+ /* @__PURE__ */ jsx("div", { children })
14783
+ ]
14784
+ }
14785
+ );
14786
+ }
14787
+ function SideDialogFooterGroup({ children }) {
14788
+ return /* @__PURE__ */ jsx("div", { className: "flex items-baseline gap-[1rem]", children });
14789
+ }
14790
+
14791
+ function SideDialogContent({ children, className, isCentered, isFullHeight, variant }) {
14792
+ return /* @__PURE__ */ jsx("div", { className: cn("p-[3rem] py-[2rem] overflow-y-scroll", className), children: /* @__PURE__ */ jsx(
14793
+ "div",
14794
+ {
14795
+ className: cn("grid gap-[2rem] max-w-[50rem] w-full mx-auto pb-[1rem] ", {
14796
+ "items-center justify-center h-full content-center": isCentered,
14797
+ "min-h-full": isFullHeight,
14798
+ "content-start": !isFullHeight && !isCentered
14799
+ }),
14800
+ children
14801
+ }
14802
+ ) });
14803
+ }
14804
+ function SideDialogSection({ children }) {
14805
+ return /* @__PURE__ */ jsx(
14806
+ "div",
14807
+ {
14808
+ className: cn(
14809
+ "grid text-[0.875rem] text-icon5 gap-[1rem] justify-items-start",
14810
+ "[&>h3]:text-icon3 [&>h3]:text-[1rem] [&>h3]:font-semibold [&>h3]:border-b [&>h3]:border-border1 [&>h3]:pb-[1rem] [&>h3]:pr-[1rem] [&>h3]:inline-flex [&>h3]:gap-[.5rem] [&>h3]:items-center",
14811
+ "[&>h3>svg]:w-[1em] [&>h3>svg]:h-[1em] [&>h3>svg]:text-icon3"
14812
+ ),
14813
+ children
14814
+ }
14815
+ );
14816
+ }
14817
+ function SideDialogKeyValueList({ items, className }) {
14818
+ return /* @__PURE__ */ jsx("dl", { className: cn("grid grid-cols-[auto_1fr] gap-x-[2rem] gap-y-[.5rem] text-[0.875rem] content-start", className), children: items.map((item, index) => /* @__PURE__ */ jsxs(Fragment, { children: [
14819
+ /* @__PURE__ */ jsxs("dt", { className: "text-icon3", children: [
14820
+ item.key,
14821
+ ":"
14699
14822
  ] }),
14700
- /* @__PURE__ */ jsxs("div", { className: "grid lg:grid-cols-[1fr_1fr] gap-x-[6rem] mt-[2rem] ", children: [
14701
- /* @__PURE__ */ jsxs("div", { className: "grid", children: [
14702
- /* @__PURE__ */ jsx(
14703
- "p",
14704
- {
14705
- className: cn("mb-[1rem] text-[0.875rem] text-icon4 mt-[.5rem] leading-[1.75]", {
14706
- "bg-surface4 rounded-lg ": isLoading
14707
- }),
14708
- children: isLoading ? /* @__PURE__ */ jsx(Fragment, { children: " " }) : description
14709
- }
14710
- ),
14711
- !isLoading && templateSlug && /* @__PURE__ */ jsxs(
14712
- "div",
14713
- {
14714
- className: cn(
14715
- "bg-surface2 border border-surface4 rounded-lg p-[1rem] mb-[1rem]",
14716
- "flex items-start gap-[0.75rem]"
14717
- ),
14718
- children: [
14719
- /* @__PURE__ */ jsx("div", { className: "flex-shrink-0 mt-[0.125rem]", children: /* @__PURE__ */ jsx(InfoIcon$1, { className: "w-[1.1em] h-[1.1em] text-blue-500" }) }),
14720
- /* @__PURE__ */ jsxs("div", { className: "flex-1 space-y-[0.5rem]", children: [
14721
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-[0.5rem]", children: [
14722
- /* @__PURE__ */ jsx(GitBranchIcon, { className: "w-[1em] h-[1em] text-icon4" }),
14723
- /* @__PURE__ */ jsx("span", { className: "text-[0.875rem] font-medium text-icon5", children: "A new Git branch will be created" })
14823
+ /* @__PURE__ */ jsx("dd", { className: "text-icon4", children: item.value })
14824
+ ] })) });
14825
+ }
14826
+
14827
+ function SideDialogTop({ children, onNext, onPrevious, showInnerNav, className }) {
14828
+ const handleOnNext = () => {
14829
+ onNext?.();
14830
+ };
14831
+ const handleOnPrevious = () => {
14832
+ onPrevious?.();
14833
+ };
14834
+ return /* @__PURE__ */ jsx(
14835
+ "div",
14836
+ {
14837
+ className: cn(`flex justify-between h-[3.5rem] items-center text-icon5 text-[.875rem] pl-[1.5rem]`, className),
14838
+ children: /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-[2rem]", "[&_svg]:w-[1.1em] [&_svg]:h-[1.1em] [&_svg]:text-icon3"), children: [
14839
+ children,
14840
+ (onNext || onPrevious) && showInnerNav && /* @__PURE__ */ jsxs(Fragment, { children: [
14841
+ /* @__PURE__ */ jsx("span", { className: "text-icon3", children: "|" }),
14842
+ /* @__PURE__ */ jsxs(
14843
+ "div",
14844
+ {
14845
+ className: cn(
14846
+ "flex gap-[1rem] items-baseline"
14847
+ // '[&>button]:text-[0.875rem] [&>button]:flex [&>button]:items-center [&>button]:px-[0.5rem] [&>button]:py-[0.8rem] [&>button]:leading-[1]',
14848
+ ),
14849
+ children: [
14850
+ /* @__PURE__ */ jsxs(Button, { onClick: handleOnPrevious, disabled: !onPrevious, variant: "ghost", children: [
14851
+ "Previous",
14852
+ /* @__PURE__ */ jsx(ArrowUpIcon, {})
14724
14853
  ] }),
14725
- /* @__PURE__ */ jsxs("div", { className: "text-[0.8125rem] text-icon4 space-y-[0.25rem]", children: [
14726
- /* @__PURE__ */ jsxs("div", { children: [
14727
- /* @__PURE__ */ jsx("span", { className: "font-medium", children: "Branch name:" }),
14728
- " ",
14729
- /* @__PURE__ */ jsx("code", { className: "bg-surface3 px-[0.375rem] py-[0.125rem] rounded text-[0.75rem] font-mono", children: branchName })
14730
- ] }),
14731
- /* @__PURE__ */ jsx("div", { children: "This ensures safe installation with easy rollback if needed. Your main branch remains unchanged." })
14854
+ /* @__PURE__ */ jsxs(Button, { onClick: handleOnNext, disabled: !onNext, variant: "ghost", children: [
14855
+ "Next",
14856
+ /* @__PURE__ */ jsx(ArrowDownIcon, {})
14732
14857
  ] })
14733
- ] })
14734
- ]
14735
- }
14736
- ),
14737
- githubUrl && /* @__PURE__ */ jsxs(
14738
- "a",
14739
- {
14740
- href: githubUrl,
14741
- target: "_blank",
14742
- rel: "noopener noreferrer",
14743
- className: "flex items-center gap-[.5rem] mt-auto text-icon3 text-[0.875rem] hover:text-icon5",
14744
- children: [
14745
- /* @__PURE__ */ jsx(GithubIcon, {}),
14746
- githubUrl?.split("/")?.pop()
14747
- ]
14748
- }
14749
- )
14750
- ] }),
14751
- infoData && /* @__PURE__ */ jsx(KeyValueList, { data: infoData, LinkComponent: Link, labelsAreHidden: true, isLoading })
14752
- ] })
14753
- ] });
14858
+ ]
14859
+ }
14860
+ )
14861
+ ] })
14862
+ ] })
14863
+ }
14864
+ );
14754
14865
  }
14755
14866
 
14756
- function TemplateForm({
14757
- providerOptions,
14758
- selectedProvider,
14759
- onProviderChange,
14760
- variables,
14761
- errors,
14762
- handleInstallTemplate,
14763
- handleVariableChange,
14764
- isLoadingEnvVars,
14765
- defaultModelProvider,
14766
- defaultModelId,
14767
- onModelUpdate
14768
- }) {
14769
- return /* @__PURE__ */ jsx(Container, { children: /* @__PURE__ */ jsxs("div", { className: "max-w-[40rem] my-[1rem] p-[1rem] lg:p-[2rem] mx-auto gap-[2rem] grid", children: [
14770
- /* @__PURE__ */ jsxs(
14771
- "h2",
14772
- {
14773
- className: cn(
14774
- "text-icon5 text-[1.125rem] font-semibold flex items-center gap-[0.5rem]",
14775
- "[&>svg]:w-[1.2em] [&_svg]:h-[1.2em] [&_svg]:opacity-70 "
14776
- ),
14777
- children: [
14778
- "Install Template ",
14779
- /* @__PURE__ */ jsx(PackageOpenIcon, {})
14780
- ]
14781
- }
14782
- ),
14867
+ const useCodemirrorTheme = () => {
14868
+ return useMemo(
14869
+ () => draculaInit({
14870
+ settings: {
14871
+ fontFamily: "var(--geist-mono)",
14872
+ fontSize: "0.8125rem",
14873
+ lineHighlight: "transparent",
14874
+ gutterBackground: "transparent",
14875
+ gutterForeground: "#939393",
14876
+ background: "transparent"
14877
+ },
14878
+ styles: [{ tag: [tags.className, tags.propertyName] }]
14879
+ }),
14880
+ []
14881
+ );
14882
+ };
14883
+ function SideDialogCodeSection({ codeStr = "", title }) {
14884
+ const theme = useCodemirrorTheme();
14885
+ const [showAsMultilineText, setShowAsMultilineText] = useState(false);
14886
+ const hasMultilineText = useMemo(() => {
14887
+ try {
14888
+ const parsed = JSON.parse(codeStr);
14889
+ return containsInnerNewline(parsed || "");
14890
+ } catch {
14891
+ return false;
14892
+ }
14893
+ }, [codeStr]);
14894
+ const finalCodeStr = showAsMultilineText ? codeStr?.replace(/\\n/g, "\n") : codeStr;
14895
+ return /* @__PURE__ */ jsx("section", { className: "border border-border1 rounded-lg", children: /* @__PURE__ */ jsxs("div", { className: "border-b border-border1 last:border-b-0 grid", children: [
14896
+ /* @__PURE__ */ jsxs("div", { className: "p-[1rem] px-[1.5rem] border-b border-border1 grid grid-cols-[1fr_auto]", children: [
14897
+ /* @__PURE__ */ jsx("h3", { children: title }),
14898
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-2 items-center justify-end", children: [
14899
+ /* @__PURE__ */ jsx(CopyButton, { content: codeStr || "No content" }),
14900
+ hasMultilineText && /* @__PURE__ */ jsx(Button, { variant: "ghost", onClick: () => setShowAsMultilineText(!showAsMultilineText), children: showAsMultilineText ? /* @__PURE__ */ jsx(AlignLeftIcon, {}) : /* @__PURE__ */ jsx(AlignJustifyIcon, {}) })
14901
+ ] })
14902
+ ] }),
14783
14903
  /* @__PURE__ */ jsx(
14784
- SelectField,
14904
+ "div",
14785
14905
  {
14786
- options: providerOptions,
14787
- label: "Provider",
14788
- onValueChange: onProviderChange,
14789
- value: selectedProvider,
14790
- placeholder: "Select a provider"
14791
- }
14792
- ),
14793
- selectedProvider && Object.entries(variables || {}).length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
14794
- /* @__PURE__ */ jsxs("div", { className: "space-y-[0.5rem]", children: [
14795
- /* @__PURE__ */ jsx("h3", { className: "text-icon3 text-[0.875rem] font-medium", children: "Select AI Model for Template Installation *" }),
14796
- /* @__PURE__ */ jsx("p", { className: "text-icon4 text-[0.75rem]", children: "This model will be used by the workflow to process and install the template" }),
14797
- /* @__PURE__ */ jsx(
14798
- AgentMetadataModelSwitcher,
14799
- {
14800
- defaultProvider: defaultModelProvider || "",
14801
- defaultModel: defaultModelId || "",
14802
- updateModel: onModelUpdate || (() => Promise.resolve({ message: "Updated" })),
14803
- closeEditor: () => {
14804
- },
14805
- modelProviders: ["openai", "anthropic", "google", "xai", "groq"]
14806
- }
14807
- ),
14808
- (!defaultModelProvider || !defaultModelId) && /* @__PURE__ */ jsx("p", { className: "text-red-500 text-[0.75rem]", children: "Please select an AI model to continue" })
14809
- ] }),
14810
- /* @__PURE__ */ jsx("h3", { className: "text-icon3 text-[0.875rem]", children: "Set required Environmental Variables" }),
14811
- /* @__PURE__ */ jsx("div", { className: "grid grid-cols-[1fr_1fr] gap-[1rem] items-start", children: isLoadingEnvVars ? /* @__PURE__ */ jsxs(
14812
- "div",
14813
- {
14814
- className: cn(
14815
- "flex items-center justify-center col-span-2 text-icon3 text-[0.75rem] gap-[1rem]",
14816
- "[&_svg]:opacity-50 [&_svg]:w-[1.1em] [&_svg]:h-[1.1em]",
14817
- "animate-in fade-in duration-300"
14818
- ),
14819
- children: [
14820
- /* @__PURE__ */ jsx(Spinner, {}),
14821
- " Loading variables..."
14822
- ]
14823
- }
14824
- ) : Object.entries(variables).map(([key, value]) => /* @__PURE__ */ jsxs(Fragment$1, { children: [
14825
- /* @__PURE__ */ jsx(
14826
- InputField,
14827
- {
14828
- name: `env-${key}`,
14829
- labelIsHidden: true,
14830
- label: "Key",
14831
- value: key,
14832
- disabled: true,
14833
- className: "w-full"
14834
- }
14835
- ),
14836
- /* @__PURE__ */ jsx(
14837
- InputField,
14838
- {
14839
- name: key,
14840
- labelIsHidden: true,
14841
- label: "Value",
14842
- value,
14843
- onChange: handleVariableChange,
14844
- errorMsg: errors.includes(key) ? `Value is required.` : "",
14845
- autoComplete: "off",
14846
- className: "w-full"
14847
- }
14848
- )
14849
- ] }, key)) })
14850
- ] }),
14851
- selectedProvider && !isLoadingEnvVars && /* @__PURE__ */ jsxs(
14852
- "button",
14853
- {
14854
- className: cn(
14855
- "flex items-center gap-[0.5rem] justify-center text-[0.875rem] w-full bg-surface5 min-h-[2.5rem] rounded-lg text-icon5 hover:bg-surface6 transition-colors",
14856
- "[&>svg]:w-[1.1em] [&_svg]:h-[1.1em] [&_svg]:text-icon5"
14857
- ),
14858
- onClick: handleInstallTemplate,
14859
- disabled: !selectedProvider || !defaultModelProvider || !defaultModelId || errors.length > 0,
14860
- children: [
14861
- "Install ",
14862
- /* @__PURE__ */ jsx(ArrowRightIcon, {})
14863
- ]
14906
+ className: cn("bg-surface3 p-[1rem] overflow-auto text-icon4 text-[0.875rem] [&>div]:border-none break-all"),
14907
+ children: codeStr && /* @__PURE__ */ jsx(CodeMirror, { extensions: [json(), EditorView.lineWrapping], theme, value: finalCodeStr })
14864
14908
  }
14865
14909
  )
14866
14910
  ] }) });
14867
14911
  }
14868
-
14869
- function getStatusIcon(status) {
14870
- switch (status) {
14871
- case "running":
14872
- return /* @__PURE__ */ jsx(Spinner, {});
14873
- case "success":
14874
- return /* @__PURE__ */ jsx(CheckIcon$1, {});
14875
- case "failed":
14876
- return /* @__PURE__ */ jsx(XIcon, {});
14877
- default:
14878
- return null;
14912
+ function containsInnerNewline(obj) {
14913
+ if (typeof obj === "string") {
14914
+ const idx = obj.indexOf("\n");
14915
+ return idx !== -1 && idx !== obj.length - 1;
14916
+ } else if (Array.isArray(obj)) {
14917
+ return obj.some((item) => containsInnerNewline(item));
14918
+ } else if (obj && typeof obj === "object") {
14919
+ return Object.values(obj).some((value) => containsInnerNewline(value));
14879
14920
  }
14921
+ return false;
14880
14922
  }
14881
14923
 
14882
- function ProcessStepListItem({ stepId, step, isActive, position }) {
14883
- const formatStepTitle = (stepId2) => {
14884
- return stepId2.charAt(0).toUpperCase() + stepId2.slice(1).replace(/-/g, " ");
14885
- };
14924
+ function SideDialogHeading({ children, className, as = "h1" }) {
14925
+ const HeadingTag = as;
14926
+ return /* @__PURE__ */ jsx(
14927
+ HeadingTag,
14928
+ {
14929
+ className: cn(
14930
+ "flex items-start text-icon4 text-[1.125rem] font-semibold gap-[1rem]",
14931
+ "[&>svg]:w-[1.5em] [&>svg]:h-[1.5em]",
14932
+ {
14933
+ "text-[1.125rem]": as === "h1",
14934
+ "text-[1rem]": as === "h2"
14935
+ },
14936
+ className
14937
+ ),
14938
+ children
14939
+ }
14940
+ );
14941
+ }
14942
+
14943
+ function EntityMainHeader({
14944
+ title,
14945
+ description,
14946
+ icon,
14947
+ children,
14948
+ isLoading,
14949
+ className,
14950
+ placement = "page"
14951
+ }) {
14886
14952
  return /* @__PURE__ */ jsxs(
14887
- "div",
14953
+ "header",
14888
14954
  {
14889
- className: cn("grid gap-[1.5rem] grid-cols-[1fr_auto] py-[.75rem] px-[1rem] rounded-lg", {
14890
- "border border-dashed border-gray-500": isActive
14891
- }),
14955
+ className: cn(
14956
+ "grid gap-[.5rem]",
14957
+ "[&>h1]:text-icon6 [&>h1]:text-[1.25rem] [&>h1]:font-normal [&>h1]:flex [&>h1]:items-center [&>h1]:gap-[0.5rem]",
14958
+ "[&_svg]:w-[1.4rem] [&_svg]:h-[1.4rem] [&_svg]:text-icon3",
14959
+ "[&>p]:text-icon4 [&>p]:text-[0.875rem] [&>p]:m-0",
14960
+ { "pt-[2rem] pb-[2rem]": placement === "page" },
14961
+ { "pt-[1.5em] pb-[1rem]": placement === "sidebar" },
14962
+ className
14963
+ ),
14892
14964
  children: [
14893
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[auto_1fr] gap-[.5rem]", children: [
14894
- /* @__PURE__ */ jsxs("span", { className: "text-[0.875rem] text-icon5 min-w-[1.5rem] flex justify-end", children: [
14895
- position,
14896
- "."
14897
- ] }),
14898
- /* @__PURE__ */ jsxs("div", { children: [
14899
- /* @__PURE__ */ jsx("h4", { className: "text-[0.875rem] text-icon5", children: formatStepTitle(stepId) }),
14900
- step.description && /* @__PURE__ */ jsx("p", { className: "text-[0.875rem] -mt-[0.125rem]", children: step.description })
14901
- ] })
14965
+ /* @__PURE__ */ jsxs("h1", { children: [
14966
+ icon && icon,
14967
+ " ",
14968
+ title
14902
14969
  ] }),
14903
- /* @__PURE__ */ jsx(
14904
- "div",
14905
- {
14906
- className: cn("w-[1.75rem] h-[1.75rem] rounded-full flex items-center justify-center self-center", {
14907
- "border border-gray-500 border-dashed": step.status === "pending",
14908
- "[&>svg]:text-white [&>svg]:w-[1rem] [&>svg]:h-[1rem]": step.status !== "running",
14909
- "w-[1.75rem] h-[1.75rem]": step.status === "running",
14910
- "bg-green-900": step.status === "success",
14911
- "bg-red-900": step.status === "failed"
14912
- }),
14913
- children: getStatusIcon(step.status)
14914
- }
14915
- )
14970
+ description && /* @__PURE__ */ jsx("p", { children: description })
14916
14971
  ]
14917
14972
  }
14918
14973
  );
14919
14974
  }
14920
14975
 
14921
- function ProcessStepList({ currentStep, steps = [], className }) {
14922
- return /* @__PURE__ */ jsx("div", { className: cn(className), children: steps.map((step, idx) => /* @__PURE__ */ jsx(
14923
- ProcessStepListItem,
14976
+ function PageHeader({ title, description, icon, className }) {
14977
+ return /* @__PURE__ */ jsxs(
14978
+ "header",
14924
14979
  {
14925
- stepId: step.id,
14926
- step,
14927
- isActive: currentStep?.id === step.id,
14928
- position: idx + 1
14929
- },
14930
- step.id
14931
- )) });
14980
+ className: cn(
14981
+ "grid gap-[.5rem] pt-[2rem] pb-[2rem]",
14982
+ "[&>h1]:text-icon6 [&>h1]:text-[1.25rem] [&>h1]:font-normal [&>h1]:flex [&>h1]:items-center [&>h1]:gap-[0.5rem]",
14983
+ "[&_svg]:w-[1.4rem] [&_svg]:h-[1.4rem] [&_svg]:text-icon3",
14984
+ "[&>p]:text-icon4 [&>p]:text-[0.875rem] [&>p]:m-0",
14985
+ className
14986
+ ),
14987
+ children: [
14988
+ /* @__PURE__ */ jsxs("h1", { children: [
14989
+ icon && icon,
14990
+ " ",
14991
+ title
14992
+ ] }),
14993
+ description && /* @__PURE__ */ jsx("p", { children: description })
14994
+ ]
14995
+ }
14996
+ );
14932
14997
  }
14933
14998
 
14934
- function ProcessStepProgressBar({ steps }) {
14935
- const totalSteps = steps.length;
14936
- const completedSteps = steps.filter((step) => step.status === "success").length;
14937
- return /* @__PURE__ */ jsxs("div", { className: "flex justify-center flex-col gap-[1rem] content-center w-full", children: [
14938
- /* @__PURE__ */ jsx("div", { className: "grid grid-cols-[0_repeat(9,1fr)] w-full", children: steps.map((step, idx) => {
14939
- return /* @__PURE__ */ jsx(
14940
- "div",
14941
- {
14942
- className: cn("flex justify-end items-center relative h-[2rem] ", {
14943
- "bg-green-900": step.status === "success" && steps?.[idx - 1]?.status === "success"
14944
- }),
14945
- children: /* @__PURE__ */ jsx(
14946
- "div",
14947
- {
14948
- className: cn(
14949
- "w-[2rem] h-[2rem] rounded-full flex items-center justify-center self-center absolute right-0 translate-x-[50%] bg-surface3 z-10 text-icon3 font-bold text-[0.75rem]",
14950
- {
14951
- "border border-gray-500 border-dashed": step.status === "pending",
14952
- "[&>svg]:text-surface4 [&>svg]:w-[1.1rem] [&>svg]:h-[1.1rem]": step.status !== "running",
14953
- "bg-green-900 text-white": step.status === "success",
14954
- "bg-red-900 text-white": step.status === "failed"
14955
- }
14956
- ),
14957
- children: step.status === "running" ? /* @__PURE__ */ jsx(Spinner, {}) : idx + 1
14958
- }
14959
- )
14960
- },
14961
- step.id
14962
- );
14963
- }) }),
14964
- /* @__PURE__ */ jsxs("div", { className: "text-xs text-icon3 text-center", children: [
14965
- completedSteps,
14966
- " of ",
14967
- totalSteps,
14968
- " steps completed"
14969
- ] })
14999
+ function DatePicker({ className, classNames, showOutsideDays = true, ...props }) {
15000
+ return /* @__PURE__ */ jsx(
15001
+ DayPicker,
15002
+ {
15003
+ showOutsideDays,
15004
+ className: cn("p-3", className),
15005
+ classNames: {
15006
+ months: "flex flex-col space-y-4 sm:space-y-0 ",
15007
+ month: "space-y-4 text-[0.75rem] ",
15008
+ caption: "flex justify-between pt-1 items-center pl-2",
15009
+ caption_label: "text-text font-medium ",
15010
+ nav: "flex items-center",
15011
+ nav_button_previous: cn(
15012
+ "flex justify-center items-center h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100"
15013
+ ),
15014
+ nav_button_next: cn("flex justify-center items-center h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100"),
15015
+ dropdown_month: "w-full border-collapse space-y-1",
15016
+ weeknumber: "flex",
15017
+ day: cn(
15018
+ "relative p-0 text-center focus-within:relative focus-within:z-20 [&:has([aria-selected])]:bg-accent [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected].day-range-end)]:rounded-r-md",
15019
+ props.mode === "range" ? "[&:has(>.day-range-end)]:rounded-r-md [&:has(>.day-range-start)]:rounded-l-md first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md" : "[&:has([aria-selected])]:rounded-md",
15020
+ "h-8 w-8 p-0 hover:bg-lightGray-7/50 font-normal aria-selected:opacity-100"
15021
+ ),
15022
+ day_range_start: "day-range-start",
15023
+ day_range_end: "day-range-end",
15024
+ day_selected: "!bg-primary/50 !text-primary-foreground hover:bg-primary rounded-md hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground",
15025
+ day_today: "bg-primary/10 text-accent-foreground",
15026
+ day_outside: "day-outside text-muted-foreground opacity-50 aria-selected:bg-accent/50 aria-selected:text-muted-foreground aria-selected:opacity-30",
15027
+ day_disabled: "text-muted-foreground opacity-50",
15028
+ day_range_middle: "aria-selected:bg-accent aria-selected:text-accent-foreground",
15029
+ day_hidden: "invisible",
15030
+ head_cell: "text-[0.625rem] text-muted-foreground",
15031
+ ...classNames
15032
+ },
15033
+ ...props
15034
+ }
15035
+ );
15036
+ }
15037
+
15038
+ function Select({ name, onChange, defaultValue, value, options, placeholder }) {
15039
+ return /* @__PURE__ */ jsxs(Select$1, { name, onValueChange: onChange, value, children: [
15040
+ /* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, { placeholder: placeholder || "Select..." }) }),
15041
+ /* @__PURE__ */ jsx(SelectContent, { children: (options || []).map((option, idx) => /* @__PURE__ */ jsx(SelectItem, { value: `${idx}`, children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-[0.5rem] [&>svg]:w-[1.2em] [&>svg]:h-[1.2em] [&>svg]:text-icon3", children: option }) }, option)) })
14970
15042
  ] });
14971
15043
  }
14972
15044
 
14973
- function TemplateInstallation({ name, streamResult, runId, workflowInfo }) {
14974
- const phase = streamResult?.phase || "initializing";
14975
- const workflowState = streamResult?.payload?.workflowState;
14976
- const currentStep = streamResult?.payload?.currentStep;
14977
- const error = streamResult?.error;
14978
- const workflowSteps = workflowState?.steps || {};
14979
- const hasSteps = Object.keys(workflowSteps).length > 0;
14980
- const isUserVisibleStep = (stepId) => {
14981
- if (stepId === "input" || stepId.endsWith(".input")) return false;
14982
- if (stepId.startsWith("Mapping_") && /[0-9a-f]{8}/.test(stepId)) return false;
14983
- if (/[0-9a-f]{8,}/.test(stepId)) return false;
14984
- if (workflowInfo?.allSteps) {
14985
- return stepId in workflowInfo.allSteps;
15045
+ const hourOptions = ["12", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"];
15046
+ const minuteOptions = ["00", "15", "30", "45", "59"];
15047
+ const timePeriodOptions = ["AM", "PM"];
15048
+ function TimePicker({ defaultValue, onValueChange, className }) {
15049
+ const [hour, setHour] = useState("12");
15050
+ const [minute, setMinute] = useState("00");
15051
+ const [timePeriod, setTimePeriod] = useState("AM");
15052
+ useEffect(() => {
15053
+ if (defaultValue) {
15054
+ const timeRegex = /^(\d{1,2}):(\d{2})(?::\d{2})?\s*(AM|PM|am|pm)?$/;
15055
+ const match = defaultValue.match(timeRegex);
15056
+ if (match) {
15057
+ let parsedHour = parseInt(match[1], 10);
15058
+ const parsedMinute = parseInt(match[2], 10);
15059
+ const period = match[3]?.toUpperCase();
15060
+ if (parsedHour >= 1 && parsedHour <= 12 && parsedMinute >= 0 && parsedMinute <= 59) {
15061
+ setHour(parsedHour.toString());
15062
+ setMinute(parsedMinute === 0 ? "00" : parsedMinute.toString());
15063
+ setTimePeriod(period || "AM");
15064
+ }
15065
+ }
14986
15066
  }
14987
- return true;
15067
+ }, [defaultValue]);
15068
+ const handleHourChange = (val) => {
15069
+ setHour(val);
15070
+ onValueChange(`${hourOptions[+val]}:${minute} ${timePeriod}`.trim());
14988
15071
  };
14989
- const visibleSteps = Object.entries(workflowSteps).filter(([stepId, _]) => isUserVisibleStep(stepId));
14990
- const totalSteps = visibleSteps.length;
14991
- const getPhaseMessage = () => {
14992
- switch (phase) {
14993
- case "initializing":
14994
- return "Preparing template installation...";
14995
- case "processing":
14996
- return `Installing ${name} template`;
14997
- case "completed":
14998
- return "Template installation completed!";
14999
- case "error":
15000
- return "Template installation failed";
15001
- default:
15002
- return "Installing template...";
15003
- }
15072
+ const handleMinuteChange = (val) => {
15073
+ setMinute(minuteOptions[+val]);
15074
+ onValueChange(`${hour}:${minuteOptions[+val]} ${timePeriod}`.trim());
15004
15075
  };
15005
- const steps = visibleSteps.map(([stepId, stepData]) => ({
15006
- id: stepId,
15007
- status: stepData?.status,
15008
- description: stepData?.description,
15009
- title: stepId.charAt(0).toUpperCase() + stepId.slice(1).replace(/-/g, " "),
15010
- isActive: currentStep?.id === stepId
15011
- }));
15012
- return /* @__PURE__ */ jsxs(Container, { className: "space-y-6 text-icon3 mb-[2rem] content-center", children: [
15013
- /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
15014
- /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-icon5", children: getPhaseMessage() }),
15015
- streamResult?.runId && /* @__PURE__ */ jsxs("div", { className: "mt-[0.5rem] text-[0.75rem] text-icon3", children: [
15016
- "Run ID: ",
15017
- streamResult.runId
15018
- ] })
15019
- ] }),
15020
- hasSteps && totalSteps > 0 && !["error"].includes(phase) && /* @__PURE__ */ jsx("div", { className: "max-w-[30rem] w-full mx-auto px-[1.5rem]", children: /* @__PURE__ */ jsx(ProcessStepProgressBar, { steps }) }),
15021
- error && phase === "error" && /* @__PURE__ */ jsxs(
15022
- "div",
15076
+ const handleTimePeriodChange = (val) => {
15077
+ setTimePeriod(timePeriodOptions[+val]);
15078
+ onValueChange(`${hour}:${minute} ${timePeriodOptions[+val]}`.trim());
15079
+ };
15080
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex gap-[0.5rem] items-center", className), children: [
15081
+ /* @__PURE__ */ jsx(
15082
+ Select,
15023
15083
  {
15024
- className: cn(
15025
- "rounded-lg text-icon5 p-[1.5rem] flex items-center gap-[.75rem] text-[0.875rem] bg-red-500/10",
15026
- "[&>svg]:w-[1.5rem] [&>svg]:h-[1.5rem] [&>svg]:opacity-70 [&>svg]:text-red-500"
15027
- ),
15028
- children: [
15029
- /* @__PURE__ */ jsx(OctagonXIcon, {}),
15030
- error || "Something went wrong"
15031
- ]
15084
+ name: "hour",
15085
+ value: hourOptions.indexOf(hour).toString(),
15086
+ onChange: handleHourChange,
15087
+ options: hourOptions
15032
15088
  }
15033
15089
  ),
15034
- hasSteps && /* @__PURE__ */ jsx(ProcessStepList, { steps, currentStep, className: "pb-[1rem]" }),
15035
- !hasSteps && phase === "initializing" && /* @__PURE__ */ jsxs("div", { className: "text-center text-sm text-icon3 grid gap-[1rem] justify-items-center", children: [
15036
- /* @__PURE__ */ jsx(Spinner, {}),
15037
- /* @__PURE__ */ jsx("p", { children: "This may take some time..." })
15038
- ] })
15090
+ ":",
15091
+ /* @__PURE__ */ jsx(
15092
+ Select,
15093
+ {
15094
+ name: "minute",
15095
+ value: minuteOptions.indexOf(minute).toString(),
15096
+ onChange: handleMinuteChange,
15097
+ options: minuteOptions
15098
+ }
15099
+ ),
15100
+ /* @__PURE__ */ jsx(
15101
+ Select,
15102
+ {
15103
+ name: "period",
15104
+ value: timePeriodOptions.indexOf(timePeriod).toString(),
15105
+ onChange: handleTimePeriodChange,
15106
+ options: timePeriodOptions
15107
+ }
15108
+ )
15039
15109
  ] });
15040
15110
  }
15041
15111
 
15042
- function TemplateSuccess({ name, installedEntities, linkComponent }) {
15043
- const LinkComponent = linkComponent || "a";
15112
+ const DateTimePicker = ({
15113
+ value,
15114
+ minValue,
15115
+ maxValue,
15116
+ defaultTimeStrValue,
15117
+ onValueChange,
15118
+ children,
15119
+ className,
15120
+ placeholder,
15121
+ ...props
15122
+ }) => {
15123
+ const [openPopover, setOpenPopover] = React.useState(false);
15124
+ return /* @__PURE__ */ jsxs(Popover, { open: openPopover, onOpenChange: setOpenPopover, children: [
15125
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: children ? children : /* @__PURE__ */ jsx(
15126
+ DefaultTrigger,
15127
+ {
15128
+ value,
15129
+ placeholder,
15130
+ className,
15131
+ "data-testid": "datepicker-button"
15132
+ }
15133
+ ) }),
15134
+ /* @__PURE__ */ jsx(
15135
+ PopoverContent,
15136
+ {
15137
+ className: "backdrop-blur-4xl w-auto p-0 bg-surface4 max-w-[16.5rem]",
15138
+ align: "start",
15139
+ "data-testid": "datepicker-calendar",
15140
+ children: /* @__PURE__ */ jsx(
15141
+ DateTimePickerContent,
15142
+ {
15143
+ value,
15144
+ minValue,
15145
+ maxValue,
15146
+ onValueChange,
15147
+ setOpenPopover,
15148
+ defaultTimeStrValue,
15149
+ ...props
15150
+ }
15151
+ )
15152
+ }
15153
+ )
15154
+ ] });
15155
+ };
15156
+ function getCompoundDate({ date, timeStr = "" }) {
15157
+ if (!isValid(date)) {
15158
+ return null;
15159
+ }
15160
+ if (timeStr) {
15161
+ const dateStr = format(date, "yyyy-MM-dd");
15162
+ const newDate = /* @__PURE__ */ new Date(`${dateStr} ${timeStr}`);
15163
+ if (isValid(newDate)) {
15164
+ return newDate;
15165
+ }
15166
+ }
15167
+ return date;
15168
+ }
15169
+ const DateTimePickerContent = ({
15170
+ value,
15171
+ minValue,
15172
+ maxValue,
15173
+ onValueChange,
15174
+ setOpenPopover,
15175
+ placeholder,
15176
+ className,
15177
+ defaultTimeStrValue,
15178
+ ...props
15179
+ }) => {
15180
+ const [localErrorMsg, setLocalErrorMsg] = React.useState(null);
15181
+ const [dateInputValue, setDateInputValue] = React.useState(
15182
+ value ? format(getCompoundDate({ date: value, timeStr: defaultTimeStrValue }) || "", "PP p") : ""
15183
+ );
15184
+ const [timeStrValue, setTimeStrValue] = React.useState(defaultTimeStrValue || "");
15185
+ const [selected, setSelected] = React.useState(value ? new Date(value) : void 0);
15186
+ const debouncedDateUpdate = useDebouncedCallback((date) => {
15187
+ if (isValid(date)) {
15188
+ setSelected(date);
15189
+ onValueChange?.(date);
15190
+ setOpenPopover?.(false);
15191
+ }
15192
+ }, 500);
15193
+ const handleInputChange = (e) => {
15194
+ setDateInputValue(e.currentTarget.value);
15195
+ const date = new Date(e.currentTarget.value);
15196
+ debouncedDateUpdate(date);
15197
+ };
15198
+ const updateInputValue = (date) => {
15199
+ if (isValid(date)) {
15200
+ if (maxValue && date > maxValue) {
15201
+ setLocalErrorMsg(`The selected date should be before ${format(maxValue, "PP p")}`);
15202
+ setDateInputValue("");
15203
+ } else if (minValue && date < minValue) {
15204
+ setLocalErrorMsg(`The selected date should be after ${format(minValue, "PP p")}`);
15205
+ setDateInputValue("");
15206
+ } else {
15207
+ setDateInputValue(format(date, "PP p"));
15208
+ setLocalErrorMsg("");
15209
+ }
15210
+ } else {
15211
+ setDateInputValue("");
15212
+ setLocalErrorMsg("");
15213
+ }
15214
+ };
15215
+ const dateInputValueDate = new Date(dateInputValue);
15216
+ const dateInputValueIsValid = isValid(dateInputValueDate);
15217
+ const newValueDefined = dateInputValueIsValid && dateInputValueDate.getTime() !== value?.getTime();
15218
+ const handleDaySelect = (date) => {
15219
+ setSelected(date);
15220
+ if (date) {
15221
+ const newDate = getCompoundDate({ date, timeStr: timeStrValue });
15222
+ updateInputValue(newDate || "");
15223
+ } else {
15224
+ updateInputValue("");
15225
+ }
15226
+ };
15227
+ const handleMonthSelect = (date) => {
15228
+ setSelected(date);
15229
+ if (date) {
15230
+ const newDate = getCompoundDate({ date, timeStr: timeStrValue });
15231
+ updateInputValue(newDate || "");
15232
+ } else {
15233
+ updateInputValue("");
15234
+ }
15235
+ };
15236
+ const handleTimeStrChange = (val) => {
15237
+ setTimeStrValue(val);
15238
+ if (dateInputValueIsValid) {
15239
+ const newDate = getCompoundDate({ date: dateInputValueDate, timeStr: val });
15240
+ updateInputValue(newDate || "");
15241
+ }
15242
+ };
15243
+ const handleCancel = () => {
15244
+ setOpenPopover?.(false);
15245
+ };
15246
+ const handleApply = () => {
15247
+ if (isValid(dateInputValueDate)) {
15248
+ onValueChange(dateInputValueDate);
15249
+ }
15250
+ setOpenPopover?.(false);
15251
+ };
15252
+ const handleClear = () => {
15253
+ onValueChange(void 0);
15254
+ setSelected(void 0);
15255
+ setDateInputValue("");
15256
+ setTimeStrValue("");
15257
+ setOpenPopover?.(false);
15258
+ };
15044
15259
  return /* @__PURE__ */ jsxs(
15045
- Container,
15260
+ "div",
15046
15261
  {
15047
- className: cn(
15048
- "grid items-center justify-items-center gap-[1rem] content-center",
15049
- "[&>svg]:w-[2rem] [&>svg]:h-[2rem]"
15050
- ),
15262
+ "aria-label": "Choose date",
15263
+ className: cn("relative mt-2 flex flex-col ", className),
15264
+ onKeyDown: (e) => {
15265
+ e.stopPropagation();
15266
+ if (e.key === "Escape") {
15267
+ setOpenPopover?.(false);
15268
+ }
15269
+ },
15051
15270
  children: [
15052
- /* @__PURE__ */ jsx(PackageOpenIcon, {}),
15053
- /* @__PURE__ */ jsx("h2", { className: "text-[1.25rem ]", children: "Done!" }),
15054
- /* @__PURE__ */ jsxs("p", { className: "text-[0.875rem] text-center text-icon3 ", children: [
15055
- "The ",
15056
- /* @__PURE__ */ jsx("b", { className: "text-icon4", children: name }),
15057
- " template has been successfully installed.",
15058
- installedEntities && installedEntities.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
15059
- /* @__PURE__ */ jsx("br", {}),
15060
- " Installed entities are listed below."
15061
- ] })
15062
- ] }),
15063
- installedEntities && installedEntities.length > 0 && /* @__PURE__ */ jsx(KeyValueList, { data: installedEntities, LinkComponent })
15271
+ /* @__PURE__ */ jsx(
15272
+ InputField,
15273
+ {
15274
+ type: "text",
15275
+ value: dateInputValue,
15276
+ onChange: handleInputChange,
15277
+ placeholder,
15278
+ className: "m-4 mb-0 !w-auto"
15279
+ }
15280
+ ),
15281
+ localErrorMsg && /* @__PURE__ */ jsxs(
15282
+ "div",
15283
+ {
15284
+ className: cn(
15285
+ "text-[0.875rem] m-[1rem] mb-0 text-icon3",
15286
+ "[&>svg]:w-[1.1em] [&>svg]:h-[1.1em] [&>svg]:mt-[0.2em] [&>svg]:text-red-500 [&>svg]:float-left [&>svg]:mr-[0.5rem]"
15287
+ ),
15288
+ children: [
15289
+ /* @__PURE__ */ jsx(CircleAlertIcon, {}),
15290
+ " ",
15291
+ localErrorMsg
15292
+ ]
15293
+ }
15294
+ ),
15295
+ /* @__PURE__ */ jsx(
15296
+ DatePicker,
15297
+ {
15298
+ mode: "single",
15299
+ month: selected,
15300
+ selected,
15301
+ onMonthChange: handleMonthSelect,
15302
+ onSelect: handleDaySelect,
15303
+ ...props
15304
+ }
15305
+ ),
15306
+ /* @__PURE__ */ jsx(
15307
+ TimePicker,
15308
+ {
15309
+ onValueChange: handleTimeStrChange,
15310
+ className: "m-4 mt-0 w-auto",
15311
+ defaultValue: value ? formatDate(new Date(value), "hh:mm a") : defaultTimeStrValue
15312
+ }
15313
+ ),
15314
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[1fr_auto] gap-[0.5rem] m-4 mt-0", children: [
15315
+ /* @__PURE__ */ jsx(
15316
+ Button,
15317
+ {
15318
+ variant: "primary",
15319
+ tabIndex: 0,
15320
+ onClick: () => {
15321
+ dateInputValueIsValid ? handleApply() : handleCancel();
15322
+ },
15323
+ children: newValueDefined ? `Apply` : `Cancel`
15324
+ }
15325
+ ),
15326
+ newValueDefined && /* @__PURE__ */ jsx(Button, { variant: "outline", tabIndex: 0, onClick: handleClear, children: "Clear" })
15327
+ ] })
15064
15328
  ]
15065
15329
  }
15066
15330
  );
15067
- }
15331
+ };
15332
+ const DefaultTrigger = React.forwardRef(
15333
+ ({ value, placeholder, className, ...props }, ref) => {
15334
+ return /* @__PURE__ */ jsxs(Button, { ref, variant: "outline", className: cn("justify-start", className), ...props, children: [
15335
+ /* @__PURE__ */ jsx(CalendarIcon, { className: "h-4 w-4" }),
15336
+ value ? /* @__PURE__ */ jsx("span", { className: "text-white", children: format(value, "PPP p") }) : /* @__PURE__ */ jsx("span", { className: "text-gray", children: placeholder ?? "Pick a date" })
15337
+ ] });
15338
+ }
15339
+ );
15068
15340
 
15069
- function TemplateFailure({ errorMsg, validationErrors }) {
15070
- const isSchemaError = errorMsg?.includes("Invalid schema for function");
15071
- const isValidationError = errorMsg?.includes("validation issue") || validationErrors && validationErrors.length > 0;
15072
- const getUserFriendlyMessage = () => {
15073
- if (isValidationError) {
15074
- return "Template installation completed but some validation issues remain. The template may still be functional, but you should review and fix these issues.";
15075
- }
15076
- if (isSchemaError) {
15077
- return "There was an issue with the AI model configuration. This may be related to the selected model or AI SDK version compatibility.";
15078
- }
15079
- return "An unexpected error occurred during template installation.";
15080
- };
15081
- const getIconAndTitle = () => {
15082
- if (isValidationError) {
15083
- return {
15084
- icon: /* @__PURE__ */ jsx(AlertTriangleIcon, { className: "text-yellow-500" }),
15085
- title: "Template Installed with Warnings"
15086
- };
15341
+ function TextAndIcon({ children, className }) {
15342
+ return /* @__PURE__ */ jsx(
15343
+ "span",
15344
+ {
15345
+ className: cn(
15346
+ "flex items-center gap-[0.25rem] text-icon4 text-[0.875rem]",
15347
+ "[&>svg]:w-[1.2em] [&>svg]:h-[1.2em] [&>svg]:opacity-50",
15348
+ className
15349
+ ),
15350
+ children
15087
15351
  }
15088
- return {
15089
- icon: /* @__PURE__ */ jsx(FrownIcon, {}),
15090
- title: "Template Installation Failed"
15091
- };
15092
- };
15093
- const { icon, title } = getIconAndTitle();
15094
- return /* @__PURE__ */ jsxs(Container, { className: "space-y-4 text-icon3 mb-[2rem] content-center max-w-2xl mx-auto", children: [
15095
- /* @__PURE__ */ jsxs(
15352
+ );
15353
+ }
15354
+
15355
+ function getShortId(id) {
15356
+ if (!id) return void 0;
15357
+ return id.slice(0, 8);
15358
+ }
15359
+
15360
+ function TemplatesTools({
15361
+ tagOptions,
15362
+ selectedTag,
15363
+ providerOptions,
15364
+ selectedProvider,
15365
+ onTagChange,
15366
+ onProviderChange,
15367
+ searchTerm,
15368
+ onSearchChange,
15369
+ onReset,
15370
+ className,
15371
+ isLoading
15372
+ }) {
15373
+ if (isLoading) {
15374
+ return /* @__PURE__ */ jsxs(
15096
15375
  "div",
15097
15376
  {
15098
15377
  className: cn(
15099
- "grid items-center justify-items-center gap-[1rem] content-center",
15100
- "[&>svg]:w-[2rem] [&>svg]:h-[2rem]"
15378
+ "h-[6.5rem] flex items-center gap-[2rem]",
15379
+ "[&>div]:bg-surface3 [&>div]:w-[12rem] [&>div]:h-[2rem] [&>div]:animate-pulse",
15380
+ className
15101
15381
  ),
15102
15382
  children: [
15103
- icon,
15104
- /* @__PURE__ */ jsxs("div", { className: "text-center space-y-2", children: [
15105
- /* @__PURE__ */ jsx("p", { className: "text-[0.875rem] font-medium text-icon5", children: title }),
15106
- /* @__PURE__ */ jsx("p", { className: "text-[0.875rem] text-icon3", children: getUserFriendlyMessage() })
15107
- ] })
15383
+ /* @__PURE__ */ jsx("div", {}),
15384
+ " ",
15385
+ /* @__PURE__ */ jsx("div", {}),
15386
+ " ",
15387
+ /* @__PURE__ */ jsx("div", {})
15108
15388
  ]
15109
15389
  }
15110
- ),
15111
- validationErrors && validationErrors.length > 0 && /* @__PURE__ */ jsxs("details", { className: "text-xs", children: [
15112
- /* @__PURE__ */ jsxs("summary", { className: "cursor-pointer text-icon3 hover:text-icon4 select-none text-center", children: [
15113
- "Show Validation Issues (",
15114
- validationErrors.length,
15115
- ")"
15116
- ] }),
15117
- /* @__PURE__ */ jsx("div", { className: "mt-4 p-3 bg-gray-100 dark:bg-gray-800 rounded text-xs overflow-auto max-h-60 text-left space-y-2", children: validationErrors.map((error, index) => /* @__PURE__ */ jsxs("div", { className: "border-l-2 border-red-400 pl-2", children: [
15118
- /* @__PURE__ */ jsx("div", { className: "font-medium text-red-600 dark:text-red-400", children: error.type === "typescript" ? "🔴 TypeScript Error" : "⚠️ Lint Error" }),
15119
- /* @__PURE__ */ jsx("div", { className: "text-xs font-mono text-gray-700 dark:text-gray-300 mt-1 whitespace-pre-wrap break-words", children: error.message })
15120
- ] }, index)) })
15121
- ] }),
15122
- errorMsg && !isValidationError && /* @__PURE__ */ jsxs("details", { className: "text-xs", children: [
15123
- /* @__PURE__ */ jsx("summary", { className: "cursor-pointer text-icon3 hover:text-icon4 select-none text-center", children: "Show Details" }),
15124
- /* @__PURE__ */ jsx("div", { className: "mt-4 p-3 bg-gray-100 dark:bg-gray-800 rounded text-xs font-mono overflow-auto max-h-60 text-left", children: /* @__PURE__ */ jsx("div", { className: "whitespace-pre-wrap break-words", children: errorMsg }) })
15390
+ );
15391
+ }
15392
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-wrap mx-auto sticky top-0 gap-[2rem] bg-surface2 py-[2rem]", className), children: [
15393
+ /* @__PURE__ */ jsx(
15394
+ SearchField,
15395
+ {
15396
+ label: "Search templates",
15397
+ value: searchTerm,
15398
+ onChange: (e) => onSearchChange?.(e.target.value),
15399
+ placeholder: "Search Template"
15400
+ }
15401
+ ),
15402
+ /* @__PURE__ */ jsx(SelectField, { label: "Filter by tag", value: selectedTag, onValueChange: onTagChange, options: tagOptions }),
15403
+ /* @__PURE__ */ jsx(
15404
+ SelectField,
15405
+ {
15406
+ label: "Filter by provider",
15407
+ value: selectedProvider,
15408
+ onValueChange: onProviderChange,
15409
+ options: providerOptions
15410
+ }
15411
+ ),
15412
+ onReset && /* @__PURE__ */ jsxs(Button, { onClick: onReset, children: [
15413
+ "Reset ",
15414
+ /* @__PURE__ */ jsx(XIcon, {})
15125
15415
  ] })
15126
15416
  ] });
15127
15417
  }
15128
15418
 
15129
- const TraceContext = createContext({});
15130
- function TraceProvider({
15131
- children,
15132
- initialTraces: traces = []
15133
- }) {
15134
- const [open, setOpen] = useState(false);
15135
- const [trace, setTrace] = useState(null);
15136
- const [currentTraceIndex, setCurrentTraceIndex] = useState(0);
15137
- const [span, setSpan] = useState(null);
15138
- const nextTrace = () => {
15139
- if (currentTraceIndex < traces.length - 1) {
15140
- const nextIndex = currentTraceIndex + 1;
15141
- setCurrentTraceIndex(nextIndex);
15142
- const nextTrace2 = traces[nextIndex].trace;
15143
- setTrace(nextTrace2);
15144
- const parentSpan = nextTrace2.find((span2) => span2.parentSpanId === null) || nextTrace2[0];
15145
- setSpan(parentSpan);
15146
- }
15147
- };
15148
- const prevTrace = () => {
15149
- if (currentTraceIndex > 0) {
15150
- const prevIndex = currentTraceIndex - 1;
15151
- setCurrentTraceIndex(prevIndex);
15152
- const prevTrace2 = traces[prevIndex].trace;
15153
- setTrace(prevTrace2);
15154
- const parentSpan = prevTrace2.find((span2) => span2.parentSpanId === null) || prevTrace2[0];
15155
- setSpan(parentSpan);
15156
- }
15157
- };
15158
- const clearData = () => {
15159
- setOpen(false);
15160
- setTrace(null);
15161
- setSpan(null);
15162
- };
15419
+ function getRepoName(githubUrl) {
15420
+ return githubUrl.replace(/\/$/, "").split("/").pop();
15421
+ }
15422
+ function Container({ children, className }) {
15163
15423
  return /* @__PURE__ */ jsx(
15164
- TraceContext.Provider,
15424
+ "div",
15165
15425
  {
15166
- value: {
15167
- isOpen: open,
15168
- setIsOpen: setOpen,
15169
- trace,
15170
- setTrace,
15171
- traces,
15172
- currentTraceIndex,
15173
- setCurrentTraceIndex,
15174
- nextTrace,
15175
- prevTrace,
15176
- span,
15177
- setSpan,
15178
- clearData
15179
- },
15426
+ className: cn(
15427
+ "border border-border1 rounded-lg mt-[3rem] py-[2rem] lg:min-h-[25rem] transition-height px-[1rem] lg:px-[3rem]",
15428
+ className
15429
+ ),
15180
15430
  children
15181
15431
  }
15182
15432
  );
15183
15433
  }
15184
15434
 
15185
- const useOpenTrace = () => {
15186
- const {
15187
- setTrace,
15188
- isOpen: open,
15189
- setIsOpen: setOpen,
15190
- trace: currentTrace,
15191
- setSpan,
15192
- setCurrentTraceIndex
15193
- } = useContext(TraceContext);
15194
- const openTrace = (trace, traceIndex) => {
15195
- setTrace(trace);
15196
- const parentSpan = trace.find((span) => span.parentSpanId === null) || trace[0];
15197
- setSpan(parentSpan);
15198
- setCurrentTraceIndex(traceIndex);
15199
- if (open && currentTrace?.[0]?.id !== trace[0].id) return;
15200
- setOpen((prev) => !prev);
15201
- };
15202
- return { openTrace };
15203
- };
15204
-
15205
- const TracesTableEmpty = ({ colsCount }) => {
15206
- 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" }) }) }) });
15207
- };
15208
- const TracesTableError = ({ error, colsCount }) => {
15209
- 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 }) }) }) });
15210
- };
15211
- const TraceRow = ({ trace, index, isActive }) => {
15212
- const { openTrace } = useOpenTrace();
15213
- const hasFailure = trace.trace.some((span) => span.status.code === 2);
15214
- return /* @__PURE__ */ jsxs(Row, { className: isActive ? "bg-surface4" : "", onClick: () => openTrace(trace.trace, index), children: [
15215
- /* @__PURE__ */ jsx(DateTimeCell, { dateTime: new Date(trace.started / 1e3) }),
15216
- /* @__PURE__ */ jsxs(TxtCell, { title: trace.traceId, children: [
15217
- trace.traceId.substring(0, 7),
15218
- "..."
15219
- ] }),
15220
- /* @__PURE__ */ jsx(UnitCell, { unit: "ms", children: toSigFigs(trace.duration / 1e3, 3) }),
15221
- /* @__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 }) }) }),
15222
- /* @__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" }) })
15223
- ] });
15224
- };
15225
- const TracesTable = ({ traces, error }) => {
15226
- const hasNoTraces = !traces || traces.length === 0;
15227
- const { currentTraceIndex } = useContext(TraceContext);
15228
- const colsCount = 4;
15229
- return /* @__PURE__ */ jsxs(Table$1, { size: "small", children: [
15230
- /* @__PURE__ */ jsxs(Thead, { children: [
15231
- /* @__PURE__ */ jsx(Th, { width: 120, children: "Time" }),
15232
- /* @__PURE__ */ jsx(Th, { width: "auto", children: "Trace Id" }),
15233
- /* @__PURE__ */ jsx(Th, { width: 120, children: "Duration" }),
15234
- /* @__PURE__ */ jsx(Th, { width: 120, children: "Spans" }),
15235
- /* @__PURE__ */ jsx(Th, { width: 120, children: "Status" })
15236
- ] }),
15237
- 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(
15238
- TraceRow,
15435
+ function TemplatesList({ templates, linkComponent, className, isLoading }) {
15436
+ const LinkComponent = linkComponent || "a";
15437
+ if (isLoading) {
15438
+ return /* @__PURE__ */ jsx("div", { className: cn("grid gap-y-[1rem]", className), children: Array.from({ length: 5 }).map((_, index) => /* @__PURE__ */ jsx("div", { className: "h-[4rem] bg-surface3 animate-pulse rounded-lg" }, index)) });
15439
+ }
15440
+ return /* @__PURE__ */ jsx("div", { className: cn("grid gap-y-[1rem]", className), children: templates.map((template) => {
15441
+ const hasMetaInfo = template?.agents || template?.tools || template?.networks || template?.workflows || template?.mcp;
15442
+ return /* @__PURE__ */ jsxs(
15443
+ "article",
15239
15444
  {
15240
- trace,
15241
- index,
15242
- isActive: index === currentTraceIndex
15445
+ className: cn(
15446
+ "border border-border1 rounded-lg overflow-hidden w-full grid grid-cols-[1fr_auto] bg-surface3 transition-colors hover:bg-surface4"
15447
+ ),
15448
+ children: [
15449
+ /* @__PURE__ */ jsxs(
15450
+ LinkComponent,
15451
+ {
15452
+ to: `/templates/${template.slug}`,
15453
+ className: cn("grid [&:hover_p]:text-icon5", {
15454
+ "grid-cols-[8rem_1fr] lg:grid-cols-[12rem_1fr]": template.imageURL
15455
+ }),
15456
+ children: [
15457
+ template.imageURL && /* @__PURE__ */ jsx("div", { className: cn("relative overflow-hidden"), children: /* @__PURE__ */ jsx(
15458
+ "div",
15459
+ {
15460
+ className: "w-full h-full bg-cover thumb transition-scale duration-150",
15461
+ style: {
15462
+ backgroundImage: `url(${template.imageURL})`
15463
+ }
15464
+ }
15465
+ ) }),
15466
+ /* @__PURE__ */ jsxs(
15467
+ "div",
15468
+ {
15469
+ className: cn(
15470
+ "grid py-[.75rem] px-[1.5rem] w-full gap-[0.1rem]",
15471
+ "[&_svg]:w-[1em] [&_svg]:h-[1em] [&_svg]:text-icon3"
15472
+ ),
15473
+ children: [
15474
+ /* @__PURE__ */ jsx("h2", { className: "text-[1rem] text-icon5", children: template.title }),
15475
+ /* @__PURE__ */ jsx("p", { className: "text-[0.875rem] text-icon4 transition-colors duration-500", children: template.description }),
15476
+ /* @__PURE__ */ jsxs("div", { className: "hidden 2xl:flex text-icon3 text-[0.875rem] flex-wrap items-center gap-[1rem] mt-[0.75rem]", children: [
15477
+ hasMetaInfo && /* @__PURE__ */ jsxs(
15478
+ "ul",
15479
+ {
15480
+ className: cn(
15481
+ "flex gap-[1rem] text-[0.875rem] text-icon3 m-0 p-0 list-none",
15482
+ "[&>li]:flex [&>li]:items-center [&>li]:gap-[0.1rem] text-icon4"
15483
+ ),
15484
+ children: [
15485
+ template?.agents && template.agents.length > 0 && /* @__PURE__ */ jsxs("li", { children: [
15486
+ /* @__PURE__ */ jsx(AgentIcon, {}),
15487
+ " ",
15488
+ template.agents.length
15489
+ ] }),
15490
+ template?.tools && template.tools.length > 0 && /* @__PURE__ */ jsxs("li", { children: [
15491
+ /* @__PURE__ */ jsx(ToolsIcon, {}),
15492
+ " ",
15493
+ template.tools.length
15494
+ ] }),
15495
+ template?.networks && template.networks.length > 0 && /* @__PURE__ */ jsxs("li", { children: [
15496
+ /* @__PURE__ */ jsx(NetworkIcon, {}),
15497
+ " ",
15498
+ template.networks.length
15499
+ ] }),
15500
+ template?.workflows && template.workflows.length > 0 && /* @__PURE__ */ jsxs("li", { children: [
15501
+ /* @__PURE__ */ jsx(WorkflowIcon$1, {}),
15502
+ " ",
15503
+ template.workflows.length
15504
+ ] }),
15505
+ template?.mcp && template.mcp.length > 0 && /* @__PURE__ */ jsxs("li", { children: [
15506
+ /* @__PURE__ */ jsx(McpServerIcon, {}),
15507
+ " ",
15508
+ template.mcp.length
15509
+ ] })
15510
+ ]
15511
+ }
15512
+ ),
15513
+ hasMetaInfo && template.supportedProviders && /* @__PURE__ */ jsx("small", { children: "|" }),
15514
+ /* @__PURE__ */ jsx("div", { className: "flex items-center text-icon3 gap-[1rem]", children: template.supportedProviders.map((provider) => /* @__PURE__ */ jsx("span", { className: "", children: provider }, provider)) })
15515
+ ] })
15516
+ ]
15517
+ }
15518
+ )
15519
+ ]
15520
+ }
15521
+ ),
15522
+ /* @__PURE__ */ jsx(
15523
+ "a",
15524
+ {
15525
+ href: template.githubUrl,
15526
+ className: cn("group items-center gap-[0.5rem] text-[0.875rem] ml-auto pr-[1rem] hidden", "lg:flex"),
15527
+ target: "_blank",
15528
+ rel: "noopener noreferrer",
15529
+ children: /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-[0.5rem] px-[0.5rem] py-[0.25rem] rounded bg-surface1 group-hover:bg-surface2 text-icon3 transition-colors group-hover:text-icon5 ", children: [
15530
+ /* @__PURE__ */ jsx(GithubIcon, {}),
15531
+ " ",
15532
+ getRepoName(template.githubUrl)
15533
+ ] })
15534
+ }
15535
+ )
15536
+ ]
15243
15537
  },
15244
- trace.traceId + index
15245
- )) }) })
15246
- ] });
15247
- };
15248
-
15538
+ template.slug
15539
+ );
15540
+ }) });
15541
+ }
15542
+
15543
+ function TemplateInfo({
15544
+ title,
15545
+ description,
15546
+ imageURL,
15547
+ githubUrl,
15548
+ isLoading,
15549
+ infoData,
15550
+ templateSlug
15551
+ }) {
15552
+ const branchName = templateSlug ? `feat/install-template-${templateSlug}` : "feat/install-template-[slug]";
15553
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
15554
+ /* @__PURE__ */ jsxs("div", { className: cn("grid lg:grid-cols-[1fr_1fr] gap-x-[6rem] mt-[2rem] lg:min-h-[4rem] items-center "), children: [
15555
+ /* @__PURE__ */ jsxs(
15556
+ "div",
15557
+ {
15558
+ className: cn(
15559
+ "text-[1.5rem] flex items-center gap-[0.75rem] ",
15560
+ "[&>svg]:w-[1.2em] [&>svg]:h-[1.2em] [&>svg]:opacity-50",
15561
+ {
15562
+ "[&>svg]:opacity-20": isLoading
15563
+ }
15564
+ ),
15565
+ children: [
15566
+ /* @__PURE__ */ jsx(PackageIcon, {}),
15567
+ /* @__PURE__ */ jsx(
15568
+ "h2",
15569
+ {
15570
+ className: cn({
15571
+ "bg-surface4 flex rounded-lg min-w-[50%]": isLoading
15572
+ }),
15573
+ children: isLoading ? /* @__PURE__ */ jsx(Fragment, { children: " " }) : title
15574
+ }
15575
+ )
15576
+ ]
15577
+ }
15578
+ ),
15579
+ /* @__PURE__ */ jsx(
15580
+ "div",
15581
+ {
15582
+ className: "w-full h-full bg-cover bg-center transition-scale duration-150 rounded-lg overflow-hidden min-h-[2rem] mt-[2rem] lg:mt-0",
15583
+ style: {
15584
+ backgroundImage: `url(${imageURL})`
15585
+ }
15586
+ }
15587
+ )
15588
+ ] }),
15589
+ /* @__PURE__ */ jsxs("div", { className: "grid lg:grid-cols-[1fr_1fr] gap-x-[6rem] mt-[2rem] ", children: [
15590
+ /* @__PURE__ */ jsxs("div", { className: "grid", children: [
15591
+ /* @__PURE__ */ jsx(
15592
+ "p",
15593
+ {
15594
+ className: cn("mb-[1rem] text-[0.875rem] text-icon4 mt-[.5rem] leading-[1.75]", {
15595
+ "bg-surface4 rounded-lg ": isLoading
15596
+ }),
15597
+ children: isLoading ? /* @__PURE__ */ jsx(Fragment, { children: " " }) : description
15598
+ }
15599
+ ),
15600
+ !isLoading && templateSlug && /* @__PURE__ */ jsxs(
15601
+ "div",
15602
+ {
15603
+ className: cn(
15604
+ "bg-surface2 border border-surface4 rounded-lg p-[1rem] mb-[1rem]",
15605
+ "flex items-start gap-[0.75rem]"
15606
+ ),
15607
+ children: [
15608
+ /* @__PURE__ */ jsx("div", { className: "flex-shrink-0 mt-[0.125rem]", children: /* @__PURE__ */ jsx(InfoIcon$1, { className: "w-[1.1em] h-[1.1em] text-blue-500" }) }),
15609
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 space-y-[0.5rem]", children: [
15610
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-[0.5rem]", children: [
15611
+ /* @__PURE__ */ jsx(GitBranchIcon, { className: "w-[1em] h-[1em] text-icon4" }),
15612
+ /* @__PURE__ */ jsx("span", { className: "text-[0.875rem] font-medium text-icon5", children: "A new Git branch will be created" })
15613
+ ] }),
15614
+ /* @__PURE__ */ jsxs("div", { className: "text-[0.8125rem] text-icon4 space-y-[0.25rem]", children: [
15615
+ /* @__PURE__ */ jsxs("div", { children: [
15616
+ /* @__PURE__ */ jsx("span", { className: "font-medium", children: "Branch name:" }),
15617
+ " ",
15618
+ /* @__PURE__ */ jsx("code", { className: "bg-surface3 px-[0.375rem] py-[0.125rem] rounded text-[0.75rem] font-mono", children: branchName })
15619
+ ] }),
15620
+ /* @__PURE__ */ jsx("div", { children: "This ensures safe installation with easy rollback if needed. Your main branch remains unchanged." })
15621
+ ] })
15622
+ ] })
15623
+ ]
15624
+ }
15625
+ ),
15626
+ githubUrl && /* @__PURE__ */ jsxs(
15627
+ "a",
15628
+ {
15629
+ href: githubUrl,
15630
+ target: "_blank",
15631
+ rel: "noopener noreferrer",
15632
+ className: "flex items-center gap-[.5rem] mt-auto text-icon3 text-[0.875rem] hover:text-icon5",
15633
+ children: [
15634
+ /* @__PURE__ */ jsx(GithubIcon, {}),
15635
+ githubUrl?.split("/")?.pop()
15636
+ ]
15637
+ }
15638
+ )
15639
+ ] }),
15640
+ infoData && /* @__PURE__ */ jsx(KeyValueList, { data: infoData, LinkComponent: Link, labelsAreHidden: true, isLoading })
15641
+ ] })
15642
+ ] });
15643
+ }
15644
+
15645
+ function TemplateForm({
15646
+ providerOptions,
15647
+ selectedProvider,
15648
+ onProviderChange,
15649
+ variables,
15650
+ errors,
15651
+ handleInstallTemplate,
15652
+ handleVariableChange,
15653
+ isLoadingEnvVars,
15654
+ defaultModelProvider,
15655
+ defaultModelId,
15656
+ onModelUpdate
15657
+ }) {
15658
+ return /* @__PURE__ */ jsx(Container, { children: /* @__PURE__ */ jsxs("div", { className: "max-w-[40rem] my-[1rem] p-[1rem] lg:p-[2rem] mx-auto gap-[2rem] grid", children: [
15659
+ /* @__PURE__ */ jsxs(
15660
+ "h2",
15661
+ {
15662
+ className: cn(
15663
+ "text-icon5 text-[1.125rem] font-semibold flex items-center gap-[0.5rem]",
15664
+ "[&>svg]:w-[1.2em] [&_svg]:h-[1.2em] [&_svg]:opacity-70 "
15665
+ ),
15666
+ children: [
15667
+ "Install Template ",
15668
+ /* @__PURE__ */ jsx(PackageOpenIcon, {})
15669
+ ]
15670
+ }
15671
+ ),
15672
+ /* @__PURE__ */ jsx(
15673
+ SelectField,
15674
+ {
15675
+ options: providerOptions,
15676
+ label: "Provider",
15677
+ onValueChange: onProviderChange,
15678
+ value: selectedProvider,
15679
+ placeholder: "Select a provider"
15680
+ }
15681
+ ),
15682
+ selectedProvider && Object.entries(variables || {}).length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
15683
+ /* @__PURE__ */ jsxs("div", { className: "space-y-[0.5rem]", children: [
15684
+ /* @__PURE__ */ jsx("h3", { className: "text-icon3 text-[0.875rem] font-medium", children: "Select AI Model for Template Installation *" }),
15685
+ /* @__PURE__ */ jsx("p", { className: "text-icon4 text-[0.75rem]", children: "This model will be used by the workflow to process and install the template" }),
15686
+ /* @__PURE__ */ jsx(
15687
+ AgentMetadataModelSwitcher,
15688
+ {
15689
+ defaultProvider: defaultModelProvider || "",
15690
+ defaultModel: defaultModelId || "",
15691
+ updateModel: onModelUpdate || (() => Promise.resolve({ message: "Updated" })),
15692
+ closeEditor: () => {
15693
+ },
15694
+ modelProviders: ["openai", "anthropic", "google", "xai", "groq"]
15695
+ }
15696
+ ),
15697
+ (!defaultModelProvider || !defaultModelId) && /* @__PURE__ */ jsx("p", { className: "text-red-500 text-[0.75rem]", children: "Please select an AI model to continue" })
15698
+ ] }),
15699
+ /* @__PURE__ */ jsx("h3", { className: "text-icon3 text-[0.875rem]", children: "Set required Environmental Variables" }),
15700
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-[1fr_1fr] gap-[1rem] items-start", children: isLoadingEnvVars ? /* @__PURE__ */ jsxs(
15701
+ "div",
15702
+ {
15703
+ className: cn(
15704
+ "flex items-center justify-center col-span-2 text-icon3 text-[0.75rem] gap-[1rem]",
15705
+ "[&_svg]:opacity-50 [&_svg]:w-[1.1em] [&_svg]:h-[1.1em]",
15706
+ "animate-in fade-in duration-300"
15707
+ ),
15708
+ children: [
15709
+ /* @__PURE__ */ jsx(Spinner, {}),
15710
+ " Loading variables..."
15711
+ ]
15712
+ }
15713
+ ) : Object.entries(variables).map(([key, value]) => /* @__PURE__ */ jsxs(Fragment$1, { children: [
15714
+ /* @__PURE__ */ jsx(
15715
+ InputField,
15716
+ {
15717
+ name: `env-${key}`,
15718
+ labelIsHidden: true,
15719
+ label: "Key",
15720
+ value: key,
15721
+ disabled: true,
15722
+ className: "w-full"
15723
+ }
15724
+ ),
15725
+ /* @__PURE__ */ jsx(
15726
+ InputField,
15727
+ {
15728
+ name: key,
15729
+ labelIsHidden: true,
15730
+ label: "Value",
15731
+ value,
15732
+ onChange: handleVariableChange,
15733
+ errorMsg: errors.includes(key) ? `Value is required.` : "",
15734
+ autoComplete: "off",
15735
+ className: "w-full"
15736
+ }
15737
+ )
15738
+ ] }, key)) })
15739
+ ] }),
15740
+ selectedProvider && !isLoadingEnvVars && /* @__PURE__ */ jsxs(
15741
+ "button",
15742
+ {
15743
+ className: cn(
15744
+ "flex items-center gap-[0.5rem] justify-center text-[0.875rem] w-full bg-surface5 min-h-[2.5rem] rounded-lg text-icon5 hover:bg-surface6 transition-colors",
15745
+ "[&>svg]:w-[1.1em] [&_svg]:h-[1.1em] [&_svg]:text-icon5"
15746
+ ),
15747
+ onClick: handleInstallTemplate,
15748
+ disabled: !selectedProvider || !defaultModelProvider || !defaultModelId || errors.length > 0,
15749
+ children: [
15750
+ "Install ",
15751
+ /* @__PURE__ */ jsx(ArrowRightIcon, {})
15752
+ ]
15753
+ }
15754
+ )
15755
+ ] }) });
15756
+ }
15757
+
15758
+ function getStatusIcon(status) {
15759
+ switch (status) {
15760
+ case "running":
15761
+ return /* @__PURE__ */ jsx(Spinner, {});
15762
+ case "success":
15763
+ return /* @__PURE__ */ jsx(CheckIcon$1, {});
15764
+ case "failed":
15765
+ return /* @__PURE__ */ jsx(XIcon, {});
15766
+ default:
15767
+ return null;
15768
+ }
15769
+ }
15770
+
15771
+ function ProcessStepListItem({ stepId, step, isActive, position }) {
15772
+ const formatStepTitle = (stepId2) => {
15773
+ return stepId2.charAt(0).toUpperCase() + stepId2.slice(1).replace(/-/g, " ");
15774
+ };
15775
+ return /* @__PURE__ */ jsxs(
15776
+ "div",
15777
+ {
15778
+ className: cn("grid gap-[1.5rem] grid-cols-[1fr_auto] py-[.75rem] px-[1rem] rounded-lg", {
15779
+ "border border-dashed border-gray-500": isActive
15780
+ }),
15781
+ children: [
15782
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[auto_1fr] gap-[.5rem]", children: [
15783
+ /* @__PURE__ */ jsxs("span", { className: "text-[0.875rem] text-icon5 min-w-[1.5rem] flex justify-end", children: [
15784
+ position,
15785
+ "."
15786
+ ] }),
15787
+ /* @__PURE__ */ jsxs("div", { children: [
15788
+ /* @__PURE__ */ jsx("h4", { className: "text-[0.875rem] text-icon5", children: formatStepTitle(stepId) }),
15789
+ step.description && /* @__PURE__ */ jsx("p", { className: "text-[0.875rem] -mt-[0.125rem]", children: step.description })
15790
+ ] })
15791
+ ] }),
15792
+ /* @__PURE__ */ jsx(
15793
+ "div",
15794
+ {
15795
+ className: cn("w-[1.75rem] h-[1.75rem] rounded-full flex items-center justify-center self-center", {
15796
+ "border border-gray-500 border-dashed": step.status === "pending",
15797
+ "[&>svg]:text-white [&>svg]:w-[1rem] [&>svg]:h-[1rem]": step.status !== "running",
15798
+ "w-[1.75rem] h-[1.75rem]": step.status === "running",
15799
+ "bg-green-900": step.status === "success",
15800
+ "bg-red-900": step.status === "failed"
15801
+ }),
15802
+ children: getStatusIcon(step.status)
15803
+ }
15804
+ )
15805
+ ]
15806
+ }
15807
+ );
15808
+ }
15809
+
15810
+ function ProcessStepList({ currentStep, steps = [], className }) {
15811
+ return /* @__PURE__ */ jsx("div", { className: cn(className), children: steps.map((step, idx) => /* @__PURE__ */ jsx(
15812
+ ProcessStepListItem,
15813
+ {
15814
+ stepId: step.id,
15815
+ step,
15816
+ isActive: currentStep?.id === step.id,
15817
+ position: idx + 1
15818
+ },
15819
+ step.id
15820
+ )) });
15821
+ }
15822
+
15823
+ function ProcessStepProgressBar({ steps }) {
15824
+ const totalSteps = steps.length;
15825
+ const completedSteps = steps.filter((step) => step.status === "success").length;
15826
+ return /* @__PURE__ */ jsxs("div", { className: "flex justify-center flex-col gap-[1rem] content-center w-full", children: [
15827
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-[0_repeat(9,1fr)] w-full", children: steps.map((step, idx) => {
15828
+ return /* @__PURE__ */ jsx(
15829
+ "div",
15830
+ {
15831
+ className: cn("flex justify-end items-center relative h-[2rem] ", {
15832
+ "bg-green-900": step.status === "success" && steps?.[idx - 1]?.status === "success"
15833
+ }),
15834
+ children: /* @__PURE__ */ jsx(
15835
+ "div",
15836
+ {
15837
+ className: cn(
15838
+ "w-[2rem] h-[2rem] rounded-full flex items-center justify-center self-center absolute right-0 translate-x-[50%] bg-surface3 z-10 text-icon3 font-bold text-[0.75rem]",
15839
+ {
15840
+ "border border-gray-500 border-dashed": step.status === "pending",
15841
+ "[&>svg]:text-surface4 [&>svg]:w-[1.1rem] [&>svg]:h-[1.1rem]": step.status !== "running",
15842
+ "bg-green-900 text-white": step.status === "success",
15843
+ "bg-red-900 text-white": step.status === "failed"
15844
+ }
15845
+ ),
15846
+ children: step.status === "running" ? /* @__PURE__ */ jsx(Spinner, {}) : idx + 1
15847
+ }
15848
+ )
15849
+ },
15850
+ step.id
15851
+ );
15852
+ }) }),
15853
+ /* @__PURE__ */ jsxs("div", { className: "text-xs text-icon3 text-center", children: [
15854
+ completedSteps,
15855
+ " of ",
15856
+ totalSteps,
15857
+ " steps completed"
15858
+ ] })
15859
+ ] });
15860
+ }
15861
+
15862
+ function TemplateInstallation({ name, streamResult, runId, workflowInfo }) {
15863
+ const phase = streamResult?.phase || "initializing";
15864
+ const workflowState = streamResult?.payload?.workflowState;
15865
+ const currentStep = streamResult?.payload?.currentStep;
15866
+ const error = streamResult?.error;
15867
+ const workflowSteps = workflowState?.steps || {};
15868
+ const hasSteps = Object.keys(workflowSteps).length > 0;
15869
+ const isUserVisibleStep = (stepId) => {
15870
+ if (stepId === "input" || stepId.endsWith(".input")) return false;
15871
+ if (stepId.startsWith("Mapping_") && /[0-9a-f]{8}/.test(stepId)) return false;
15872
+ if (/[0-9a-f]{8,}/.test(stepId)) return false;
15873
+ if (workflowInfo?.allSteps) {
15874
+ return stepId in workflowInfo.allSteps;
15875
+ }
15876
+ return true;
15877
+ };
15878
+ const visibleSteps = Object.entries(workflowSteps).filter(([stepId, _]) => isUserVisibleStep(stepId));
15879
+ const totalSteps = visibleSteps.length;
15880
+ const getPhaseMessage = () => {
15881
+ switch (phase) {
15882
+ case "initializing":
15883
+ return "Preparing template installation...";
15884
+ case "processing":
15885
+ return `Installing ${name} template`;
15886
+ case "completed":
15887
+ return "Template installation completed!";
15888
+ case "error":
15889
+ return "Template installation failed";
15890
+ default:
15891
+ return "Installing template...";
15892
+ }
15893
+ };
15894
+ const steps = visibleSteps.map(([stepId, stepData]) => ({
15895
+ id: stepId,
15896
+ status: stepData?.status,
15897
+ description: stepData?.description,
15898
+ title: stepId.charAt(0).toUpperCase() + stepId.slice(1).replace(/-/g, " "),
15899
+ isActive: currentStep?.id === stepId
15900
+ }));
15901
+ return /* @__PURE__ */ jsxs(Container, { className: "space-y-6 text-icon3 mb-[2rem] content-center", children: [
15902
+ /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
15903
+ /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-icon5", children: getPhaseMessage() }),
15904
+ streamResult?.runId && /* @__PURE__ */ jsxs("div", { className: "mt-[0.5rem] text-[0.75rem] text-icon3", children: [
15905
+ "Run ID: ",
15906
+ streamResult.runId
15907
+ ] })
15908
+ ] }),
15909
+ hasSteps && totalSteps > 0 && !["error"].includes(phase) && /* @__PURE__ */ jsx("div", { className: "max-w-[30rem] w-full mx-auto px-[1.5rem]", children: /* @__PURE__ */ jsx(ProcessStepProgressBar, { steps }) }),
15910
+ error && phase === "error" && /* @__PURE__ */ jsxs(
15911
+ "div",
15912
+ {
15913
+ className: cn(
15914
+ "rounded-lg text-icon5 p-[1.5rem] flex items-center gap-[.75rem] text-[0.875rem] bg-red-500/10",
15915
+ "[&>svg]:w-[1.5rem] [&>svg]:h-[1.5rem] [&>svg]:opacity-70 [&>svg]:text-red-500"
15916
+ ),
15917
+ children: [
15918
+ /* @__PURE__ */ jsx(OctagonXIcon, {}),
15919
+ error || "Something went wrong"
15920
+ ]
15921
+ }
15922
+ ),
15923
+ hasSteps && /* @__PURE__ */ jsx(ProcessStepList, { steps, currentStep, className: "pb-[1rem]" }),
15924
+ !hasSteps && phase === "initializing" && /* @__PURE__ */ jsxs("div", { className: "text-center text-sm text-icon3 grid gap-[1rem] justify-items-center", children: [
15925
+ /* @__PURE__ */ jsx(Spinner, {}),
15926
+ /* @__PURE__ */ jsx("p", { children: "This may take some time..." })
15927
+ ] })
15928
+ ] });
15929
+ }
15930
+
15931
+ function TemplateSuccess({ name, installedEntities, linkComponent }) {
15932
+ const LinkComponent = linkComponent || "a";
15933
+ return /* @__PURE__ */ jsxs(
15934
+ Container,
15935
+ {
15936
+ className: cn(
15937
+ "grid items-center justify-items-center gap-[1rem] content-center",
15938
+ "[&>svg]:w-[2rem] [&>svg]:h-[2rem]"
15939
+ ),
15940
+ children: [
15941
+ /* @__PURE__ */ jsx(PackageOpenIcon, {}),
15942
+ /* @__PURE__ */ jsx("h2", { className: "text-[1.25rem ]", children: "Done!" }),
15943
+ /* @__PURE__ */ jsxs("p", { className: "text-[0.875rem] text-center text-icon3 ", children: [
15944
+ "The ",
15945
+ /* @__PURE__ */ jsx("b", { className: "text-icon4", children: name }),
15946
+ " template has been successfully installed.",
15947
+ installedEntities && installedEntities.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
15948
+ /* @__PURE__ */ jsx("br", {}),
15949
+ " Installed entities are listed below."
15950
+ ] })
15951
+ ] }),
15952
+ installedEntities && installedEntities.length > 0 && /* @__PURE__ */ jsx(KeyValueList, { data: installedEntities, LinkComponent })
15953
+ ]
15954
+ }
15955
+ );
15956
+ }
15957
+
15958
+ function TemplateFailure({ errorMsg, validationErrors }) {
15959
+ const isSchemaError = errorMsg?.includes("Invalid schema for function");
15960
+ const isValidationError = errorMsg?.includes("validation issue") || validationErrors && validationErrors.length > 0;
15961
+ const getUserFriendlyMessage = () => {
15962
+ if (isValidationError) {
15963
+ return "Template installation completed but some validation issues remain. The template may still be functional, but you should review and fix these issues.";
15964
+ }
15965
+ if (isSchemaError) {
15966
+ return "There was an issue with the AI model configuration. This may be related to the selected model or AI SDK version compatibility.";
15967
+ }
15968
+ return "An unexpected error occurred during template installation.";
15969
+ };
15970
+ const getIconAndTitle = () => {
15971
+ if (isValidationError) {
15972
+ return {
15973
+ icon: /* @__PURE__ */ jsx(AlertTriangleIcon, { className: "text-yellow-500" }),
15974
+ title: "Template Installed with Warnings"
15975
+ };
15976
+ }
15977
+ return {
15978
+ icon: /* @__PURE__ */ jsx(FrownIcon, {}),
15979
+ title: "Template Installation Failed"
15980
+ };
15981
+ };
15982
+ const { icon, title } = getIconAndTitle();
15983
+ return /* @__PURE__ */ jsxs(Container, { className: "space-y-4 text-icon3 mb-[2rem] content-center max-w-2xl mx-auto", children: [
15984
+ /* @__PURE__ */ jsxs(
15985
+ "div",
15986
+ {
15987
+ className: cn(
15988
+ "grid items-center justify-items-center gap-[1rem] content-center",
15989
+ "[&>svg]:w-[2rem] [&>svg]:h-[2rem]"
15990
+ ),
15991
+ children: [
15992
+ icon,
15993
+ /* @__PURE__ */ jsxs("div", { className: "text-center space-y-2", children: [
15994
+ /* @__PURE__ */ jsx("p", { className: "text-[0.875rem] font-medium text-icon5", children: title }),
15995
+ /* @__PURE__ */ jsx("p", { className: "text-[0.875rem] text-icon3", children: getUserFriendlyMessage() })
15996
+ ] })
15997
+ ]
15998
+ }
15999
+ ),
16000
+ validationErrors && validationErrors.length > 0 && /* @__PURE__ */ jsxs("details", { className: "text-xs", children: [
16001
+ /* @__PURE__ */ jsxs("summary", { className: "cursor-pointer text-icon3 hover:text-icon4 select-none text-center", children: [
16002
+ "Show Validation Issues (",
16003
+ validationErrors.length,
16004
+ ")"
16005
+ ] }),
16006
+ /* @__PURE__ */ jsx("div", { className: "mt-4 p-3 bg-gray-100 dark:bg-gray-800 rounded text-xs overflow-auto max-h-60 text-left space-y-2", children: validationErrors.map((error, index) => /* @__PURE__ */ jsxs("div", { className: "border-l-2 border-red-400 pl-2", children: [
16007
+ /* @__PURE__ */ jsx("div", { className: "font-medium text-red-600 dark:text-red-400", children: error.type === "typescript" ? "🔴 TypeScript Error" : "⚠️ Lint Error" }),
16008
+ /* @__PURE__ */ jsx("div", { className: "text-xs font-mono text-gray-700 dark:text-gray-300 mt-1 whitespace-pre-wrap break-words", children: error.message })
16009
+ ] }, index)) })
16010
+ ] }),
16011
+ errorMsg && !isValidationError && /* @__PURE__ */ jsxs("details", { className: "text-xs", children: [
16012
+ /* @__PURE__ */ jsx("summary", { className: "cursor-pointer text-icon3 hover:text-icon4 select-none text-center", children: "Show Details" }),
16013
+ /* @__PURE__ */ jsx("div", { className: "mt-4 p-3 bg-gray-100 dark:bg-gray-800 rounded text-xs font-mono overflow-auto max-h-60 text-left", children: /* @__PURE__ */ jsx("div", { className: "whitespace-pre-wrap break-words", children: errorMsg }) })
16014
+ ] })
16015
+ ] });
16016
+ }
16017
+
16018
+ const TraceContext = createContext({});
16019
+ function TraceProvider({
16020
+ children,
16021
+ initialTraces: traces = []
16022
+ }) {
16023
+ const [open, setOpen] = useState(false);
16024
+ const [trace, setTrace] = useState(null);
16025
+ const [currentTraceIndex, setCurrentTraceIndex] = useState(0);
16026
+ const [span, setSpan] = useState(null);
16027
+ const nextTrace = () => {
16028
+ if (currentTraceIndex < traces.length - 1) {
16029
+ const nextIndex = currentTraceIndex + 1;
16030
+ setCurrentTraceIndex(nextIndex);
16031
+ const nextTrace2 = traces[nextIndex].trace;
16032
+ setTrace(nextTrace2);
16033
+ const parentSpan = nextTrace2.find((span2) => span2.parentSpanId === null) || nextTrace2[0];
16034
+ setSpan(parentSpan);
16035
+ }
16036
+ };
16037
+ const prevTrace = () => {
16038
+ if (currentTraceIndex > 0) {
16039
+ const prevIndex = currentTraceIndex - 1;
16040
+ setCurrentTraceIndex(prevIndex);
16041
+ const prevTrace2 = traces[prevIndex].trace;
16042
+ setTrace(prevTrace2);
16043
+ const parentSpan = prevTrace2.find((span2) => span2.parentSpanId === null) || prevTrace2[0];
16044
+ setSpan(parentSpan);
16045
+ }
16046
+ };
16047
+ const clearData = () => {
16048
+ setOpen(false);
16049
+ setTrace(null);
16050
+ setSpan(null);
16051
+ };
16052
+ return /* @__PURE__ */ jsx(
16053
+ TraceContext.Provider,
16054
+ {
16055
+ value: {
16056
+ isOpen: open,
16057
+ setIsOpen: setOpen,
16058
+ trace,
16059
+ setTrace,
16060
+ traces,
16061
+ currentTraceIndex,
16062
+ setCurrentTraceIndex,
16063
+ nextTrace,
16064
+ prevTrace,
16065
+ span,
16066
+ setSpan,
16067
+ clearData
16068
+ },
16069
+ children
16070
+ }
16071
+ );
16072
+ }
16073
+
16074
+ const useOpenTrace = () => {
16075
+ const {
16076
+ setTrace,
16077
+ isOpen: open,
16078
+ setIsOpen: setOpen,
16079
+ trace: currentTrace,
16080
+ setSpan,
16081
+ setCurrentTraceIndex
16082
+ } = useContext(TraceContext);
16083
+ const openTrace = (trace, traceIndex) => {
16084
+ setTrace(trace);
16085
+ const parentSpan = trace.find((span) => span.parentSpanId === null) || trace[0];
16086
+ setSpan(parentSpan);
16087
+ setCurrentTraceIndex(traceIndex);
16088
+ if (open && currentTrace?.[0]?.id !== trace[0].id) return;
16089
+ setOpen((prev) => !prev);
16090
+ };
16091
+ return { openTrace };
16092
+ };
16093
+
16094
+ const TracesTableEmpty = ({ colsCount }) => {
16095
+ 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" }) }) }) });
16096
+ };
16097
+ const TracesTableError = ({ error, colsCount }) => {
16098
+ 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 }) }) }) });
16099
+ };
16100
+ const TraceRow = ({ trace, index, isActive }) => {
16101
+ const { openTrace } = useOpenTrace();
16102
+ const hasFailure = trace.trace.some((span) => span.status.code === 2);
16103
+ return /* @__PURE__ */ jsxs(Row, { className: isActive ? "bg-surface4" : "", onClick: () => openTrace(trace.trace, index), children: [
16104
+ /* @__PURE__ */ jsx(DateTimeCell, { dateTime: new Date(trace.started / 1e3) }),
16105
+ /* @__PURE__ */ jsxs(TxtCell, { title: trace.traceId, children: [
16106
+ trace.traceId.substring(0, 7),
16107
+ "..."
16108
+ ] }),
16109
+ /* @__PURE__ */ jsx(UnitCell, { unit: "ms", children: toSigFigs(trace.duration / 1e3, 3) }),
16110
+ /* @__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 }) }) }),
16111
+ /* @__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" }) })
16112
+ ] });
16113
+ };
16114
+ const TracesTable = ({ traces, error }) => {
16115
+ const hasNoTraces = !traces || traces.length === 0;
16116
+ const { currentTraceIndex } = useContext(TraceContext);
16117
+ const colsCount = 4;
16118
+ return /* @__PURE__ */ jsxs(Table$1, { size: "small", children: [
16119
+ /* @__PURE__ */ jsxs(Thead, { children: [
16120
+ /* @__PURE__ */ jsx(Th, { width: 120, children: "Time" }),
16121
+ /* @__PURE__ */ jsx(Th, { width: "auto", children: "Trace Id" }),
16122
+ /* @__PURE__ */ jsx(Th, { width: 120, children: "Duration" }),
16123
+ /* @__PURE__ */ jsx(Th, { width: 120, children: "Spans" }),
16124
+ /* @__PURE__ */ jsx(Th, { width: 120, children: "Status" })
16125
+ ] }),
16126
+ 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(
16127
+ TraceRow,
16128
+ {
16129
+ trace,
16130
+ index,
16131
+ isActive: index === currentTraceIndex
16132
+ },
16133
+ trace.traceId + index
16134
+ )) }) })
16135
+ ] });
16136
+ };
16137
+
15249
16138
  const useResizeColumn = ({
15250
16139
  defaultWidth,
15251
16140
  minimumWidth,
@@ -15333,518 +16222,1362 @@ const TraceTree = ({ children }) => {
15333
16222
  return /* @__PURE__ */ jsx("ol", { children });
15334
16223
  };
15335
16224
 
15336
- const variantClasses = {
15337
- agent: "bg-accent1"
16225
+ const variantClasses = {
16226
+ agent: "bg-accent1"
16227
+ };
16228
+ const Time = ({ durationMs, tokenCount, variant, progressPercent, offsetPercent }) => {
16229
+ const variantClass = variant ? variantClasses[variant] : "bg-accent3";
16230
+ const percent = Math.min(100, progressPercent);
16231
+ return /* @__PURE__ */ jsxs("div", { className: "w-[80px] xl:w-[166px] shrink-0", children: [
16232
+ /* @__PURE__ */ jsx("div", { className: "bg-surface4 relative h-[6px] w-full rounded-full p-px overflow-hidden", children: /* @__PURE__ */ jsx(
16233
+ "div",
16234
+ {
16235
+ className: clsx("absolute h-1 rounded-full", variantClass),
16236
+ style: { width: `${percent}%`, left: `${offsetPercent}%` }
16237
+ }
16238
+ ) }),
16239
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4 pt-0.5", children: [
16240
+ /* @__PURE__ */ jsxs(Txt, { variant: "ui-sm", className: "text-icon2 font-medium", children: [
16241
+ toSigFigs(durationMs, 3),
16242
+ "ms"
16243
+ ] }),
16244
+ tokenCount && /* @__PURE__ */ jsxs(Txt, { variant: "ui-sm", className: "text-icon2 font-medium", children: [
16245
+ tokenCount,
16246
+ "t"
16247
+ ] })
16248
+ ] })
16249
+ ] });
16250
+ };
16251
+
16252
+ const spanIconMap = {
16253
+ tool: ToolsIcon,
16254
+ agent: AgentIcon,
16255
+ workflow: WorkflowIcon,
16256
+ memory: MemoryIcon,
16257
+ rag: TraceIcon,
16258
+ storage: DbIcon,
16259
+ eval: ScoreIcon,
16260
+ other: TraceIcon
16261
+ };
16262
+ const spanVariantClasses = {
16263
+ tool: "text-[#ECB047]",
16264
+ agent: "text-accent1",
16265
+ workflow: "text-accent3",
16266
+ memory: "text-accent2",
16267
+ rag: "text-accent2",
16268
+ storage: "text-accent2",
16269
+ eval: "text-accent4",
16270
+ other: "text-icon6"
16271
+ };
16272
+ const Span = ({
16273
+ children,
16274
+ durationMs,
16275
+ variant,
16276
+ tokenCount,
16277
+ spans,
16278
+ isRoot,
16279
+ onClick,
16280
+ isActive,
16281
+ offsetMs,
16282
+ totalDurationMs
16283
+ }) => {
16284
+ const [isExpanded, setIsExpanded] = useState(true);
16285
+ const VariantIcon = spanIconMap[variant];
16286
+ const variantClass = spanVariantClasses[variant];
16287
+ const progressPercent = durationMs / totalDurationMs * 100;
16288
+ const offsetPercent = offsetMs / totalDurationMs * 100;
16289
+ const TextEl = onClick ? "button" : "div";
16290
+ return /* @__PURE__ */ jsxs("li", { children: [
16291
+ /* @__PURE__ */ jsxs("div", { className: clsx("flex justify-between items-center gap-2 rounded-md pl-2", isActive && "bg-surface4"), children: [
16292
+ /* @__PURE__ */ jsxs("div", { className: "flex h-8 items-center gap-1 min-w-0", children: [
16293
+ spans ? /* @__PURE__ */ jsx(
16294
+ "button",
16295
+ {
16296
+ type: "button",
16297
+ "aria-label": isExpanded ? "Collapse span" : "Expand span",
16298
+ "aria-expanded": isExpanded,
16299
+ className: "text-icon3 flex h-4 w-4",
16300
+ onClick: () => setIsExpanded(!isExpanded),
16301
+ children: /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(ChevronIcon, { className: clsx("transition-transform -rotate-90", { "rotate-0": isExpanded }) }) })
16302
+ }
16303
+ ) : /* @__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" }) }),
16304
+ /* @__PURE__ */ jsxs(TextEl, { className: "flex items-center gap-2 min-w-0", onClick, children: [
16305
+ /* @__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, {}) }) }),
16306
+ /* @__PURE__ */ jsx(Txt, { variant: "ui-md", className: "text-icon6 truncate", children })
16307
+ ] })
16308
+ ] }),
16309
+ /* @__PURE__ */ jsx(
16310
+ Time,
16311
+ {
16312
+ durationMs,
16313
+ tokenCount,
16314
+ variant: variant === "agent" ? "agent" : void 0,
16315
+ progressPercent,
16316
+ offsetPercent
16317
+ }
16318
+ )
16319
+ ] }),
16320
+ isExpanded && spans && /* @__PURE__ */ jsx("div", { className: "ml-4", children: spans })
16321
+ ] });
16322
+ };
16323
+
16324
+ const Spans = ({ children }) => {
16325
+ return /* @__PURE__ */ jsx("ol", { children });
16326
+ };
16327
+
16328
+ const Trace = ({
16329
+ name,
16330
+ spans,
16331
+ durationMs,
16332
+ tokenCount,
16333
+ onClick,
16334
+ variant,
16335
+ isActive,
16336
+ totalDurationMs
16337
+ }) => {
16338
+ return /* @__PURE__ */ jsx(
16339
+ Span,
16340
+ {
16341
+ isRoot: true,
16342
+ durationMs,
16343
+ variant,
16344
+ spans: /* @__PURE__ */ jsx(Spans, { children: spans }),
16345
+ onClick,
16346
+ isActive,
16347
+ offsetMs: 0,
16348
+ totalDurationMs,
16349
+ children: name
16350
+ }
16351
+ );
16352
+ };
16353
+
16354
+ const getSpanVariant = (span) => {
16355
+ const attributes = Object.keys(span.attributes || {}).map((k) => k.toLowerCase());
16356
+ const lowerCaseName = span.name.toLowerCase();
16357
+ const isAiSpan = lowerCaseName.startsWith("ai.");
16358
+ if (isAiSpan) {
16359
+ const isAiAboutTool = lowerCaseName.includes("tool");
16360
+ if (isAiAboutTool) return "tool";
16361
+ return "other";
16362
+ }
16363
+ const hasMemoryRelatedAttributes = attributes.some((key) => key.includes("memory") || key.includes("storage"));
16364
+ if (hasMemoryRelatedAttributes) return "memory";
16365
+ const hasToolRelatedAttributes = attributes.some((key) => key.includes("tool"));
16366
+ if (hasToolRelatedAttributes) return "tool";
16367
+ const hasAgentRelatedAttributes = attributes.some((key) => key.includes("agent."));
16368
+ if (hasAgentRelatedAttributes) return "agent";
16369
+ if (lowerCaseName.includes(".insert")) {
16370
+ const evalRelatedAttribute = attributes.find((key) => String(span.attributes?.[key])?.includes("mastra_evals"));
16371
+ if (evalRelatedAttribute) return "eval";
16372
+ }
16373
+ return "other";
16374
+ };
16375
+
16376
+ function buildTree(spans, minStartTime, totalDurationMs, parentSpanId = null) {
16377
+ return spans.filter((span) => span.parentSpanId === parentSpanId).map((span) => {
16378
+ return {
16379
+ ...span,
16380
+ children: buildTree(spans, minStartTime, totalDurationMs, span.id),
16381
+ offset: (span.startTime - minStartTime) / 1e3,
16382
+ // ns to ms
16383
+ duration: span.duration / 1e3,
16384
+ totalDurationMs
16385
+ };
16386
+ });
16387
+ }
16388
+ const createSpanTree = (spans) => {
16389
+ if (spans.length === 0) return [];
16390
+ let minStartTime;
16391
+ let maxEndTime;
16392
+ const orderedTree = [];
16393
+ const listSize = spans.length;
16394
+ for (let i = listSize - 1; i >= 0; i--) {
16395
+ const span = spans[i];
16396
+ if (!minStartTime || span.startTime < minStartTime) {
16397
+ minStartTime = span.startTime;
16398
+ }
16399
+ if (!maxEndTime || span.endTime > maxEndTime) {
16400
+ maxEndTime = span.endTime;
16401
+ }
16402
+ if (span.name !== ".insert" && span.name !== "mastra.getStorage") {
16403
+ orderedTree.push(span);
16404
+ }
16405
+ }
16406
+ if (!minStartTime || !maxEndTime) return [];
16407
+ const totalDurationMs = (maxEndTime - minStartTime) / 1e3;
16408
+ return buildTree(orderedTree, minStartTime, totalDurationMs);
16409
+ };
16410
+
16411
+ const NestedSpans = ({ spanNodes }) => {
16412
+ const { span: activeSpan, setSpan } = useContext(TraceContext);
16413
+ return /* @__PURE__ */ jsx(Spans, { children: spanNodes.map((spanNode) => {
16414
+ const isActive = spanNode.id === activeSpan?.id;
16415
+ return /* @__PURE__ */ jsx(
16416
+ Span,
16417
+ {
16418
+ spans: spanNode.children.length > 0 && /* @__PURE__ */ jsx(NestedSpans, { spanNodes: spanNode.children }),
16419
+ durationMs: spanNode.duration,
16420
+ offsetMs: spanNode.offset,
16421
+ variant: getSpanVariant(spanNode),
16422
+ isActive,
16423
+ onClick: () => setSpan(spanNode),
16424
+ totalDurationMs: spanNode.totalDurationMs,
16425
+ children: spanNode.name
16426
+ },
16427
+ spanNode.id
16428
+ );
16429
+ }) });
16430
+ };
16431
+ function SpanView({ trace }) {
16432
+ const { span: activeSpan, setSpan } = useContext(TraceContext);
16433
+ const tree = createSpanTree(trace);
16434
+ return /* @__PURE__ */ jsx(TraceTree, { children: tree.map((node) => /* @__PURE__ */ jsx(
16435
+ Trace,
16436
+ {
16437
+ name: node.name,
16438
+ durationMs: node.duration,
16439
+ totalDurationMs: node.totalDurationMs,
16440
+ spans: /* @__PURE__ */ jsx(NestedSpans, { spanNodes: node.children }),
16441
+ variant: getSpanVariant(node),
16442
+ isActive: node.id === activeSpan?.id,
16443
+ onClick: () => setSpan(node)
16444
+ }
16445
+ )) });
16446
+ }
16447
+
16448
+ const Header = ({ children, border = true }) => {
16449
+ return /* @__PURE__ */ jsx(
16450
+ "header",
16451
+ {
16452
+ className: clsx("h-header-default z-50 flex w-full items-center gap-[18px] bg-transparent px-5", {
16453
+ "border-b-sm border-border1": border
16454
+ }),
16455
+ children
16456
+ }
16457
+ );
15338
16458
  };
15339
- const Time = ({ durationMs, tokenCount, variant, progressPercent, offsetPercent }) => {
15340
- const variantClass = variant ? variantClasses[variant] : "bg-accent3";
15341
- const percent = Math.min(100, progressPercent);
15342
- return /* @__PURE__ */ jsxs("div", { className: "w-[80px] xl:w-[166px] shrink-0", children: [
15343
- /* @__PURE__ */ jsx("div", { className: "bg-surface4 relative h-[6px] w-full rounded-full p-px overflow-hidden", children: /* @__PURE__ */ jsx(
15344
- "div",
15345
- {
15346
- className: clsx("absolute h-1 rounded-full", variantClass),
15347
- style: { width: `${percent}%`, left: `${offsetPercent}%` }
15348
- }
15349
- ) }),
15350
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4 pt-0.5", children: [
15351
- /* @__PURE__ */ jsxs(Txt, { variant: "ui-sm", className: "text-icon2 font-medium", children: [
15352
- toSigFigs(durationMs, 3),
15353
- "ms"
15354
- ] }),
15355
- tokenCount && /* @__PURE__ */ jsxs(Txt, { variant: "ui-sm", className: "text-icon2 font-medium", children: [
15356
- tokenCount,
15357
- "t"
15358
- ] })
15359
- ] })
15360
- ] });
16459
+ const HeaderTitle = ({ children }) => {
16460
+ return /* @__PURE__ */ jsx(Txt, { as: "h1", variant: "ui-lg", className: "font-medium text-white", children });
15361
16461
  };
15362
-
15363
- const spanIconMap = {
15364
- tool: ToolsIcon,
15365
- agent: AgentIcon,
15366
- workflow: WorkflowIcon,
15367
- memory: MemoryIcon,
15368
- rag: TraceIcon,
15369
- storage: DbIcon,
15370
- eval: ScoreIcon,
15371
- other: TraceIcon
16462
+ const HeaderAction = ({ children }) => {
16463
+ return /* @__PURE__ */ jsx("div", { className: "ml-auto", children });
15372
16464
  };
15373
- const spanVariantClasses = {
15374
- tool: "text-[#ECB047]",
15375
- agent: "text-accent1",
15376
- workflow: "text-accent3",
15377
- memory: "text-accent2",
15378
- rag: "text-accent2",
15379
- storage: "text-accent2",
15380
- eval: "text-accent4",
15381
- other: "text-icon6"
16465
+ const HeaderGroup = ({ children }) => {
16466
+ return /* @__PURE__ */ jsx("div", { className: "gap-lg flex items-center", children });
15382
16467
  };
15383
- const Span = ({
15384
- children,
15385
- durationMs,
15386
- variant,
15387
- tokenCount,
15388
- spans,
15389
- isRoot,
15390
- onClick,
15391
- isActive,
15392
- offsetMs,
15393
- totalDurationMs
15394
- }) => {
15395
- const [isExpanded, setIsExpanded] = useState(true);
15396
- const VariantIcon = spanIconMap[variant];
15397
- const variantClass = spanVariantClasses[variant];
15398
- const progressPercent = durationMs / totalDurationMs * 100;
15399
- const offsetPercent = offsetMs / totalDurationMs * 100;
15400
- const TextEl = onClick ? "button" : "div";
15401
- return /* @__PURE__ */ jsxs("li", { children: [
15402
- /* @__PURE__ */ jsxs("div", { className: clsx("flex justify-between items-center gap-2 rounded-md pl-2", isActive && "bg-surface4"), children: [
15403
- /* @__PURE__ */ jsxs("div", { className: "flex h-8 items-center gap-1 min-w-0", children: [
15404
- spans ? /* @__PURE__ */ jsx(
15405
- "button",
16468
+
16469
+ function TraceDetails() {
16470
+ const { trace, currentTraceIndex, prevTrace, nextTrace, traces } = useContext(TraceContext);
16471
+ const actualTrace = traces[currentTraceIndex];
16472
+ if (!actualTrace || !trace) return null;
16473
+ const hasFailure = trace.some((span) => span.status.code === 2);
16474
+ return /* @__PURE__ */ jsxs("aside", { children: [
16475
+ /* @__PURE__ */ jsxs(Header, { children: [
16476
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
16477
+ /* @__PURE__ */ jsx(Button$1, { className: "bg-transparent border-none", onClick: prevTrace, disabled: currentTraceIndex === 0, children: /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(ChevronUp, {}) }) }),
16478
+ /* @__PURE__ */ jsx(
16479
+ Button$1,
15406
16480
  {
15407
- type: "button",
15408
- "aria-label": isExpanded ? "Collapse span" : "Expand span",
15409
- "aria-expanded": isExpanded,
15410
- className: "text-icon3 flex h-4 w-4",
15411
- onClick: () => setIsExpanded(!isExpanded),
15412
- children: /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(ChevronIcon, { className: clsx("transition-transform -rotate-90", { "rotate-0": isExpanded }) }) })
16481
+ className: "bg-transparent border-none",
16482
+ onClick: nextTrace,
16483
+ disabled: currentTraceIndex === traces.length - 1,
16484
+ children: /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(ChevronDown, {}) })
15413
16485
  }
15414
- ) : /* @__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" }) }),
15415
- /* @__PURE__ */ jsxs(TextEl, { className: "flex items-center gap-2 min-w-0", onClick, children: [
15416
- /* @__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, {}) }) }),
15417
- /* @__PURE__ */ jsx(Txt, { variant: "ui-md", className: "text-icon6 truncate", children })
15418
- ] })
16486
+ )
15419
16487
  ] }),
15420
- /* @__PURE__ */ jsx(
15421
- Time,
15422
- {
15423
- durationMs,
15424
- tokenCount,
15425
- variant: variant === "agent" ? "agent" : void 0,
15426
- progressPercent,
15427
- offsetPercent
15428
- }
15429
- )
16488
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 justify-between w-full", children: [
16489
+ /* @__PURE__ */ jsxs(Txt, { variant: "ui-lg", className: "font-medium text-icon5 shrink-0", children: [
16490
+ "Trace ",
16491
+ /* @__PURE__ */ jsx("span", { className: "ml-2 text-icon3", children: actualTrace.traceId.substring(0, 7) })
16492
+ ] }),
16493
+ hasFailure && /* @__PURE__ */ jsx(Badge$1, { variant: "error", icon: /* @__PURE__ */ jsx(X, {}), children: "Failed" })
16494
+ ] })
15430
16495
  ] }),
15431
- isExpanded && spans && /* @__PURE__ */ jsx("div", { className: "ml-4", children: spans })
16496
+ /* @__PURE__ */ jsx("div", { className: "p-5", children: /* @__PURE__ */ jsx(SpanView, { trace }) })
16497
+ ] });
16498
+ }
16499
+
16500
+ function formatDuration(duration, fixedPoint = 2) {
16501
+ const durationInSecs = duration / 1e3;
16502
+ return durationInSecs.toFixed(fixedPoint);
16503
+ }
16504
+ function formatOtelTimestamp(otelTimestamp) {
16505
+ const date = new Date(otelTimestamp / 1e3);
16506
+ return new Intl.DateTimeFormat("en-US", {
16507
+ month: "numeric",
16508
+ day: "numeric",
16509
+ year: "numeric",
16510
+ hour: "numeric",
16511
+ minute: "numeric",
16512
+ second: "numeric",
16513
+ hour12: true
16514
+ }).format(date);
16515
+ }
16516
+ function formatOtelTimestamp2(otelTimestamp) {
16517
+ const date = new Date(otelTimestamp / 1e6);
16518
+ return new Intl.DateTimeFormat("en-US", {
16519
+ month: "numeric",
16520
+ day: "numeric",
16521
+ year: "numeric",
16522
+ hour: "numeric",
16523
+ minute: "numeric",
16524
+ second: "numeric",
16525
+ hour12: true
16526
+ }).format(date);
16527
+ }
16528
+ function transformKey(key) {
16529
+ if (key.includes(".argument.")) {
16530
+ return `Input`;
16531
+ }
16532
+ if (key.includes(".result")) {
16533
+ return "Output";
16534
+ }
16535
+ const newKey = key.split(".").join(" ").split("_").join(" ").replaceAll("ai", "AI");
16536
+ return newKey.substring(0, 1).toUpperCase() + newKey.substring(1);
16537
+ }
16538
+ function cleanString(string) {
16539
+ return string.replace(/\\n/g, "").replace(/\n/g, "").replace(/\s+/g, " ").trim();
16540
+ }
16541
+ const allowedAiSpanAttributes = [
16542
+ "operation.name",
16543
+ "ai.operationId",
16544
+ "ai.model.provider",
16545
+ "ai.model.id",
16546
+ "ai.prompt.format",
16547
+ "ai.prompt.messages",
16548
+ "ai.prompt.tools",
16549
+ "ai.prompt.toolChoice",
16550
+ "ai.settings.toolChoice",
16551
+ "ai.schema",
16552
+ "ai.settings.output",
16553
+ "ai.response.object",
16554
+ "ai.response.text",
16555
+ "ai.response.timestamp",
16556
+ "componentName",
16557
+ "ai.usage.promptTokens",
16558
+ "ai.usage.completionTokens"
16559
+ ];
16560
+
16561
+ function SpanDetail() {
16562
+ const { span, setSpan, trace, setIsOpen } = useContext(TraceContext);
16563
+ if (!span || !trace) return null;
16564
+ const prevSpan = () => {
16565
+ const currentIndex = trace.findIndex((t) => t.id === span.id);
16566
+ if (currentIndex !== -1 && currentIndex < trace.length - 1) {
16567
+ setSpan(trace[currentIndex + 1]);
16568
+ }
16569
+ };
16570
+ const nextSpan = () => {
16571
+ const currentIndex = trace.findIndex((t) => t.id === span.id);
16572
+ if (currentIndex !== -1 && currentIndex > 0) {
16573
+ setSpan(trace[currentIndex - 1]);
16574
+ }
16575
+ };
16576
+ const SpanIcon = spanIconMap[getSpanVariant(span)];
16577
+ const variantClass = spanVariantClasses[getSpanVariant(span)];
16578
+ return /* @__PURE__ */ jsxs("aside", { children: [
16579
+ /* @__PURE__ */ jsxs(Header, { children: [
16580
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
16581
+ /* @__PURE__ */ jsx(Button$1, { className: "bg-transparent border-none", onClick: prevSpan, children: /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(ChevronUp, {}) }) }),
16582
+ /* @__PURE__ */ jsx(Button$1, { className: "bg-transparent border-none", onClick: nextSpan, children: /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(ChevronDown, {}) }) })
16583
+ ] }),
16584
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(Txt, { variant: "ui-lg", className: "font-medium text-icon5", as: "h2", children: [
16585
+ "Span ",
16586
+ /* @__PURE__ */ jsx("span", { className: "ml-2 text-icon3", children: span.id.substring(0, 7) })
16587
+ ] }) }),
16588
+ /* @__PURE__ */ jsx("div", { className: "ml-auto flex items-center gap-2", children: /* @__PURE__ */ jsx(Button$1, { className: "bg-transparent border-none", onClick: () => setIsOpen(false), children: /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(X, {}) }) }) })
16589
+ ] }),
16590
+ /* @__PURE__ */ jsxs("div", { className: "p-5", children: [
16591
+ /* @__PURE__ */ jsxs(Txt, { variant: "header-md", as: "h3", className: "text-icon-6 flex items-center gap-4 pb-3", children: [
16592
+ /* @__PURE__ */ jsx(Icon, { size: "lg", className: "bg-surface4 p-1 rounded-md", children: /* @__PURE__ */ jsx(SpanIcon, { className: variantClass }) }),
16593
+ span.name
16594
+ ] }),
16595
+ /* @__PURE__ */ jsx("div", { className: "flex flex-row gap-2 items-center", children: span.status.code === 2 ? /* @__PURE__ */ jsxs(Badge$1, { variant: "error", icon: /* @__PURE__ */ jsx(X, {}), children: [
16596
+ "Failed in ",
16597
+ toSigFigs(span.duration, 3),
16598
+ "ms"
16599
+ ] }) : /* @__PURE__ */ jsxs(Badge$1, { icon: /* @__PURE__ */ jsx(LatencyIcon, {}), variant: "success", children: [
16600
+ toSigFigs(span.duration, 3),
16601
+ "ms"
16602
+ ] }) }),
16603
+ /* @__PURE__ */ jsx("hr", { className: "border-border1 border-sm my-5" }),
16604
+ /* @__PURE__ */ jsxs("dl", { className: "grid grid-cols-2 justify-between gap-2", children: [
16605
+ /* @__PURE__ */ jsx("dt", { className: "font-medium text-ui-md text-icon3", children: "ID" }),
16606
+ /* @__PURE__ */ jsx("dd", { className: "text-ui-md text-icon6", children: span.id }),
16607
+ /* @__PURE__ */ jsx("dt", { className: "font-medium text-ui-md text-icon3", children: "Created at" }),
16608
+ /* @__PURE__ */ jsx("dd", { className: "text-ui-md text-icon6", children: span.startTime ? formatOtelTimestamp(span.startTime) : "" })
16609
+ ] }),
16610
+ span.attributes && /* @__PURE__ */ jsx(Attributes, { attributes: span.attributes }),
16611
+ span.events?.length > 0 && /* @__PURE__ */ jsx(Events, { span })
16612
+ ] })
15432
16613
  ] });
16614
+ }
16615
+ function Attributes({ attributes }) {
16616
+ if (!attributes) return null;
16617
+ const entries = Object.entries(attributes);
16618
+ if (entries.length === 0) return null;
16619
+ const keysToHide = ["http.request_id", "componentName"];
16620
+ return /* @__PURE__ */ jsx("div", { children: entries.filter(([key]) => !keysToHide.includes(key)).map(([key, val]) => {
16621
+ return /* @__PURE__ */ jsxs("div", { children: [
16622
+ /* @__PURE__ */ jsx("hr", { className: "border-border1 border-sm my-5" }),
16623
+ /* @__PURE__ */ jsx(Txt, { as: "h4", variant: "ui-md", className: "text-icon3 pb-2", children: transformKey(key) }),
16624
+ /* @__PURE__ */ jsx(AttributeValue, { value: val })
16625
+ ] }, key);
16626
+ }) });
16627
+ }
16628
+ const AttributeValue = ({ value }) => {
16629
+ if (!value)
16630
+ return /* @__PURE__ */ jsx(Txt, { as: "p", variant: "ui-md", className: "text-icon6", children: "N/A" });
16631
+ if (typeof value === "number" || typeof value === "boolean") {
16632
+ return /* @__PURE__ */ jsx(Txt, { as: "p", variant: "ui-md", className: "text-icon6", children: String(value) });
16633
+ }
16634
+ if (typeof value === "object") {
16635
+ return /* @__PURE__ */ jsx(SyntaxHighlighter$1, { data: value });
16636
+ }
16637
+ try {
16638
+ return /* @__PURE__ */ jsx(SyntaxHighlighter$1, { data: JSON.parse(value) });
16639
+ } catch {
16640
+ return /* @__PURE__ */ jsx(Txt, { as: "p", variant: "ui-md", className: "text-icon6", children: String(value) });
16641
+ }
15433
16642
  };
16643
+ function Events({ span }) {
16644
+ if (!span.events) return null;
16645
+ return /* @__PURE__ */ jsxs("div", { children: [
16646
+ /* @__PURE__ */ jsx("hr", { className: "border-border1 border-sm my-5" }),
16647
+ /* @__PURE__ */ jsx(Txt, { as: "p", variant: "ui-md", className: "text-icon6 pb-2", children: "Events" }),
16648
+ span.events.map((event) => {
16649
+ const isLast = event === span.events[span.events.length - 1];
16650
+ return /* @__PURE__ */ jsxs(React__default.Fragment, { children: [
16651
+ /* @__PURE__ */ jsxs("div", { children: [
16652
+ /* @__PURE__ */ jsxs("dl", { className: "grid grid-cols-2 justify-between gap-2 pb-2", children: [
16653
+ /* @__PURE__ */ jsx("dt", { className: "font-medium text-ui-md text-icon3", children: "Name" }),
16654
+ /* @__PURE__ */ jsx("dd", { className: "text-ui-md text-icon6", children: event.name }),
16655
+ /* @__PURE__ */ jsx("dt", { className: "font-medium text-ui-md text-icon3", children: "Time" }),
16656
+ /* @__PURE__ */ jsx("dd", { className: "text-ui-md text-icon6", children: event.timeUnixNano ? formatOtelTimestamp2(Number(event.timeUnixNano)) : "N/A" })
16657
+ ] }),
16658
+ event.attributes?.length > 0 ? /* @__PURE__ */ jsx("ul", { className: "space-y-2", children: event.attributes.filter((attribute) => attribute !== null).map((attribute) => /* @__PURE__ */ jsxs("li", { children: [
16659
+ /* @__PURE__ */ jsx(Txt, { as: "h4", variant: "ui-md", className: "text-icon3 pb-2", children: transformKey(attribute.key) }),
16660
+ /* @__PURE__ */ jsx(AttributeValue, { value: attribute.value })
16661
+ ] }, attribute.key)) }) : null
16662
+ ] }, event.name),
16663
+ !isLast && /* @__PURE__ */ jsx("hr", { className: "border-border1 border-sm my-5" })
16664
+ ] }, event.name);
16665
+ })
16666
+ ] });
16667
+ }
15434
16668
 
15435
- const Spans = ({ children }) => {
15436
- return /* @__PURE__ */ jsx("ol", { children });
15437
- };
15438
-
15439
- const Trace = ({
15440
- name,
15441
- spans,
15442
- durationMs,
15443
- tokenCount,
15444
- onClick,
15445
- variant,
15446
- isActive,
15447
- totalDurationMs
15448
- }) => {
16669
+ const TracesSidebar = ({ onResize }) => {
15449
16670
  return /* @__PURE__ */ jsx(
15450
- Span,
16671
+ MastraResizablePanel,
15451
16672
  {
15452
- isRoot: true,
15453
- durationMs,
15454
- variant,
15455
- spans: /* @__PURE__ */ jsx(Spans, { children: spans }),
15456
- onClick,
15457
- isActive,
15458
- offsetMs: 0,
15459
- totalDurationMs,
15460
- children: name
16673
+ className: "h-full absolute right-0 inset-y-0 bg-surface2",
16674
+ defaultWidth: 80,
16675
+ minimumWidth: 50,
16676
+ maximumWidth: 80,
16677
+ setCurrentWidth: onResize,
16678
+ children: /* @__PURE__ */ jsxs("div", { className: "h-full grid grid-cols-2", children: [
16679
+ /* @__PURE__ */ jsx("div", { className: "overflow-x-scroll w-full h-[calc(100%-40px)]", children: /* @__PURE__ */ jsx(TraceDetails, {}) }),
16680
+ /* @__PURE__ */ jsx("div", { className: "h-[calc(100%-40px)] overflow-x-scroll w-full border-l border-border1", children: /* @__PURE__ */ jsx(SpanDetail, {}) })
16681
+ ] })
15461
16682
  }
15462
16683
  );
15463
16684
  };
15464
16685
 
15465
- const getSpanVariant = (span) => {
15466
- const attributes = Object.keys(span.attributes || {}).map((k) => k.toLowerCase());
15467
- const lowerCaseName = span.name.toLowerCase();
15468
- const isAiSpan = lowerCaseName.startsWith("ai.");
15469
- if (isAiSpan) {
15470
- const isAiAboutTool = lowerCaseName.includes("tool");
15471
- if (isAiAboutTool) return "tool";
15472
- return "other";
15473
- }
15474
- const hasMemoryRelatedAttributes = attributes.some((key) => key.includes("memory") || key.includes("storage"));
15475
- if (hasMemoryRelatedAttributes) return "memory";
15476
- const hasToolRelatedAttributes = attributes.some((key) => key.includes("tool"));
15477
- if (hasToolRelatedAttributes) return "tool";
15478
- const hasAgentRelatedAttributes = attributes.some((key) => key.includes("agent."));
15479
- if (hasAgentRelatedAttributes) return "agent";
15480
- if (lowerCaseName.includes(".insert")) {
15481
- const evalRelatedAttribute = attributes.find((key) => String(span.attributes?.[key])?.includes("mastra_evals"));
15482
- if (evalRelatedAttribute) return "eval";
16686
+ function TracesView({
16687
+ isLoading,
16688
+ error,
16689
+ traces,
16690
+ runId,
16691
+ stepName,
16692
+ className,
16693
+ setEndOfListElement
16694
+ }) {
16695
+ if (isLoading) {
16696
+ return /* @__PURE__ */ jsx(TracesViewSkeleton, {});
15483
16697
  }
15484
- return "other";
16698
+ return /* @__PURE__ */ jsx(TraceProvider, { initialTraces: traces || [], children: /* @__PURE__ */ jsx(
16699
+ TracesViewInner,
16700
+ {
16701
+ traces,
16702
+ error,
16703
+ runId,
16704
+ stepName,
16705
+ className,
16706
+ setEndOfListElement
16707
+ }
16708
+ ) });
16709
+ }
16710
+ function TracesViewInner({ traces, error, runId, stepName, className, setEndOfListElement }) {
16711
+ const hasRunRef = useRef(false);
16712
+ const [sidebarWidth, setSidebarWidth] = useState(100);
16713
+ const { isOpen: open, setTrace, setIsOpen, setSpan } = useContext(TraceContext);
16714
+ useEffect(() => {
16715
+ if (hasRunRef.current) return;
16716
+ if (!runId || !stepName) return;
16717
+ const matchingTrace = traces.find((trace) => trace.runId === runId);
16718
+ if (!matchingTrace) return;
16719
+ const matchingSpan = matchingTrace.trace.find((span) => span.name.includes(stepName));
16720
+ if (!matchingSpan) return;
16721
+ setTrace(matchingTrace.trace);
16722
+ setSpan(matchingSpan);
16723
+ setIsOpen(true);
16724
+ hasRunRef.current = true;
16725
+ }, [runId, traces, setTrace]);
16726
+ return /* @__PURE__ */ jsxs("div", { className: clsx("h-full relative overflow-hidden flex", className), children: [
16727
+ /* @__PURE__ */ jsxs("div", { className: "h-full overflow-y-scroll w-full", children: [
16728
+ /* @__PURE__ */ jsx(TracesTable, { traces, error }),
16729
+ /* @__PURE__ */ jsx("div", { "aria-hidden": true, ref: setEndOfListElement })
16730
+ ] }),
16731
+ open && /* @__PURE__ */ jsx(TracesSidebar, { width: sidebarWidth, onResize: setSidebarWidth })
16732
+ ] });
16733
+ }
16734
+ const TracesViewSkeleton = () => {
16735
+ 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" }) }) });
15485
16736
  };
15486
16737
 
15487
- function buildTree(spans, minStartTime, totalDurationMs, parentSpanId = null) {
15488
- return spans.filter((span) => span.parentSpanId === parentSpanId).map((span) => {
15489
- return {
15490
- ...span,
15491
- children: buildTree(spans, minStartTime, totalDurationMs, span.id),
15492
- offset: (span.startTime - minStartTime) / 1e3,
15493
- // ns to ms
15494
- duration: span.duration / 1e3,
15495
- totalDurationMs
16738
+ const formatHierarchicalSpans = (spans) => {
16739
+ if (!spans || spans.length === 0) {
16740
+ return [];
16741
+ }
16742
+ const spanMap = /* @__PURE__ */ new Map();
16743
+ const rootSpans = [];
16744
+ spans.forEach((spanRecord) => {
16745
+ const startDate = new Date(spanRecord.startedAt);
16746
+ const endDate = spanRecord.endedAt ? new Date(spanRecord.endedAt) : void 0;
16747
+ const uiSpan = {
16748
+ id: spanRecord.spanId,
16749
+ name: spanRecord.name,
16750
+ type: spanRecord.spanType,
16751
+ latency: endDate ? endDate.getTime() - startDate.getTime() : 0,
16752
+ startTime: startDate.toISOString(),
16753
+ endTime: endDate ? endDate.toISOString() : void 0,
16754
+ spans: []
15496
16755
  };
16756
+ spanMap.set(spanRecord.spanId, uiSpan);
16757
+ });
16758
+ spans.forEach((spanRecord) => {
16759
+ const uiSpan = spanMap.get(spanRecord.spanId);
16760
+ if (spanRecord?.parentSpanId === null) {
16761
+ rootSpans.push(uiSpan);
16762
+ } else {
16763
+ const parent = spanMap.get(spanRecord.parentSpanId);
16764
+ if (parent) {
16765
+ parent.spans.push(uiSpan);
16766
+ } else {
16767
+ rootSpans.push(uiSpan);
16768
+ }
16769
+ }
15497
16770
  });
16771
+ const sortSpansByStartTime = (spans2) => {
16772
+ return spans2.sort((a, b) => new Date(a.startTime).getTime() - new Date(b.startTime).getTime());
16773
+ };
16774
+ const sortedRootSpans = sortSpansByStartTime(rootSpans);
16775
+ const sortNestedSpans = (spans2) => {
16776
+ spans2.forEach((span) => {
16777
+ if (span.spans && span.spans.length > 0) {
16778
+ span.spans = sortSpansByStartTime(span.spans);
16779
+ sortNestedSpans(span.spans);
16780
+ }
16781
+ });
16782
+ };
16783
+ sortNestedSpans(sortedRootSpans);
16784
+ return sortedRootSpans;
16785
+ };
16786
+
16787
+ const spanTypePrefixes = ["agent", "workflow", "llm", "tool"];
16788
+ function getSpanTypeUi(type) {
16789
+ const typePrefix = type?.toLowerCase().split("_")[0];
16790
+ const spanTypeToUiElements = {
16791
+ agent: {
16792
+ icon: /* @__PURE__ */ jsx(AgentIcon, {}),
16793
+ color: "oklch(0.75 0.15 250)",
16794
+ label: "Agent"
16795
+ },
16796
+ workflow: {
16797
+ icon: /* @__PURE__ */ jsx(WorkflowIcon, {}),
16798
+ color: "oklch(0.75 0.15 200)",
16799
+ label: "Workflow"
16800
+ },
16801
+ llm: {
16802
+ icon: /* @__PURE__ */ jsx(BrainIcon, {}),
16803
+ color: "oklch(0.75 0.15 320)",
16804
+ label: "LLM"
16805
+ },
16806
+ tool: {
16807
+ icon: /* @__PURE__ */ jsx(ToolsIcon, {}),
16808
+ color: "oklch(0.75 0.15 100)",
16809
+ label: "Tool"
16810
+ }
16811
+ };
16812
+ if (typePrefix in spanTypeToUiElements) {
16813
+ return spanTypeToUiElements[typePrefix];
16814
+ }
16815
+ return null;
16816
+ }
16817
+
16818
+ function TraceTimelineSpan({
16819
+ span,
16820
+ depth = 0,
16821
+ onSpanClick,
16822
+ selectedSpanId,
16823
+ isLastChild,
16824
+ overallLatency,
16825
+ overallStartTime
16826
+ }) {
16827
+ const { Link } = useLinkComponent();
16828
+ const [isHovered, setIsHovered] = useState(false);
16829
+ const hasChildren = span.spans && span.spans.length > 0;
16830
+ const isRootSpan = depth === 0;
16831
+ const percentageSpanLatency = overallLatency ? Math.ceil(span.latency / overallLatency * 100) : 0;
16832
+ const overallStartTimeDate = overallStartTime ? new Date(overallStartTime) : null;
16833
+ const spanStartTimeDate = span.startTime ? new Date(span.startTime) : null;
16834
+ const spanStartTimeShift = spanStartTimeDate && overallStartTimeDate ? spanStartTimeDate.getTime() - overallStartTimeDate.getTime() : 0;
16835
+ const percentageSpanStartTime = overallLatency && Math.floor(spanStartTimeShift / overallLatency * 100);
16836
+ const spanUI = getSpanTypeUi(span?.type);
16837
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
16838
+ /* @__PURE__ */ jsx(
16839
+ "button",
16840
+ {
16841
+ onClick: () => onSpanClick?.(span.id),
16842
+ onMouseEnter: () => setIsHovered(true),
16843
+ onMouseLeave: () => setIsHovered(false),
16844
+ type: "button",
16845
+ "aria-label": `View details for span ${span.name}`,
16846
+ className: cn(
16847
+ "rounded-md transition-colors cursor-pointer flex py-[0.5rem] opacity-80 min-h-[3.5rem]",
16848
+ "mt-[1rem] xl:mt-0",
16849
+ {
16850
+ "bg-icon1/30 text-white": selectedSpanId === span.id,
16851
+ "bg-icon1/10 opacity-100": isHovered
16852
+ }
16853
+ ),
16854
+ style: { paddingLeft: `${depth * 1.4}rem` },
16855
+ children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-[1rem] w-full", children: [
16856
+ !isRootSpan && /* @__PURE__ */ jsx(TreePositionMark, { isLastChild, hasChildren: Boolean(hasChildren) }),
16857
+ /* @__PURE__ */ jsxs("div", { className: cn("text-[0.875rem] flex items-center text-left break-all gap-[0.5rem] text-[#fff] w-full"), children: [
16858
+ spanUI?.icon && /* @__PURE__ */ jsx("span", { className: "[&>svg]:w-[1.25em] [&>svg]:h-[1.25em] [&>svg]:shrink-0", style: { color: spanUI?.color }, children: spanUI?.icon }),
16859
+ span.name
16860
+ ] })
16861
+ ] })
16862
+ }
16863
+ ),
16864
+ /* @__PURE__ */ jsxs(HoverCard.Root, { openDelay: 250, children: [
16865
+ /* @__PURE__ */ jsxs(
16866
+ HoverCard.Trigger,
16867
+ {
16868
+ className: cn(
16869
+ "rounded-md transition-colors content-center cursor-help grid min-h-[3.5rem] opacity-80 px-[2.5rem] items-center relative",
16870
+ "bg-surface2 xl:bg-surface3",
16871
+ 'xl:last-of-type:before:content-[""] last-of-type:before:absolute last-of-type:before:bottom-[-1rem] last-of-type:before:h-[1rem] last-of-type:before:w-full last-of-type:before:bg-surface3',
16872
+ 'xl:first-of-type:before:content-[""] first-of-type:before:absolute first-of-type:before:top-[-1rem] first-of-type:before:h-[1rem] first-of-type:before:w-full first-of-type:before:bg-surface3',
16873
+ {
16874
+ "bg-icon1/10 xl:bg-icon1/10 opacity-100": isHovered
16875
+ }
16876
+ ),
16877
+ onMouseEnter: () => setIsHovered(true),
16878
+ onMouseLeave: () => setIsHovered(false),
16879
+ children: [
16880
+ /* @__PURE__ */ jsx("div", { className: "text-left text-[0.75rem] relative w-full h-[1.4rem] ", children: /* @__PURE__ */ jsxs(
16881
+ "span",
16882
+ {
16883
+ className: cn(
16884
+ "absolute flex pt-[0.1rem] items-center gap-[0.5rem] text-icon5",
16885
+ "[&>svg]:w-[1.25em] [&>svg]:h-[1.25em] [&>svg]:shrink-0 [&>svg]:opacity-50 mb-[0.1em] [&>svg]:mb-[0.1rem]"
16886
+ ),
16887
+ style: { width: `${percentageSpanLatency}%`, left: `${percentageSpanStartTime}%` },
16888
+ children: [
16889
+ /* @__PURE__ */ jsx(ChevronsLeftRight, {}),
16890
+ /* @__PURE__ */ jsxs(
16891
+ "span",
16892
+ {
16893
+ style: {
16894
+ transform: percentageSpanStartTime && percentageSpanStartTime > 70 ? "translateX(calc((100% + 2rem) * -1))" : "none"
16895
+ },
16896
+ children: [
16897
+ (span.latency / 1e3).toFixed(2),
16898
+ " s"
16899
+ ]
16900
+ }
16901
+ )
16902
+ ]
16903
+ }
16904
+ ) }),
16905
+ /* @__PURE__ */ jsx("div", { className: "relative w-full bg-surface5 h-[3px] ", children: /* @__PURE__ */ jsx(
16906
+ "div",
16907
+ {
16908
+ className: cn("bg-icon1 h-full absolute rounded-full"),
16909
+ style: {
16910
+ width: `${percentageSpanLatency}%`,
16911
+ left: `${percentageSpanStartTime}%`,
16912
+ backgroundColor: spanUI?.color
16913
+ }
16914
+ }
16915
+ ) })
16916
+ ]
16917
+ }
16918
+ ),
16919
+ /* @__PURE__ */ jsx(HoverCard.Portal, { children: /* @__PURE__ */ jsxs(
16920
+ HoverCard.Content,
16921
+ {
16922
+ className: "z-[100] w-auto max-w-[25rem] rounded-md bg-[#222] p-[.5rem] px-[1rem] pr-[1.5rem] text-[.75rem] text-icon5 text-center border border-border1",
16923
+ sideOffset: 5,
16924
+ side: "top",
16925
+ children: [
16926
+ /* @__PURE__ */ jsxs(
16927
+ "div",
16928
+ {
16929
+ className: cn(
16930
+ "text-[0.875rem] flex items-center gap-[0.5rem] mb-[1rem]",
16931
+ "[&>svg]:w-[1.25em] [&>svg]:h-[1.25em] [&>svg]:shrink-0 [&>svg]:opacity-50"
16932
+ ),
16933
+ children: [
16934
+ /* @__PURE__ */ jsx(TimerIcon, {}),
16935
+ " Span Timing"
16936
+ ]
16937
+ }
16938
+ ),
16939
+ /* @__PURE__ */ jsx(
16940
+ KeyValueList,
16941
+ {
16942
+ className: " [&>dd]:text-[0.875rem] [&>dt]:text-[0.875rem] [&>dt]:min-h-0 [&>dd]:min-h-0",
16943
+ data: [
16944
+ {
16945
+ key: "Latency",
16946
+ label: "Latency",
16947
+ value: `${span.latency} ms`,
16948
+ icon: /* @__PURE__ */ jsx(ChevronsLeftRightIcon, {})
16949
+ },
16950
+ {
16951
+ key: "startTime",
16952
+ label: "Started at",
16953
+ value: span.startTime ? format$1(new Date(span.startTime), "hh:mm:ss:SSS a") : "-",
16954
+ icon: /* @__PURE__ */ jsx(ChevronFirstIcon, {})
16955
+ },
16956
+ {
16957
+ key: "endTime",
16958
+ label: "Ended at",
16959
+ value: span.endTime ? format$1(new Date(span.endTime), "hh:mm:ss:SSS a") : "-",
16960
+ icon: /* @__PURE__ */ jsx(ChevronLastIcon, {})
16961
+ },
16962
+ {
16963
+ key: "startShift",
16964
+ label: "Start Shift",
16965
+ value: `${spanStartTimeShift}ms`,
16966
+ icon: /* @__PURE__ */ jsx(ChevronsRightIcon, {})
16967
+ }
16968
+ ],
16969
+ LinkComponent: Link
16970
+ }
16971
+ ),
16972
+ /* @__PURE__ */ jsx(HoverCard.Arrow, { className: "fill-surface5" })
16973
+ ]
16974
+ }
16975
+ ) })
16976
+ ] }),
16977
+ hasChildren && span.spans?.map((childSpan, idx, array) => {
16978
+ const isLastChild2 = idx === array.length - 1;
16979
+ return /* @__PURE__ */ jsx(
16980
+ TraceTimelineSpan,
16981
+ {
16982
+ span: childSpan,
16983
+ depth: depth + 1,
16984
+ onSpanClick,
16985
+ selectedSpanId,
16986
+ isLastChild: isLastChild2,
16987
+ overallLatency,
16988
+ overallStartTime
16989
+ },
16990
+ childSpan.id
16991
+ );
16992
+ })
16993
+ ] });
15498
16994
  }
15499
- const createSpanTree = (spans) => {
15500
- if (spans.length === 0) return [];
15501
- let minStartTime;
15502
- let maxEndTime;
15503
- const orderedTree = [];
15504
- const listSize = spans.length;
15505
- for (let i = listSize - 1; i >= 0; i--) {
15506
- const span = spans[i];
15507
- if (!minStartTime || span.startTime < minStartTime) {
15508
- minStartTime = span.startTime;
15509
- }
15510
- if (!maxEndTime || span.endTime > maxEndTime) {
15511
- maxEndTime = span.endTime;
15512
- }
15513
- if (span.name !== ".insert" && span.name !== "mastra.getStorage") {
15514
- orderedTree.push(span);
15515
- }
15516
- }
15517
- if (!minStartTime || !maxEndTime) return [];
15518
- const totalDurationMs = (maxEndTime - minStartTime) / 1e3;
15519
- return buildTree(orderedTree, minStartTime, totalDurationMs);
15520
- };
15521
-
15522
- const NestedSpans = ({ spanNodes }) => {
15523
- const { span: activeSpan, setSpan } = useContext(TraceContext);
15524
- return /* @__PURE__ */ jsx(Spans, { children: spanNodes.map((spanNode) => {
15525
- const isActive = spanNode.id === activeSpan?.id;
15526
- return /* @__PURE__ */ jsx(
15527
- Span,
15528
- {
15529
- spans: spanNode.children.length > 0 && /* @__PURE__ */ jsx(NestedSpans, { spanNodes: spanNode.children }),
15530
- durationMs: spanNode.duration,
15531
- offsetMs: spanNode.offset,
15532
- variant: getSpanVariant(spanNode),
15533
- isActive,
15534
- onClick: () => setSpan(spanNode),
15535
- totalDurationMs: spanNode.totalDurationMs,
15536
- children: spanNode.name
15537
- },
15538
- spanNode.id
15539
- );
15540
- }) });
15541
- };
15542
- function SpanView({ trace }) {
15543
- const { span: activeSpan, setSpan } = useContext(TraceContext);
15544
- const tree = createSpanTree(trace);
15545
- return /* @__PURE__ */ jsx(TraceTree, { children: tree.map((node) => /* @__PURE__ */ jsx(
15546
- Trace,
16995
+ function TreePositionMark({ isLastChild, hasChildren = false }) {
16996
+ return /* @__PURE__ */ jsx(
16997
+ "div",
15547
16998
  {
15548
- name: node.name,
15549
- durationMs: node.duration,
15550
- totalDurationMs: node.totalDurationMs,
15551
- spans: /* @__PURE__ */ jsx(NestedSpans, { spanNodes: node.children }),
15552
- variant: getSpanVariant(node),
15553
- isActive: node.id === activeSpan?.id,
15554
- onClick: () => setSpan(node)
16999
+ className: cn(
17000
+ "w-[1.5rem] h-[2.2rem] relative opacity-50 ",
17001
+ 'after:content-[""] after:absolute after:left-0 after:top-0 after:bottom-0 after:w-[0px] after:border-r-[0.5px] after:border-white after:border-dashed',
17002
+ 'before:content-[""] before:absolute before:left-0 before:top-[50%] before:w-full before:h-[0px] before:border-b-[0.5px] before:border-white before:border-dashed',
17003
+ {
17004
+ "after:bottom-[50%]": isLastChild
17005
+ }
17006
+ ),
17007
+ children: hasChildren && /* @__PURE__ */ jsx("div", { className: "absolute -right-[1px] top-[50%] bottom-0 w-[0px] border-r-[0.5px] border-white border-dashed" })
15555
17008
  }
15556
- )) });
17009
+ );
15557
17010
  }
15558
17011
 
15559
- const Header = ({ children, border = true }) => {
15560
- return /* @__PURE__ */ jsx(
15561
- "header",
15562
- {
15563
- className: clsx("h-header-default z-50 flex w-full items-center gap-[18px] bg-transparent px-5", {
15564
- "border-b-sm border-border1": border
15565
- }),
15566
- children
15567
- }
17012
+ function TraceTimelineLegend({ spans = [] }) {
17013
+ const activeSpanTypes = spanTypePrefixes.filter(
17014
+ (typePrefix) => spans.some((span) => span?.spanType?.startsWith(typePrefix))
15568
17015
  );
15569
- };
15570
- const HeaderTitle = ({ children }) => {
15571
- return /* @__PURE__ */ jsx(Txt, { as: "h1", variant: "ui-lg", className: "font-medium text-white", children });
15572
- };
15573
- const HeaderAction = ({ children }) => {
15574
- return /* @__PURE__ */ jsx("div", { className: "ml-auto", children });
15575
- };
15576
- const HeaderGroup = ({ children }) => {
15577
- return /* @__PURE__ */ jsx("div", { className: "gap-lg flex items-center", children });
15578
- };
17016
+ return /* @__PURE__ */ jsx("div", { className: cn("flex justify-start gap-[2rem] mb-2 text-[0.75rem] opacity-90"), children: activeSpanTypes.map((item) => {
17017
+ const spanUI = getSpanTypeUi(item);
17018
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-[.5rem]"), children: [
17019
+ /* @__PURE__ */ jsx("span", { className: cn("[&>svg]:w-[1.2em] [&>svg]:h-[1.2em]"), style: { color: spanUI?.color }, children: spanUI?.icon && spanUI.icon }),
17020
+ spanUI?.label
17021
+ ] }, item);
17022
+ }) });
17023
+ }
15579
17024
 
15580
- function TraceDetails() {
15581
- const { trace, currentTraceIndex, prevTrace, nextTrace, traces } = useContext(TraceContext);
15582
- const actualTrace = traces[currentTraceIndex];
15583
- if (!actualTrace || !trace) return null;
15584
- const hasFailure = trace.some((span) => span.status.code === 2);
15585
- return /* @__PURE__ */ jsxs("aside", { children: [
15586
- /* @__PURE__ */ jsxs(Header, { children: [
15587
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
15588
- /* @__PURE__ */ jsx(Button$1, { className: "bg-transparent border-none", onClick: prevTrace, disabled: currentTraceIndex === 0, children: /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(ChevronUp, {}) }) }),
15589
- /* @__PURE__ */ jsx(
15590
- Button$1,
15591
- {
15592
- className: "bg-transparent border-none",
15593
- onClick: nextTrace,
15594
- disabled: currentTraceIndex === traces.length - 1,
15595
- children: /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(ChevronDown, {}) })
15596
- }
15597
- )
17025
+ function TraceTimeline({
17026
+ spans = [],
17027
+ hierarchicalSpans = [],
17028
+ onSpanClick,
17029
+ selectedSpanId,
17030
+ isLoading,
17031
+ className
17032
+ }) {
17033
+ const overallLatency = hierarchicalSpans?.[0]?.latency || 0;
17034
+ const overallStartTime = hierarchicalSpans?.[0]?.startTime || "";
17035
+ return /* @__PURE__ */ jsxs("div", { className: cn("grid gap-[1rem]", className), children: [
17036
+ /* @__PURE__ */ jsxs("div", { className: "flex w-full justify-between pr-[2.5rem]", children: [
17037
+ /* @__PURE__ */ jsxs(SideDialogHeading, { as: "h2", children: [
17038
+ /* @__PURE__ */ jsx(ListTreeIcon, {}),
17039
+ " Timeline"
15598
17040
  ] }),
15599
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 justify-between w-full", children: [
15600
- /* @__PURE__ */ jsxs(Txt, { variant: "ui-lg", className: "font-medium text-icon5 shrink-0", children: [
15601
- "Trace ",
15602
- /* @__PURE__ */ jsx("span", { className: "ml-2 text-icon3", children: actualTrace.traceId.substring(0, 7) })
15603
- ] }),
15604
- hasFailure && /* @__PURE__ */ jsx(Badge$1, { variant: "error", icon: /* @__PURE__ */ jsx(X, {}), children: "Failed" })
15605
- ] })
17041
+ /* @__PURE__ */ jsx(TraceTimelineLegend, { spans })
15606
17042
  ] }),
15607
- /* @__PURE__ */ jsx("div", { className: "p-5", children: /* @__PURE__ */ jsx(SpanView, { trace }) })
17043
+ isLoading ? /* @__PURE__ */ jsxs(
17044
+ "div",
17045
+ {
17046
+ className: cn(
17047
+ "flex items-center text-[0.875rem] gap-[1rem] bg-surface3/50 rounded-md p-[1.5rem] mr-[1.5rem] justify-center text-icon3 mt-[.5rem]",
17048
+ "[&_svg]:w-[1.25em] [&_svg]:h-[1.25em] [&_svg]:opacity-50"
17049
+ ),
17050
+ children: [
17051
+ /* @__PURE__ */ jsx(Spinner, {}),
17052
+ " Loading Trace Timeline ..."
17053
+ ]
17054
+ }
17055
+ ) : /* @__PURE__ */ jsx(
17056
+ "div",
17057
+ {
17058
+ className: cn(
17059
+ "overflow-y-auto grid items-start content-start gap-y-[2px] xl:py-[1rem]",
17060
+ "xl:grid-cols-[3fr_2fr] xl:gap-x-[1rem]"
17061
+ ),
17062
+ children: hierarchicalSpans?.map((span) => /* @__PURE__ */ jsx(
17063
+ TraceTimelineSpan,
17064
+ {
17065
+ span,
17066
+ onSpanClick,
17067
+ selectedSpanId,
17068
+ overallLatency,
17069
+ overallStartTime
17070
+ },
17071
+ span.id
17072
+ ))
17073
+ }
17074
+ )
15608
17075
  ] });
15609
17076
  }
15610
17077
 
15611
- function formatDuration(duration, fixedPoint = 2) {
15612
- const durationInSecs = duration / 1e3;
15613
- return durationInSecs.toFixed(fixedPoint);
15614
- }
15615
- function formatOtelTimestamp(otelTimestamp) {
15616
- const date = new Date(otelTimestamp / 1e3);
15617
- return new Intl.DateTimeFormat("en-US", {
15618
- month: "numeric",
15619
- day: "numeric",
15620
- year: "numeric",
15621
- hour: "numeric",
15622
- minute: "numeric",
15623
- second: "numeric",
15624
- hour12: true
15625
- }).format(date);
15626
- }
15627
- function formatOtelTimestamp2(otelTimestamp) {
15628
- const date = new Date(otelTimestamp / 1e6);
15629
- return new Intl.DateTimeFormat("en-US", {
15630
- month: "numeric",
15631
- day: "numeric",
15632
- year: "numeric",
15633
- hour: "numeric",
15634
- minute: "numeric",
15635
- second: "numeric",
15636
- hour12: true
15637
- }).format(date);
15638
- }
15639
- function transformKey(key) {
15640
- if (key.includes(".argument.")) {
15641
- return `Input`;
17078
+ function TraceSpanUsage({ traceUsage, traceSpans = [], spanUsage, className }) {
17079
+ if (!traceUsage && !spanUsage) {
17080
+ console.warn("No usage data available");
17081
+ return null;
15642
17082
  }
15643
- if (key.includes(".result")) {
15644
- return "Output";
17083
+ if (traceUsage && spanUsage) {
17084
+ console.warn("Only one of traceUsage or spanUsage should be provided");
17085
+ return null;
15645
17086
  }
15646
- const newKey = key.split(".").join(" ").split("_").join(" ").replaceAll("ai", "AI");
15647
- return newKey.substring(0, 1).toUpperCase() + newKey.substring(1);
15648
- }
15649
- function cleanString(string) {
15650
- return string.replace(/\\n/g, "").replace(/\n/g, "").replace(/\s+/g, " ").trim();
15651
- }
15652
- const allowedAiSpanAttributes = [
15653
- "operation.name",
15654
- "ai.operationId",
15655
- "ai.model.provider",
15656
- "ai.model.id",
15657
- "ai.prompt.format",
15658
- "ai.prompt.messages",
15659
- "ai.prompt.tools",
15660
- "ai.prompt.toolChoice",
15661
- "ai.settings.toolChoice",
15662
- "ai.schema",
15663
- "ai.settings.output",
15664
- "ai.response.object",
15665
- "ai.response.text",
15666
- "ai.response.timestamp",
15667
- "componentName",
15668
- "ai.usage.promptTokens",
15669
- "ai.usage.completionTokens"
15670
- ];
15671
-
15672
- function SpanDetail() {
15673
- const { span, setSpan, trace, setIsOpen } = useContext(TraceContext);
15674
- if (!span || !trace) return null;
15675
- const prevSpan = () => {
15676
- const currentIndex = trace.findIndex((t) => t.id === span.id);
15677
- if (currentIndex !== -1 && currentIndex < trace.length - 1) {
15678
- setSpan(trace[currentIndex + 1]);
15679
- }
15680
- };
15681
- const nextSpan = () => {
15682
- const currentIndex = trace.findIndex((t) => t.id === span.id);
15683
- if (currentIndex !== -1 && currentIndex > 0) {
15684
- setSpan(trace[currentIndex - 1]);
15685
- }
15686
- };
15687
- const SpanIcon = spanIconMap[getSpanVariant(span)];
15688
- const variantClass = spanVariantClasses[getSpanVariant(span)];
15689
- return /* @__PURE__ */ jsxs("aside", { children: [
15690
- /* @__PURE__ */ jsxs(Header, { children: [
15691
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
15692
- /* @__PURE__ */ jsx(Button$1, { className: "bg-transparent border-none", onClick: prevSpan, children: /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(ChevronUp, {}) }) }),
15693
- /* @__PURE__ */ jsx(Button$1, { className: "bg-transparent border-none", onClick: nextSpan, children: /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(ChevronDown, {}) }) })
15694
- ] }),
15695
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(Txt, { variant: "ui-lg", className: "font-medium text-icon5", as: "h2", children: [
15696
- "Span ",
15697
- /* @__PURE__ */ jsx("span", { className: "ml-2 text-icon3", children: span.id.substring(0, 7) })
15698
- ] }) }),
15699
- /* @__PURE__ */ jsx("div", { className: "ml-auto flex items-center gap-2", children: /* @__PURE__ */ jsx(Button$1, { className: "bg-transparent border-none", onClick: () => setIsOpen(false), children: /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(X, {}) }) }) })
15700
- ] }),
15701
- /* @__PURE__ */ jsxs("div", { className: "p-5", children: [
15702
- /* @__PURE__ */ jsxs(Txt, { variant: "header-md", as: "h3", className: "text-icon-6 flex items-center gap-4 pb-3", children: [
15703
- /* @__PURE__ */ jsx(Icon, { size: "lg", className: "bg-surface4 p-1 rounded-md", children: /* @__PURE__ */ jsx(SpanIcon, { className: variantClass }) }),
15704
- span.name
15705
- ] }),
15706
- /* @__PURE__ */ jsx("div", { className: "flex flex-row gap-2 items-center", children: span.status.code === 2 ? /* @__PURE__ */ jsxs(Badge$1, { variant: "error", icon: /* @__PURE__ */ jsx(X, {}), children: [
15707
- "Failed in ",
15708
- toSigFigs(span.duration, 3),
15709
- "ms"
15710
- ] }) : /* @__PURE__ */ jsxs(Badge$1, { icon: /* @__PURE__ */ jsx(LatencyIcon, {}), variant: "success", children: [
15711
- toSigFigs(span.duration, 3),
15712
- "ms"
15713
- ] }) }),
15714
- /* @__PURE__ */ jsx("hr", { className: "border-border1 border-sm my-5" }),
15715
- /* @__PURE__ */ jsxs("dl", { className: "grid grid-cols-2 justify-between gap-2", children: [
15716
- /* @__PURE__ */ jsx("dt", { className: "font-medium text-ui-md text-icon3", children: "ID" }),
15717
- /* @__PURE__ */ jsx("dd", { className: "text-ui-md text-icon6", children: span.id }),
15718
- /* @__PURE__ */ jsx("dt", { className: "font-medium text-ui-md text-icon3", children: "Created at" }),
15719
- /* @__PURE__ */ jsx("dd", { className: "text-ui-md text-icon6", children: span.startTime ? formatOtelTimestamp(span.startTime) : "" })
15720
- ] }),
15721
- span.attributes && /* @__PURE__ */ jsx(Attributes, { attributes: span.attributes }),
15722
- span.events?.length > 0 && /* @__PURE__ */ jsx(Events, { span })
15723
- ] })
15724
- ] });
17087
+ const generationSpans = traceSpans.filter((span) => span.spanType === "llm_generation");
17088
+ const tokensByProvider = generationSpans.reduce(
17089
+ (acc, span) => {
17090
+ const spanUsage2 = span.attributes?.usage || {};
17091
+ const model = span?.attributes?.model || "";
17092
+ const provider = span?.attributes?.provider || "";
17093
+ const spanModelProvider = `${provider}${provider && model ? " / " : ""}${model}`;
17094
+ if (!acc?.[spanModelProvider]) {
17095
+ acc[spanModelProvider] = { promptTokens: 0, completionTokens: 0, totalTokens: 0 };
17096
+ }
17097
+ acc[spanModelProvider].promptTokens += spanUsage2.promptTokens || 0;
17098
+ acc[spanModelProvider].completionTokens += spanUsage2.completionTokens || 0;
17099
+ acc[spanModelProvider].totalTokens += (spanUsage2.promptTokens || 0) + (spanUsage2.completionTokens || 0);
17100
+ return acc;
17101
+ },
17102
+ {}
17103
+ );
17104
+ const traceTokensBasedOnSpans = Object.keys(
17105
+ tokensByProvider
17106
+ ).reduce(
17107
+ (acc, provider) => {
17108
+ const { promptTokens, completionTokens, totalTokens } = tokensByProvider[provider];
17109
+ acc.promptTokens += promptTokens;
17110
+ acc.completionTokens += completionTokens;
17111
+ acc.totalTokens += totalTokens;
17112
+ return acc;
17113
+ },
17114
+ { promptTokens: 0, completionTokens: 0, totalTokens: 0 }
17115
+ );
17116
+ const tokensByProviderValid = JSON.stringify(traceUsage) === JSON.stringify(traceTokensBasedOnSpans);
17117
+ const tokenPresentations = {
17118
+ totalTokens: {
17119
+ label: "Total LLM Tokens",
17120
+ icon: /* @__PURE__ */ jsx(CoinsIcon, {})
17121
+ },
17122
+ promptTokens: {
17123
+ label: "Prompt Tokens",
17124
+ icon: /* @__PURE__ */ jsx(ArrowRightIcon, {})
17125
+ },
17126
+ completionTokens: {
17127
+ label: "Completion Tokens",
17128
+ icon: /* @__PURE__ */ jsx(ArrowRightToLineIcon, {})
17129
+ }
17130
+ };
17131
+ const usageKeyOrder = ["totalTokens", "promptTokens", "completionTokens"];
17132
+ const usageAsArray = Object.entries(traceUsage || spanUsage || {}).map(([key, value]) => ({ key, value })).sort((a, b) => usageKeyOrder.indexOf(a.key) - usageKeyOrder.indexOf(b.key));
17133
+ return /* @__PURE__ */ jsx(
17134
+ "div",
17135
+ {
17136
+ className: cn(
17137
+ "grid gap-[1.5rem]",
17138
+ {
17139
+ "xl:grid-cols-3": usageAsArray.length === 3,
17140
+ "xl:grid-cols-2": usageAsArray.length === 2
17141
+ },
17142
+ className
17143
+ ),
17144
+ children: usageAsArray.map(({ key, value }) => /* @__PURE__ */ jsxs(
17145
+ "div",
17146
+ {
17147
+ className: cn("bg-white/5 p-[1rem] px-[1.25rem] rounded-lg text-[0.875rem]", {
17148
+ "min-h-[5.5rem]": traceUsage
17149
+ }),
17150
+ children: [
17151
+ /* @__PURE__ */ jsxs(
17152
+ "div",
17153
+ {
17154
+ className: cn(
17155
+ "grid grid-cols-[1.5rem_1fr_auto] gap-[.5rem] items-center",
17156
+ "[&>svg]:w-[1.5em] [&>svg]:h-[1.5em] [&>svg]:opacity-70"
17157
+ ),
17158
+ children: [
17159
+ tokenPresentations?.[key]?.icon,
17160
+ /* @__PURE__ */ jsx("span", { className: "text-[0.875rem]", children: tokenPresentations?.[key]?.label }),
17161
+ /* @__PURE__ */ jsx("b", { className: "text-[1rem]", children: value })
17162
+ ]
17163
+ }
17164
+ ),
17165
+ tokensByProviderValid && /* @__PURE__ */ jsx("div", { className: "text-[0.875rem] mt-[0.5rem] pl-[2rem] ", children: Object.entries(tokensByProvider).map(([provider, providerTokens]) => /* @__PURE__ */ jsxs(
17166
+ "dl",
17167
+ {
17168
+ className: "grid grid-cols-[1fr_auto] gap-x-[1rem] gap-y-[.25rem] justify-between text-icon3",
17169
+ children: [
17170
+ /* @__PURE__ */ jsx("dt", { children: provider }),
17171
+ /* @__PURE__ */ jsx("dd", { children: providerTokens?.[key] })
17172
+ ]
17173
+ },
17174
+ provider
17175
+ )) })
17176
+ ]
17177
+ },
17178
+ key
17179
+ ))
17180
+ }
17181
+ );
15725
17182
  }
15726
- function Attributes({ attributes }) {
15727
- if (!attributes) return null;
15728
- const entries = Object.entries(attributes);
15729
- if (entries.length === 0) return null;
15730
- const keysToHide = ["http.request_id", "componentName"];
15731
- return /* @__PURE__ */ jsx("div", { children: entries.filter(([key]) => !keysToHide.includes(key)).map(([key, val]) => {
15732
- return /* @__PURE__ */ jsxs("div", { children: [
15733
- /* @__PURE__ */ jsx("hr", { className: "border-border1 border-sm my-5" }),
15734
- /* @__PURE__ */ jsx(Txt, { as: "h4", variant: "ui-md", className: "text-icon3 pb-2", children: transformKey(key) }),
15735
- /* @__PURE__ */ jsx(AttributeValue, { value: val })
15736
- ] }, key);
15737
- }) });
17183
+
17184
+ function getTraceInfo(trace) {
17185
+ if (!trace) {
17186
+ return [];
17187
+ }
17188
+ return [
17189
+ {
17190
+ key: "entityId",
17191
+ label: "Entity Id",
17192
+ value: [
17193
+ {
17194
+ id: trace?.metadata?.resourceId,
17195
+ name: trace?.attributes?.agentId || trace?.attributes?.workflowId || "-",
17196
+ path: trace?.attributes?.agentId ? `/agents/${trace?.metadata?.resourceId}` : trace?.attributes?.workflowId ? `/workflows/${trace?.metadata?.resourceId}` : void 0
17197
+ }
17198
+ ]
17199
+ },
17200
+ {
17201
+ key: "entityType",
17202
+ label: "Entity Type",
17203
+ value: [
17204
+ {
17205
+ id: trace?.attributes?.agentId || trace?.attributes?.workflowId,
17206
+ name: trace?.attributes?.agentId ? "Agent" : trace?.attributes?.workflowId ? "Workflow" : "-",
17207
+ path: trace?.attributes?.agentId ? `/agents` : trace?.attributes?.workflowId ? `/workflows` : void 0
17208
+ }
17209
+ ]
17210
+ },
17211
+ {
17212
+ key: "status",
17213
+ label: "Status",
17214
+ value: trace?.attributes?.status || "-"
17215
+ },
17216
+ {
17217
+ key: "createdAt",
17218
+ label: "Created at",
17219
+ value: trace?.createdAt ? format(new Date(trace?.createdAt), "PPpp") : "-"
17220
+ }
17221
+ ];
15738
17222
  }
15739
- const AttributeValue = ({ value }) => {
15740
- if (!value)
15741
- return /* @__PURE__ */ jsx(Txt, { as: "p", variant: "ui-md", className: "text-icon6", children: "N/A" });
15742
- if (typeof value === "number" || typeof value === "boolean") {
15743
- return /* @__PURE__ */ jsx(Txt, { as: "p", variant: "ui-md", className: "text-icon6", children: String(value) });
17223
+ function getSpanInfo({ span, withTraceId = true, withSpanId = true }) {
17224
+ if (!span) {
17225
+ return [];
15744
17226
  }
15745
- if (typeof value === "object") {
15746
- return /* @__PURE__ */ jsx(SyntaxHighlighter$1, { data: value });
17227
+ const baseInfo = [
17228
+ {
17229
+ key: "spanType",
17230
+ label: "Span Type",
17231
+ value: span?.spanType
17232
+ },
17233
+ {
17234
+ key: "createdAt",
17235
+ label: "Created at",
17236
+ value: span?.createdAt ? format(new Date(span?.createdAt), "MMM dd, HH:mm:ss.SSS") : "-"
17237
+ },
17238
+ {
17239
+ key: "startedAt",
17240
+ label: "Started At",
17241
+ value: span?.startedAt ? format(new Date(span.startedAt), "MMM dd, HH:mm:ss.SSS") : "-"
17242
+ },
17243
+ {
17244
+ key: "endedAt",
17245
+ label: "Ended At",
17246
+ value: span?.endedAt ? format(new Date(span.endedAt), "MMM dd, HH:mm:ss.SSS") : "-"
17247
+ }
17248
+ ];
17249
+ if (withTraceId) {
17250
+ baseInfo.unshift({
17251
+ key: "traceId",
17252
+ label: "Trace Id",
17253
+ value: span?.traceId
17254
+ });
15747
17255
  }
15748
- try {
15749
- return /* @__PURE__ */ jsx(SyntaxHighlighter$1, { data: JSON.parse(value) });
15750
- } catch {
15751
- return /* @__PURE__ */ jsx(Txt, { as: "p", variant: "ui-md", className: "text-icon6", children: String(value) });
17256
+ if (withSpanId) {
17257
+ baseInfo.unshift({
17258
+ key: "spanId",
17259
+ label: "Span Id",
17260
+ value: span?.spanId
17261
+ });
15752
17262
  }
15753
- };
15754
- function Events({ span }) {
15755
- if (!span.events) return null;
15756
- return /* @__PURE__ */ jsxs("div", { children: [
15757
- /* @__PURE__ */ jsx("hr", { className: "border-border1 border-sm my-5" }),
15758
- /* @__PURE__ */ jsx(Txt, { as: "p", variant: "ui-md", className: "text-icon6 pb-2", children: "Events" }),
15759
- span.events.map((event) => {
15760
- const isLast = event === span.events[span.events.length - 1];
15761
- return /* @__PURE__ */ jsxs(React__default.Fragment, { children: [
15762
- /* @__PURE__ */ jsxs("div", { children: [
15763
- /* @__PURE__ */ jsxs("dl", { className: "grid grid-cols-2 justify-between gap-2 pb-2", children: [
15764
- /* @__PURE__ */ jsx("dt", { className: "font-medium text-ui-md text-icon3", children: "Name" }),
15765
- /* @__PURE__ */ jsx("dd", { className: "text-ui-md text-icon6", children: event.name }),
15766
- /* @__PURE__ */ jsx("dt", { className: "font-medium text-ui-md text-icon3", children: "Time" }),
15767
- /* @__PURE__ */ jsx("dd", { className: "text-ui-md text-icon6", children: event.timeUnixNano ? formatOtelTimestamp2(Number(event.timeUnixNano)) : "N/A" })
15768
- ] }),
15769
- event.attributes?.length > 0 ? /* @__PURE__ */ jsx("ul", { className: "space-y-2", children: event.attributes.filter((attribute) => attribute !== null).map((attribute) => /* @__PURE__ */ jsxs("li", { children: [
15770
- /* @__PURE__ */ jsx(Txt, { as: "h4", variant: "ui-md", className: "text-icon3 pb-2", children: transformKey(attribute.key) }),
15771
- /* @__PURE__ */ jsx(AttributeValue, { value: attribute.value })
15772
- ] }, attribute.key)) }) : null
15773
- ] }, event.name),
15774
- !isLast && /* @__PURE__ */ jsx("hr", { className: "border-border1 border-sm my-5" })
15775
- ] }, event.name);
15776
- })
17263
+ return baseInfo;
17264
+ }
17265
+
17266
+ function SpanDetails({ span }) {
17267
+ if (!span) {
17268
+ return null;
17269
+ }
17270
+ return /* @__PURE__ */ jsxs("div", { className: "grid gap-[1.5rem] mb-[2rem]", children: [
17271
+ /* @__PURE__ */ jsx(SideDialogCodeSection, { title: "Input", codeStr: JSON.stringify(span.input || null, null, 2) }),
17272
+ /* @__PURE__ */ jsx(SideDialogCodeSection, { title: "Output", codeStr: JSON.stringify(span.output || null, null, 2) }),
17273
+ /* @__PURE__ */ jsx(SideDialogCodeSection, { title: "Metadata", codeStr: JSON.stringify(span.metadata || null, null, 2) }),
17274
+ /* @__PURE__ */ jsx(SideDialogCodeSection, { title: "Attributes", codeStr: JSON.stringify(span.attributes || null, null, 2) })
15777
17275
  ] });
15778
17276
  }
15779
17277
 
15780
- const TracesSidebar = ({ onResize }) => {
15781
- return /* @__PURE__ */ jsx(
15782
- MastraResizablePanel,
17278
+ function SpanDialog({
17279
+ span,
17280
+ isOpen,
17281
+ onClose,
17282
+ onNext,
17283
+ onPrevious,
17284
+ onViewToggle,
17285
+ spanInfo = []
17286
+ }) {
17287
+ const { Link } = useLinkComponent();
17288
+ return /* @__PURE__ */ jsxs(
17289
+ SideDialog,
15783
17290
  {
15784
- className: "h-full absolute right-0 inset-y-0 bg-surface2",
15785
- defaultWidth: 80,
15786
- minimumWidth: 50,
15787
- maximumWidth: 80,
15788
- setCurrentWidth: onResize,
15789
- children: /* @__PURE__ */ jsxs("div", { className: "h-full grid grid-cols-2", children: [
15790
- /* @__PURE__ */ jsx("div", { className: "overflow-x-scroll w-full h-[calc(100%-40px)]", children: /* @__PURE__ */ jsx(TraceDetails, {}) }),
15791
- /* @__PURE__ */ jsx("div", { className: "h-[calc(100%-40px)] overflow-x-scroll w-full border-l border-border1", children: /* @__PURE__ */ jsx(SpanDetail, {}) })
15792
- ] })
17291
+ dialogTitle: "Observability Span",
17292
+ dialogDescription: "View and analyze span details",
17293
+ isOpen,
17294
+ onClose,
17295
+ hasCloseButton: true,
17296
+ className: cn("w-[calc(100vw-20rem)] max-w-[60%]", "3xl:max-w-[50rem]", "4xl:max-w-[40%]"),
17297
+ children: [
17298
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between pr-[1.5rem]", children: [
17299
+ /* @__PURE__ */ jsx(SideDialogTop, { onNext, onPrevious, showInnerNav: true, children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-[1rem] text-icon4 text-[0.875rem]", children: [
17300
+ /* @__PURE__ */ jsxs(TextAndIcon, { children: [
17301
+ /* @__PURE__ */ jsx(EyeIcon, {}),
17302
+ " ",
17303
+ getShortId(span?.traceId)
17304
+ ] }),
17305
+ "›",
17306
+ /* @__PURE__ */ jsxs(TextAndIcon, { children: [
17307
+ /* @__PURE__ */ jsx(ChevronsLeftRightEllipsisIcon, {}),
17308
+ getShortId(span?.spanId)
17309
+ ] })
17310
+ ] }) }),
17311
+ /* @__PURE__ */ jsx("button", { className: "flex items-center gap-1", onClick: onViewToggle, children: /* @__PURE__ */ jsx(PanelTopIcon, {}) })
17312
+ ] }),
17313
+ /* @__PURE__ */ jsxs("div", { className: "p-[1.5rem] px-[2.5rem] overflow-y-auto grid gap-[1.5rem] content-start", children: [
17314
+ /* @__PURE__ */ jsxs(SideDialogHeader, { className: "flex gap-[1rem] items-baseline pr-[2.5rem]", children: [
17315
+ /* @__PURE__ */ jsxs(SideDialogHeading, { children: [
17316
+ /* @__PURE__ */ jsx(ChevronsLeftRightEllipsisIcon, {}),
17317
+ " ",
17318
+ span?.name
17319
+ ] }),
17320
+ /* @__PURE__ */ jsxs(TextAndIcon, { children: [
17321
+ /* @__PURE__ */ jsx(HashIcon, {}),
17322
+ " ",
17323
+ span?.spanId
17324
+ ] })
17325
+ ] }),
17326
+ span?.attributes?.usage && /* @__PURE__ */ jsx(TraceSpanUsage, { spanUsage: span.attributes.usage, className: "mt-[1.5rem]" }),
17327
+ /* @__PURE__ */ jsx(KeyValueList, { data: spanInfo, LinkComponent: Link, className: "mt-[1.5rem]" }),
17328
+ /* @__PURE__ */ jsx(SpanDetails, { span })
17329
+ ] })
17330
+ ]
15793
17331
  }
15794
17332
  );
15795
- };
17333
+ }
15796
17334
 
15797
- function TracesView({
15798
- isLoading,
15799
- error,
15800
- traces,
15801
- runId,
15802
- stepName,
15803
- className,
15804
- setEndOfListElement
17335
+ function TraceDialog({
17336
+ traceId,
17337
+ traceSpans = [],
17338
+ traceDetails,
17339
+ isOpen,
17340
+ onClose,
17341
+ onNext,
17342
+ onPrevious,
17343
+ isLoadingSpans
15805
17344
  }) {
15806
- if (isLoading) {
15807
- return /* @__PURE__ */ jsx(TracesViewSkeleton, {});
15808
- }
15809
- return /* @__PURE__ */ jsx(TraceProvider, { initialTraces: traces || [], children: /* @__PURE__ */ jsx(
15810
- TracesViewInner,
15811
- {
15812
- traces,
15813
- error,
15814
- runId,
15815
- stepName,
15816
- className,
15817
- setEndOfListElement
17345
+ const { Link } = useLinkComponent();
17346
+ const [dialogIsOpen, setDialogIsOpen] = useState(false);
17347
+ const [selectedSpanId, setSelectedSpanId] = useState(void 0);
17348
+ const [combinedView, setCombinedView] = useState(false);
17349
+ const selectedSpan = traceSpans.find((span) => span.spanId === selectedSpanId);
17350
+ const hierarchicalSpans = useMemo(() => {
17351
+ return formatHierarchicalSpans(traceSpans);
17352
+ }, [traceSpans]);
17353
+ const flatSpans = useMemo(() => {
17354
+ const flattenSpans = (spans) => {
17355
+ const result = [];
17356
+ const traverse = (span) => {
17357
+ result.push(span);
17358
+ if (span.spans && span.spans.length > 0) {
17359
+ span.spans.forEach(traverse);
17360
+ }
17361
+ };
17362
+ spans.forEach(traverse);
17363
+ return result;
17364
+ };
17365
+ return flattenSpans(hierarchicalSpans);
17366
+ }, [hierarchicalSpans]);
17367
+ const handleSpanClick = (id) => {
17368
+ setSelectedSpanId(id);
17369
+ setDialogIsOpen(true);
17370
+ };
17371
+ const toNextSpan = () => {
17372
+ const currentIndex = flatSpans.findIndex((span) => span.id === selectedSpanId);
17373
+ const nextItem = flatSpans[currentIndex + 1];
17374
+ if (nextItem) {
17375
+ setSelectedSpanId(nextItem.id);
15818
17376
  }
15819
- ) });
17377
+ };
17378
+ const toPreviousSpan = () => {
17379
+ const currentIndex = flatSpans.findIndex((span) => span.id === selectedSpanId);
17380
+ const previousItem = flatSpans[currentIndex - 1];
17381
+ if (previousItem) {
17382
+ setSelectedSpanId(previousItem.id);
17383
+ }
17384
+ };
17385
+ const thereIsNextSpan = () => {
17386
+ const currentIndex = flatSpans.findIndex((span) => span.id === selectedSpanId);
17387
+ return currentIndex < flatSpans.length - 1;
17388
+ };
17389
+ const thereIsPreviousSpan = () => {
17390
+ const currentIndex = flatSpans.findIndex((span) => span.id === selectedSpanId);
17391
+ return currentIndex > 0;
17392
+ };
17393
+ const traceInfo = getTraceInfo(traceDetails);
17394
+ const selectedSpanInfo = getSpanInfo({ span: selectedSpan, withTraceId: !combinedView, withSpanId: combinedView });
17395
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
17396
+ /* @__PURE__ */ jsxs(
17397
+ SideDialog,
17398
+ {
17399
+ dialogTitle: "Observability Trace",
17400
+ dialogDescription: "View and analyze trace details",
17401
+ isOpen,
17402
+ onClose,
17403
+ hasCloseButton: !dialogIsOpen || combinedView,
17404
+ className: cn("w-[calc(100vw-20rem)] max-w-[75%]", "3xl:max-w-[60rem]", "4xl:max-w-[60%]"),
17405
+ children: [
17406
+ /* @__PURE__ */ jsx(SideDialogTop, { onNext, onPrevious, showInnerNav: true, children: /* @__PURE__ */ jsxs(TextAndIcon, { children: [
17407
+ /* @__PURE__ */ jsx(EyeIcon, {}),
17408
+ " ",
17409
+ getShortId(traceId)
17410
+ ] }) }),
17411
+ /* @__PURE__ */ jsxs(
17412
+ "div",
17413
+ {
17414
+ className: cn("pt-[1.5rem] pl-[2.5rem] grid-rows-[auto_1fr] grid h-full overflow-y-auto", {
17415
+ "grid-rows-[auto_1fr_1fr]": selectedSpan && combinedView
17416
+ }),
17417
+ children: [
17418
+ /* @__PURE__ */ jsxs(SideDialogHeader, { className: "flex gap-[1rem] items-baseline pr-[2.5rem]", children: [
17419
+ /* @__PURE__ */ jsxs(SideDialogHeading, { children: [
17420
+ /* @__PURE__ */ jsx(EyeIcon, {}),
17421
+ " ",
17422
+ traceDetails?.name
17423
+ ] }),
17424
+ /* @__PURE__ */ jsxs(TextAndIcon, { children: [
17425
+ /* @__PURE__ */ jsx(HashIcon, {}),
17426
+ " ",
17427
+ traceId
17428
+ ] })
17429
+ ] }),
17430
+ /* @__PURE__ */ jsxs("div", { className: "overflow-y-auto pb-[2.5rem]", children: [
17431
+ traceDetails?.metadata?.usage && /* @__PURE__ */ jsx(
17432
+ TraceSpanUsage,
17433
+ {
17434
+ traceUsage: traceDetails?.metadata?.usage,
17435
+ traceSpans,
17436
+ className: "mt-[2rem] pr-[1.5rem]"
17437
+ }
17438
+ ),
17439
+ /* @__PURE__ */ jsx(KeyValueList, { data: traceInfo, LinkComponent: Link, className: "mt-[2rem]" }),
17440
+ /* @__PURE__ */ jsx(
17441
+ TraceTimeline,
17442
+ {
17443
+ hierarchicalSpans,
17444
+ spans: traceSpans,
17445
+ onSpanClick: handleSpanClick,
17446
+ selectedSpanId,
17447
+ isLoading: isLoadingSpans,
17448
+ className: "pr-[2.5rem] pt-[2.5rem]"
17449
+ }
17450
+ )
17451
+ ] }),
17452
+ selectedSpan && combinedView && /* @__PURE__ */ jsxs("div", { className: "overflow-y-auto grid grid-rows-[auto_1fr] relative", children: [
17453
+ /* @__PURE__ */ jsx("div", { className: "absolute left-0 right-[2.5rem] h-[.5rem] bg-surface1 rounded-full top-0" }),
17454
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between pb-[.5rem] pt-[1rem] border-b border-border1 pr-[2.5rem]", children: [
17455
+ /* @__PURE__ */ jsx(
17456
+ SideDialogTop,
17457
+ {
17458
+ onNext: thereIsNextSpan() ? toNextSpan : void 0,
17459
+ onPrevious: thereIsPreviousSpan() ? toPreviousSpan : void 0,
17460
+ showInnerNav: true,
17461
+ className: "pl-0",
17462
+ children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-[1rem] text-icon4 text-[0.875rem]", children: [
17463
+ /* @__PURE__ */ jsxs(TextAndIcon, { children: [
17464
+ /* @__PURE__ */ jsx(EyeIcon, {}),
17465
+ " ",
17466
+ getShortId(traceId)
17467
+ ] }),
17468
+ "›",
17469
+ /* @__PURE__ */ jsxs(TextAndIcon, { children: [
17470
+ /* @__PURE__ */ jsx(EyeIcon, {}),
17471
+ " ",
17472
+ getShortId(selectedSpanId)
17473
+ ] })
17474
+ ] })
17475
+ }
17476
+ ),
17477
+ /* @__PURE__ */ jsx("div", { className: "flex items-center gap-[1rem]", children: /* @__PURE__ */ jsx("button", { className: "flex items-center gap-1", onClick: () => setCombinedView(false), children: /* @__PURE__ */ jsx(PanelLeftIcon, {}) }) })
17478
+ ] }),
17479
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[20rem_1fr] gap-[1rem] overflow-y-auto", children: [
17480
+ /* @__PURE__ */ jsxs("div", { className: "overflow-y-auto grid content-start p-[1.5rem] pl-0 gap-[2rem]", children: [
17481
+ /* @__PURE__ */ jsxs(SideDialogHeading, { as: "h2", children: [
17482
+ /* @__PURE__ */ jsx(ChevronsLeftRightEllipsisIcon, {}),
17483
+ " ",
17484
+ selectedSpan?.name
17485
+ ] }),
17486
+ selectedSpan?.attributes?.usage && /* @__PURE__ */ jsx(
17487
+ TraceSpanUsage,
17488
+ {
17489
+ spanUsage: selectedSpan.attributes.usage,
17490
+ className: "xl:grid-cols-1 xl:gap-[1rem]"
17491
+ }
17492
+ ),
17493
+ /* @__PURE__ */ jsx(KeyValueList, { data: selectedSpanInfo, LinkComponent: Link })
17494
+ ] }),
17495
+ /* @__PURE__ */ jsx("div", { className: "overflow-y-auto pr-[2.5rem] pt-[2rem]", children: /* @__PURE__ */ jsx(SpanDetails, { span: selectedSpan }) })
17496
+ ] })
17497
+ ] })
17498
+ ]
17499
+ }
17500
+ )
17501
+ ]
17502
+ }
17503
+ ),
17504
+ /* @__PURE__ */ jsx(
17505
+ SpanDialog,
17506
+ {
17507
+ span: selectedSpan,
17508
+ isOpen: Boolean(dialogIsOpen && selectedSpanId && !combinedView),
17509
+ onClose: () => setDialogIsOpen(false),
17510
+ onNext: thereIsNextSpan() ? toNextSpan : void 0,
17511
+ onPrevious: thereIsPreviousSpan() ? toPreviousSpan : void 0,
17512
+ onViewToggle: () => setCombinedView(!combinedView),
17513
+ spanInfo: selectedSpanInfo
17514
+ }
17515
+ )
17516
+ ] });
15820
17517
  }
15821
- function TracesViewInner({ traces, error, runId, stepName, className, setEndOfListElement }) {
15822
- const hasRunRef = useRef(false);
15823
- const [sidebarWidth, setSidebarWidth] = useState(100);
15824
- const { isOpen: open, setTrace, setIsOpen, setSpan } = useContext(TraceContext);
15825
- useEffect(() => {
15826
- if (hasRunRef.current) return;
15827
- if (!runId || !stepName) return;
15828
- const matchingTrace = traces.find((trace) => trace.runId === runId);
15829
- if (!matchingTrace) return;
15830
- const matchingSpan = matchingTrace.trace.find((span) => span.name.includes(stepName));
15831
- if (!matchingSpan) return;
15832
- setTrace(matchingTrace.trace);
15833
- setSpan(matchingSpan);
15834
- setIsOpen(true);
15835
- hasRunRef.current = true;
15836
- }, [runId, traces, setTrace]);
15837
- return /* @__PURE__ */ jsxs("div", { className: clsx("h-full relative overflow-hidden flex", className), children: [
15838
- /* @__PURE__ */ jsxs("div", { className: "h-full overflow-y-scroll w-full", children: [
15839
- /* @__PURE__ */ jsx(TracesTable, { traces, error }),
15840
- /* @__PURE__ */ jsx("div", { "aria-hidden": true, ref: setEndOfListElement })
17518
+
17519
+ function TracesTools({
17520
+ onEntityChange,
17521
+ onReset,
17522
+ selectedEntity,
17523
+ entityOptions,
17524
+ onDateChange,
17525
+ selectedDateFrom,
17526
+ selectedDateTo,
17527
+ isLoading
17528
+ }) {
17529
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-wrap gap-x-[2rem] gap-y-[1rem]"), children: [
17530
+ /* @__PURE__ */ jsx(
17531
+ SelectField,
17532
+ {
17533
+ label: "Filter by Entity",
17534
+ name: "select-entity",
17535
+ placeholder: "Select...",
17536
+ options: entityOptions || [],
17537
+ onValueChange: (val) => {
17538
+ const entity = entityOptions?.find((entity2) => entity2.value === val);
17539
+ if (entity) {
17540
+ onEntityChange(entity);
17541
+ }
17542
+ },
17543
+ value: selectedEntity?.value || "",
17544
+ className: "min-w-[20rem]",
17545
+ disabled: isLoading
17546
+ }
17547
+ ),
17548
+ /* @__PURE__ */ jsxs("div", { className: cn("flex gap-[1rem] items-center flex-wrap mr-auto"), children: [
17549
+ /* @__PURE__ */ jsx("span", { className: cn("shrink-0 text-[0.875rem] text-icon3"), children: "Filter by Date & time range" }),
17550
+ /* @__PURE__ */ jsx(
17551
+ DateTimePicker,
17552
+ {
17553
+ placeholder: "From",
17554
+ value: selectedDateFrom,
17555
+ maxValue: selectedDateTo,
17556
+ onValueChange: (date) => onDateChange?.(date, "from"),
17557
+ className: "min-w-[15rem]",
17558
+ defaultTimeStrValue: "12:00 AM",
17559
+ disabled: isLoading
17560
+ }
17561
+ ),
17562
+ /* @__PURE__ */ jsx(
17563
+ DateTimePicker,
17564
+ {
17565
+ placeholder: "To",
17566
+ value: selectedDateTo,
17567
+ minValue: selectedDateFrom,
17568
+ onValueChange: (date) => onDateChange?.(date, "to"),
17569
+ className: "min-w-[15rem]",
17570
+ defaultTimeStrValue: "11:59 PM",
17571
+ disabled: isLoading
17572
+ }
17573
+ )
15841
17574
  ] }),
15842
- open && /* @__PURE__ */ jsx(TracesSidebar, { width: sidebarWidth, onResize: setSidebarWidth })
17575
+ /* @__PURE__ */ jsxs(Button, { variant: "primary", onClick: onReset, disabled: isLoading, children: [
17576
+ "Reset ",
17577
+ /* @__PURE__ */ jsx(XIcon, {})
17578
+ ] })
15843
17579
  ] });
15844
17580
  }
15845
- const TracesViewSkeleton = () => {
15846
- 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" }) }) });
15847
- };
15848
17581
 
15849
17582
  const DataTable = ({
15850
17583
  columns,
@@ -16448,5 +18181,5 @@ const MemorySearch = ({
16448
18181
  ] });
16449
18182
  };
16450
18183
 
16451
- 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$1 as Button, Cell, ChatThreads, CheckIcon, ChevronIcon, Collapsible, CollapsibleContent, CollapsibleTrigger, 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, FormActions, GithubCoinIcon, GithubIcon, GoogleIcon, Header, HeaderAction, HeaderGroup, HeaderTitle, HomeIcon, Icon, InfoIcon, InputField, JudgeIcon, Kbd, KeyValueList, LatencyIcon, LegacyWorkflowGraph, LegacyWorkflowTrigger, LinkComponentProvider, LogsIcon, MainContentContent, MainContentLayout, MastraClientProvider, MastraResizablePanel, McpCoinIcon, McpServerIcon, MemoryIcon, MemorySearch, NetworkChat, NetworkContext, NetworkProvider, NetworkTable, NetworkTableEmpty, NetworkTableSkeleton, OpenAIIcon, PlaygroundQueryClient, PlaygroundTabs, PromptIcon, RadioGroup, RadioGroupField, RadioGroupItem, RepoIcon, Row, RuntimeContext, RuntimeContextWrapper, ScoreIcon, ScorerList, ScorerSkeleton, SearchField, Searchbar, SelectField, SettingsIcon, SlashIcon, SliderField, Tab, TabContent, TabList, Table$1 as Table, Tbody, TemplateFailure, TemplateForm, TemplateInfo, TemplateInstallation, TemplateSuccess, TemplatesList, TemplatesTools, TextareaField, 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 };
18184
+ 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$1 as Button, Cell, ChatThreads, CheckIcon, ChevronIcon, Collapsible, CollapsibleContent, CollapsibleTrigger, CommitIcon, CrossIcon, Crumb, DarkLogo, DataTable, DateTimeCell, DateTimePicker, DateTimePickerContent, DbIcon, DebugIcon, DefaultTrigger, DeploymentIcon, DividerIcon, DocsIcon, DynamicForm, EmptyAgentsTable, EmptyScorerList, EmptyState, EmptyWorkflowsTable, Entity, EntityContent, EntityDescription, EntityHeader, EntityIcon, EntityMainHeader, EntityName, Entry, EntryCell, EntryList, EntryListItem, EntryListPageHeader, EntryListStatusCell, EntryListTextCell, EntryListToolbar, EnvIcon, EvaluatorCoinIcon, FiltersIcon, FolderIcon, FormActions, GithubCoinIcon, GithubIcon, GoogleIcon, Header, HeaderAction, HeaderGroup, HeaderTitle, HomeIcon, Icon, InfoIcon, InputField, JudgeIcon, Kbd, KeyValueList, LatencyIcon, LegacyWorkflowGraph, LegacyWorkflowTrigger, LinkComponentProvider, LogsIcon, MainContentContent, MainContentLayout, MastraClientProvider, MastraResizablePanel, McpCoinIcon, McpServerIcon, MemoryIcon, MemorySearch, NetworkChat, NetworkContext, NetworkProvider, NetworkTable, NetworkTableEmpty, NetworkTableSkeleton, OpenAIIcon, PageHeader, PlaygroundQueryClient, PlaygroundTabs, PromptIcon, RadioGroup, RadioGroupField, RadioGroupItem, RepoIcon, Row, RuntimeContext, RuntimeContextWrapper, ScoreIcon, ScorerList, ScorerSkeleton, SearchField, Searchbar, SelectField, SettingsIcon, SideDialog, SideDialogCodeSection, SideDialogContent, SideDialogFooter, SideDialogFooterGroup, SideDialogHeader, SideDialogHeading, SideDialogKeyValueList, SideDialogSection, SideDialogTop, SlashIcon, SliderField, Tab, TabContent, TabList, Table$1 as Table, Tbody, TemplateFailure, TemplateForm, TemplateInfo, TemplateInstallation, TemplateSuccess, TemplatesList, TemplatesTools, TextAndIcon, TextareaField, Th, Thead, ThreadDeleteButton, ThreadItem, ThreadLink, ThreadList, Threads, ToolCoinIcon, ToolList, ToolListEmpty, ToolListSkeleton, ToolsIcon, TraceDialog, TraceIcon, TraceTimeline, TraceTimelineLegend, TraceTimelineSpan, TracesTools, TracesView, TracesViewSkeleton, TsIcon, Txt, TxtCell, UnitCell, VNextNetworkChat, VariablesIcon, WorkflowCoinIcon, WorkflowGraph, WorkflowIcon, WorkflowRunContext, WorkflowRunProvider, WorkflowRuns, WorkflowTable, WorkflowTableSkeleton, WorkflowTrigger, WorkingMemoryContext, WorkingMemoryProvider, allowedAiSpanAttributes, cleanString, formatDuration, formatHierarchicalSpans, formatOtelTimestamp, formatOtelTimestamp2, getColumnTemplate, getShortId, getSpanTypeUi, providerMapToIcon, spanTypePrefixes, transformKey, useAgentSettings, useCurrentRun, useInView, useLinkComponent, useMastraClient, usePlaygroundStore, usePolling, useScorer, useScorers, useScoresByEntityId, useScoresByScorerId, useSpeechRecognition, useWorkingMemory };
16452
18185
  //# sourceMappingURL=index.es.js.map