@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/CHANGELOG.md +39 -0
- package/dist/index.cjs.js +850 -103
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +842 -106
- package/dist/index.es.js.map +1 -1
- package/dist/src/domains/metrics/components/metrics-utils.d.ts +1 -0
- package/dist/src/domains/metrics/hooks/use-model-cost-kpi-metrics.d.ts +7 -0
- package/dist/src/domains/metrics/hooks/use-model-usage-cost-metrics.d.ts +2 -0
- package/dist/src/domains/metrics/hooks/use-token-usage-by-agent-metrics.d.ts +2 -0
- package/dist/src/domains/observability/components/traces-list.d.ts +1 -0
- package/dist/src/domains/observability/components/traces-tools.d.ts +23 -1
- package/dist/src/domains/observability/hooks/use-environments.d.ts +1 -0
- package/dist/src/domains/observability/hooks/use-service-names.d.ts +1 -0
- package/dist/src/domains/observability/hooks/use-tags.d.ts +1 -0
- package/dist/src/domains/observability/index.d.ts +3 -0
- package/dist/src/ds/components/FormFieldBlocks/index.d.ts +5 -0
- package/dist/src/ds/components/MetricsCard/metrics-card-title-and-description.d.ts +1 -0
- package/dist/src/ds/components/MetricsCard/metrics-card-title.d.ts +2 -1
- package/dist/src/ds/components/ScrollArea/scroll-area.d.ts +2 -0
- package/dist/src/index.d.ts +5 -0
- package/package.json +8 -8
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:
|
|
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(
|
|
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$
|
|
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$
|
|
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$
|
|
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({
|
|
41166
|
-
|
|
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)
|
|
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)
|
|
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)
|
|
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)
|
|
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(() => "
|
|
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.
|
|
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
|
-
|
|
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)
|
|
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)
|
|
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(
|
|
41928
|
-
|
|
41929
|
-
|
|
41930
|
-
|
|
41931
|
-
|
|
41932
|
-
|
|
41933
|
-
|
|
41934
|
-
|
|
41935
|
-
|
|
41936
|
-
|
|
41937
|
-
|
|
41938
|
-
|
|
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
|
-
|
|
42142
|
-
|
|
42143
|
-
|
|
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
|
-
|
|
42146
|
-
|
|
42147
|
-
placeholder: "
|
|
42148
|
-
|
|
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(
|
|
42161
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
42162
|
-
|
|
42163
|
-
|
|
42164
|
-
|
|
42165
|
-
|
|
42166
|
-
|
|
42167
|
-
|
|
42168
|
-
|
|
42169
|
-
|
|
42170
|
-
|
|
42171
|
-
|
|
42172
|
-
|
|
42173
|
-
|
|
42174
|
-
|
|
42175
|
-
|
|
42176
|
-
|
|
42177
|
-
|
|
42178
|
-
|
|
42179
|
-
|
|
42180
|
-
|
|
42181
|
-
|
|
42182
|
-
|
|
42183
|
-
|
|
42184
|
-
|
|
42185
|
-
|
|
42186
|
-
|
|
42187
|
-
|
|
42188
|
-
|
|
42189
|
-
|
|
42190
|
-
|
|
42191
|
-
|
|
42192
|
-
|
|
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
|
|
42209
|
-
const isTodayDate = dateFns.isToday(
|
|
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(
|
|
42214
|
-
time: dateFns.format(
|
|
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;
|