@mastra/playground-ui 19.0.1-alpha.2 → 19.1.0-alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs.js CHANGED
@@ -8617,9 +8617,12 @@ function DatePicker({ className, classNames, showOutsideDays = true, ...props })
8617
8617
  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",
8618
8618
  "h-8 w-8 p-0 hover:bg-lightGray-7/50 font-normal aria-selected:opacity-100"
8619
8619
  ),
8620
- day_range_start: "day-range-start",
8621
- day_range_end: "day-range-end",
8622
- day_selected: "!bg-neutral6/50 !text-surface2 hover:bg-neutral6 rounded-md hover:text-surface2 focus:bg-neutral6 focus:text-surface2",
8620
+ day_range_start: "day-range-start rounded-l-md",
8621
+ day_range_end: "day-range-end rounded-r-md",
8622
+ day_selected: cn(
8623
+ "!bg-accent1 !text-white hover:!bg-accent1/80 focus:!bg-accent1/80 focus:!text-white",
8624
+ props.mode !== "range" && "rounded-md"
8625
+ ),
8623
8626
  day_today: "bg-neutral6/10 text-neutral5",
8624
8627
  day_outside: "day-outside text-neutral3 opacity-50 aria-selected:bg-surface5/50 aria-selected:text-neutral3 aria-selected:opacity-30",
8625
8628
  day_disabled: "text-neutral3 opacity-50",
@@ -10824,7 +10827,7 @@ const useAutoscroll = (ref, { enabled = true }) => {
10824
10827
  };
10825
10828
 
10826
10829
  const ScrollArea = React__namespace.forwardRef(
10827
- ({ className, children, viewPortClassName, maxHeight, autoScroll = false, ...props }, ref) => {
10830
+ ({ className, children, viewPortClassName, maxHeight, autoScroll = false, orientation = "vertical", ...props }, ref) => {
10828
10831
  const areaRef = React__namespace.useRef(null);
10829
10832
  useAutoscroll(areaRef, { enabled: autoScroll });
10830
10833
  return /* @__PURE__ */ jsxRuntime.jsxs(ScrollAreaPrimitive__namespace.Root, { ref, className: cn("relative overflow-hidden", className), ...props, children: [
@@ -10837,8 +10840,9 @@ const ScrollArea = React__namespace.forwardRef(
10837
10840
  children
10838
10841
  }
10839
10842
  ),
10840
- /* @__PURE__ */ jsxRuntime.jsx(ScrollBar, {}),
10841
- /* @__PURE__ */ jsxRuntime.jsx(ScrollAreaPrimitive__namespace.Corner, {})
10843
+ (orientation === "vertical" || orientation === "both") && /* @__PURE__ */ jsxRuntime.jsx(ScrollBar, { orientation: "vertical" }),
10844
+ (orientation === "horizontal" || orientation === "both") && /* @__PURE__ */ jsxRuntime.jsx(ScrollBar, { orientation: "horizontal" }),
10845
+ orientation === "both" && /* @__PURE__ */ jsxRuntime.jsx(ScrollAreaPrimitive__namespace.Corner, {})
10842
10846
  ] });
10843
10847
  }
10844
10848
  );
@@ -40932,14 +40936,14 @@ function TemplateFailure({ errorMsg, validationErrors }) {
40932
40936
  ] });
40933
40937
  }
40934
40938
 
40935
- const DATE_PRESETS$1 = [
40939
+ const DATE_PRESETS$2 = [
40936
40940
  { label: "Last 24 hours", value: "24h" },
40937
40941
  { label: "Last 3 days", value: "3d" },
40938
40942
  { label: "Last 7 days", value: "7d" },
40939
40943
  { label: "Last 14 days", value: "14d" },
40940
40944
  { label: "Last 30 days", value: "30d" }
40941
40945
  ];
40942
- const VALID_PRESETS = new Set(DATE_PRESETS$1.map((p) => p.value));
40946
+ const VALID_PRESETS = new Set(DATE_PRESETS$2.map((p) => p.value));
40943
40947
  function isValidPreset(value) {
40944
40948
  return typeof value === "string" && (VALID_PRESETS.has(value) || value === "custom");
40945
40949
  }
@@ -40986,7 +40990,7 @@ function useMetrics() {
40986
40990
  }
40987
40991
  function getDateRangeLabel(preset, customRange) {
40988
40992
  if (preset !== "custom") {
40989
- return DATE_PRESETS$1.find((p) => p.value === preset).label;
40993
+ return DATE_PRESETS$2.find((p) => p.value === preset).label;
40990
40994
  }
40991
40995
  if (customRange?.from) {
40992
40996
  if (customRange.to) {
@@ -41101,6 +41105,12 @@ function formatCompact(n) {
41101
41105
  if (n >= 1e3) return `${(n / 1e3).toFixed(1)}K`;
41102
41106
  return n.toLocaleString();
41103
41107
  }
41108
+ function formatCost(value, unit) {
41109
+ if (unit?.toLowerCase() === "usd" || !unit) {
41110
+ return `$${value < 0.01 && value > 0 ? value.toFixed(4) : value.toFixed(2)}`;
41111
+ }
41112
+ return `${value.toFixed(4)} ${unit}`;
41113
+ }
41104
41114
  const CHART_COLORS = {
41105
41115
  green: "#22c55e",
41106
41116
  orange: "#fb923c",
@@ -41162,17 +41172,21 @@ function MetricsCardSummary({ value, label, className }) {
41162
41172
  ] });
41163
41173
  }
41164
41174
 
41165
- function MetricsCardTitle({ children, className }) {
41166
- return /* @__PURE__ */ jsxRuntime.jsx("h3", { className: cn("text-ui-md font-normal text-neutral4", className), children });
41175
+ function MetricsCardTitle({
41176
+ children,
41177
+ className,
41178
+ as: Tag = "h2"
41179
+ }) {
41180
+ return /* @__PURE__ */ jsxRuntime.jsx(Tag, { className: cn("text-ui-md font-normal text-neutral4", className), children });
41167
41181
  }
41168
41182
 
41169
41183
  function MetricsCardTitleAndDescription(props) {
41170
41184
  if ("children" in props) {
41171
41185
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: props.className, children: props.children });
41172
41186
  }
41173
- const { title, description } = props;
41187
+ const { title, description, titleAs } = props;
41174
41188
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: props.className, children: [
41175
- /* @__PURE__ */ jsxRuntime.jsx(MetricsCardTitle, { children: title }),
41189
+ /* @__PURE__ */ jsxRuntime.jsx(MetricsCardTitle, { as: titleAs, children: title }),
41176
41190
  description && /* @__PURE__ */ jsxRuntime.jsx(MetricsCardDescription, { children: description })
41177
41191
  ] });
41178
41192
  }
@@ -41443,6 +41457,28 @@ function useAvgScoreKpiMetrics() {
41443
41457
  });
41444
41458
  }
41445
41459
 
41460
+ function useModelCostKpiMetrics() {
41461
+ const client = react.useMastraClient();
41462
+ const { datePreset, customRange, timestamp } = useMetricsFilters();
41463
+ return reactQuery.useQuery({
41464
+ queryKey: ["metrics", "model-cost-kpi", datePreset, customRange],
41465
+ queryFn: async () => {
41466
+ const res = await client.getMetricAggregate({
41467
+ name: ["mastra_model_total_input_tokens", "mastra_model_total_output_tokens"],
41468
+ aggregation: "sum",
41469
+ filters: { timestamp },
41470
+ comparePeriod: "previous_period"
41471
+ });
41472
+ return {
41473
+ cost: res.estimatedCost ?? null,
41474
+ costUnit: res.costUnit ?? null,
41475
+ previousCost: res.previousEstimatedCost ?? null,
41476
+ costChangePercent: res.costChangePercent ?? null
41477
+ };
41478
+ }
41479
+ });
41480
+ }
41481
+
41446
41482
  function useTotalTokensKpiMetrics() {
41447
41483
  const client = react.useMastraClient();
41448
41484
  const { datePreset, customRange, timestamp } = useMetricsFilters();
@@ -41492,6 +41528,21 @@ function AgentRunsKpiCard() {
41492
41528
  ) : /* @__PURE__ */ jsxRuntime.jsx(MetricsKpiCard.NoChange, {}) : /* @__PURE__ */ jsxRuntime.jsx(MetricsKpiCard.NoData, {})
41493
41529
  ] });
41494
41530
  }
41531
+ function ModelCostKpiCard() {
41532
+ const { data: costKpi, isLoading, isError } = useModelCostKpiMetrics();
41533
+ const hasData = costKpi?.cost != null;
41534
+ return /* @__PURE__ */ jsxRuntime.jsxs(MetricsKpiCard, { children: [
41535
+ /* @__PURE__ */ jsxRuntime.jsx(MetricsKpiCard.Label, { children: "Total Model Cost" }),
41536
+ /* @__PURE__ */ jsxRuntime.jsx(MetricsKpiCard.Value, { className: hasData ? void 0 : "invisible", children: hasData ? formatCost(costKpi.cost, costKpi.costUnit) : "—" }),
41537
+ isError ? /* @__PURE__ */ jsxRuntime.jsx(MetricsKpiCard.Error, {}) : isLoading ? /* @__PURE__ */ jsxRuntime.jsx(MetricsKpiCard.Loading, {}) : hasData ? costKpi.costChangePercent != null ? /* @__PURE__ */ jsxRuntime.jsx(
41538
+ MetricsKpiCard.Change,
41539
+ {
41540
+ changePct: costKpi.costChangePercent,
41541
+ prevValue: costKpi.previousCost != null ? formatCost(costKpi.previousCost, costKpi.costUnit) : void 0
41542
+ }
41543
+ ) : /* @__PURE__ */ jsxRuntime.jsx(MetricsKpiCard.NoChange, {}) : /* @__PURE__ */ jsxRuntime.jsx(MetricsKpiCard.NoData, {})
41544
+ ] });
41545
+ }
41495
41546
  function TotalTokensKpiCard() {
41496
41547
  const { data: totalTokensKpi, isLoading, isError } = useTotalTokensKpiMetrics();
41497
41548
  const hasData = totalTokensKpi?.value != null;
@@ -41548,32 +41599,48 @@ function useModelUsageCostMetrics() {
41548
41599
  const modelMap = /* @__PURE__ */ new Map();
41549
41600
  const ensureModel = (model) => {
41550
41601
  if (!modelMap.has(model)) {
41551
- modelMap.set(model, { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 });
41602
+ modelMap.set(model, { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: null, costUnit: null });
41552
41603
  }
41553
41604
  return modelMap.get(model);
41554
41605
  };
41606
+ const addCost = (entry, group) => {
41607
+ if (group.estimatedCost != null) {
41608
+ entry.cost = (entry.cost ?? 0) + group.estimatedCost;
41609
+ if (group.costUnit) entry.costUnit = group.costUnit;
41610
+ }
41611
+ };
41555
41612
  for (const group of inputRes.groups) {
41556
41613
  const m = group.dimensions.model ?? "unknown";
41557
- ensureModel(m).input = group.value;
41614
+ const entry = ensureModel(m);
41615
+ entry.input = group.value;
41616
+ addCost(entry, group);
41558
41617
  }
41559
41618
  for (const group of outputRes.groups) {
41560
41619
  const m = group.dimensions.model ?? "unknown";
41561
- ensureModel(m).output = group.value;
41620
+ const entry = ensureModel(m);
41621
+ entry.output = group.value;
41622
+ addCost(entry, group);
41562
41623
  }
41563
41624
  for (const group of cacheReadRes.groups) {
41564
41625
  const m = group.dimensions.model ?? "unknown";
41565
- ensureModel(m).cacheRead = group.value;
41626
+ const entry = ensureModel(m);
41627
+ entry.cacheRead = group.value;
41628
+ addCost(entry, group);
41566
41629
  }
41567
41630
  for (const group of cacheWriteRes.groups) {
41568
41631
  const m = group.dimensions.model ?? "unknown";
41569
- ensureModel(m).cacheWrite = group.value;
41632
+ const entry = ensureModel(m);
41633
+ entry.cacheWrite = group.value;
41634
+ addCost(entry, group);
41570
41635
  }
41571
41636
  return Array.from(modelMap.entries()).map(([model, vals]) => ({
41572
41637
  model,
41573
41638
  input: formatCompact(vals.input),
41574
41639
  output: formatCompact(vals.output),
41575
41640
  cacheRead: formatCompact(vals.cacheRead),
41576
- cacheWrite: formatCompact(vals.cacheWrite)
41641
+ cacheWrite: formatCompact(vals.cacheWrite),
41642
+ cost: vals.cost,
41643
+ costUnit: vals.costUnit
41577
41644
  })).sort((a, b) => a.model.localeCompare(b.model));
41578
41645
  }
41579
41646
  });
@@ -41585,12 +41652,12 @@ function MetricsDataTable({
41585
41652
  className
41586
41653
  }) {
41587
41654
  if (columns.length === 0) return null;
41588
- return /* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { className: cn("w-full h-full", className), maxHeight: "20rem", children: /* @__PURE__ */ jsxRuntime.jsxs(
41655
+ return /* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { className: cn("w-full h-full", className), maxHeight: "20rem", orientation: "both", children: /* @__PURE__ */ jsxRuntime.jsxs(
41589
41656
  "div",
41590
41657
  {
41591
41658
  className: "grid items-center",
41592
41659
  style: {
41593
- gridTemplateColumns: `auto ${columns.slice(1).map(() => "1fr").join(" ")}`
41660
+ gridTemplateColumns: `auto ${columns.slice(1).map(() => "auto").join(" ")}`
41594
41661
  },
41595
41662
  children: [
41596
41663
  columns.map((col, i) => /* @__PURE__ */ jsxRuntime.jsx(
@@ -41628,7 +41695,14 @@ function ModelUsageCostCard() {
41628
41695
  const { data: rows, isLoading, isError } = useModelUsageCostMetrics();
41629
41696
  const hasData = !!rows && rows.length > 0;
41630
41697
  return /* @__PURE__ */ jsxRuntime.jsxs(MetricsCard, { children: [
41631
- /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.TopBar, { children: /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.TitleAndDescription, { title: "Model Usage", description: "Token consumption by model." }) }),
41698
+ /* @__PURE__ */ jsxRuntime.jsxs(MetricsCard.TopBar, { children: [
41699
+ /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.TitleAndDescription, { title: "Model Usage & Cost", description: "Token consumption by model." }),
41700
+ hasData && (() => {
41701
+ const totalCost = rows.reduce((sum, r) => sum + (r.cost ?? 0), 0);
41702
+ const unit = rows.find((r) => r.costUnit)?.costUnit;
41703
+ return /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.Summary, { value: totalCost > 0 ? formatCost(totalCost, unit) : "—", label: "Total cost" });
41704
+ })()
41705
+ ] }),
41632
41706
  isLoading ? /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.Loading, {}) : isError ? /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.Error, { message: "Failed to load model usage data" }) : /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.Content, { children: !hasData ? /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.NoData, { message: "No model usage data yet" }) : /* @__PURE__ */ jsxRuntime.jsx(
41633
41707
  MetricsDataTable,
41634
41708
  {
@@ -41637,8 +41711,12 @@ function ModelUsageCostCard() {
41637
41711
  { label: "Input", value: (row) => row.input },
41638
41712
  { label: "Output", value: (row) => row.output },
41639
41713
  { label: "Cache Read", value: (row) => row.cacheRead },
41640
- { label: "Cache Write", value: (row) => row.cacheWrite }
41641
- // { label: 'Cost', value: () => '—', highlight: true },
41714
+ { label: "Cache Write", value: (row) => row.cacheWrite },
41715
+ {
41716
+ label: "Cost",
41717
+ value: (row) => row.cost != null ? formatCost(row.cost, row.costUnit) : "—",
41718
+ highlight: true
41719
+ }
41642
41720
  ],
41643
41721
  data: rows.map((row) => ({ ...row, key: row.model }))
41644
41722
  }
@@ -41792,7 +41870,7 @@ function useTokenUsageByAgentMetrics() {
41792
41870
  return reactQuery.useQuery({
41793
41871
  queryKey: ["metrics", "token-usage-by-agent", datePreset, customRange],
41794
41872
  queryFn: async () => {
41795
- const [inputRes, outputRes] = await Promise.all([
41873
+ const [inputRes, outputRes, cacheReadRes, cacheWriteRes] = await Promise.all([
41796
41874
  client.getMetricBreakdown({
41797
41875
  name: ["mastra_model_total_input_tokens"],
41798
41876
  groupBy: ["entityName"],
@@ -41804,28 +41882,62 @@ function useTokenUsageByAgentMetrics() {
41804
41882
  groupBy: ["entityName"],
41805
41883
  aggregation: "sum",
41806
41884
  filters: { timestamp }
41885
+ }),
41886
+ client.getMetricBreakdown({
41887
+ name: ["mastra_model_input_cache_read_tokens"],
41888
+ groupBy: ["entityName"],
41889
+ aggregation: "sum",
41890
+ filters: { timestamp }
41891
+ }),
41892
+ client.getMetricBreakdown({
41893
+ name: ["mastra_model_input_cache_write_tokens"],
41894
+ groupBy: ["entityName"],
41895
+ aggregation: "sum",
41896
+ filters: { timestamp }
41807
41897
  })
41808
41898
  ]);
41809
41899
  const agentMap = /* @__PURE__ */ new Map();
41810
41900
  const ensure = (name) => {
41811
41901
  if (!agentMap.has(name)) {
41812
- agentMap.set(name, { input: 0, output: 0 });
41902
+ agentMap.set(name, { input: 0, output: 0, cost: null, costUnit: null });
41813
41903
  }
41814
41904
  return agentMap.get(name);
41815
41905
  };
41906
+ const addCost = (entry, group) => {
41907
+ if (group.estimatedCost != null) {
41908
+ entry.cost = (entry.cost ?? 0) + group.estimatedCost;
41909
+ if (group.costUnit) entry.costUnit = group.costUnit;
41910
+ }
41911
+ };
41816
41912
  for (const group of inputRes.groups) {
41817
41913
  const name = group.dimensions.entityName ?? "unknown";
41818
- ensure(name).input = group.value;
41914
+ const entry = ensure(name);
41915
+ entry.input = group.value;
41916
+ addCost(entry, group);
41819
41917
  }
41820
41918
  for (const group of outputRes.groups) {
41821
41919
  const name = group.dimensions.entityName ?? "unknown";
41822
- ensure(name).output = group.value;
41920
+ const entry = ensure(name);
41921
+ entry.output = group.value;
41922
+ addCost(entry, group);
41923
+ }
41924
+ for (const group of cacheReadRes.groups) {
41925
+ const name = group.dimensions.entityName ?? "unknown";
41926
+ const entry = ensure(name);
41927
+ addCost(entry, group);
41928
+ }
41929
+ for (const group of cacheWriteRes.groups) {
41930
+ const name = group.dimensions.entityName ?? "unknown";
41931
+ const entry = ensure(name);
41932
+ addCost(entry, group);
41823
41933
  }
41824
41934
  return Array.from(agentMap.entries()).map(([name, vals]) => ({
41825
41935
  name,
41826
41936
  input: vals.input,
41827
41937
  output: vals.output,
41828
- total: vals.input + vals.output
41938
+ total: vals.input + vals.output,
41939
+ cost: vals.cost,
41940
+ costUnit: vals.costUnit
41829
41941
  })).sort((a, b) => b.total - a.total);
41830
41942
  }
41831
41943
  });
@@ -41911,8 +42023,15 @@ function HorizontalBars({
41911
42023
 
41912
42024
  function TokenUsageByAgentCard() {
41913
42025
  const { data, isLoading, isError } = useTokenUsageByAgentMetrics();
42026
+ const [activeTab, setActiveTab] = React.useState("tokens");
41914
42027
  const hasData = !!data && data.length > 0;
41915
42028
  const totalTokens = data?.reduce((s, d) => s + d.total, 0) ?? 0;
42029
+ const costRows = data?.filter((d) => d.cost != null && d.cost > 0) ?? [];
42030
+ const uniqueCostUnits = new Set(costRows.map((d) => d.costUnit ?? "usd"));
42031
+ const hasSingleCostUnit = uniqueCostUnits.size <= 1;
42032
+ const costUnit = hasSingleCostUnit ? costRows[0]?.costUnit ?? null : null;
42033
+ const totalCost = hasSingleCostUnit ? costRows.reduce((s, d) => s + (d.cost ?? 0), 0) : 0;
42034
+ const hasCostData = hasSingleCostUnit && totalCost > 0;
41916
42035
  return /* @__PURE__ */ jsxRuntime.jsxs(MetricsCard, { children: [
41917
42036
  /* @__PURE__ */ jsxRuntime.jsxs(MetricsCard.TopBar, { children: [
41918
42037
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -41922,23 +42041,44 @@ function TokenUsageByAgentCard() {
41922
42041
  description: "Token consumption grouped by agent."
41923
42042
  }
41924
42043
  ),
41925
- hasData && /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.Summary, { value: formatCompact(totalTokens), label: "Total tokens" })
42044
+ hasData && (activeTab === "cost" && hasCostData ? /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.Summary, { value: formatCost(totalCost, costUnit), label: "Total cost" }) : /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.Summary, { value: formatCompact(totalTokens), label: "Total tokens" }))
41926
42045
  ] }),
41927
- isLoading ? /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.Loading, {}) : isError ? /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.Error, { message: "Failed to load token usage data" }) : /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.Content, { children: !hasData ? /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.NoData, { message: "No token usage data yet" }) : /* @__PURE__ */ jsxRuntime.jsxs(Tabs, { defaultTab: "tokens", className: "grid grid-rows-[auto_1fr] overflow-y-auto h-full", children: [
41928
- /* @__PURE__ */ jsxRuntime.jsx(TabList, { children: /* @__PURE__ */ jsxRuntime.jsx(Tab, { value: "tokens", children: "Tokens" }) }),
41929
- /* @__PURE__ */ jsxRuntime.jsx(TabContent, { value: "tokens", children: /* @__PURE__ */ jsxRuntime.jsx(
41930
- HorizontalBars,
41931
- {
41932
- data: data.map((d) => ({ name: d.name, values: [d.input, d.output] })),
41933
- segments: [
41934
- { label: "Input", color: CHART_COLORS.blueDark },
41935
- { label: "Output", color: CHART_COLORS.blue }
41936
- ],
41937
- maxVal: Math.max(...data.map((d) => d.input + d.output)),
41938
- fmt: formatCompact
41939
- }
41940
- ) })
41941
- ] }) })
42046
+ isLoading ? /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.Loading, {}) : isError ? /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.Error, { message: "Failed to load token usage data" }) : /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.Content, { children: !hasData ? /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.NoData, { message: "No token usage data yet" }) : /* @__PURE__ */ jsxRuntime.jsxs(
42047
+ Tabs,
42048
+ {
42049
+ defaultTab: "tokens",
42050
+ value: activeTab,
42051
+ onValueChange: (v) => setActiveTab(v),
42052
+ className: "grid grid-rows-[auto_1fr] overflow-y-auto h-full",
42053
+ children: [
42054
+ /* @__PURE__ */ jsxRuntime.jsxs(TabList, { children: [
42055
+ /* @__PURE__ */ jsxRuntime.jsx(Tab, { value: "tokens", children: "Tokens" }),
42056
+ /* @__PURE__ */ jsxRuntime.jsx(Tab, { value: "cost", children: "Cost" })
42057
+ ] }),
42058
+ /* @__PURE__ */ jsxRuntime.jsx(TabContent, { value: "tokens", children: /* @__PURE__ */ jsxRuntime.jsx(
42059
+ HorizontalBars,
42060
+ {
42061
+ data: data.map((d) => ({ name: d.name, values: [d.input, d.output] })),
42062
+ segments: [
42063
+ { label: "Input", color: CHART_COLORS.blueDark },
42064
+ { label: "Output", color: CHART_COLORS.blue }
42065
+ ],
42066
+ maxVal: Math.max(...data.map((d) => d.input + d.output)),
42067
+ fmt: formatCompact
42068
+ }
42069
+ ) }),
42070
+ /* @__PURE__ */ jsxRuntime.jsx(TabContent, { value: "cost", children: hasCostData ? /* @__PURE__ */ jsxRuntime.jsx(
42071
+ HorizontalBars,
42072
+ {
42073
+ data: data.filter((d) => d.cost != null && d.cost > 0).sort((a, b) => (b.cost ?? 0) - (a.cost ?? 0)).map((d) => ({ name: d.name, values: [d.cost] })),
42074
+ segments: [{ label: "Cost", color: CHART_COLORS.purple }],
42075
+ maxVal: Math.max(...data.map((d) => d.cost ?? 0)),
42076
+ fmt: (v) => formatCost(v, costUnit)
42077
+ }
42078
+ ) : /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.NoData, { message: "No cost data yet" }) })
42079
+ ]
42080
+ }
42081
+ ) })
41942
42082
  ] });
41943
42083
  }
41944
42084
 
@@ -42065,6 +42205,7 @@ function MetricsDashboard() {
42065
42205
  ] }),
42066
42206
  /* @__PURE__ */ jsxRuntime.jsxs(MetricsFlexGrid, { children: [
42067
42207
  /* @__PURE__ */ jsxRuntime.jsx(AgentRunsKpiCard, {}),
42208
+ /* @__PURE__ */ jsxRuntime.jsx(ModelCostKpiCard, {}),
42068
42209
  /* @__PURE__ */ jsxRuntime.jsx(TotalTokensKpiCard, {}),
42069
42210
  /* @__PURE__ */ jsxRuntime.jsx(AvgScoreKpiCard, {})
42070
42211
  ] }),
@@ -42078,7 +42219,7 @@ function MetricsDashboard() {
42078
42219
  ] });
42079
42220
  }
42080
42221
 
42081
- const DATE_PRESETS = [
42222
+ const DATE_PRESETS$1 = [
42082
42223
  { label: "Last 24 hours", value: "24h" },
42083
42224
  { label: "Last 3 days", value: "3d" },
42084
42225
  { label: "Last 7 days", value: "7d" },
@@ -42093,7 +42234,7 @@ function DateRangeSelector() {
42093
42234
  name: "date-range",
42094
42235
  labelIsHidden: true,
42095
42236
  value: datePreset,
42096
- options: DATE_PRESETS,
42237
+ options: DATE_PRESETS$1,
42097
42238
  onValueChange: (value) => setDatePreset(value)
42098
42239
  }
42099
42240
  );
@@ -42126,6 +42267,108 @@ function groupTracesByThread(traces) {
42126
42267
  return { groups, ungrouped };
42127
42268
  }
42128
42269
 
42270
+ const CONTEXT_FIELD_IDS = [
42271
+ "environment",
42272
+ "serviceName",
42273
+ "source",
42274
+ "scope",
42275
+ "userId",
42276
+ "organizationId",
42277
+ "resourceId",
42278
+ "runId",
42279
+ "sessionId",
42280
+ "threadId",
42281
+ "requestId",
42282
+ "experimentId",
42283
+ "spanType",
42284
+ "entityName",
42285
+ "parentEntityType",
42286
+ "parentEntityId",
42287
+ "parentEntityName",
42288
+ "rootEntityType",
42289
+ "rootEntityId",
42290
+ "rootEntityName"
42291
+ ];
42292
+ const CONTEXT_FIELD_META = {
42293
+ environment: { label: "Environment", group: "Deployment" },
42294
+ serviceName: { label: "Service Name", group: "Deployment" },
42295
+ source: { label: "Source", group: "Deployment" },
42296
+ scope: { label: "Scope", group: "Deployment" },
42297
+ userId: { label: "User ID", group: "Identity" },
42298
+ organizationId: { label: "Organization ID", group: "Identity" },
42299
+ resourceId: { label: "Resource ID", group: "Identity" },
42300
+ runId: { label: "Run ID", group: "Correlation" },
42301
+ sessionId: { label: "Session ID", group: "Correlation" },
42302
+ threadId: { label: "Thread ID", group: "Correlation" },
42303
+ requestId: { label: "Request ID", group: "Correlation" },
42304
+ experimentId: { label: "Experiment ID", group: "Experimentation" },
42305
+ spanType: { label: "Span Type", group: "Span" },
42306
+ entityName: { label: "Entity Name", group: "Entity" },
42307
+ parentEntityType: { label: "Parent Entity Type", group: "Entity" },
42308
+ parentEntityId: { label: "Parent Entity ID", group: "Entity" },
42309
+ parentEntityName: { label: "Parent Entity Name", group: "Entity" },
42310
+ rootEntityType: { label: "Root Entity Type", group: "Entity" },
42311
+ rootEntityId: { label: "Root Entity ID", group: "Entity" },
42312
+ rootEntityName: { label: "Root Entity Name", group: "Entity" }
42313
+ };
42314
+ const CONTEXT_FILTER_CATEGORIES = CONTEXT_FIELD_IDS.map((id) => ({
42315
+ id,
42316
+ ...CONTEXT_FIELD_META[id]
42317
+ }));
42318
+ const DATE_PRESETS = [
42319
+ { value: "all", label: "All" },
42320
+ { value: "last-24h", label: "Last 24 hours", ms: 24 * 60 * 60 * 1e3 },
42321
+ { value: "last-3d", label: "Last 3 days", ms: 3 * 24 * 60 * 60 * 1e3 },
42322
+ { value: "last-7d", label: "Last 7 days", ms: 7 * 24 * 60 * 60 * 1e3 },
42323
+ { value: "last-14d", label: "Last 14 days", ms: 14 * 24 * 60 * 60 * 1e3 },
42324
+ { value: "last-30d", label: "Last 30 days", ms: 30 * 24 * 60 * 60 * 1e3 },
42325
+ { value: "custom", label: "Custom range..." }
42326
+ ];
42327
+ function buildDateWithTime(date, timeStr) {
42328
+ const dateOnly = new Date(date.getFullYear(), date.getMonth(), date.getDate());
42329
+ const combined = dateFns.parse(timeStr, "h:mm a", dateOnly);
42330
+ return dateFns.isValid(combined) ? combined : null;
42331
+ }
42332
+ const subContentClass = cn(
42333
+ "bg-surface5 backdrop-blur-xl z-50 min-w-[8rem] overflow-auto rounded-lg p-2 shadow-md",
42334
+ "data-[state=open]:animate-in data-[state=closed]:animate-out",
42335
+ "data-[state=open]:fade-in-0 data-[state=closed]:fade-out-0",
42336
+ "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95"
42337
+ );
42338
+ function PortalSubContent({ className, children, ...props }) {
42339
+ return /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuPrimitive.SubContent, { className: cn(subContentClass, className), ...props, children }) });
42340
+ }
42341
+ const SUBMENU_SEARCH_THRESHOLD = 6;
42342
+ function SubMenuSearch({
42343
+ value,
42344
+ onChange,
42345
+ label = "Search"
42346
+ }) {
42347
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("px-2 pb-2"), children: /* @__PURE__ */ jsxRuntime.jsxs(
42348
+ "div",
42349
+ {
42350
+ className: cn(
42351
+ "flex items-center gap-2 border border-border1 rounded-md px-2 py-1",
42352
+ "focus-within:border-neutral2"
42353
+ ),
42354
+ children: [
42355
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.SearchIcon, { className: cn("text-neutral3 h-3.5 w-3.5 shrink-0") }),
42356
+ /* @__PURE__ */ jsxRuntime.jsx(
42357
+ "input",
42358
+ {
42359
+ type: "text",
42360
+ placeholder: "Search...",
42361
+ "aria-label": label,
42362
+ value,
42363
+ onChange: (e) => onChange(e.target.value),
42364
+ onKeyDown: (e) => e.stopPropagation(),
42365
+ className: cn("bg-transparent text-ui-sm text-neutral4 placeholder:text-neutral3 outline-none w-full")
42366
+ }
42367
+ )
42368
+ ]
42369
+ }
42370
+ ) });
42371
+ }
42129
42372
  function TracesTools({
42130
42373
  onEntityChange,
42131
42374
  onReset,
@@ -42136,63 +42379,481 @@ function TracesTools({
42136
42379
  selectedDateTo,
42137
42380
  isLoading,
42138
42381
  groupByThread,
42139
- onGroupByThreadChange
42382
+ onGroupByThreadChange,
42383
+ searchQuery: _searchQuery,
42384
+ onSearchChange,
42385
+ datePreset = "all",
42386
+ onDatePresetChange,
42387
+ selectedTags,
42388
+ availableTags,
42389
+ onTagsChange,
42390
+ errorOnly,
42391
+ onErrorOnlyChange,
42392
+ selectedMetadata,
42393
+ availableMetadata,
42394
+ onMetadataChange,
42395
+ contextFilters,
42396
+ availableContextValues,
42397
+ onContextFiltersChange
42140
42398
  }) {
42141
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-wrap gap-x-8 gap-y-4"), children: [
42142
- /* @__PURE__ */ jsxRuntime.jsx(
42143
- SelectField,
42399
+ const [filterSearch, setFilterSearch] = React.useState("");
42400
+ const [customRangeOpen, setCustomRangeOpen] = React.useState(false);
42401
+ const [draftDateFrom, setDraftDateFrom] = React.useState(selectedDateFrom);
42402
+ const [draftDateTo, setDraftDateTo] = React.useState(selectedDateTo);
42403
+ const [draftTimeFrom, setDraftTimeFrom] = React.useState("12:00 AM");
42404
+ const [draftTimeTo, setDraftTimeTo] = React.useState("11:59 PM");
42405
+ const [entitySearch, setEntitySearch] = React.useState("");
42406
+ const [tagSearch, setTagSearch] = React.useState("");
42407
+ const [metadataKeySearch, setMetadataKeySearch] = React.useState("");
42408
+ const [subValueSearch, setSubValueSearch] = React.useState("");
42409
+ const [contextFieldSearch, setContextFieldSearch] = React.useState("");
42410
+ const [customRangeError, setCustomRangeError] = React.useState();
42411
+ const resetSubSearch = React.useCallback(
42412
+ (setter) => (open) => {
42413
+ if (!open) setter("");
42414
+ },
42415
+ []
42416
+ );
42417
+ const datePresetLabel = DATE_PRESETS.find((p) => p.value === datePreset)?.label ?? "All";
42418
+ const handleDatePresetSelect = (preset) => {
42419
+ onDatePresetChange?.(preset);
42420
+ if (preset === "custom") {
42421
+ setDraftDateFrom(selectedDateFrom);
42422
+ setDraftDateTo(selectedDateTo);
42423
+ setDraftTimeFrom("12:00 AM");
42424
+ setDraftTimeTo("11:59 PM");
42425
+ setCustomRangeOpen(true);
42426
+ return;
42427
+ }
42428
+ const entry = DATE_PRESETS.find((p) => p.value === preset);
42429
+ if (entry?.ms) {
42430
+ onDateChange?.(new Date(Date.now() - entry.ms), "from");
42431
+ onDateChange?.(void 0, "to");
42432
+ } else {
42433
+ onDateChange?.(void 0, "from");
42434
+ onDateChange?.(void 0, "to");
42435
+ }
42436
+ };
42437
+ const applyCustomRange = () => {
42438
+ const fromDate = draftDateFrom ? buildDateWithTime(draftDateFrom, draftTimeFrom) ?? draftDateFrom : void 0;
42439
+ const toDate = draftDateTo ? buildDateWithTime(draftDateTo, draftTimeTo) ?? draftDateTo : void 0;
42440
+ if (fromDate && toDate && fromDate.getTime() > toDate.getTime()) {
42441
+ setCustomRangeError("Start date/time must be before end date/time");
42442
+ return;
42443
+ }
42444
+ setCustomRangeError(void 0);
42445
+ onDateChange?.(fromDate, "from");
42446
+ onDateChange?.(toDate, "to");
42447
+ setCustomRangeOpen(false);
42448
+ };
42449
+ const metadataCount = Object.keys(selectedMetadata ?? {}).length;
42450
+ const activeFilterCount = React.useMemo(() => {
42451
+ let count = 0;
42452
+ if (selectedEntity && selectedEntity.value !== "all") count++;
42453
+ if (errorOnly) count++;
42454
+ if ((selectedTags ?? []).length > 0) count++;
42455
+ if (metadataCount > 0) count++;
42456
+ if (contextFilters) {
42457
+ count += Object.values(contextFilters).filter((v) => v.trim()).length;
42458
+ }
42459
+ return count;
42460
+ }, [selectedEntity, errorOnly, selectedTags, metadataCount, contextFilters]);
42461
+ const contextFilterGroups = React.useMemo(() => {
42462
+ const groups = {};
42463
+ for (const cat of CONTEXT_FILTER_CATEGORIES) {
42464
+ if (!groups[cat.group]) groups[cat.group] = [];
42465
+ groups[cat.group].push({ id: cat.id, label: cat.label });
42466
+ }
42467
+ return groups;
42468
+ }, []);
42469
+ const metadataKeys = React.useMemo(() => Object.keys(availableMetadata ?? {}).sort(), [availableMetadata]);
42470
+ const filterCategories = React.useMemo(() => {
42471
+ const q = filterSearch.toLowerCase();
42472
+ const categories = [
42473
+ { id: "status", label: "Status" },
42474
+ { id: "entity-type", label: "Entity Type" },
42475
+ { id: "tags", label: "Tags" },
42476
+ { id: "metadata", label: "Metadata" },
42477
+ ...Object.keys(contextFilterGroups).map((group) => ({ id: `ctx-${group}`, label: group }))
42478
+ ];
42479
+ if (!q) return categories;
42480
+ return categories.filter((c) => {
42481
+ if (c.label.toLowerCase().includes(q)) return true;
42482
+ if (c.id.startsWith("ctx-")) {
42483
+ const group = c.label;
42484
+ return contextFilterGroups[group]?.some((f) => f.label.toLowerCase().includes(q));
42485
+ }
42486
+ if (c.id === "metadata") {
42487
+ return metadataKeys.some((k) => k.toLowerCase().includes(q));
42488
+ }
42489
+ return false;
42490
+ });
42491
+ }, [filterSearch, contextFilterGroups, metadataKeys]);
42492
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("grid gap-3"), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex items-center gap-3"), children: [
42493
+ onSearchChange && /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex-1 max-w-sm"), children: /* @__PURE__ */ jsxRuntime.jsx(
42494
+ Searchbar,
42144
42495
  {
42145
- label: "Filter by Entity",
42146
- name: "select-entity",
42147
- placeholder: "Select...",
42148
- options: entityOptions || [],
42149
- onValueChange: (val) => {
42150
- const entity = entityOptions?.find((entity2) => entity2.value === val);
42151
- if (entity) {
42152
- onEntityChange(entity);
42153
- }
42154
- },
42155
- value: selectedEntity?.value || "",
42156
- className: "min-w-[20rem]",
42157
- disabled: isLoading
42496
+ onSearch: onSearchChange,
42497
+ label: "Search traces",
42498
+ placeholder: "Search name, ID, content...",
42499
+ size: "md"
42158
42500
  }
42159
- ),
42160
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex gap-4 items-center flex-wrap"), children: [
42161
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("shrink-0 text-ui-md text-neutral3"), children: "Filter by Date & time range" }),
42162
- /* @__PURE__ */ jsxRuntime.jsx(
42163
- DateTimePicker,
42164
- {
42165
- placeholder: "From",
42166
- value: selectedDateFrom,
42167
- maxValue: selectedDateTo,
42168
- onValueChange: (date) => onDateChange?.(date, "from"),
42169
- className: "min-w-32",
42170
- defaultTimeStrValue: "12:00 AM",
42171
- disabled: isLoading
42172
- }
42173
- ),
42174
- /* @__PURE__ */ jsxRuntime.jsx(
42175
- DateTimePicker,
42176
- {
42177
- placeholder: "To",
42178
- value: selectedDateTo,
42179
- minValue: selectedDateFrom,
42180
- onValueChange: (date) => onDateChange?.(date, "to"),
42181
- className: "min-w-32",
42182
- defaultTimeStrValue: "11:59 PM",
42183
- disabled: isLoading
42184
- }
42185
- ),
42186
- /* @__PURE__ */ jsxRuntime.jsxs("label", { className: cn("flex gap-2 items-center shrink-0 cursor-pointer"), children: [
42187
- /* @__PURE__ */ jsxRuntime.jsx(Switch, { checked: groupByThread, onCheckedChange: onGroupByThreadChange, disabled: isLoading }),
42188
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-ui-md text-neutral3"), children: "Group by thread" })
42189
- ] }),
42190
- /* @__PURE__ */ jsxRuntime.jsxs(Button, { variant: "light", size: "lg", className: "min-w-32", onClick: onReset, disabled: isLoading, children: [
42191
- /* @__PURE__ */ jsxRuntime.jsx(Icon, { children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.XIcon, {}) }),
42192
- "Reset"
42501
+ ) }),
42502
+ datePreset === "custom" ? /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: customRangeOpen, onOpenChange: setCustomRangeOpen, children: [
42503
+ /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(Button, { variant: "outline", size: "md", disabled: isLoading, children: [
42504
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CalendarIcon, {}),
42505
+ selectedDateFrom ? selectedDateFrom.toLocaleDateString() : "Start",
42506
+ " ",
42507
+ " ",
42508
+ selectedDateTo ? selectedDateTo.toLocaleDateString() : "End"
42509
+ ] }) }),
42510
+ /* @__PURE__ */ jsxRuntime.jsxs(PopoverContent, { align: "start", className: cn("w-auto p-0"), children: [
42511
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex"), children: [
42512
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("border-r border-border1"), children: [
42513
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-ui-sm text-neutral3 font-medium px-4 pt-3 block"), children: "Start" }),
42514
+ /* @__PURE__ */ jsxRuntime.jsx(
42515
+ DatePicker,
42516
+ {
42517
+ mode: "single",
42518
+ selected: draftDateFrom,
42519
+ month: draftDateFrom,
42520
+ onSelect: setDraftDateFrom,
42521
+ disabled: isLoading,
42522
+ toDate: draftDateTo
42523
+ }
42524
+ ),
42525
+ /* @__PURE__ */ jsxRuntime.jsx(
42526
+ TimePicker,
42527
+ {
42528
+ className: "mx-4 mb-3 w-auto",
42529
+ defaultValue: draftTimeFrom,
42530
+ onValueChange: setDraftTimeFrom
42531
+ }
42532
+ )
42533
+ ] }),
42534
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
42535
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-ui-sm text-neutral3 font-medium px-4 pt-3 block"), children: "End" }),
42536
+ /* @__PURE__ */ jsxRuntime.jsx(
42537
+ DatePicker,
42538
+ {
42539
+ mode: "single",
42540
+ selected: draftDateTo,
42541
+ month: draftDateTo,
42542
+ onSelect: setDraftDateTo,
42543
+ disabled: isLoading,
42544
+ fromDate: draftDateFrom
42545
+ }
42546
+ ),
42547
+ /* @__PURE__ */ jsxRuntime.jsx(TimePicker, { className: "mx-4 mb-3 w-auto", defaultValue: draftTimeTo, onValueChange: setDraftTimeTo })
42548
+ ] })
42549
+ ] }),
42550
+ customRangeError && /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("text-ui-sm text-red-500 px-4 pb-1"), children: customRangeError }),
42551
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex justify-between items-center px-4 pb-3"), children: [
42552
+ /* @__PURE__ */ jsxRuntime.jsx(
42553
+ "button",
42554
+ {
42555
+ type: "button",
42556
+ className: cn("text-ui-sm text-neutral3 hover:text-neutral4"),
42557
+ onClick: () => {
42558
+ setCustomRangeError(void 0);
42559
+ handleDatePresetSelect("all");
42560
+ },
42561
+ children: "← Presets"
42562
+ }
42563
+ ),
42564
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "primary", size: "sm", onClick: applyCustomRange, children: "Apply" })
42565
+ ] })
42566
+ ] })
42567
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu, { children: [
42568
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(Button, { variant: "outline", size: "md", disabled: isLoading, children: [
42569
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CalendarIcon, {}),
42570
+ datePresetLabel
42571
+ ] }) }),
42572
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenu.Content, { align: "start", children: DATE_PRESETS.map((preset) => /* @__PURE__ */ jsxRuntime.jsx(DropdownMenu.Item, { onSelect: () => handleDatePresetSelect(preset.value), children: preset.label }, preset.value)) })
42573
+ ] }),
42574
+ /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu, { modal: false, children: [
42575
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(Button, { variant: "outline", size: "md", disabled: isLoading, children: [
42576
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FilterIcon, {}),
42577
+ "Filter",
42578
+ activeFilterCount > 0 && /* @__PURE__ */ jsxRuntime.jsx(
42579
+ "span",
42580
+ {
42581
+ className: cn(
42582
+ "ml-0.5 inline-flex items-center justify-center rounded-full bg-accent1/50 text-neutral5 text-ui-sm w-5 h-5"
42583
+ ),
42584
+ children: activeFilterCount
42585
+ }
42586
+ )
42587
+ ] }) }),
42588
+ /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu.Content, { align: "end", className: cn("min-w-[12rem]"), children: [
42589
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("px-2 pb-2"), children: /* @__PURE__ */ jsxRuntime.jsxs(
42590
+ "div",
42591
+ {
42592
+ className: cn(
42593
+ "flex items-center gap-2 border border-border1 rounded-md px-2 py-1",
42594
+ "focus-within:border-neutral2"
42595
+ ),
42596
+ children: [
42597
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.SearchIcon, { className: cn("text-neutral3 h-3.5 w-3.5 shrink-0") }),
42598
+ /* @__PURE__ */ jsxRuntime.jsx(
42599
+ "input",
42600
+ {
42601
+ type: "text",
42602
+ placeholder: "Search filters...",
42603
+ "aria-label": "Search filters",
42604
+ value: filterSearch,
42605
+ onChange: (e) => setFilterSearch(e.target.value),
42606
+ onKeyDown: (e) => e.stopPropagation(),
42607
+ className: cn(
42608
+ "bg-transparent text-ui-sm text-neutral4 placeholder:text-neutral3 outline-none w-full"
42609
+ )
42610
+ }
42611
+ )
42612
+ ]
42613
+ }
42614
+ ) }),
42615
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenu.Separator, {}),
42616
+ filterCategories.some((c) => c.id === "status") && onErrorOnlyChange && /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu.Sub, { children: [
42617
+ /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu.SubTrigger, { children: [
42618
+ "Status",
42619
+ errorOnly && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("ml-auto text-ui-sm text-accent1"), children: "1" })
42620
+ ] }),
42621
+ /* @__PURE__ */ jsxRuntime.jsxs(PortalSubContent, { children: [
42622
+ /* @__PURE__ */ jsxRuntime.jsx(
42623
+ DropdownMenu.CheckboxItem,
42624
+ {
42625
+ checked: !errorOnly,
42626
+ onCheckedChange: () => onErrorOnlyChange(false),
42627
+ onSelect: (e) => e.preventDefault(),
42628
+ children: "All"
42629
+ }
42630
+ ),
42631
+ /* @__PURE__ */ jsxRuntime.jsx(
42632
+ DropdownMenu.CheckboxItem,
42633
+ {
42634
+ checked: errorOnly,
42635
+ onCheckedChange: () => onErrorOnlyChange(true),
42636
+ onSelect: (e) => e.preventDefault(),
42637
+ children: "Error only"
42638
+ }
42639
+ )
42640
+ ] })
42641
+ ] }),
42642
+ filterCategories.some((c) => c.id === "entity-type") && entityOptions && /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu.Sub, { onOpenChange: resetSubSearch(setEntitySearch), children: [
42643
+ /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu.SubTrigger, { children: [
42644
+ "Entity Type",
42645
+ selectedEntity && selectedEntity.value !== "all" && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("ml-auto text-ui-sm text-accent1"), children: "1" })
42646
+ ] }),
42647
+ /* @__PURE__ */ jsxRuntime.jsxs(PortalSubContent, { children: [
42648
+ entityOptions.length >= SUBMENU_SEARCH_THRESHOLD && /* @__PURE__ */ jsxRuntime.jsx(SubMenuSearch, { value: entitySearch, onChange: setEntitySearch, label: "Search entity types" }),
42649
+ /* @__PURE__ */ jsxRuntime.jsx(
42650
+ DropdownMenu.RadioGroup,
42651
+ {
42652
+ value: selectedEntity?.value ?? "all",
42653
+ onValueChange: (val) => {
42654
+ const entity = entityOptions.find((e) => e.value === val);
42655
+ if (entity) onEntityChange(entity);
42656
+ },
42657
+ children: entityOptions.filter(
42658
+ (option) => !entitySearch || option.label.toLowerCase().includes(entitySearch.toLowerCase())
42659
+ ).map((option) => /* @__PURE__ */ jsxRuntime.jsx(DropdownMenu.RadioItem, { value: option.value, children: option.label }, option.value))
42660
+ }
42661
+ )
42662
+ ] })
42663
+ ] }),
42664
+ filterCategories.some((c) => c.id === "tags") && onTagsChange && (availableTags ?? []).length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu.Sub, { onOpenChange: resetSubSearch(setTagSearch), children: [
42665
+ /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu.SubTrigger, { children: [
42666
+ "Tags",
42667
+ (selectedTags ?? []).length > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("ml-auto text-ui-sm text-accent1"), children: selectedTags?.length })
42668
+ ] }),
42669
+ /* @__PURE__ */ jsxRuntime.jsxs(PortalSubContent, { children: [
42670
+ (availableTags ?? []).length >= SUBMENU_SEARCH_THRESHOLD && /* @__PURE__ */ jsxRuntime.jsx(SubMenuSearch, { value: tagSearch, onChange: setTagSearch, label: "Search tags" }),
42671
+ (availableTags ?? []).filter((tag) => !tagSearch || tag.toLowerCase().includes(tagSearch.toLowerCase())).map((tag) => /* @__PURE__ */ jsxRuntime.jsx(
42672
+ DropdownMenu.CheckboxItem,
42673
+ {
42674
+ checked: (selectedTags ?? []).includes(tag),
42675
+ onCheckedChange: (checked) => {
42676
+ if (checked) {
42677
+ onTagsChange([...selectedTags ?? [], tag]);
42678
+ } else {
42679
+ onTagsChange((selectedTags ?? []).filter((t) => t !== tag));
42680
+ }
42681
+ },
42682
+ onSelect: (e) => e.preventDefault(),
42683
+ children: tag
42684
+ },
42685
+ tag
42686
+ ))
42687
+ ] })
42688
+ ] }),
42689
+ filterCategories.some((c) => c.id === "metadata") && onMetadataChange && metadataKeys.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu.Sub, { onOpenChange: resetSubSearch(setMetadataKeySearch), children: [
42690
+ /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu.SubTrigger, { children: [
42691
+ "Metadata",
42692
+ metadataCount > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("ml-auto text-ui-sm text-accent1"), children: metadataCount })
42693
+ ] }),
42694
+ /* @__PURE__ */ jsxRuntime.jsxs(PortalSubContent, { className: cn("max-h-[20rem]"), children: [
42695
+ metadataKeys.length >= SUBMENU_SEARCH_THRESHOLD && /* @__PURE__ */ jsxRuntime.jsx(
42696
+ SubMenuSearch,
42697
+ {
42698
+ value: metadataKeySearch,
42699
+ onChange: setMetadataKeySearch,
42700
+ label: "Search metadata keys"
42701
+ }
42702
+ ),
42703
+ metadataKeys.filter((key) => !metadataKeySearch || key.toLowerCase().includes(metadataKeySearch.toLowerCase())).map((key) => {
42704
+ const values = availableMetadata?.[key] ?? [];
42705
+ const selectedValue = selectedMetadata?.[key];
42706
+ return /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu.Sub, { onOpenChange: resetSubSearch(setSubValueSearch), children: [
42707
+ /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu.SubTrigger, { children: [
42708
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("truncate"), children: key }),
42709
+ selectedValue && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("ml-auto text-ui-sm text-accent1"), children: "1" })
42710
+ ] }),
42711
+ /* @__PURE__ */ jsxRuntime.jsxs(PortalSubContent, { className: cn("max-h-[20rem]"), children: [
42712
+ values.length >= SUBMENU_SEARCH_THRESHOLD && /* @__PURE__ */ jsxRuntime.jsx(
42713
+ SubMenuSearch,
42714
+ {
42715
+ value: subValueSearch,
42716
+ onChange: setSubValueSearch,
42717
+ label: "Search metadata values"
42718
+ }
42719
+ ),
42720
+ /* @__PURE__ */ jsxRuntime.jsx(
42721
+ DropdownMenu.CheckboxItem,
42722
+ {
42723
+ checked: !selectedValue,
42724
+ onCheckedChange: () => {
42725
+ const next = { ...selectedMetadata };
42726
+ delete next[key];
42727
+ onMetadataChange(next);
42728
+ },
42729
+ onSelect: (e) => e.preventDefault(),
42730
+ children: "Any"
42731
+ }
42732
+ ),
42733
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenu.Separator, {}),
42734
+ values.filter(
42735
+ (value) => !subValueSearch || value.toLowerCase().includes(subValueSearch.toLowerCase())
42736
+ ).map((value) => /* @__PURE__ */ jsxRuntime.jsx(
42737
+ DropdownMenu.CheckboxItem,
42738
+ {
42739
+ checked: selectedValue === value,
42740
+ onCheckedChange: (checked) => {
42741
+ const next = { ...selectedMetadata };
42742
+ if (checked) {
42743
+ next[key] = value;
42744
+ } else {
42745
+ delete next[key];
42746
+ }
42747
+ onMetadataChange(next);
42748
+ },
42749
+ onSelect: (e) => e.preventDefault(),
42750
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("truncate"), children: value })
42751
+ },
42752
+ value
42753
+ ))
42754
+ ] })
42755
+ ] }, key);
42756
+ })
42757
+ ] })
42758
+ ] }),
42759
+ onContextFiltersChange && Object.entries(contextFilterGroups).map(([group, fields]) => {
42760
+ if (!filterCategories.some((c) => c.id === `ctx-${group}`)) return null;
42761
+ const q = filterSearch.toLowerCase();
42762
+ const visibleFields = q ? fields.filter((f) => f.label.toLowerCase().includes(q) || group.toLowerCase().includes(q)) : fields;
42763
+ const fieldsWithValues = visibleFields.filter((f) => (availableContextValues?.[f.id] ?? []).length > 0);
42764
+ if (fieldsWithValues.length === 0) return null;
42765
+ const activeInGroup = fieldsWithValues.filter((f) => contextFilters?.[f.id]?.trim()).length;
42766
+ return /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu.Sub, { onOpenChange: resetSubSearch(setContextFieldSearch), children: [
42767
+ /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu.SubTrigger, { children: [
42768
+ group,
42769
+ activeInGroup > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("ml-auto text-ui-sm text-accent1"), children: activeInGroup })
42770
+ ] }),
42771
+ /* @__PURE__ */ jsxRuntime.jsxs(PortalSubContent, { className: cn("max-h-[20rem]"), children: [
42772
+ fieldsWithValues.length >= SUBMENU_SEARCH_THRESHOLD && /* @__PURE__ */ jsxRuntime.jsx(
42773
+ SubMenuSearch,
42774
+ {
42775
+ value: contextFieldSearch,
42776
+ onChange: setContextFieldSearch,
42777
+ label: "Search context fields"
42778
+ }
42779
+ ),
42780
+ fieldsWithValues.filter(
42781
+ (field) => !contextFieldSearch || field.label.toLowerCase().includes(contextFieldSearch.toLowerCase())
42782
+ ).map((field) => {
42783
+ const values = availableContextValues?.[field.id] ?? [];
42784
+ const selectedValue = contextFilters?.[field.id];
42785
+ return /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu.Sub, { onOpenChange: resetSubSearch(setSubValueSearch), children: [
42786
+ /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu.SubTrigger, { children: [
42787
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("truncate"), children: field.label }),
42788
+ selectedValue && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("ml-auto text-ui-sm text-accent1"), children: "1" })
42789
+ ] }),
42790
+ /* @__PURE__ */ jsxRuntime.jsxs(PortalSubContent, { className: cn("max-h-[20rem]"), children: [
42791
+ values.length >= SUBMENU_SEARCH_THRESHOLD && /* @__PURE__ */ jsxRuntime.jsx(
42792
+ SubMenuSearch,
42793
+ {
42794
+ value: subValueSearch,
42795
+ onChange: setSubValueSearch,
42796
+ label: "Search context values"
42797
+ }
42798
+ ),
42799
+ /* @__PURE__ */ jsxRuntime.jsx(
42800
+ DropdownMenu.CheckboxItem,
42801
+ {
42802
+ checked: !selectedValue,
42803
+ onCheckedChange: () => {
42804
+ const next = { ...contextFilters };
42805
+ delete next[field.id];
42806
+ onContextFiltersChange(next);
42807
+ },
42808
+ onSelect: (e) => e.preventDefault(),
42809
+ children: "Any"
42810
+ }
42811
+ ),
42812
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenu.Separator, {}),
42813
+ values.filter(
42814
+ (value) => !subValueSearch || value.toLowerCase().includes(subValueSearch.toLowerCase())
42815
+ ).map((value) => /* @__PURE__ */ jsxRuntime.jsx(
42816
+ DropdownMenu.CheckboxItem,
42817
+ {
42818
+ checked: selectedValue === value,
42819
+ onCheckedChange: (checked) => {
42820
+ const next = { ...contextFilters };
42821
+ if (checked) {
42822
+ next[field.id] = value;
42823
+ } else {
42824
+ delete next[field.id];
42825
+ }
42826
+ onContextFiltersChange(next);
42827
+ },
42828
+ onSelect: (e) => e.preventDefault(),
42829
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("truncate"), children: value })
42830
+ },
42831
+ value
42832
+ ))
42833
+ ] })
42834
+ ] }, field.id);
42835
+ })
42836
+ ] })
42837
+ ] }, group);
42838
+ }),
42839
+ activeFilterCount > 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
42840
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenu.Separator, {}),
42841
+ /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu.Item, { onSelect: () => onReset?.(), children: [
42842
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.XIcon, {}),
42843
+ "Clear all filters"
42844
+ ] })
42845
+ ] })
42193
42846
  ] })
42847
+ ] }),
42848
+ onReset && /* @__PURE__ */ jsxRuntime.jsxs(Button, { variant: "outline", size: "md", disabled: isLoading, onClick: () => onReset(), children: [
42849
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.XIcon, {}),
42850
+ "Reset"
42851
+ ] }),
42852
+ onGroupByThreadChange && /* @__PURE__ */ jsxRuntime.jsxs("label", { className: cn("flex gap-2 items-center shrink-0 cursor-pointer"), children: [
42853
+ /* @__PURE__ */ jsxRuntime.jsx(Switch, { checked: groupByThread, onCheckedChange: onGroupByThreadChange, disabled: isLoading }),
42854
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-ui-md text-neutral3"), children: "Group by thread" })
42194
42855
  ] })
42195
- ] });
42856
+ ] }) });
42196
42857
  }
42197
42858
 
42198
42859
  const tracesListColumns = [
@@ -42205,13 +42866,13 @@ const tracesListColumns = [
42205
42866
  { name: "status", label: "Status", size: "3rem" }
42206
42867
  ];
42207
42868
  function traceToEntry(trace, selectedTraceId) {
42208
- const createdAtDate = new Date(trace.createdAt);
42209
- const isTodayDate = dateFns.isToday(createdAtDate);
42869
+ const displayDate = new Date(trace.startedAt ?? trace.createdAt);
42870
+ const isTodayDate = dateFns.isToday(displayDate);
42210
42871
  return {
42211
42872
  id: trace.traceId,
42212
42873
  shortId: getShortId(trace?.traceId) || "n/a",
42213
- date: isTodayDate ? "Today" : dateFns.format(createdAtDate, "MMM dd"),
42214
- time: dateFns.format(createdAtDate, "h:mm:ss aaa"),
42874
+ date: isTodayDate ? "Today" : dateFns.format(displayDate, "MMM dd"),
42875
+ time: dateFns.format(displayDate, "h:mm:ss aaa"),
42215
42876
  name: trace?.name,
42216
42877
  input: getInputPreview(trace?.input),
42217
42878
  entityId: trace?.entityName || trace?.entityId || trace?.attributes?.agentId || trace?.attributes?.workflowId,
@@ -42693,6 +43354,54 @@ const SpanScoring = ({
42693
43354
  ] });
42694
43355
  };
42695
43356
 
43357
+ const useTags = () => {
43358
+ const client = react.useMastraClient();
43359
+ return reactQuery.useQuery({
43360
+ queryKey: ["observability-tags"],
43361
+ queryFn: async () => {
43362
+ try {
43363
+ return await client.getTags();
43364
+ } catch {
43365
+ return { tags: [] };
43366
+ }
43367
+ },
43368
+ select: (data) => data?.tags ?? [],
43369
+ retry: false
43370
+ });
43371
+ };
43372
+
43373
+ const useEnvironments = () => {
43374
+ const client = react.useMastraClient();
43375
+ return reactQuery.useQuery({
43376
+ queryKey: ["observability-environments"],
43377
+ queryFn: async () => {
43378
+ try {
43379
+ return await client.getEnvironments();
43380
+ } catch {
43381
+ return { environments: [] };
43382
+ }
43383
+ },
43384
+ select: (data) => data?.environments ?? [],
43385
+ retry: false
43386
+ });
43387
+ };
43388
+
43389
+ const useServiceNames = () => {
43390
+ const client = react.useMastraClient();
43391
+ return reactQuery.useQuery({
43392
+ queryKey: ["observability-service-names"],
43393
+ queryFn: async () => {
43394
+ try {
43395
+ return await client.getServiceNames();
43396
+ } catch {
43397
+ return { serviceNames: [] };
43398
+ }
43399
+ },
43400
+ select: (data) => data?.serviceNames ?? [],
43401
+ retry: false
43402
+ });
43403
+ };
43404
+
42696
43405
  const useDatasetItemVersions = (datasetId, itemId) => {
42697
43406
  const client = react.useMastraClient();
42698
43407
  return reactQuery.useQuery({
@@ -49475,6 +50184,32 @@ const CommandShortcut = ({ className, ...props }) => {
49475
50184
  };
49476
50185
  CommandShortcut.displayName = "CommandShortcut";
49477
50186
 
50187
+ function FieldBlocksLayoutColumn({ children, className }) {
50188
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("grid gap-6 content-start", className), children });
50189
+ }
50190
+
50191
+ function FieldBlocksLayoutRoot({ children, className, columns = 1, gap }) {
50192
+ return /* @__PURE__ */ jsxRuntime.jsx(
50193
+ "div",
50194
+ {
50195
+ className: cn(
50196
+ "grid",
50197
+ {
50198
+ "grid-cols-1": columns === 1,
50199
+ "grid-cols-2": columns === 2
50200
+ },
50201
+ gap ?? "gap-6",
50202
+ className
50203
+ ),
50204
+ children
50205
+ }
50206
+ );
50207
+ }
50208
+
50209
+ const FieldBlocksLayout = Object.assign(FieldBlocksLayoutRoot, {
50210
+ Column: FieldBlocksLayoutColumn
50211
+ });
50212
+
49478
50213
  const themeClasses = {
49479
50214
  light: "bg-gray-100 border-gray-300 text-gray-700 shadow-[0_1px_0_rgba(0,0,0,0.1)]",
49480
50215
  dark: "bg-surface4 border-border1 text-neutral5 shadow-[0_1px_0_rgba(0,0,0,0.3)]"
@@ -52527,6 +53262,7 @@ exports.ButtonWithTooltip = ButtonWithTooltip;
52527
53262
  exports.ButtonsGroup = ButtonsGroup;
52528
53263
  exports.CHART_COLORS = CHART_COLORS;
52529
53264
  exports.CODE_AGENT_OVERRIDE_SECTIONS = CODE_AGENT_OVERRIDE_SECTIONS;
53265
+ exports.CONTEXT_FIELD_IDS = CONTEXT_FIELD_IDS;
52530
53266
  exports.CSVImportDialog = CSVImportDialog;
52531
53267
  exports.Cell = Cell;
52532
53268
  exports.ChatThreads = ChatThreads;
@@ -52562,6 +53298,7 @@ exports.CreateDatasetDialog = CreateDatasetDialog;
52562
53298
  exports.CreateDatasetFromItemsDialog = CreateDatasetFromItemsDialog;
52563
53299
  exports.CrossIcon = CrossIcon;
52564
53300
  exports.Crumb = Crumb;
53301
+ exports.DashboardCard = DashboardCard;
52565
53302
  exports.DatasetCombobox = DatasetCombobox;
52566
53303
  exports.DatasetCompareVersionToolbar = DatasetCompareVersionToolbar;
52567
53304
  exports.DatasetCompareVersionsList = DatasetCompareVersionsList;
@@ -52599,6 +53336,7 @@ exports.DialogTrigger = DialogTrigger;
52599
53336
  exports.DisplayConditionsDialog = DisplayConditionsDialog;
52600
53337
  exports.DividerIcon = DividerIcon;
52601
53338
  exports.DocsIcon = DocsIcon;
53339
+ exports.DropdownMenu = DropdownMenu;
52602
53340
  exports.DuplicateDatasetDialog = DuplicateDatasetDialog;
52603
53341
  exports.DynamicForm = DynamicForm;
52604
53342
  exports.EditDatasetDialog = EditDatasetDialog;
@@ -52630,6 +53368,8 @@ exports.ExperimentResultsPanel = ExperimentResultsPanel;
52630
53368
  exports.ExperimentStats = ExperimentStats;
52631
53369
  exports.ExperimentTriggerDialog = ExperimentTriggerDialog;
52632
53370
  exports.Field = Field;
53371
+ exports.FieldBlock = FieldBlock;
53372
+ exports.FieldBlocksLayout = FieldBlocksLayout;
52633
53373
  exports.FieldDescription = FieldDescription;
52634
53374
  exports.FieldList = FieldList;
52635
53375
  exports.FieldName = FieldName;
@@ -52653,6 +53393,7 @@ exports.HomeIcon = HomeIcon;
52653
53393
  exports.HorizontalBars = HorizontalBars;
52654
53394
  exports.HoverPopover = HoverPopover;
52655
53395
  exports.Icon = Icon;
53396
+ exports.IconButton = IconButton;
52656
53397
  exports.InfoIcon = InfoIcon;
52657
53398
  exports.InformationPage = InformationPage;
52658
53399
  exports.Input = Input;
@@ -52779,6 +53520,7 @@ exports.ScoresList = ScoresList;
52779
53520
  exports.ScoresTools = ScoresTools;
52780
53521
  exports.ScrollArea = ScrollArea;
52781
53522
  exports.ScrollBar = ScrollBar;
53523
+ exports.SearchFieldBlock = SearchFieldBlock;
52782
53524
  exports.SearchSkillsPanel = SearchSkillsPanel;
52783
53525
  exports.SearchWorkspacePanel = SearchWorkspacePanel;
52784
53526
  exports.Searchbar = Searchbar;
@@ -52789,6 +53531,7 @@ exports.Sections = Sections;
52789
53531
  exports.Select = Select;
52790
53532
  exports.SelectContent = SelectContent;
52791
53533
  exports.SelectField = SelectField;
53534
+ exports.SelectFieldBlock = SelectFieldBlock;
52792
53535
  exports.SelectGroup = SelectGroup;
52793
53536
  exports.SelectItem = SelectItem;
52794
53537
  exports.SelectTrigger = SelectTrigger;
@@ -52830,6 +53573,7 @@ exports.TemplateSuccess = TemplateSuccess;
52830
53573
  exports.TemplatesList = TemplatesList;
52831
53574
  exports.TemplatesTools = TemplatesTools;
52832
53575
  exports.TextAndIcon = TextAndIcon;
53576
+ exports.TextFieldBlock = TextFieldBlock;
52833
53577
  exports.Th = Th;
52834
53578
  exports.Thead = Thead;
52835
53579
  exports.ThreadDeleteButton = ThreadDeleteButton;
@@ -53035,6 +53779,7 @@ exports.useDeleteScorerVersion = useDeleteScorerVersion;
53035
53779
  exports.useDeleteThread = useDeleteThread;
53036
53780
  exports.useDeleteWorkflowRun = useDeleteWorkflowRun;
53037
53781
  exports.useDeleteWorkspaceFile = useDeleteWorkspaceFile;
53782
+ exports.useEnvironments = useEnvironments;
53038
53783
  exports.useExecuteAgentTool = useExecuteAgentTool;
53039
53784
  exports.useExecuteMCPTool = useExecuteMCPTool;
53040
53785
  exports.useExecuteProcessor = useExecuteProcessor;
@@ -53109,6 +53854,7 @@ exports.useScoresMetrics = useScoresMetrics;
53109
53854
  exports.useSearchSkillsSh = useSearchSkillsSh;
53110
53855
  exports.useSearchWorkspace = useSearchWorkspace;
53111
53856
  exports.useSearchWorkspaceSkills = useSearchWorkspaceSkills;
53857
+ exports.useServiceNames = useServiceNames;
53112
53858
  exports.useSkillPreview = useSkillPreview;
53113
53859
  exports.useSpeechRecognition = useSpeechRecognition;
53114
53860
  exports.useStoredAgent = useStoredAgent;
@@ -53122,6 +53868,7 @@ exports.useStoredScorerMutations = useStoredScorerMutations;
53122
53868
  exports.useStoredSkills = useStoredSkills;
53123
53869
  exports.useStudioConfig = useStudioConfig;
53124
53870
  exports.useTableKeyboardNavigation = useTableKeyboardNavigation;
53871
+ exports.useTags = useTags;
53125
53872
  exports.useThread = useThread;
53126
53873
  exports.useThreadInput = useThreadInput;
53127
53874
  exports.useThreads = useThreads;