@copilotz/admin 0.9.24 → 0.9.27
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 +1204 -700
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +32 -2
- package/dist/index.d.ts +32 -2
- package/dist/index.js +1217 -697
- package/dist/index.js.map +1 -1
- package/dist/styles.css +183 -60
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -256,6 +256,22 @@ async function fetchAdminAgents(search, namespace, options) {
|
|
|
256
256
|
limit: "8"
|
|
257
257
|
}, options);
|
|
258
258
|
}
|
|
259
|
+
async function fetchAdminUsage(filters, options) {
|
|
260
|
+
return await fetchAdminJson("/v1/admin/usage", {
|
|
261
|
+
from: filters.from,
|
|
262
|
+
to: filters.to,
|
|
263
|
+
interval: filters.interval,
|
|
264
|
+
metric: filters.metric,
|
|
265
|
+
groupBy: filters.groupBy,
|
|
266
|
+
attribution: filters.attribution,
|
|
267
|
+
threadId: filters.threadId,
|
|
268
|
+
participantId: filters.participantId,
|
|
269
|
+
participantType: filters.participantType,
|
|
270
|
+
namespace: filters.namespace,
|
|
271
|
+
provider: filters.provider,
|
|
272
|
+
model: filters.model
|
|
273
|
+
}, options);
|
|
274
|
+
}
|
|
259
275
|
async function fetchThreadDetail(threadId, options) {
|
|
260
276
|
return await fetchAdminJson(
|
|
261
277
|
`/v1/threads/${encodeURIComponent(threadId)}`,
|
|
@@ -520,6 +536,16 @@ function CardHeader({ className, ...props }) {
|
|
|
520
536
|
}
|
|
521
537
|
);
|
|
522
538
|
}
|
|
539
|
+
function CardTitle({ className, ...props }) {
|
|
540
|
+
return /* @__PURE__ */ jsx(
|
|
541
|
+
"div",
|
|
542
|
+
{
|
|
543
|
+
"data-slot": "card-title",
|
|
544
|
+
className: cn("leading-none font-semibold", className),
|
|
545
|
+
...props
|
|
546
|
+
}
|
|
547
|
+
);
|
|
548
|
+
}
|
|
523
549
|
function CardContent({ className, ...props }) {
|
|
524
550
|
return /* @__PURE__ */ jsx(
|
|
525
551
|
"div",
|
|
@@ -1513,7 +1539,26 @@ var AdminHeader = ({
|
|
|
1513
1539
|
};
|
|
1514
1540
|
|
|
1515
1541
|
// src/components/views/DashboardView.tsx
|
|
1516
|
-
import
|
|
1542
|
+
import React6 from "react";
|
|
1543
|
+
import {
|
|
1544
|
+
Bar,
|
|
1545
|
+
BarChart,
|
|
1546
|
+
CartesianGrid,
|
|
1547
|
+
Legend,
|
|
1548
|
+
Tooltip as Tooltip2,
|
|
1549
|
+
XAxis,
|
|
1550
|
+
YAxis
|
|
1551
|
+
} from "recharts";
|
|
1552
|
+
import {
|
|
1553
|
+
Activity as Activity2,
|
|
1554
|
+
Database as Database2,
|
|
1555
|
+
Filter,
|
|
1556
|
+
RefreshCw as RefreshCw2,
|
|
1557
|
+
Search,
|
|
1558
|
+
Sparkles,
|
|
1559
|
+
Users as Users2,
|
|
1560
|
+
Wallet
|
|
1561
|
+
} from "lucide-react";
|
|
1517
1562
|
|
|
1518
1563
|
// src/components/ui/badge.tsx
|
|
1519
1564
|
import { Slot as Slot3 } from "@radix-ui/react-slot";
|
|
@@ -1552,8 +1597,124 @@ function Badge({
|
|
|
1552
1597
|
);
|
|
1553
1598
|
}
|
|
1554
1599
|
|
|
1555
|
-
// src/components/
|
|
1600
|
+
// src/components/ui/chart.tsx
|
|
1601
|
+
import * as React5 from "react";
|
|
1602
|
+
import * as RechartsPrimitive from "recharts";
|
|
1556
1603
|
import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1604
|
+
var ChartContext = React5.createContext(null);
|
|
1605
|
+
function useChart() {
|
|
1606
|
+
const context = React5.useContext(ChartContext);
|
|
1607
|
+
if (!context) {
|
|
1608
|
+
throw new Error("useChart must be used within a ChartContainer");
|
|
1609
|
+
}
|
|
1610
|
+
return context;
|
|
1611
|
+
}
|
|
1612
|
+
function ChartContainer({
|
|
1613
|
+
id,
|
|
1614
|
+
className,
|
|
1615
|
+
config,
|
|
1616
|
+
children,
|
|
1617
|
+
...props
|
|
1618
|
+
}) {
|
|
1619
|
+
const uniqueId = React5.useId();
|
|
1620
|
+
const chartId = `chart-${id ?? uniqueId.replace(/:/g, "")}`;
|
|
1621
|
+
return /* @__PURE__ */ jsx12(ChartContext.Provider, { value: config, children: /* @__PURE__ */ jsxs7(
|
|
1622
|
+
"div",
|
|
1623
|
+
{
|
|
1624
|
+
"data-chart": chartId,
|
|
1625
|
+
className: cn(
|
|
1626
|
+
"flex aspect-auto justify-center text-xs text-muted-foreground [&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/70 [&_.recharts-cursor]:fill-muted [&_.recharts-legend-wrapper]:text-muted-foreground [&_.recharts-tooltip-cursor]:fill-muted",
|
|
1627
|
+
className
|
|
1628
|
+
),
|
|
1629
|
+
...props,
|
|
1630
|
+
children: [
|
|
1631
|
+
/* @__PURE__ */ jsx12("style", { children: Object.entries(config).map(([key, item]) => {
|
|
1632
|
+
return `[data-chart=${chartId}] { --color-${key}: ${item.color}; }`;
|
|
1633
|
+
}).join("\n") }),
|
|
1634
|
+
/* @__PURE__ */ jsx12(RechartsPrimitive.ResponsiveContainer, { children })
|
|
1635
|
+
]
|
|
1636
|
+
}
|
|
1637
|
+
) });
|
|
1638
|
+
}
|
|
1639
|
+
function ChartTooltipContent({
|
|
1640
|
+
active,
|
|
1641
|
+
payload,
|
|
1642
|
+
label,
|
|
1643
|
+
className,
|
|
1644
|
+
formatter,
|
|
1645
|
+
labelFormatter
|
|
1646
|
+
}) {
|
|
1647
|
+
const config = useChart();
|
|
1648
|
+
if (!active || !payload?.length) return null;
|
|
1649
|
+
const total = payload.reduce((sum, item) => {
|
|
1650
|
+
const value = typeof item.value === "number" ? item.value : Number(item.value ?? 0);
|
|
1651
|
+
return sum + (Number.isFinite(value) ? value : 0);
|
|
1652
|
+
}, 0);
|
|
1653
|
+
return /* @__PURE__ */ jsxs7(
|
|
1654
|
+
"div",
|
|
1655
|
+
{
|
|
1656
|
+
className: cn(
|
|
1657
|
+
"min-w-44 rounded-lg border bg-popover px-3 py-2 text-popover-foreground shadow-md",
|
|
1658
|
+
className
|
|
1659
|
+
),
|
|
1660
|
+
children: [
|
|
1661
|
+
/* @__PURE__ */ jsxs7("div", { className: "mb-2 flex items-center justify-between gap-4 border-b pb-2", children: [
|
|
1662
|
+
/* @__PURE__ */ jsx12("p", { className: "text-xs font-medium text-muted-foreground", children: labelFormatter ? labelFormatter(label) : label }),
|
|
1663
|
+
/* @__PURE__ */ jsx12("p", { className: "text-xs font-semibold text-foreground", children: formatter ? formatter(total) : total })
|
|
1664
|
+
] }),
|
|
1665
|
+
/* @__PURE__ */ jsx12("div", { className: "space-y-1.5", children: payload.filter((item) => Number(item.value ?? 0) > 0).map((item) => {
|
|
1666
|
+
const key = String(item.dataKey ?? item.name ?? "");
|
|
1667
|
+
const itemConfig = config[key];
|
|
1668
|
+
const color = item.color ?? itemConfig?.color ?? "currentColor";
|
|
1669
|
+
return /* @__PURE__ */ jsxs7(
|
|
1670
|
+
"div",
|
|
1671
|
+
{
|
|
1672
|
+
className: "grid grid-cols-[0.6rem_1fr_auto] items-center gap-2",
|
|
1673
|
+
children: [
|
|
1674
|
+
/* @__PURE__ */ jsx12(
|
|
1675
|
+
"span",
|
|
1676
|
+
{
|
|
1677
|
+
className: "size-2 rounded-[2px]",
|
|
1678
|
+
style: { backgroundColor: color }
|
|
1679
|
+
}
|
|
1680
|
+
),
|
|
1681
|
+
/* @__PURE__ */ jsx12("span", { className: "max-w-48 truncate text-muted-foreground", children: itemConfig?.label ?? item.name ?? key }),
|
|
1682
|
+
/* @__PURE__ */ jsx12("span", { className: "font-medium text-foreground", children: formatter ? formatter(item.value ?? 0) : item.value })
|
|
1683
|
+
]
|
|
1684
|
+
},
|
|
1685
|
+
key
|
|
1686
|
+
);
|
|
1687
|
+
}) })
|
|
1688
|
+
]
|
|
1689
|
+
}
|
|
1690
|
+
);
|
|
1691
|
+
}
|
|
1692
|
+
function ChartLegendContent({
|
|
1693
|
+
payload,
|
|
1694
|
+
className
|
|
1695
|
+
}) {
|
|
1696
|
+
const config = useChart();
|
|
1697
|
+
if (!payload?.length) return null;
|
|
1698
|
+
return /* @__PURE__ */ jsx12("div", { className: cn("flex flex-wrap items-center gap-x-4 gap-y-2", className), children: payload.map((item) => {
|
|
1699
|
+
const key = String(item.dataKey ?? item.value ?? "");
|
|
1700
|
+
const itemConfig = config[key];
|
|
1701
|
+
return /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2", children: [
|
|
1702
|
+
/* @__PURE__ */ jsx12(
|
|
1703
|
+
"span",
|
|
1704
|
+
{
|
|
1705
|
+
className: "size-2 rounded-[2px]",
|
|
1706
|
+
style: {
|
|
1707
|
+
backgroundColor: item.color ?? itemConfig?.color ?? "currentColor"
|
|
1708
|
+
}
|
|
1709
|
+
}
|
|
1710
|
+
),
|
|
1711
|
+
/* @__PURE__ */ jsx12("span", { className: "max-w-52 truncate text-xs text-muted-foreground", children: itemConfig?.label ?? item.value ?? key })
|
|
1712
|
+
] }, key);
|
|
1713
|
+
}) });
|
|
1714
|
+
}
|
|
1715
|
+
|
|
1716
|
+
// src/components/views/DashboardView.tsx
|
|
1717
|
+
import { Fragment as Fragment3, jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1557
1718
|
var DashboardView = ({
|
|
1558
1719
|
config,
|
|
1559
1720
|
overview,
|
|
@@ -1568,423 +1729,650 @@ var DashboardView = ({
|
|
|
1568
1729
|
onThreadSearchChange,
|
|
1569
1730
|
onParticipantSearchChange,
|
|
1570
1731
|
onAgentSearchChange,
|
|
1571
|
-
onThreadClick
|
|
1732
|
+
onThreadClick,
|
|
1733
|
+
namespace
|
|
1572
1734
|
}) => {
|
|
1573
|
-
|
|
1574
|
-
|
|
1735
|
+
void overview;
|
|
1736
|
+
void activity;
|
|
1737
|
+
void threads;
|
|
1738
|
+
void participants;
|
|
1739
|
+
void agents;
|
|
1740
|
+
void interval;
|
|
1741
|
+
void threadSearch;
|
|
1742
|
+
void participantSearch;
|
|
1743
|
+
void agentSearch;
|
|
1744
|
+
void onThreadSearchChange;
|
|
1745
|
+
void onParticipantSearchChange;
|
|
1746
|
+
void onAgentSearchChange;
|
|
1747
|
+
void onThreadClick;
|
|
1748
|
+
if (!config.features.showOverview) {
|
|
1749
|
+
return /* @__PURE__ */ jsx13(
|
|
1750
|
+
EmptyDashboard,
|
|
1751
|
+
{
|
|
1752
|
+
description: config.labels.emptyDescription,
|
|
1753
|
+
title: config.labels.emptyTitle
|
|
1754
|
+
}
|
|
1755
|
+
);
|
|
1756
|
+
}
|
|
1757
|
+
return /* @__PURE__ */ jsx13(
|
|
1758
|
+
UsageDashboard,
|
|
1759
|
+
{
|
|
1760
|
+
config,
|
|
1761
|
+
namespace
|
|
1762
|
+
}
|
|
1575
1763
|
);
|
|
1576
|
-
|
|
1577
|
-
|
|
1764
|
+
};
|
|
1765
|
+
function UsageDashboard({
|
|
1766
|
+
config,
|
|
1767
|
+
namespace
|
|
1768
|
+
}) {
|
|
1769
|
+
const [period, setPeriod] = React6.useState("7d");
|
|
1770
|
+
const [bucket, setBucket] = React6.useState("day");
|
|
1771
|
+
const [metricKind, setMetricKind] = React6.useState(
|
|
1772
|
+
"cost"
|
|
1578
1773
|
);
|
|
1579
|
-
const
|
|
1580
|
-
const
|
|
1581
|
-
|
|
1582
|
-
usageMetricKind,
|
|
1583
|
-
usageDimension
|
|
1774
|
+
const [dimension, setDimension] = React6.useState("total");
|
|
1775
|
+
const [groupBy, setGroupBy] = React6.useState(
|
|
1776
|
+
"participant"
|
|
1584
1777
|
);
|
|
1585
|
-
const
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
const
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
{
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1778
|
+
const [attribution, setAttribution] = React6.useState(
|
|
1779
|
+
"initiatedBy"
|
|
1780
|
+
);
|
|
1781
|
+
const [participantType, setParticipantType] = React6.useState("all");
|
|
1782
|
+
const [threadId, setThreadId] = React6.useState("");
|
|
1783
|
+
const [participantId, setParticipantId] = React6.useState("");
|
|
1784
|
+
const [provider, setProvider] = React6.useState("");
|
|
1785
|
+
const [model, setModel] = React6.useState("");
|
|
1786
|
+
const [customFrom, setCustomFrom] = React6.useState("");
|
|
1787
|
+
const [customTo, setCustomTo] = React6.useState("");
|
|
1788
|
+
const [usage, setUsage] = React6.useState(null);
|
|
1789
|
+
const [isLoading, setIsLoading] = React6.useState(false);
|
|
1790
|
+
const [error, setError] = React6.useState(null);
|
|
1791
|
+
const range = React6.useMemo(() => getUsageRange(period, customFrom, customTo), [
|
|
1792
|
+
customFrom,
|
|
1793
|
+
customTo,
|
|
1794
|
+
period
|
|
1795
|
+
]);
|
|
1796
|
+
const loadUsage = React6.useCallback(async () => {
|
|
1797
|
+
setIsLoading(true);
|
|
1798
|
+
setError(null);
|
|
1799
|
+
try {
|
|
1800
|
+
const next = await fetchAdminUsage({
|
|
1801
|
+
from: range.from,
|
|
1802
|
+
to: range.to,
|
|
1803
|
+
interval: bucket,
|
|
1804
|
+
metric: metricKind,
|
|
1805
|
+
groupBy,
|
|
1806
|
+
attribution,
|
|
1807
|
+
namespace: namespace || void 0,
|
|
1808
|
+
participantType,
|
|
1809
|
+
threadId: emptyToUndefined(threadId),
|
|
1810
|
+
participantId: emptyToUndefined(participantId),
|
|
1811
|
+
provider: emptyToUndefined(provider),
|
|
1812
|
+
model: emptyToUndefined(model)
|
|
1813
|
+
}, {
|
|
1814
|
+
baseUrl: config.baseUrl,
|
|
1815
|
+
getRequestHeaders: config.getRequestHeaders
|
|
1816
|
+
});
|
|
1817
|
+
setUsage(next);
|
|
1818
|
+
} catch (err) {
|
|
1819
|
+
setError(err instanceof Error ? err.message : "Failed to load usage");
|
|
1820
|
+
setUsage(null);
|
|
1821
|
+
} finally {
|
|
1822
|
+
setIsLoading(false);
|
|
1616
1823
|
}
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1824
|
+
}, [
|
|
1825
|
+
attribution,
|
|
1826
|
+
bucket,
|
|
1827
|
+
config.baseUrl,
|
|
1828
|
+
config.getRequestHeaders,
|
|
1829
|
+
groupBy,
|
|
1830
|
+
metricKind,
|
|
1831
|
+
model,
|
|
1832
|
+
namespace,
|
|
1833
|
+
participantId,
|
|
1834
|
+
participantType,
|
|
1835
|
+
provider,
|
|
1836
|
+
range.from,
|
|
1837
|
+
range.to,
|
|
1838
|
+
threadId
|
|
1839
|
+
]);
|
|
1840
|
+
React6.useEffect(() => {
|
|
1841
|
+
void loadUsage();
|
|
1842
|
+
}, [loadUsage]);
|
|
1843
|
+
const points = usage?.points ?? [];
|
|
1844
|
+
const totals = usage?.totals ?? EMPTY_TOTALS;
|
|
1845
|
+
const chartState = React6.useMemo(() => buildChartState(points, metricKind, dimension, bucket), [
|
|
1846
|
+
bucket,
|
|
1847
|
+
dimension,
|
|
1848
|
+
metricKind,
|
|
1849
|
+
points
|
|
1850
|
+
]);
|
|
1851
|
+
const groupedRows = React6.useMemo(() => aggregateUsageRows(points, metricKind, dimension), [
|
|
1852
|
+
dimension,
|
|
1853
|
+
metricKind,
|
|
1854
|
+
points
|
|
1855
|
+
]);
|
|
1856
|
+
const activeFilterCount = [
|
|
1857
|
+
participantType !== "all" ? participantType : "",
|
|
1858
|
+
threadId,
|
|
1859
|
+
participantId,
|
|
1860
|
+
provider,
|
|
1861
|
+
model,
|
|
1862
|
+
period === "custom" ? customFrom : "",
|
|
1863
|
+
period === "custom" ? customTo : ""
|
|
1864
|
+
].filter((value) => value.trim().length > 0).length;
|
|
1865
|
+
return /* @__PURE__ */ jsxs8("div", { className: "space-y-4", children: [
|
|
1866
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex flex-col gap-3 lg:flex-row lg:items-start lg:justify-between", children: [
|
|
1867
|
+
/* @__PURE__ */ jsxs8("div", { children: [
|
|
1868
|
+
/* @__PURE__ */ jsx13("h2", { className: "text-2xl font-semibold tracking-tight", children: config.labels.llmUsageTitle }),
|
|
1869
|
+
/* @__PURE__ */ jsxs8("div", { className: "mt-2 flex flex-wrap items-center gap-2", children: [
|
|
1870
|
+
/* @__PURE__ */ jsx13(Badge, { variant: "outline", children: formatUsageRangeLabel(period, range) }),
|
|
1871
|
+
/* @__PURE__ */ jsx13(Badge, { variant: "secondary", children: getGroupByLabel(groupBy) }),
|
|
1872
|
+
groupBy === "participant" && /* @__PURE__ */ jsx13(Badge, { variant: "outline", children: attribution === "initiatedBy" ? "Initiated by sender" : "Generated by caller" })
|
|
1873
|
+
] })
|
|
1874
|
+
] }),
|
|
1875
|
+
/* @__PURE__ */ jsxs8(
|
|
1876
|
+
Button,
|
|
1628
1877
|
{
|
|
1629
|
-
className: "
|
|
1878
|
+
className: "w-full sm:w-auto",
|
|
1879
|
+
disabled: isLoading,
|
|
1880
|
+
onClick: () => void loadUsage(),
|
|
1881
|
+
size: "sm",
|
|
1882
|
+
variant: "outline",
|
|
1630
1883
|
children: [
|
|
1631
|
-
/* @__PURE__ */
|
|
1632
|
-
|
|
1633
|
-
card.value,
|
|
1634
|
-
card.metricKind ?? "tokens"
|
|
1635
|
-
) }),
|
|
1636
|
-
/* @__PURE__ */ jsx12("p", { className: "mt-2 text-xs text-muted-foreground", children: card.detail })
|
|
1884
|
+
/* @__PURE__ */ jsx13(RefreshCw2, { className: cn("size-4", isLoading && "animate-spin") }),
|
|
1885
|
+
config.labels.refresh
|
|
1637
1886
|
]
|
|
1638
|
-
}
|
|
1639
|
-
|
|
1640
|
-
)) })
|
|
1887
|
+
}
|
|
1888
|
+
)
|
|
1641
1889
|
] }),
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1890
|
+
/* @__PURE__ */ jsx13(
|
|
1891
|
+
UsageSummary,
|
|
1892
|
+
{
|
|
1893
|
+
dimension,
|
|
1894
|
+
labels: config.labels,
|
|
1895
|
+
metricKind,
|
|
1896
|
+
totals
|
|
1897
|
+
}
|
|
1898
|
+
),
|
|
1899
|
+
/* @__PURE__ */ jsx13(Card, { className: "gap-4 overflow-hidden py-4", children: /* @__PURE__ */ jsxs8(CardContent, { className: "space-y-4 px-4 lg:px-5", children: [
|
|
1900
|
+
/* @__PURE__ */ jsxs8("div", { className: "grid gap-2 md:grid-cols-2 xl:grid-cols-6", children: [
|
|
1901
|
+
/* @__PURE__ */ jsx13(
|
|
1902
|
+
UsageSelect,
|
|
1903
|
+
{
|
|
1904
|
+
label: "Period",
|
|
1905
|
+
onValueChange: (value) => setPeriod(value),
|
|
1906
|
+
options: [
|
|
1907
|
+
["24h", config.labels.range24h],
|
|
1908
|
+
["7d", config.labels.range7d],
|
|
1909
|
+
["30d", config.labels.range30d],
|
|
1910
|
+
["custom", "Custom"]
|
|
1911
|
+
],
|
|
1912
|
+
value: period
|
|
1913
|
+
}
|
|
1914
|
+
),
|
|
1915
|
+
/* @__PURE__ */ jsx13(
|
|
1916
|
+
UsageSelect,
|
|
1917
|
+
{
|
|
1918
|
+
label: "Bucket",
|
|
1919
|
+
onValueChange: (value) => setBucket(value),
|
|
1920
|
+
options: [
|
|
1921
|
+
["minute", "Minute"],
|
|
1922
|
+
["hour", "Hour"],
|
|
1923
|
+
["day", "Day"],
|
|
1924
|
+
["week", "Week"],
|
|
1925
|
+
["month", "Month"]
|
|
1926
|
+
],
|
|
1927
|
+
value: bucket
|
|
1928
|
+
}
|
|
1929
|
+
),
|
|
1930
|
+
/* @__PURE__ */ jsx13(
|
|
1931
|
+
UsageSelect,
|
|
1932
|
+
{
|
|
1933
|
+
label: config.labels.usageMetricLabel,
|
|
1934
|
+
onValueChange: (value) => setMetricKind(value),
|
|
1935
|
+
options: [
|
|
1936
|
+
["cost", config.labels.usageMetricCost],
|
|
1937
|
+
["tokens", config.labels.usageMetricTokens],
|
|
1938
|
+
["calls", "Calls"]
|
|
1939
|
+
],
|
|
1940
|
+
value: metricKind
|
|
1941
|
+
}
|
|
1942
|
+
),
|
|
1943
|
+
/* @__PURE__ */ jsx13(
|
|
1944
|
+
UsageSelect,
|
|
1945
|
+
{
|
|
1946
|
+
label: "Group",
|
|
1947
|
+
onValueChange: (value) => setGroupBy(value),
|
|
1948
|
+
options: [
|
|
1949
|
+
["participant", "Participant"],
|
|
1950
|
+
["thread", "Thread"],
|
|
1951
|
+
["namespace", "Namespace"],
|
|
1952
|
+
["provider", "Provider"],
|
|
1953
|
+
["model", "Model"]
|
|
1954
|
+
],
|
|
1955
|
+
value: groupBy
|
|
1956
|
+
}
|
|
1957
|
+
),
|
|
1958
|
+
/* @__PURE__ */ jsx13(
|
|
1959
|
+
UsageSelect,
|
|
1960
|
+
{
|
|
1961
|
+
label: "Attribution",
|
|
1962
|
+
onValueChange: (value) => setAttribution(value),
|
|
1963
|
+
options: [
|
|
1964
|
+
["initiatedBy", "Initiated by"],
|
|
1965
|
+
["generatedBy", "Generated by"]
|
|
1966
|
+
],
|
|
1967
|
+
value: attribution
|
|
1968
|
+
}
|
|
1969
|
+
),
|
|
1970
|
+
/* @__PURE__ */ jsx13(
|
|
1971
|
+
UsageSelect,
|
|
1972
|
+
{
|
|
1973
|
+
label: config.labels.usageDimensionLabel,
|
|
1974
|
+
onValueChange: (value) => setDimension(value),
|
|
1975
|
+
options: USAGE_DIMENSIONS.map((nextDimension) => [
|
|
1976
|
+
nextDimension,
|
|
1977
|
+
getUsageDimensionLabel(config.labels, nextDimension)
|
|
1978
|
+
]),
|
|
1979
|
+
value: dimension
|
|
1980
|
+
}
|
|
1981
|
+
)
|
|
1982
|
+
] }),
|
|
1983
|
+
/* @__PURE__ */ jsxs8("div", { className: "rounded-lg border bg-muted/30 p-3", children: [
|
|
1984
|
+
/* @__PURE__ */ jsxs8("div", { className: "mb-3 flex items-center justify-between gap-3", children: [
|
|
1985
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2 text-sm font-medium", children: [
|
|
1986
|
+
/* @__PURE__ */ jsx13(Filter, { className: "size-4" }),
|
|
1987
|
+
/* @__PURE__ */ jsx13("span", { children: "Filters" }),
|
|
1988
|
+
activeFilterCount > 0 && /* @__PURE__ */ jsx13(Badge, { variant: "secondary", children: activeFilterCount })
|
|
1989
|
+
] }),
|
|
1990
|
+
activeFilterCount > 0 && /* @__PURE__ */ jsx13(
|
|
1991
|
+
Button,
|
|
1992
|
+
{
|
|
1993
|
+
onClick: () => {
|
|
1994
|
+
setParticipantType("all");
|
|
1995
|
+
setThreadId("");
|
|
1996
|
+
setParticipantId("");
|
|
1997
|
+
setProvider("");
|
|
1998
|
+
setModel("");
|
|
1999
|
+
setCustomFrom("");
|
|
2000
|
+
setCustomTo("");
|
|
2001
|
+
},
|
|
2002
|
+
size: "sm",
|
|
2003
|
+
variant: "ghost",
|
|
2004
|
+
children: "Clear"
|
|
2005
|
+
}
|
|
2006
|
+
)
|
|
2007
|
+
] }),
|
|
2008
|
+
/* @__PURE__ */ jsxs8("div", { className: "grid gap-2 md:grid-cols-2 xl:grid-cols-6", children: [
|
|
2009
|
+
period === "custom" && /* @__PURE__ */ jsxs8(Fragment3, { children: [
|
|
2010
|
+
/* @__PURE__ */ jsx13(
|
|
2011
|
+
FilterInput,
|
|
1650
2012
|
{
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
/* @__PURE__ */ jsxs7(SelectContent, { children: [
|
|
1656
|
-
/* @__PURE__ */ jsx12(SelectItem, { value: "tokens", children: config.labels.usageMetricTokens }),
|
|
1657
|
-
/* @__PURE__ */ jsx12(SelectItem, { value: "cost", children: config.labels.usageMetricCost })
|
|
1658
|
-
] })
|
|
1659
|
-
]
|
|
2013
|
+
label: "From",
|
|
2014
|
+
onChange: setCustomFrom,
|
|
2015
|
+
type: "datetime-local",
|
|
2016
|
+
value: customFrom
|
|
1660
2017
|
}
|
|
1661
|
-
)
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
/* @__PURE__ */ jsx12("p", { className: "text-xs font-medium uppercase tracking-[0.18em] text-muted-foreground", children: config.labels.usageDimensionLabel }),
|
|
1665
|
-
/* @__PURE__ */ jsxs7(
|
|
1666
|
-
Select,
|
|
2018
|
+
),
|
|
2019
|
+
/* @__PURE__ */ jsx13(
|
|
2020
|
+
FilterInput,
|
|
1667
2021
|
{
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
/* @__PURE__ */ jsx12(SelectContent, { children: USAGE_DIMENSIONS.map((dimension) => /* @__PURE__ */ jsx12(SelectItem, { value: dimension, children: getUsageDimensionLabel(config.labels, dimension) }, dimension)) })
|
|
1673
|
-
]
|
|
2022
|
+
label: "To",
|
|
2023
|
+
onChange: setCustomTo,
|
|
2024
|
+
type: "datetime-local",
|
|
2025
|
+
value: customTo
|
|
1674
2026
|
}
|
|
1675
2027
|
)
|
|
1676
|
-
] })
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
/* @__PURE__ */ jsx12("div", { className: "grid gap-4 sm:grid-cols-2 xl:grid-cols-3", children: usageBreakdownCards.map((card) => {
|
|
1680
|
-
const isSelected = card.dimension === usageDimension;
|
|
1681
|
-
return /* @__PURE__ */ jsxs7(
|
|
1682
|
-
"div",
|
|
1683
|
-
{
|
|
1684
|
-
className: cn(
|
|
1685
|
-
"rounded-xl border bg-card p-5 shadow-sm transition-colors",
|
|
1686
|
-
isSelected && "border-primary/60 ring-1 ring-primary/15"
|
|
1687
|
-
),
|
|
1688
|
-
children: [
|
|
1689
|
-
/* @__PURE__ */ jsxs7("div", { className: "flex items-start justify-between gap-3", children: [
|
|
1690
|
-
/* @__PURE__ */ jsxs7("div", { children: [
|
|
1691
|
-
/* @__PURE__ */ jsx12("p", { className: "text-sm font-medium text-muted-foreground", children: card.label }),
|
|
1692
|
-
/* @__PURE__ */ jsx12("p", { className: "mt-3 text-2xl font-semibold tracking-tight", children: formatMetricValue(card.value, usageMetricKind) })
|
|
1693
|
-
] }),
|
|
1694
|
-
isSelected && /* @__PURE__ */ jsx12(Badge, { variant: "outline", children: config.labels.usageDimensionLabel })
|
|
1695
|
-
] }),
|
|
1696
|
-
/* @__PURE__ */ jsxs7("p", { className: "mt-2 text-xs text-muted-foreground", children: [
|
|
1697
|
-
overview?.llmTotals.totalCalls ?? 0,
|
|
1698
|
-
" ",
|
|
1699
|
-
config.labels.usageCallsDetail
|
|
1700
|
-
] })
|
|
1701
|
-
]
|
|
1702
|
-
},
|
|
1703
|
-
card.dimension
|
|
1704
|
-
);
|
|
1705
|
-
}) })
|
|
1706
|
-
] }),
|
|
1707
|
-
config.features.showActivity && /* @__PURE__ */ jsxs7("section", { className: "space-y-4", children: [
|
|
1708
|
-
/* @__PURE__ */ jsx12(SectionHeading, { title: config.labels.activityTitle }),
|
|
1709
|
-
/* @__PURE__ */ jsx12(
|
|
1710
|
-
ActivityChart,
|
|
1711
|
-
{
|
|
1712
|
-
interval,
|
|
1713
|
-
labels: config.labels,
|
|
1714
|
-
maxBars: config.ui.maxActivityBars,
|
|
1715
|
-
points: activity,
|
|
1716
|
-
usageDimension,
|
|
1717
|
-
usageMetricKind
|
|
1718
|
-
}
|
|
1719
|
-
)
|
|
1720
|
-
] }),
|
|
1721
|
-
/* @__PURE__ */ jsxs7("div", { className: "grid gap-6 lg:grid-cols-3", children: [
|
|
1722
|
-
config.features.showThreads && /* @__PURE__ */ jsx12(
|
|
1723
|
-
DataTable,
|
|
1724
|
-
{
|
|
1725
|
-
rows: threads,
|
|
1726
|
-
searchPlaceholder: config.labels.threadSearchPlaceholder,
|
|
1727
|
-
searchValue: threadSearch,
|
|
1728
|
-
setSearchValue: onThreadSearchChange,
|
|
1729
|
-
title: config.labels.threadsTitle,
|
|
1730
|
-
children: /* @__PURE__ */ jsx12(
|
|
1731
|
-
ThreadsTable,
|
|
2028
|
+
] }),
|
|
2029
|
+
/* @__PURE__ */ jsx13(
|
|
2030
|
+
UsageSelect,
|
|
1732
2031
|
{
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
2032
|
+
label: "Type",
|
|
2033
|
+
onValueChange: (value) => setParticipantType(
|
|
2034
|
+
value
|
|
2035
|
+
),
|
|
2036
|
+
options: [
|
|
2037
|
+
["all", "All"],
|
|
2038
|
+
["human", "Human"],
|
|
2039
|
+
["agent", "Agent"],
|
|
2040
|
+
["job", "Job"]
|
|
2041
|
+
],
|
|
2042
|
+
value: participantType
|
|
1736
2043
|
}
|
|
1737
|
-
)
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
config.features.showParticipants && /* @__PURE__ */ jsx12(
|
|
1741
|
-
DataTable,
|
|
1742
|
-
{
|
|
1743
|
-
rows: participants,
|
|
1744
|
-
searchPlaceholder: config.labels.participantSearchPlaceholder,
|
|
1745
|
-
searchValue: participantSearch,
|
|
1746
|
-
setSearchValue: onParticipantSearchChange,
|
|
1747
|
-
title: config.labels.participantsTitle,
|
|
1748
|
-
children: /* @__PURE__ */ jsx12(ParticipantsTable, { rows: participants, labels: config.labels })
|
|
1749
|
-
}
|
|
1750
|
-
),
|
|
1751
|
-
config.features.showAgents && /* @__PURE__ */ jsx12(
|
|
1752
|
-
DataTable,
|
|
1753
|
-
{
|
|
1754
|
-
rows: agents,
|
|
1755
|
-
searchPlaceholder: config.labels.agentSearchPlaceholder,
|
|
1756
|
-
searchValue: agentSearch,
|
|
1757
|
-
setSearchValue: onAgentSearchChange,
|
|
1758
|
-
title: config.labels.agentsTitle,
|
|
1759
|
-
children: /* @__PURE__ */ jsx12(
|
|
1760
|
-
AgentsTable,
|
|
2044
|
+
),
|
|
2045
|
+
/* @__PURE__ */ jsx13(
|
|
2046
|
+
FilterInput,
|
|
1761
2047
|
{
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
2048
|
+
icon: /* @__PURE__ */ jsx13(Search, { className: "size-3.5" }),
|
|
2049
|
+
label: "Thread",
|
|
2050
|
+
onChange: setThreadId,
|
|
2051
|
+
value: threadId
|
|
1766
2052
|
}
|
|
1767
|
-
)
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
] })
|
|
1771
|
-
] });
|
|
1772
|
-
};
|
|
1773
|
-
function SectionHeading({ title }) {
|
|
1774
|
-
return /* @__PURE__ */ jsx12("h3", { className: "text-lg font-semibold tracking-tight", children: title });
|
|
1775
|
-
}
|
|
1776
|
-
function ActivityChart(props) {
|
|
1777
|
-
const trimmedPoints = props.points.slice(-props.maxBars);
|
|
1778
|
-
const maxUsageValue = Math.max(
|
|
1779
|
-
...trimmedPoints.map(
|
|
1780
|
-
(point) => getActivityUsageValue(
|
|
1781
|
-
point,
|
|
1782
|
-
props.usageMetricKind,
|
|
1783
|
-
props.usageDimension
|
|
1784
|
-
)
|
|
1785
|
-
),
|
|
1786
|
-
1
|
|
1787
|
-
);
|
|
1788
|
-
return /* @__PURE__ */ jsx12("div", { className: "rounded-xl border bg-card p-5 shadow-sm", children: trimmedPoints.length === 0 ? /* @__PURE__ */ jsx12("p", { className: "text-sm text-muted-foreground", children: props.labels.noResults }) : /* @__PURE__ */ jsx12("div", { className: "flex min-h-48 items-end gap-2", children: trimmedPoints.map((point) => {
|
|
1789
|
-
const usageValue = getActivityUsageValue(
|
|
1790
|
-
point,
|
|
1791
|
-
props.usageMetricKind,
|
|
1792
|
-
props.usageDimension
|
|
1793
|
-
);
|
|
1794
|
-
return /* @__PURE__ */ jsxs7(
|
|
1795
|
-
"div",
|
|
1796
|
-
{
|
|
1797
|
-
className: "flex min-w-0 flex-1 flex-col items-center gap-2",
|
|
1798
|
-
children: [
|
|
1799
|
-
/* @__PURE__ */ jsx12("div", { className: "flex h-36 w-full items-end rounded-lg bg-muted px-1 pb-1", children: /* @__PURE__ */ jsx12(
|
|
1800
|
-
"div",
|
|
2053
|
+
),
|
|
2054
|
+
/* @__PURE__ */ jsx13(
|
|
2055
|
+
FilterInput,
|
|
1801
2056
|
{
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
2057
|
+
icon: /* @__PURE__ */ jsx13(Users2, { className: "size-3.5" }),
|
|
2058
|
+
label: "Participant",
|
|
2059
|
+
onChange: setParticipantId,
|
|
2060
|
+
value: participantId
|
|
1806
2061
|
}
|
|
1807
|
-
)
|
|
1808
|
-
/* @__PURE__ */
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
2062
|
+
),
|
|
2063
|
+
/* @__PURE__ */ jsx13(
|
|
2064
|
+
FilterInput,
|
|
2065
|
+
{
|
|
2066
|
+
icon: /* @__PURE__ */ jsx13(Database2, { className: "size-3.5" }),
|
|
2067
|
+
label: "Provider",
|
|
2068
|
+
onChange: setProvider,
|
|
2069
|
+
value: provider
|
|
2070
|
+
}
|
|
2071
|
+
),
|
|
2072
|
+
/* @__PURE__ */ jsx13(
|
|
2073
|
+
FilterInput,
|
|
2074
|
+
{
|
|
2075
|
+
icon: /* @__PURE__ */ jsx13(Sparkles, { className: "size-3.5" }),
|
|
2076
|
+
label: "Model",
|
|
2077
|
+
onChange: setModel,
|
|
2078
|
+
value: model
|
|
2079
|
+
}
|
|
2080
|
+
)
|
|
2081
|
+
] })
|
|
2082
|
+
] })
|
|
2083
|
+
] }) }),
|
|
2084
|
+
/* @__PURE__ */ jsxs8(Card, { className: "gap-3 overflow-hidden py-4", children: [
|
|
2085
|
+
/* @__PURE__ */ jsx13(CardHeader, { className: "px-4 lg:px-5", children: /* @__PURE__ */ jsxs8("div", { className: "flex flex-col gap-2 md:flex-row md:items-start md:justify-between", children: [
|
|
2086
|
+
/* @__PURE__ */ jsxs8("div", { children: [
|
|
2087
|
+
/* @__PURE__ */ jsx13(CardTitle, { className: "text-base", children: getUsageSummaryLabel(config.labels, metricKind, dimension) }),
|
|
2088
|
+
/* @__PURE__ */ jsxs8("p", { className: "mt-1 text-sm text-muted-foreground", children: [
|
|
2089
|
+
formatMetricValue(
|
|
2090
|
+
getUsageTotalValue(totals, metricKind, dimension),
|
|
2091
|
+
metricKind
|
|
2092
|
+
),
|
|
2093
|
+
" ",
|
|
2094
|
+
"across ",
|
|
2095
|
+
formatNumber(totals.totalCalls),
|
|
2096
|
+
" calls"
|
|
1816
2097
|
] })
|
|
1817
|
-
]
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
}
|
|
1823
|
-
function DataTable(props) {
|
|
1824
|
-
return /* @__PURE__ */ jsxs7("div", { className: "rounded-xl border bg-card p-5 shadow-sm", children: [
|
|
1825
|
-
/* @__PURE__ */ jsxs7("div", { className: "mb-4 flex items-center justify-between gap-3", children: [
|
|
1826
|
-
/* @__PURE__ */ jsx12(SectionHeading, { title: props.title }),
|
|
1827
|
-
/* @__PURE__ */ jsx12(
|
|
1828
|
-
Input,
|
|
2098
|
+
] }),
|
|
2099
|
+
isLoading && /* @__PURE__ */ jsx13(Badge, { variant: "outline", children: config.labels.loading })
|
|
2100
|
+
] }) }),
|
|
2101
|
+
/* @__PURE__ */ jsx13(CardContent, { className: "px-2 lg:px-4", children: error ? /* @__PURE__ */ jsx13("div", { className: "rounded-lg border border-destructive/30 bg-destructive/10 p-4 text-sm text-destructive", children: error }) : chartState.data.length === 0 ? /* @__PURE__ */ jsx13(
|
|
2102
|
+
EmptyDashboard,
|
|
1829
2103
|
{
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
placeholder: props.searchPlaceholder,
|
|
1833
|
-
value: props.searchValue
|
|
2104
|
+
description: config.labels.noResults,
|
|
2105
|
+
title: "No usage"
|
|
1834
2106
|
}
|
|
1835
|
-
)
|
|
2107
|
+
) : /* @__PURE__ */ jsx13(
|
|
2108
|
+
UsageChart,
|
|
2109
|
+
{
|
|
2110
|
+
chartState,
|
|
2111
|
+
metricKind
|
|
2112
|
+
}
|
|
2113
|
+
) })
|
|
1836
2114
|
] }),
|
|
1837
|
-
|
|
2115
|
+
/* @__PURE__ */ jsx13(
|
|
2116
|
+
UsageTable,
|
|
2117
|
+
{
|
|
2118
|
+
dimension,
|
|
2119
|
+
groupBy,
|
|
2120
|
+
labels: config.labels,
|
|
2121
|
+
metricKind,
|
|
2122
|
+
onRowFilter: (row) => {
|
|
2123
|
+
if (groupBy === "thread") setThreadId(row.groupKey);
|
|
2124
|
+
if (groupBy === "participant") setParticipantId(row.groupKey);
|
|
2125
|
+
if (groupBy === "provider") setProvider(row.groupKey);
|
|
2126
|
+
if (groupBy === "model") setModel(row.groupKey);
|
|
2127
|
+
},
|
|
2128
|
+
rows: groupedRows,
|
|
2129
|
+
totals
|
|
2130
|
+
}
|
|
2131
|
+
)
|
|
1838
2132
|
] });
|
|
1839
2133
|
}
|
|
1840
|
-
function
|
|
1841
|
-
|
|
2134
|
+
function UsageSummary({
|
|
2135
|
+
dimension,
|
|
1842
2136
|
labels,
|
|
1843
|
-
|
|
2137
|
+
metricKind,
|
|
2138
|
+
totals
|
|
1844
2139
|
}) {
|
|
1845
|
-
|
|
1846
|
-
"div",
|
|
2140
|
+
const summary = [
|
|
1847
2141
|
{
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
onClick: () => onThreadClick?.(thread.threadId),
|
|
1853
|
-
children: [
|
|
1854
|
-
/* @__PURE__ */ jsxs7("div", { className: "flex items-start justify-between gap-3", children: [
|
|
1855
|
-
/* @__PURE__ */ jsxs7("div", { className: "min-w-0", children: [
|
|
1856
|
-
/* @__PURE__ */ jsx12("p", { className: "font-medium", children: thread.name }),
|
|
1857
|
-
/* @__PURE__ */ jsx12("p", { className: "mt-1 truncate text-xs text-muted-foreground", children: thread.summary ?? thread.lastMessagePreview ?? "No summary yet" })
|
|
1858
|
-
] }),
|
|
1859
|
-
/* @__PURE__ */ jsx12(
|
|
1860
|
-
Badge,
|
|
1861
|
-
{
|
|
1862
|
-
variant: thread.status === "archived" ? "secondary" : "default",
|
|
1863
|
-
children: thread.status === "archived" ? labels.statusArchived : labels.statusActive
|
|
1864
|
-
}
|
|
1865
|
-
)
|
|
1866
|
-
] }),
|
|
1867
|
-
/* @__PURE__ */ jsxs7("div", { className: "mt-3 flex flex-wrap gap-3 text-xs text-muted-foreground", children: [
|
|
1868
|
-
/* @__PURE__ */ jsxs7("span", { children: [
|
|
1869
|
-
formatNumber(thread.messageCount),
|
|
1870
|
-
" messages"
|
|
1871
|
-
] }),
|
|
1872
|
-
/* @__PURE__ */ jsxs7("span", { children: [
|
|
1873
|
-
thread.participantIds.length,
|
|
1874
|
-
" participants"
|
|
1875
|
-
] }),
|
|
1876
|
-
/* @__PURE__ */ jsx12("span", { children: formatDate(thread.lastActivityAt) })
|
|
1877
|
-
] })
|
|
1878
|
-
]
|
|
2142
|
+
label: labels.usageMetricCost,
|
|
2143
|
+
value: formatMetricValue(totals.totalCostUsd, "cost"),
|
|
2144
|
+
detail: `${formatNumber(totals.totalCalls)} ${labels.usageCallsDetail}`,
|
|
2145
|
+
icon: Wallet
|
|
1879
2146
|
},
|
|
1880
|
-
|
|
1881
|
-
|
|
2147
|
+
{
|
|
2148
|
+
label: labels.usageMetricTokens,
|
|
2149
|
+
value: formatMetricValue(totals.totalTokens, "tokens"),
|
|
2150
|
+
detail: `${formatMetricValue(totals.inputTokens, "tokens")} input`,
|
|
2151
|
+
icon: Activity2
|
|
2152
|
+
},
|
|
2153
|
+
{
|
|
2154
|
+
label: labels.usageCacheRead,
|
|
2155
|
+
value: formatMetricValue(totals.cacheReadInputCostUsd, "cost"),
|
|
2156
|
+
detail: `${formatMetricValue(totals.cacheReadInputTokens, "tokens")} tokens`,
|
|
2157
|
+
icon: Database2
|
|
2158
|
+
},
|
|
2159
|
+
{
|
|
2160
|
+
label: getUsageSummaryLabel(labels, metricKind, dimension),
|
|
2161
|
+
value: formatMetricValue(
|
|
2162
|
+
getUsageTotalValue(totals, metricKind, dimension),
|
|
2163
|
+
metricKind
|
|
2164
|
+
),
|
|
2165
|
+
detail: labels.usageTotal,
|
|
2166
|
+
icon: Sparkles
|
|
2167
|
+
}
|
|
2168
|
+
];
|
|
2169
|
+
return /* @__PURE__ */ jsx13("div", { className: "grid gap-3 sm:grid-cols-2 xl:grid-cols-4", children: summary.map((item) => /* @__PURE__ */ jsx13(Card, { className: "gap-3 py-4", children: /* @__PURE__ */ jsx13(CardContent, { className: "px-4", children: /* @__PURE__ */ jsxs8("div", { className: "flex items-start justify-between gap-3", children: [
|
|
2170
|
+
/* @__PURE__ */ jsxs8("div", { className: "min-w-0", children: [
|
|
2171
|
+
/* @__PURE__ */ jsx13("p", { className: "truncate text-sm text-muted-foreground", children: item.label }),
|
|
2172
|
+
/* @__PURE__ */ jsx13("p", { className: "mt-1 truncate text-2xl font-semibold tracking-tight", children: item.value }),
|
|
2173
|
+
/* @__PURE__ */ jsx13("p", { className: "mt-1 truncate text-xs text-muted-foreground", children: item.detail })
|
|
2174
|
+
] }),
|
|
2175
|
+
/* @__PURE__ */ jsx13("div", { className: "rounded-md border bg-muted/50 p-2 text-muted-foreground", children: /* @__PURE__ */ jsx13(item.icon, { className: "size-4" }) })
|
|
2176
|
+
] }) }) }, item.label)) });
|
|
1882
2177
|
}
|
|
1883
|
-
function
|
|
1884
|
-
|
|
1885
|
-
|
|
2178
|
+
function UsageChart({
|
|
2179
|
+
chartState,
|
|
2180
|
+
metricKind
|
|
1886
2181
|
}) {
|
|
1887
|
-
return /* @__PURE__ */
|
|
1888
|
-
|
|
2182
|
+
return /* @__PURE__ */ jsx13(
|
|
2183
|
+
ChartContainer,
|
|
1889
2184
|
{
|
|
1890
|
-
className: "
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
2185
|
+
className: "h-[320px] w-full",
|
|
2186
|
+
config: chartState.config,
|
|
2187
|
+
children: /* @__PURE__ */ jsxs8(
|
|
2188
|
+
BarChart,
|
|
2189
|
+
{
|
|
2190
|
+
accessibilityLayer: true,
|
|
2191
|
+
data: chartState.data,
|
|
2192
|
+
margin: { left: 8, right: 8, top: 12 },
|
|
2193
|
+
children: [
|
|
2194
|
+
/* @__PURE__ */ jsx13(CartesianGrid, { vertical: false }),
|
|
2195
|
+
/* @__PURE__ */ jsx13(
|
|
2196
|
+
XAxis,
|
|
2197
|
+
{
|
|
2198
|
+
axisLine: false,
|
|
2199
|
+
dataKey: "label",
|
|
2200
|
+
tickLine: false,
|
|
2201
|
+
tickMargin: 10
|
|
2202
|
+
}
|
|
2203
|
+
),
|
|
2204
|
+
/* @__PURE__ */ jsx13(
|
|
2205
|
+
YAxis,
|
|
2206
|
+
{
|
|
2207
|
+
axisLine: false,
|
|
2208
|
+
tickFormatter: (value) => formatCompactMetric(value, metricKind),
|
|
2209
|
+
tickLine: false,
|
|
2210
|
+
width: 60
|
|
2211
|
+
}
|
|
2212
|
+
),
|
|
2213
|
+
/* @__PURE__ */ jsx13(
|
|
2214
|
+
Tooltip2,
|
|
2215
|
+
{
|
|
2216
|
+
content: /* @__PURE__ */ jsx13(
|
|
2217
|
+
ChartTooltipContent,
|
|
2218
|
+
{
|
|
2219
|
+
formatter: (value) => formatMetricValue(Number(value), metricKind),
|
|
2220
|
+
labelFormatter: (value) => String(value ?? "")
|
|
2221
|
+
}
|
|
2222
|
+
),
|
|
2223
|
+
cursor: false
|
|
2224
|
+
}
|
|
2225
|
+
),
|
|
2226
|
+
/* @__PURE__ */ jsx13(
|
|
2227
|
+
Legend,
|
|
2228
|
+
{
|
|
2229
|
+
content: /* @__PURE__ */ jsx13(ChartLegendContent, { className: "justify-center pt-3" })
|
|
2230
|
+
}
|
|
2231
|
+
),
|
|
2232
|
+
chartState.series.map((series) => /* @__PURE__ */ jsx13(
|
|
2233
|
+
Bar,
|
|
2234
|
+
{
|
|
2235
|
+
dataKey: series.id,
|
|
2236
|
+
fill: `var(--color-${series.id})`,
|
|
2237
|
+
radius: [4, 4, 0, 0],
|
|
2238
|
+
stackId: "usage"
|
|
2239
|
+
},
|
|
2240
|
+
series.id
|
|
2241
|
+
))
|
|
2242
|
+
]
|
|
2243
|
+
}
|
|
2244
|
+
)
|
|
2245
|
+
}
|
|
2246
|
+
);
|
|
1914
2247
|
}
|
|
1915
|
-
function
|
|
1916
|
-
|
|
2248
|
+
function UsageTable({
|
|
2249
|
+
dimension,
|
|
2250
|
+
groupBy,
|
|
1917
2251
|
labels,
|
|
1918
|
-
|
|
1919
|
-
|
|
2252
|
+
metricKind,
|
|
2253
|
+
onRowFilter,
|
|
2254
|
+
rows,
|
|
2255
|
+
totals
|
|
1920
2256
|
}) {
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
children:
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
2257
|
+
const totalValue = getUsageTotalValue(totals, metricKind, dimension);
|
|
2258
|
+
const filterable = groupBy !== "namespace";
|
|
2259
|
+
return /* @__PURE__ */ jsxs8(Card, { className: "gap-3 py-4", children: [
|
|
2260
|
+
/* @__PURE__ */ jsx13(CardHeader, { className: "px-4 lg:px-5", children: /* @__PURE__ */ jsxs8("div", { className: "flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between", children: [
|
|
2261
|
+
/* @__PURE__ */ jsx13(CardTitle, { className: "text-base", children: "Usage detail" }),
|
|
2262
|
+
/* @__PURE__ */ jsxs8(Badge, { variant: "outline", children: [
|
|
2263
|
+
formatNumber(rows.length),
|
|
2264
|
+
" ",
|
|
2265
|
+
getGroupByLabel(groupBy).toLowerCase()
|
|
2266
|
+
] })
|
|
2267
|
+
] }) }),
|
|
2268
|
+
/* @__PURE__ */ jsx13(CardContent, { className: "px-0", children: rows.length === 0 ? /* @__PURE__ */ jsx13("p", { className: "px-5 py-4 text-sm text-muted-foreground", children: labels.noResults }) : /* @__PURE__ */ jsx13("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxs8("table", { className: "w-full min-w-[940px] text-sm", children: [
|
|
2269
|
+
/* @__PURE__ */ jsx13("thead", { children: /* @__PURE__ */ jsxs8("tr", { className: "border-b text-left text-xs uppercase tracking-[0.12em] text-muted-foreground", children: [
|
|
2270
|
+
/* @__PURE__ */ jsx13("th", { className: "px-5 py-2.5 font-medium", children: getGroupByLabel(groupBy) }),
|
|
2271
|
+
/* @__PURE__ */ jsx13("th", { className: "px-3 py-2.5 text-right font-medium", children: getUsageSummaryLabel(labels, metricKind, dimension) }),
|
|
2272
|
+
/* @__PURE__ */ jsx13("th", { className: "px-3 py-2.5 text-right font-medium", children: "Share" }),
|
|
2273
|
+
/* @__PURE__ */ jsx13("th", { className: "px-3 py-2.5 text-right font-medium", children: "Calls" }),
|
|
2274
|
+
/* @__PURE__ */ jsx13("th", { className: "px-3 py-2.5 text-right font-medium", children: "Input" }),
|
|
2275
|
+
/* @__PURE__ */ jsx13("th", { className: "px-3 py-2.5 text-right font-medium", children: "Output" }),
|
|
2276
|
+
/* @__PURE__ */ jsx13("th", { className: "px-3 py-2.5 text-right font-medium", children: "Reasoning" }),
|
|
2277
|
+
/* @__PURE__ */ jsx13("th", { className: "px-3 py-2.5 text-right font-medium", children: "Cache read" }),
|
|
2278
|
+
/* @__PURE__ */ jsx13("th", { className: "px-5 py-2.5 text-right font-medium", children: "Avg/call" })
|
|
2279
|
+
] }) }),
|
|
2280
|
+
/* @__PURE__ */ jsx13("tbody", { children: rows.slice(0, 60).map((row) => {
|
|
2281
|
+
const share = totalValue > 0 ? row.value / totalValue : 0;
|
|
2282
|
+
return /* @__PURE__ */ jsxs8(
|
|
2283
|
+
"tr",
|
|
1942
2284
|
{
|
|
1943
|
-
|
|
1944
|
-
|
|
2285
|
+
className: cn(
|
|
2286
|
+
"border-b last:border-0",
|
|
2287
|
+
filterable && "cursor-pointer transition-colors hover:bg-muted/50"
|
|
2288
|
+
),
|
|
2289
|
+
onClick: () => filterable && onRowFilter(row),
|
|
2290
|
+
children: [
|
|
2291
|
+
/* @__PURE__ */ jsxs8("td", { className: "px-5 py-3", children: [
|
|
2292
|
+
/* @__PURE__ */ jsx13("div", { className: "max-w-80 truncate font-medium", children: row.groupLabel }),
|
|
2293
|
+
row.groupKey !== row.groupLabel && /* @__PURE__ */ jsx13("div", { className: "mt-0.5 max-w-80 truncate text-xs text-muted-foreground", children: row.groupKey })
|
|
2294
|
+
] }),
|
|
2295
|
+
/* @__PURE__ */ jsx13("td", { className: "px-3 py-3 text-right font-medium", children: formatMetricValue(row.value, metricKind) }),
|
|
2296
|
+
/* @__PURE__ */ jsx13("td", { className: "px-3 py-3 text-right", children: formatPercent(share) }),
|
|
2297
|
+
/* @__PURE__ */ jsx13("td", { className: "px-3 py-3 text-right", children: formatNumber(row.totalCalls) }),
|
|
2298
|
+
/* @__PURE__ */ jsx13("td", { className: "px-3 py-3 text-right", children: formatMetricValue(
|
|
2299
|
+
getUsageTotalValue(row, metricKind, "input"),
|
|
2300
|
+
metricKind
|
|
2301
|
+
) }),
|
|
2302
|
+
/* @__PURE__ */ jsx13("td", { className: "px-3 py-3 text-right", children: formatMetricValue(
|
|
2303
|
+
getUsageTotalValue(row, metricKind, "output"),
|
|
2304
|
+
metricKind
|
|
2305
|
+
) }),
|
|
2306
|
+
/* @__PURE__ */ jsx13("td", { className: "px-3 py-3 text-right", children: formatMetricValue(
|
|
2307
|
+
getUsageTotalValue(row, metricKind, "reasoning"),
|
|
2308
|
+
metricKind
|
|
2309
|
+
) }),
|
|
2310
|
+
/* @__PURE__ */ jsx13("td", { className: "px-3 py-3 text-right", children: formatMetricValue(
|
|
2311
|
+
getUsageTotalValue(row, metricKind, "cacheRead"),
|
|
2312
|
+
metricKind
|
|
2313
|
+
) }),
|
|
2314
|
+
/* @__PURE__ */ jsx13("td", { className: "px-5 py-3 text-right", children: formatMetricValue(
|
|
2315
|
+
row.totalCalls > 0 ? row.value / row.totalCalls : 0,
|
|
2316
|
+
metricKind
|
|
2317
|
+
) })
|
|
2318
|
+
]
|
|
1945
2319
|
},
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
)
|
|
1952
|
-
}
|
|
1953
|
-
].map((item) => /* @__PURE__ */ jsxs7("div", { children: [
|
|
1954
|
-
/* @__PURE__ */ jsx12("p", { className: "font-medium text-foreground", children: item.value }),
|
|
1955
|
-
/* @__PURE__ */ jsx12("p", { className: "text-muted-foreground", children: item.label })
|
|
1956
|
-
] }, item.label)) })
|
|
1957
|
-
]
|
|
1958
|
-
},
|
|
1959
|
-
`${agent.namespace}:${agent.agentId}`
|
|
1960
|
-
)) });
|
|
2320
|
+
row.groupKey
|
|
2321
|
+
);
|
|
2322
|
+
}) })
|
|
2323
|
+
] }) }) })
|
|
2324
|
+
] });
|
|
1961
2325
|
}
|
|
1962
|
-
function
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
})
|
|
1970
|
-
month: "short",
|
|
1971
|
-
day: "numeric"
|
|
1972
|
-
});
|
|
2326
|
+
function UsageSelect(props) {
|
|
2327
|
+
return /* @__PURE__ */ jsxs8("label", { className: "space-y-1", children: [
|
|
2328
|
+
/* @__PURE__ */ jsx13("span", { className: "text-[11px] font-medium uppercase tracking-[0.16em] text-muted-foreground", children: props.label }),
|
|
2329
|
+
/* @__PURE__ */ jsxs8(Select, { value: props.value, onValueChange: props.onValueChange, children: [
|
|
2330
|
+
/* @__PURE__ */ jsx13(SelectTrigger, { className: "h-9 w-full min-w-0 bg-background", children: /* @__PURE__ */ jsx13(SelectValue, {}) }),
|
|
2331
|
+
/* @__PURE__ */ jsx13(SelectContent, { children: props.options.map(([value, label]) => /* @__PURE__ */ jsx13(SelectItem, { value, children: label }, value)) })
|
|
2332
|
+
] })
|
|
2333
|
+
] });
|
|
1973
2334
|
}
|
|
1974
|
-
function
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
2335
|
+
function FilterInput(props) {
|
|
2336
|
+
return /* @__PURE__ */ jsxs8("label", { className: "space-y-1", children: [
|
|
2337
|
+
/* @__PURE__ */ jsx13("span", { className: "text-[11px] font-medium uppercase tracking-[0.16em] text-muted-foreground", children: props.label }),
|
|
2338
|
+
/* @__PURE__ */ jsxs8("div", { className: "relative", children: [
|
|
2339
|
+
props.icon && /* @__PURE__ */ jsx13("span", { className: "pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground", children: props.icon }),
|
|
2340
|
+
/* @__PURE__ */ jsx13(
|
|
2341
|
+
Input,
|
|
2342
|
+
{
|
|
2343
|
+
className: cn("h-9 bg-background", props.icon && "pl-8"),
|
|
2344
|
+
onChange: (event) => props.onChange(event.target.value),
|
|
2345
|
+
type: props.type ?? "text",
|
|
2346
|
+
value: props.value
|
|
2347
|
+
}
|
|
2348
|
+
)
|
|
2349
|
+
] })
|
|
2350
|
+
] });
|
|
1984
2351
|
}
|
|
1985
|
-
function
|
|
1986
|
-
|
|
2352
|
+
function EmptyDashboard({
|
|
2353
|
+
description,
|
|
2354
|
+
title
|
|
2355
|
+
}) {
|
|
2356
|
+
return /* @__PURE__ */ jsxs8("div", { className: "rounded-lg border border-dashed bg-muted/20 p-8 text-center", children: [
|
|
2357
|
+
/* @__PURE__ */ jsx13("h3", { className: "text-base font-semibold", children: title }),
|
|
2358
|
+
/* @__PURE__ */ jsx13("p", { className: "mt-2 text-sm text-muted-foreground", children: description })
|
|
2359
|
+
] });
|
|
1987
2360
|
}
|
|
2361
|
+
var EMPTY_TOTALS = {
|
|
2362
|
+
inputTokens: 0,
|
|
2363
|
+
outputTokens: 0,
|
|
2364
|
+
reasoningTokens: 0,
|
|
2365
|
+
cacheReadInputTokens: 0,
|
|
2366
|
+
cacheCreationInputTokens: 0,
|
|
2367
|
+
totalTokens: 0,
|
|
2368
|
+
inputCostUsd: 0,
|
|
2369
|
+
outputCostUsd: 0,
|
|
2370
|
+
reasoningCostUsd: 0,
|
|
2371
|
+
cacheReadInputCostUsd: 0,
|
|
2372
|
+
cacheCreationInputCostUsd: 0,
|
|
2373
|
+
totalCostUsd: 0,
|
|
2374
|
+
totalCalls: 0
|
|
2375
|
+
};
|
|
1988
2376
|
var USAGE_DIMENSIONS = [
|
|
1989
2377
|
"total",
|
|
1990
2378
|
"input",
|
|
@@ -1993,6 +2381,128 @@ var USAGE_DIMENSIONS = [
|
|
|
1993
2381
|
"cacheRead",
|
|
1994
2382
|
"cacheWrite"
|
|
1995
2383
|
];
|
|
2384
|
+
var USAGE_CHART_COLORS = [
|
|
2385
|
+
"hsl(var(--primary))",
|
|
2386
|
+
"hsl(var(--chart-2, 142 76% 36%))",
|
|
2387
|
+
"hsl(var(--chart-3, 38 92% 50%))",
|
|
2388
|
+
"hsl(var(--chart-4, 199 89% 48%))",
|
|
2389
|
+
"hsl(var(--chart-5, 346 77% 49%))",
|
|
2390
|
+
"hsl(var(--muted-foreground))"
|
|
2391
|
+
];
|
|
2392
|
+
function buildChartState(points, metricKind, dimension, interval) {
|
|
2393
|
+
const topGroups = topUsageGroups(points, metricKind, dimension);
|
|
2394
|
+
const groupIdByKey = new Map(topGroups.map((group, index) => [
|
|
2395
|
+
group.key,
|
|
2396
|
+
`series${index + 1}`
|
|
2397
|
+
]));
|
|
2398
|
+
const series = topGroups.map((group, index) => ({
|
|
2399
|
+
color: USAGE_CHART_COLORS[index % USAGE_CHART_COLORS.length],
|
|
2400
|
+
id: groupIdByKey.get(group.key) ?? `series${index + 1}`,
|
|
2401
|
+
key: group.key,
|
|
2402
|
+
label: group.label
|
|
2403
|
+
}));
|
|
2404
|
+
const config = Object.fromEntries(
|
|
2405
|
+
series.map((item) => [item.id, {
|
|
2406
|
+
color: item.color,
|
|
2407
|
+
label: item.label
|
|
2408
|
+
}])
|
|
2409
|
+
);
|
|
2410
|
+
const buckets = buildUsageBuckets(points);
|
|
2411
|
+
const data = buckets.map((bucket) => {
|
|
2412
|
+
const row = {
|
|
2413
|
+
bucket: bucket.bucket,
|
|
2414
|
+
label: formatUsageBucket(bucket.bucket, interval)
|
|
2415
|
+
};
|
|
2416
|
+
for (const item of series) row[item.id] = 0;
|
|
2417
|
+
for (const point of bucket.points) {
|
|
2418
|
+
const seriesId = groupIdByKey.get(point.groupKey);
|
|
2419
|
+
if (!seriesId) continue;
|
|
2420
|
+
row[seriesId] = Number(row[seriesId] ?? 0) + getUsageTotalValue(point, metricKind, dimension);
|
|
2421
|
+
}
|
|
2422
|
+
return row;
|
|
2423
|
+
});
|
|
2424
|
+
return {
|
|
2425
|
+
config,
|
|
2426
|
+
data,
|
|
2427
|
+
series
|
|
2428
|
+
};
|
|
2429
|
+
}
|
|
2430
|
+
function buildUsageBuckets(points) {
|
|
2431
|
+
const byBucket = /* @__PURE__ */ new Map();
|
|
2432
|
+
for (const point of points) {
|
|
2433
|
+
const rows = byBucket.get(point.bucket) ?? [];
|
|
2434
|
+
rows.push(point);
|
|
2435
|
+
byBucket.set(point.bucket, rows);
|
|
2436
|
+
}
|
|
2437
|
+
return Array.from(byBucket.entries()).map(([bucket, bucketPoints]) => ({ bucket, points: bucketPoints })).sort(
|
|
2438
|
+
(a, b) => new Date(a.bucket).getTime() - new Date(b.bucket).getTime()
|
|
2439
|
+
);
|
|
2440
|
+
}
|
|
2441
|
+
function aggregateUsageRows(points, metricKind, dimension) {
|
|
2442
|
+
const totals = /* @__PURE__ */ new Map();
|
|
2443
|
+
for (const point of points) {
|
|
2444
|
+
const existing = totals.get(point.groupKey) ?? {
|
|
2445
|
+
...EMPTY_TOTALS,
|
|
2446
|
+
groupKey: point.groupKey,
|
|
2447
|
+
groupLabel: point.groupLabel,
|
|
2448
|
+
value: 0
|
|
2449
|
+
};
|
|
2450
|
+
addUsageTotals(existing, point);
|
|
2451
|
+
existing.value = getUsageTotalValue(existing, metricKind, dimension);
|
|
2452
|
+
totals.set(point.groupKey, existing);
|
|
2453
|
+
}
|
|
2454
|
+
return Array.from(totals.values()).sort((a, b) => b.value - a.value);
|
|
2455
|
+
}
|
|
2456
|
+
function addUsageTotals(target, source) {
|
|
2457
|
+
target.inputTokens += source.inputTokens;
|
|
2458
|
+
target.outputTokens += source.outputTokens;
|
|
2459
|
+
target.reasoningTokens += source.reasoningTokens;
|
|
2460
|
+
target.cacheReadInputTokens += source.cacheReadInputTokens;
|
|
2461
|
+
target.cacheCreationInputTokens += source.cacheCreationInputTokens;
|
|
2462
|
+
target.totalTokens += source.totalTokens;
|
|
2463
|
+
target.inputCostUsd += source.inputCostUsd;
|
|
2464
|
+
target.outputCostUsd += source.outputCostUsd;
|
|
2465
|
+
target.reasoningCostUsd += source.reasoningCostUsd;
|
|
2466
|
+
target.cacheReadInputCostUsd += source.cacheReadInputCostUsd;
|
|
2467
|
+
target.cacheCreationInputCostUsd += source.cacheCreationInputCostUsd;
|
|
2468
|
+
target.totalCostUsd += source.totalCostUsd;
|
|
2469
|
+
target.totalCalls += source.totalCalls;
|
|
2470
|
+
}
|
|
2471
|
+
function topUsageGroups(points, metricKind, dimension) {
|
|
2472
|
+
const totals = /* @__PURE__ */ new Map();
|
|
2473
|
+
for (const point of points) {
|
|
2474
|
+
const existing = totals.get(point.groupKey) ?? {
|
|
2475
|
+
key: point.groupKey,
|
|
2476
|
+
label: point.groupLabel,
|
|
2477
|
+
value: 0
|
|
2478
|
+
};
|
|
2479
|
+
existing.value += getUsageTotalValue(point, metricKind, dimension);
|
|
2480
|
+
totals.set(point.groupKey, existing);
|
|
2481
|
+
}
|
|
2482
|
+
return Array.from(totals.values()).sort((a, b) => b.value - a.value).slice(0, 6);
|
|
2483
|
+
}
|
|
2484
|
+
function getUsageRange(period, customFrom, customTo) {
|
|
2485
|
+
if (period === "custom") {
|
|
2486
|
+
return {
|
|
2487
|
+
from: customFrom ? new Date(customFrom).toISOString() : void 0,
|
|
2488
|
+
to: customTo ? new Date(customTo).toISOString() : void 0
|
|
2489
|
+
};
|
|
2490
|
+
}
|
|
2491
|
+
const to = /* @__PURE__ */ new Date();
|
|
2492
|
+
const from = new Date(to);
|
|
2493
|
+
if (period === "24h") {
|
|
2494
|
+
from.setHours(from.getHours() - 24);
|
|
2495
|
+
} else if (period === "30d") {
|
|
2496
|
+
from.setDate(from.getDate() - 30);
|
|
2497
|
+
} else {
|
|
2498
|
+
from.setDate(from.getDate() - 7);
|
|
2499
|
+
}
|
|
2500
|
+
return { from: from.toISOString(), to: to.toISOString() };
|
|
2501
|
+
}
|
|
2502
|
+
function emptyToUndefined(value) {
|
|
2503
|
+
const trimmed = value.trim();
|
|
2504
|
+
return trimmed.length > 0 ? trimmed : void 0;
|
|
2505
|
+
}
|
|
1996
2506
|
function getUsageDimensionLabel(labels, dimension) {
|
|
1997
2507
|
switch (dimension) {
|
|
1998
2508
|
case "input":
|
|
@@ -2011,111 +2521,103 @@ function getUsageDimensionLabel(labels, dimension) {
|
|
|
2011
2521
|
}
|
|
2012
2522
|
}
|
|
2013
2523
|
function getUsageSummaryLabel(labels, metricKind, dimension) {
|
|
2014
|
-
const metricLabel = metricKind === "cost" ? labels.usageMetricCost : labels.usageMetricTokens;
|
|
2524
|
+
const metricLabel = metricKind === "cost" ? labels.usageMetricCost : metricKind === "calls" ? "Calls" : labels.usageMetricTokens;
|
|
2015
2525
|
return `${getUsageDimensionLabel(labels, dimension)} ${metricLabel}`;
|
|
2016
2526
|
}
|
|
2017
|
-
function
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
return llmTotals.cacheReadInputCostUsd;
|
|
2029
|
-
case "cacheWrite":
|
|
2030
|
-
return llmTotals.cacheCreationInputCostUsd;
|
|
2031
|
-
case "total":
|
|
2032
|
-
default:
|
|
2033
|
-
return llmTotals.totalCostUsd;
|
|
2034
|
-
}
|
|
2035
|
-
}
|
|
2036
|
-
switch (dimension) {
|
|
2037
|
-
case "input":
|
|
2038
|
-
return llmTotals.inputTokens;
|
|
2039
|
-
case "output":
|
|
2040
|
-
return llmTotals.outputTokens;
|
|
2041
|
-
case "reasoning":
|
|
2042
|
-
return llmTotals.reasoningTokens;
|
|
2043
|
-
case "cacheRead":
|
|
2044
|
-
return llmTotals.cacheReadInputTokens;
|
|
2045
|
-
case "cacheWrite":
|
|
2046
|
-
return llmTotals.cacheCreationInputTokens;
|
|
2047
|
-
case "total":
|
|
2527
|
+
function getGroupByLabel(groupBy) {
|
|
2528
|
+
switch (groupBy) {
|
|
2529
|
+
case "thread":
|
|
2530
|
+
return "Thread";
|
|
2531
|
+
case "namespace":
|
|
2532
|
+
return "Namespace";
|
|
2533
|
+
case "provider":
|
|
2534
|
+
return "Provider";
|
|
2535
|
+
case "model":
|
|
2536
|
+
return "Model";
|
|
2537
|
+
case "participant":
|
|
2048
2538
|
default:
|
|
2049
|
-
return
|
|
2539
|
+
return "Participant";
|
|
2050
2540
|
}
|
|
2051
2541
|
}
|
|
2052
|
-
function
|
|
2542
|
+
function getUsageTotalValue(totals, metricKind, dimension) {
|
|
2543
|
+
if (metricKind === "calls") return totals.totalCalls;
|
|
2053
2544
|
if (metricKind === "cost") {
|
|
2054
2545
|
switch (dimension) {
|
|
2055
2546
|
case "input":
|
|
2056
|
-
return
|
|
2547
|
+
return totals.inputCostUsd;
|
|
2057
2548
|
case "output":
|
|
2058
|
-
return
|
|
2549
|
+
return totals.outputCostUsd;
|
|
2059
2550
|
case "reasoning":
|
|
2060
|
-
return
|
|
2551
|
+
return totals.reasoningCostUsd;
|
|
2061
2552
|
case "cacheRead":
|
|
2062
|
-
return
|
|
2553
|
+
return totals.cacheReadInputCostUsd;
|
|
2063
2554
|
case "cacheWrite":
|
|
2064
|
-
return
|
|
2555
|
+
return totals.cacheCreationInputCostUsd;
|
|
2065
2556
|
case "total":
|
|
2066
2557
|
default:
|
|
2067
|
-
return
|
|
2558
|
+
return totals.totalCostUsd;
|
|
2068
2559
|
}
|
|
2069
2560
|
}
|
|
2070
2561
|
switch (dimension) {
|
|
2071
2562
|
case "input":
|
|
2072
|
-
return
|
|
2563
|
+
return totals.inputTokens;
|
|
2073
2564
|
case "output":
|
|
2074
|
-
return
|
|
2565
|
+
return totals.outputTokens;
|
|
2075
2566
|
case "reasoning":
|
|
2076
|
-
return
|
|
2567
|
+
return totals.reasoningTokens;
|
|
2077
2568
|
case "cacheRead":
|
|
2078
|
-
return
|
|
2569
|
+
return totals.cacheReadInputTokens;
|
|
2079
2570
|
case "cacheWrite":
|
|
2080
|
-
return
|
|
2571
|
+
return totals.cacheCreationInputTokens;
|
|
2081
2572
|
case "total":
|
|
2082
2573
|
default:
|
|
2083
|
-
return
|
|
2574
|
+
return totals.totalTokens;
|
|
2084
2575
|
}
|
|
2085
2576
|
}
|
|
2086
|
-
function
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
return point.cacheReadInputCostUsd;
|
|
2097
|
-
case "cacheWrite":
|
|
2098
|
-
return point.cacheCreationInputCostUsd;
|
|
2099
|
-
case "total":
|
|
2100
|
-
default:
|
|
2101
|
-
return point.totalCostUsd;
|
|
2102
|
-
}
|
|
2577
|
+
function formatUsageBucket(bucket, interval) {
|
|
2578
|
+
const date = new Date(bucket);
|
|
2579
|
+
if (Number.isNaN(date.getTime())) return bucket;
|
|
2580
|
+
if (interval === "minute" || interval === "hour") {
|
|
2581
|
+
return date.toLocaleString(void 0, {
|
|
2582
|
+
month: "short",
|
|
2583
|
+
day: "numeric",
|
|
2584
|
+
hour: "numeric",
|
|
2585
|
+
minute: interval === "minute" ? "2-digit" : void 0
|
|
2586
|
+
});
|
|
2103
2587
|
}
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
case "reasoning":
|
|
2110
|
-
return point.reasoningTokens;
|
|
2111
|
-
case "cacheRead":
|
|
2112
|
-
return point.cacheReadInputTokens;
|
|
2113
|
-
case "cacheWrite":
|
|
2114
|
-
return point.cacheCreationInputTokens;
|
|
2115
|
-
case "total":
|
|
2116
|
-
default:
|
|
2117
|
-
return point.totalTokens;
|
|
2588
|
+
if (interval === "month") {
|
|
2589
|
+
return date.toLocaleDateString(void 0, {
|
|
2590
|
+
month: "short",
|
|
2591
|
+
year: "numeric"
|
|
2592
|
+
});
|
|
2118
2593
|
}
|
|
2594
|
+
return date.toLocaleDateString(void 0, {
|
|
2595
|
+
month: "short",
|
|
2596
|
+
day: "numeric"
|
|
2597
|
+
});
|
|
2598
|
+
}
|
|
2599
|
+
function formatUsageRangeLabel(period, range) {
|
|
2600
|
+
if (period !== "custom") return period;
|
|
2601
|
+
if (!range.from && !range.to) return "Custom";
|
|
2602
|
+
return `${formatShortDate(range.from)} - ${formatShortDate(range.to)}`;
|
|
2603
|
+
}
|
|
2604
|
+
function formatShortDate(value) {
|
|
2605
|
+
if (!value) return "Open";
|
|
2606
|
+
const date = new Date(value);
|
|
2607
|
+
if (Number.isNaN(date.getTime())) return value;
|
|
2608
|
+
return date.toLocaleDateString(void 0, {
|
|
2609
|
+
month: "short",
|
|
2610
|
+
day: "numeric"
|
|
2611
|
+
});
|
|
2612
|
+
}
|
|
2613
|
+
function formatNumber(value) {
|
|
2614
|
+
return new Intl.NumberFormat().format(value);
|
|
2615
|
+
}
|
|
2616
|
+
function formatPercent(value) {
|
|
2617
|
+
return new Intl.NumberFormat(void 0, {
|
|
2618
|
+
maximumFractionDigits: 1,
|
|
2619
|
+
style: "percent"
|
|
2620
|
+
}).format(value);
|
|
2119
2621
|
}
|
|
2120
2622
|
function formatMetricValue(value, metricKind) {
|
|
2121
2623
|
if (metricKind === "cost") {
|
|
@@ -2130,10 +2632,26 @@ function formatMetricValue(value, metricKind) {
|
|
|
2130
2632
|
}
|
|
2131
2633
|
return formatNumber(value);
|
|
2132
2634
|
}
|
|
2635
|
+
function formatCompactMetric(value, metricKind) {
|
|
2636
|
+
if (metricKind === "cost") {
|
|
2637
|
+
return new Intl.NumberFormat(void 0, {
|
|
2638
|
+
compactDisplay: "short",
|
|
2639
|
+
currency: "USD",
|
|
2640
|
+
maximumFractionDigits: 1,
|
|
2641
|
+
notation: "compact",
|
|
2642
|
+
style: "currency"
|
|
2643
|
+
}).format(value);
|
|
2644
|
+
}
|
|
2645
|
+
return new Intl.NumberFormat(void 0, {
|
|
2646
|
+
compactDisplay: "short",
|
|
2647
|
+
maximumFractionDigits: 1,
|
|
2648
|
+
notation: "compact"
|
|
2649
|
+
}).format(value);
|
|
2650
|
+
}
|
|
2133
2651
|
|
|
2134
2652
|
// src/components/views/ThreadsView.tsx
|
|
2135
|
-
import { Search, MessageSquare as MessageSquare2 } from "lucide-react";
|
|
2136
|
-
import { jsx as
|
|
2653
|
+
import { Search as Search2, MessageSquare as MessageSquare2 } from "lucide-react";
|
|
2654
|
+
import { jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2137
2655
|
var ThreadsView = ({
|
|
2138
2656
|
config,
|
|
2139
2657
|
threads,
|
|
@@ -2141,10 +2659,10 @@ var ThreadsView = ({
|
|
|
2141
2659
|
onSearchChange,
|
|
2142
2660
|
onThreadClick
|
|
2143
2661
|
}) => {
|
|
2144
|
-
return /* @__PURE__ */
|
|
2145
|
-
/* @__PURE__ */
|
|
2146
|
-
/* @__PURE__ */
|
|
2147
|
-
/* @__PURE__ */
|
|
2662
|
+
return /* @__PURE__ */ jsxs9("div", { className: "space-y-4", children: [
|
|
2663
|
+
/* @__PURE__ */ jsxs9("div", { className: "relative max-w-sm", children: [
|
|
2664
|
+
/* @__PURE__ */ jsx14(Search2, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
|
|
2665
|
+
/* @__PURE__ */ jsx14(
|
|
2148
2666
|
Input,
|
|
2149
2667
|
{
|
|
2150
2668
|
className: "pl-9",
|
|
@@ -2154,19 +2672,19 @@ var ThreadsView = ({
|
|
|
2154
2672
|
}
|
|
2155
2673
|
)
|
|
2156
2674
|
] }),
|
|
2157
|
-
threads.length === 0 ? /* @__PURE__ */
|
|
2158
|
-
/* @__PURE__ */
|
|
2159
|
-
/* @__PURE__ */
|
|
2160
|
-
] }) : /* @__PURE__ */
|
|
2675
|
+
threads.length === 0 ? /* @__PURE__ */ jsxs9("div", { className: "rounded-xl border border-dashed p-10 text-center", children: [
|
|
2676
|
+
/* @__PURE__ */ jsx14(MessageSquare2, { className: "mx-auto h-8 w-8 text-muted-foreground/50" }),
|
|
2677
|
+
/* @__PURE__ */ jsx14("p", { className: "mt-3 text-sm text-muted-foreground", children: searchValue ? config.labels.noResults : config.labels.emptyDescription })
|
|
2678
|
+
] }) : /* @__PURE__ */ jsx14("div", { className: "space-y-2", children: threads.map((thread) => /* @__PURE__ */ jsxs9(
|
|
2161
2679
|
"div",
|
|
2162
2680
|
{
|
|
2163
2681
|
className: "flex items-center gap-4 rounded-lg border bg-card p-4 transition-colors hover:bg-muted/50 cursor-pointer",
|
|
2164
2682
|
onClick: () => onThreadClick?.(thread.threadId),
|
|
2165
2683
|
children: [
|
|
2166
|
-
/* @__PURE__ */
|
|
2167
|
-
/* @__PURE__ */
|
|
2168
|
-
/* @__PURE__ */
|
|
2169
|
-
/* @__PURE__ */
|
|
2684
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex-1 min-w-0", children: [
|
|
2685
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2", children: [
|
|
2686
|
+
/* @__PURE__ */ jsx14("p", { className: "font-medium truncate", children: thread.name }),
|
|
2687
|
+
/* @__PURE__ */ jsx14(
|
|
2170
2688
|
Badge,
|
|
2171
2689
|
{
|
|
2172
2690
|
variant: thread.status === "archived" ? "secondary" : "default",
|
|
@@ -2175,18 +2693,18 @@ var ThreadsView = ({
|
|
|
2175
2693
|
}
|
|
2176
2694
|
)
|
|
2177
2695
|
] }),
|
|
2178
|
-
/* @__PURE__ */
|
|
2696
|
+
/* @__PURE__ */ jsx14("p", { className: "mt-1 text-sm text-muted-foreground truncate", children: thread.summary ?? thread.lastMessagePreview ?? "No summary yet" })
|
|
2179
2697
|
] }),
|
|
2180
|
-
/* @__PURE__ */
|
|
2181
|
-
/* @__PURE__ */
|
|
2698
|
+
/* @__PURE__ */ jsxs9("div", { className: "text-right text-xs text-muted-foreground shrink-0 space-y-1", children: [
|
|
2699
|
+
/* @__PURE__ */ jsxs9("p", { children: [
|
|
2182
2700
|
formatNumber2(thread.messageCount),
|
|
2183
2701
|
" messages"
|
|
2184
2702
|
] }),
|
|
2185
|
-
/* @__PURE__ */
|
|
2703
|
+
/* @__PURE__ */ jsxs9("p", { children: [
|
|
2186
2704
|
thread.participantIds.length,
|
|
2187
2705
|
" participants"
|
|
2188
2706
|
] }),
|
|
2189
|
-
/* @__PURE__ */
|
|
2707
|
+
/* @__PURE__ */ jsx14("p", { children: formatDate(thread.lastActivityAt) })
|
|
2190
2708
|
] })
|
|
2191
2709
|
]
|
|
2192
2710
|
},
|
|
@@ -2194,7 +2712,7 @@ var ThreadsView = ({
|
|
|
2194
2712
|
)) })
|
|
2195
2713
|
] });
|
|
2196
2714
|
};
|
|
2197
|
-
function
|
|
2715
|
+
function formatDate(value) {
|
|
2198
2716
|
if (!value) return "No activity";
|
|
2199
2717
|
const date = new Date(value);
|
|
2200
2718
|
if (Number.isNaN(date.getTime())) return value;
|
|
@@ -2220,7 +2738,7 @@ import {
|
|
|
2220
2738
|
Wrench,
|
|
2221
2739
|
Cpu
|
|
2222
2740
|
} from "lucide-react";
|
|
2223
|
-
import { jsx as
|
|
2741
|
+
import { jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2224
2742
|
var MESSAGES_PAGE_SIZE = 50;
|
|
2225
2743
|
var ThreadDetailView = ({
|
|
2226
2744
|
threadId,
|
|
@@ -2278,36 +2796,36 @@ var ThreadDetailView = ({
|
|
|
2278
2796
|
}
|
|
2279
2797
|
}, [threadId, pageInfo, isLoadingMore, config.baseUrl, config.getRequestHeaders]);
|
|
2280
2798
|
if (isLoading) {
|
|
2281
|
-
return /* @__PURE__ */
|
|
2799
|
+
return /* @__PURE__ */ jsx15("div", { className: "flex items-center justify-center py-20", children: /* @__PURE__ */ jsx15(Loader2, { className: "h-6 w-6 animate-spin text-muted-foreground" }) });
|
|
2282
2800
|
}
|
|
2283
2801
|
if (error) {
|
|
2284
|
-
return /* @__PURE__ */
|
|
2285
|
-
/* @__PURE__ */
|
|
2286
|
-
/* @__PURE__ */
|
|
2287
|
-
/* @__PURE__ */
|
|
2288
|
-
/* @__PURE__ */
|
|
2802
|
+
return /* @__PURE__ */ jsxs10("div", { className: "space-y-4 py-10 text-center", children: [
|
|
2803
|
+
/* @__PURE__ */ jsx15("p", { className: "text-destructive font-medium", children: error.message }),
|
|
2804
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex justify-center gap-2", children: [
|
|
2805
|
+
/* @__PURE__ */ jsxs10(Button, { variant: "outline", onClick: onBack, children: [
|
|
2806
|
+
/* @__PURE__ */ jsx15(ArrowLeft, { className: "mr-2 h-4 w-4" }),
|
|
2289
2807
|
"Back"
|
|
2290
2808
|
] }),
|
|
2291
|
-
/* @__PURE__ */
|
|
2809
|
+
/* @__PURE__ */ jsx15(Button, { variant: "destructive", onClick: () => void loadInitial(), children: config.labels.retry })
|
|
2292
2810
|
] })
|
|
2293
2811
|
] });
|
|
2294
2812
|
}
|
|
2295
|
-
return /* @__PURE__ */
|
|
2296
|
-
/* @__PURE__ */
|
|
2297
|
-
/* @__PURE__ */
|
|
2813
|
+
return /* @__PURE__ */ jsxs10("div", { className: "space-y-6", children: [
|
|
2814
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex items-start gap-4", children: [
|
|
2815
|
+
/* @__PURE__ */ jsx15(
|
|
2298
2816
|
Button,
|
|
2299
2817
|
{
|
|
2300
2818
|
variant: "ghost",
|
|
2301
2819
|
size: "icon",
|
|
2302
2820
|
className: "mt-1 shrink-0",
|
|
2303
2821
|
onClick: onBack,
|
|
2304
|
-
children: /* @__PURE__ */
|
|
2822
|
+
children: /* @__PURE__ */ jsx15(ArrowLeft, { className: "h-4 w-4" })
|
|
2305
2823
|
}
|
|
2306
2824
|
),
|
|
2307
|
-
/* @__PURE__ */
|
|
2308
|
-
/* @__PURE__ */
|
|
2309
|
-
/* @__PURE__ */
|
|
2310
|
-
/* @__PURE__ */
|
|
2825
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex-1 min-w-0", children: [
|
|
2826
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-2", children: [
|
|
2827
|
+
/* @__PURE__ */ jsx15("h2", { className: "text-xl font-semibold truncate", children: thread?.name ?? threadId }),
|
|
2828
|
+
/* @__PURE__ */ jsx15(
|
|
2311
2829
|
Badge,
|
|
2312
2830
|
{
|
|
2313
2831
|
variant: thread?.status === "archived" ? "secondary" : "default",
|
|
@@ -2315,31 +2833,31 @@ var ThreadDetailView = ({
|
|
|
2315
2833
|
}
|
|
2316
2834
|
)
|
|
2317
2835
|
] }),
|
|
2318
|
-
thread?.summary && /* @__PURE__ */
|
|
2319
|
-
/* @__PURE__ */
|
|
2320
|
-
thread?.createdAt && /* @__PURE__ */
|
|
2836
|
+
thread?.summary && /* @__PURE__ */ jsx15("p", { className: "mt-1 text-sm text-muted-foreground", children: thread.summary }),
|
|
2837
|
+
/* @__PURE__ */ jsxs10("div", { className: "mt-2 flex flex-wrap gap-4 text-xs text-muted-foreground", children: [
|
|
2838
|
+
thread?.createdAt && /* @__PURE__ */ jsxs10("span", { children: [
|
|
2321
2839
|
"Created ",
|
|
2322
|
-
|
|
2840
|
+
formatDate2(thread.createdAt)
|
|
2323
2841
|
] }),
|
|
2324
|
-
thread?.updatedAt && /* @__PURE__ */
|
|
2842
|
+
thread?.updatedAt && /* @__PURE__ */ jsxs10("span", { children: [
|
|
2325
2843
|
"Updated ",
|
|
2326
|
-
|
|
2844
|
+
formatDate2(thread.updatedAt)
|
|
2327
2845
|
] }),
|
|
2328
|
-
thread?.participants && /* @__PURE__ */
|
|
2846
|
+
thread?.participants && /* @__PURE__ */ jsxs10("span", { children: [
|
|
2329
2847
|
thread.participants.length,
|
|
2330
2848
|
" participants"
|
|
2331
2849
|
] })
|
|
2332
2850
|
] })
|
|
2333
2851
|
] })
|
|
2334
2852
|
] }),
|
|
2335
|
-
/* @__PURE__ */
|
|
2336
|
-
/* @__PURE__ */
|
|
2853
|
+
/* @__PURE__ */ jsxs10("div", { className: "space-y-1", children: [
|
|
2854
|
+
/* @__PURE__ */ jsx15("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ jsxs10("h3", { className: "text-sm font-medium text-muted-foreground", children: [
|
|
2337
2855
|
"Messages (",
|
|
2338
2856
|
messages.length,
|
|
2339
2857
|
pageInfo?.hasMoreBefore ? "+" : "",
|
|
2340
2858
|
")"
|
|
2341
2859
|
] }) }),
|
|
2342
|
-
pageInfo?.hasMoreBefore && /* @__PURE__ */
|
|
2860
|
+
pageInfo?.hasMoreBefore && /* @__PURE__ */ jsx15("div", { className: "flex justify-center py-2", children: /* @__PURE__ */ jsxs10(
|
|
2343
2861
|
Button,
|
|
2344
2862
|
{
|
|
2345
2863
|
variant: "ghost",
|
|
@@ -2347,12 +2865,12 @@ var ThreadDetailView = ({
|
|
|
2347
2865
|
onClick: () => void loadMore(),
|
|
2348
2866
|
disabled: isLoadingMore,
|
|
2349
2867
|
children: [
|
|
2350
|
-
isLoadingMore ? /* @__PURE__ */
|
|
2868
|
+
isLoadingMore ? /* @__PURE__ */ jsx15(Loader2, { className: "mr-2 h-3 w-3 animate-spin" }) : /* @__PURE__ */ jsx15(ChevronUp2, { className: "mr-2 h-3 w-3" }),
|
|
2351
2869
|
"Load older messages"
|
|
2352
2870
|
]
|
|
2353
2871
|
}
|
|
2354
2872
|
) }),
|
|
2355
|
-
/* @__PURE__ */
|
|
2873
|
+
/* @__PURE__ */ jsx15("div", { className: "rounded-lg border bg-card", children: messages.length === 0 ? /* @__PURE__ */ jsx15("p", { className: "p-6 text-center text-sm text-muted-foreground", children: "No messages in this thread yet." }) : /* @__PURE__ */ jsx15("div", { className: "divide-y", children: messages.map((message) => /* @__PURE__ */ jsx15(MessageRow, { message }, message.id)) }) })
|
|
2356
2874
|
] })
|
|
2357
2875
|
] });
|
|
2358
2876
|
};
|
|
@@ -2360,43 +2878,43 @@ function MessageRow({ message }) {
|
|
|
2360
2878
|
const [expanded, setExpanded] = useState4(false);
|
|
2361
2879
|
const hasToolCalls = Array.isArray(message.toolCalls) && message.toolCalls.length > 0;
|
|
2362
2880
|
const hasReasoning = !!message.reasoning;
|
|
2363
|
-
return /* @__PURE__ */
|
|
2364
|
-
/* @__PURE__ */
|
|
2365
|
-
/* @__PURE__ */
|
|
2366
|
-
/* @__PURE__ */
|
|
2367
|
-
/* @__PURE__ */
|
|
2368
|
-
/* @__PURE__ */
|
|
2369
|
-
message.createdAt && /* @__PURE__ */
|
|
2881
|
+
return /* @__PURE__ */ jsx15("div", { className: "px-4 py-3", children: /* @__PURE__ */ jsxs10("div", { className: "flex items-start gap-3", children: [
|
|
2882
|
+
/* @__PURE__ */ jsx15(SenderIcon, { senderType: message.senderType }),
|
|
2883
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex-1 min-w-0", children: [
|
|
2884
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-2 text-xs", children: [
|
|
2885
|
+
/* @__PURE__ */ jsx15("span", { className: "font-medium", children: message.senderId ?? message.senderUserId ?? message.senderType }),
|
|
2886
|
+
/* @__PURE__ */ jsx15(Badge, { variant: "outline", className: "text-[10px] px-1.5 py-0", children: message.senderType }),
|
|
2887
|
+
message.createdAt && /* @__PURE__ */ jsx15("span", { className: "text-muted-foreground", children: formatTimestamp(message.createdAt) })
|
|
2370
2888
|
] }),
|
|
2371
|
-
message.content && /* @__PURE__ */
|
|
2372
|
-
(hasToolCalls || hasReasoning) && /* @__PURE__ */
|
|
2373
|
-
hasToolCalls && /* @__PURE__ */
|
|
2889
|
+
message.content && /* @__PURE__ */ jsx15("p", { className: "mt-1 text-sm whitespace-pre-wrap break-words", children: message.content }),
|
|
2890
|
+
(hasToolCalls || hasReasoning) && /* @__PURE__ */ jsxs10("div", { className: "mt-2 space-y-2", children: [
|
|
2891
|
+
hasToolCalls && /* @__PURE__ */ jsxs10(
|
|
2374
2892
|
"button",
|
|
2375
2893
|
{
|
|
2376
2894
|
type: "button",
|
|
2377
2895
|
onClick: () => setExpanded(!expanded),
|
|
2378
2896
|
className: "inline-flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground transition-colors",
|
|
2379
2897
|
children: [
|
|
2380
|
-
/* @__PURE__ */
|
|
2898
|
+
/* @__PURE__ */ jsx15(Wrench, { className: "h-3 w-3" }),
|
|
2381
2899
|
message.toolCalls.length,
|
|
2382
2900
|
" tool call",
|
|
2383
2901
|
message.toolCalls.length > 1 ? "s" : ""
|
|
2384
2902
|
]
|
|
2385
2903
|
}
|
|
2386
2904
|
),
|
|
2387
|
-
hasReasoning && /* @__PURE__ */
|
|
2905
|
+
hasReasoning && /* @__PURE__ */ jsxs10(
|
|
2388
2906
|
"button",
|
|
2389
2907
|
{
|
|
2390
2908
|
type: "button",
|
|
2391
2909
|
onClick: () => setExpanded(!expanded),
|
|
2392
2910
|
className: "inline-flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground transition-colors",
|
|
2393
2911
|
children: [
|
|
2394
|
-
/* @__PURE__ */
|
|
2912
|
+
/* @__PURE__ */ jsx15(Cpu, { className: "h-3 w-3" }),
|
|
2395
2913
|
"Reasoning"
|
|
2396
2914
|
]
|
|
2397
2915
|
}
|
|
2398
2916
|
),
|
|
2399
|
-
expanded && /* @__PURE__ */
|
|
2917
|
+
expanded && /* @__PURE__ */ jsx15("pre", { className: "mt-2 rounded-md bg-muted p-3 text-xs overflow-auto max-h-60", children: JSON.stringify(
|
|
2400
2918
|
{
|
|
2401
2919
|
...hasToolCalls ? { toolCalls: message.toolCalls } : {},
|
|
2402
2920
|
...hasReasoning ? { reasoning: message.reasoning } : {}
|
|
@@ -2412,16 +2930,16 @@ function SenderIcon({ senderType }) {
|
|
|
2412
2930
|
const base = "flex h-7 w-7 shrink-0 items-center justify-center rounded-full";
|
|
2413
2931
|
switch (senderType) {
|
|
2414
2932
|
case "agent":
|
|
2415
|
-
return /* @__PURE__ */
|
|
2933
|
+
return /* @__PURE__ */ jsx15("div", { className: cn(base, "bg-primary/10 text-primary"), children: /* @__PURE__ */ jsx15(Bot2, { className: "h-3.5 w-3.5" }) });
|
|
2416
2934
|
case "user":
|
|
2417
|
-
return /* @__PURE__ */
|
|
2935
|
+
return /* @__PURE__ */ jsx15("div", { className: cn(base, "bg-secondary text-secondary-foreground"), children: /* @__PURE__ */ jsx15(User, { className: "h-3.5 w-3.5" }) });
|
|
2418
2936
|
case "tool":
|
|
2419
|
-
return /* @__PURE__ */
|
|
2937
|
+
return /* @__PURE__ */ jsx15("div", { className: cn(base, "bg-muted text-muted-foreground"), children: /* @__PURE__ */ jsx15(Wrench, { className: "h-3.5 w-3.5" }) });
|
|
2420
2938
|
default:
|
|
2421
|
-
return /* @__PURE__ */
|
|
2939
|
+
return /* @__PURE__ */ jsx15("div", { className: cn(base, "bg-muted text-muted-foreground"), children: /* @__PURE__ */ jsx15(Cpu, { className: "h-3.5 w-3.5" }) });
|
|
2422
2940
|
}
|
|
2423
2941
|
}
|
|
2424
|
-
function
|
|
2942
|
+
function formatDate2(value) {
|
|
2425
2943
|
const date = new Date(value);
|
|
2426
2944
|
if (Number.isNaN(date.getTime())) return value;
|
|
2427
2945
|
return date.toLocaleDateString(void 0, {
|
|
@@ -2443,8 +2961,8 @@ function formatTimestamp(value) {
|
|
|
2443
2961
|
}
|
|
2444
2962
|
|
|
2445
2963
|
// src/components/views/ParticipantsView.tsx
|
|
2446
|
-
import { Search as
|
|
2447
|
-
import { jsx as
|
|
2964
|
+
import { Search as Search3, Users as Users3 } from "lucide-react";
|
|
2965
|
+
import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2448
2966
|
var ParticipantsView = ({
|
|
2449
2967
|
config,
|
|
2450
2968
|
participants,
|
|
@@ -2452,10 +2970,10 @@ var ParticipantsView = ({
|
|
|
2452
2970
|
onSearchChange,
|
|
2453
2971
|
onParticipantClick
|
|
2454
2972
|
}) => {
|
|
2455
|
-
return /* @__PURE__ */
|
|
2456
|
-
/* @__PURE__ */
|
|
2457
|
-
/* @__PURE__ */
|
|
2458
|
-
/* @__PURE__ */
|
|
2973
|
+
return /* @__PURE__ */ jsxs11("div", { className: "space-y-4", children: [
|
|
2974
|
+
/* @__PURE__ */ jsxs11("div", { className: "relative max-w-sm", children: [
|
|
2975
|
+
/* @__PURE__ */ jsx16(Search3, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
|
|
2976
|
+
/* @__PURE__ */ jsx16(
|
|
2459
2977
|
Input,
|
|
2460
2978
|
{
|
|
2461
2979
|
className: "pl-9",
|
|
@@ -2465,33 +2983,33 @@ var ParticipantsView = ({
|
|
|
2465
2983
|
}
|
|
2466
2984
|
)
|
|
2467
2985
|
] }),
|
|
2468
|
-
participants.length === 0 ? /* @__PURE__ */
|
|
2469
|
-
/* @__PURE__ */
|
|
2470
|
-
/* @__PURE__ */
|
|
2471
|
-
] }) : /* @__PURE__ */
|
|
2986
|
+
participants.length === 0 ? /* @__PURE__ */ jsxs11("div", { className: "rounded-xl border border-dashed p-10 text-center", children: [
|
|
2987
|
+
/* @__PURE__ */ jsx16(Users3, { className: "mx-auto h-8 w-8 text-muted-foreground/50" }),
|
|
2988
|
+
/* @__PURE__ */ jsx16("p", { className: "mt-3 text-sm text-muted-foreground", children: searchValue ? config.labels.noResults : config.labels.emptyDescription })
|
|
2989
|
+
] }) : /* @__PURE__ */ jsx16("div", { className: "space-y-2", children: participants.map((p) => /* @__PURE__ */ jsxs11(
|
|
2472
2990
|
"div",
|
|
2473
2991
|
{
|
|
2474
2992
|
className: "flex items-center gap-4 rounded-lg border bg-card p-4 transition-colors hover:bg-muted/50 cursor-pointer",
|
|
2475
2993
|
onClick: () => onParticipantClick?.(p.externalId),
|
|
2476
2994
|
children: [
|
|
2477
|
-
/* @__PURE__ */
|
|
2478
|
-
/* @__PURE__ */
|
|
2479
|
-
/* @__PURE__ */
|
|
2480
|
-
/* @__PURE__ */
|
|
2481
|
-
/* @__PURE__ */
|
|
2995
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex-1 min-w-0", children: [
|
|
2996
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2", children: [
|
|
2997
|
+
/* @__PURE__ */ jsx16("p", { className: "font-medium truncate", children: p.displayName }),
|
|
2998
|
+
/* @__PURE__ */ jsx16(Badge, { variant: "outline", className: "shrink-0 text-xs", children: p.participantType }),
|
|
2999
|
+
/* @__PURE__ */ jsx16(Badge, { variant: p.isGlobal ? "default" : "secondary", className: "shrink-0 text-xs", children: p.isGlobal ? config.labels.scopeGlobal : config.labels.scopeScoped })
|
|
2482
3000
|
] }),
|
|
2483
|
-
/* @__PURE__ */
|
|
3001
|
+
/* @__PURE__ */ jsx16("p", { className: "mt-1 text-xs text-muted-foreground", children: p.externalId })
|
|
2484
3002
|
] }),
|
|
2485
|
-
/* @__PURE__ */
|
|
2486
|
-
/* @__PURE__ */
|
|
3003
|
+
/* @__PURE__ */ jsxs11("div", { className: "text-right text-xs text-muted-foreground shrink-0 space-y-1", children: [
|
|
3004
|
+
/* @__PURE__ */ jsxs11("p", { children: [
|
|
2487
3005
|
formatNumber3(p.messageCount),
|
|
2488
3006
|
" messages"
|
|
2489
3007
|
] }),
|
|
2490
|
-
/* @__PURE__ */
|
|
3008
|
+
/* @__PURE__ */ jsxs11("p", { children: [
|
|
2491
3009
|
formatNumber3(p.threadCount),
|
|
2492
3010
|
" threads"
|
|
2493
3011
|
] }),
|
|
2494
|
-
/* @__PURE__ */
|
|
3012
|
+
/* @__PURE__ */ jsx16("p", { children: formatDate3(p.lastActivityAt) })
|
|
2495
3013
|
] })
|
|
2496
3014
|
]
|
|
2497
3015
|
},
|
|
@@ -2499,7 +3017,7 @@ var ParticipantsView = ({
|
|
|
2499
3017
|
)) })
|
|
2500
3018
|
] });
|
|
2501
3019
|
};
|
|
2502
|
-
function
|
|
3020
|
+
function formatDate3(value) {
|
|
2503
3021
|
if (!value) return "No activity";
|
|
2504
3022
|
const date = new Date(value);
|
|
2505
3023
|
if (Number.isNaN(date.getTime())) return value;
|
|
@@ -2512,7 +3030,7 @@ function formatNumber3(value) {
|
|
|
2512
3030
|
// src/components/views/ParticipantDetailView.tsx
|
|
2513
3031
|
import { useCallback as useCallback4, useEffect as useEffect6, useState as useState5 } from "react";
|
|
2514
3032
|
import { ArrowLeft as ArrowLeft2, Loader2 as Loader22, Save } from "lucide-react";
|
|
2515
|
-
import { jsx as
|
|
3033
|
+
import { jsx as jsx17, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2516
3034
|
var ParticipantDetailView = ({
|
|
2517
3035
|
participantId,
|
|
2518
3036
|
config,
|
|
@@ -2562,25 +3080,25 @@ var ParticipantDetailView = ({
|
|
|
2562
3080
|
}
|
|
2563
3081
|
};
|
|
2564
3082
|
if (isLoading) {
|
|
2565
|
-
return /* @__PURE__ */
|
|
3083
|
+
return /* @__PURE__ */ jsx17("div", { className: "flex items-center justify-center py-20", children: /* @__PURE__ */ jsx17(Loader22, { className: "h-6 w-6 animate-spin text-muted-foreground" }) });
|
|
2566
3084
|
}
|
|
2567
|
-
return /* @__PURE__ */
|
|
2568
|
-
/* @__PURE__ */
|
|
2569
|
-
/* @__PURE__ */
|
|
2570
|
-
/* @__PURE__ */
|
|
2571
|
-
/* @__PURE__ */
|
|
2572
|
-
/* @__PURE__ */
|
|
3085
|
+
return /* @__PURE__ */ jsxs12("div", { className: "space-y-6", children: [
|
|
3086
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-4", children: [
|
|
3087
|
+
/* @__PURE__ */ jsx17(Button, { variant: "ghost", size: "icon", onClick: onBack, children: /* @__PURE__ */ jsx17(ArrowLeft2, { className: "h-4 w-4" }) }),
|
|
3088
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex-1 min-w-0", children: [
|
|
3089
|
+
/* @__PURE__ */ jsx17("h2", { className: "text-xl font-semibold truncate", children: participantId }),
|
|
3090
|
+
/* @__PURE__ */ jsx17("p", { className: "text-sm text-muted-foreground", children: "Participant Detail" })
|
|
2573
3091
|
] }),
|
|
2574
|
-
/* @__PURE__ */
|
|
2575
|
-
saveMessage && /* @__PURE__ */
|
|
2576
|
-
/* @__PURE__ */
|
|
2577
|
-
isSaving ? /* @__PURE__ */
|
|
3092
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2", children: [
|
|
3093
|
+
saveMessage && /* @__PURE__ */ jsx17("span", { className: "text-xs text-emerald-600", children: saveMessage }),
|
|
3094
|
+
/* @__PURE__ */ jsxs12(Button, { size: "sm", onClick: () => void handleSave(), disabled: isSaving, children: [
|
|
3095
|
+
isSaving ? /* @__PURE__ */ jsx17(Loader22, { className: "mr-2 h-3 w-3 animate-spin" }) : /* @__PURE__ */ jsx17(Save, { className: "mr-2 h-3 w-3" }),
|
|
2578
3096
|
"Save"
|
|
2579
3097
|
] })
|
|
2580
3098
|
] })
|
|
2581
3099
|
] }),
|
|
2582
|
-
error && /* @__PURE__ */
|
|
2583
|
-
/* @__PURE__ */
|
|
3100
|
+
error && /* @__PURE__ */ jsx17("div", { className: "rounded-lg border border-destructive/50 bg-destructive/10 p-3 text-sm text-destructive", children: error }),
|
|
3101
|
+
/* @__PURE__ */ jsx17("div", { className: "rounded-lg border bg-card", children: /* @__PURE__ */ jsx17(
|
|
2584
3102
|
"textarea",
|
|
2585
3103
|
{
|
|
2586
3104
|
className: "w-full min-h-[400px] p-4 font-mono text-sm bg-transparent resize-y focus:outline-none",
|
|
@@ -2593,8 +3111,8 @@ var ParticipantDetailView = ({
|
|
|
2593
3111
|
};
|
|
2594
3112
|
|
|
2595
3113
|
// src/components/views/AgentsView.tsx
|
|
2596
|
-
import { Search as
|
|
2597
|
-
import { jsx as
|
|
3114
|
+
import { Search as Search4, Bot as Bot3 } from "lucide-react";
|
|
3115
|
+
import { jsx as jsx18, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
2598
3116
|
var AgentsView = ({
|
|
2599
3117
|
config,
|
|
2600
3118
|
agents,
|
|
@@ -2602,10 +3120,10 @@ var AgentsView = ({
|
|
|
2602
3120
|
onSearchChange,
|
|
2603
3121
|
onAgentClick
|
|
2604
3122
|
}) => {
|
|
2605
|
-
return /* @__PURE__ */
|
|
2606
|
-
/* @__PURE__ */
|
|
2607
|
-
/* @__PURE__ */
|
|
2608
|
-
/* @__PURE__ */
|
|
3123
|
+
return /* @__PURE__ */ jsxs13("div", { className: "space-y-4", children: [
|
|
3124
|
+
/* @__PURE__ */ jsxs13("div", { className: "relative max-w-sm", children: [
|
|
3125
|
+
/* @__PURE__ */ jsx18(Search4, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
|
|
3126
|
+
/* @__PURE__ */ jsx18(
|
|
2609
3127
|
Input,
|
|
2610
3128
|
{
|
|
2611
3129
|
className: "pl-9",
|
|
@@ -2615,48 +3133,48 @@ var AgentsView = ({
|
|
|
2615
3133
|
}
|
|
2616
3134
|
)
|
|
2617
3135
|
] }),
|
|
2618
|
-
agents.length === 0 ? /* @__PURE__ */
|
|
2619
|
-
/* @__PURE__ */
|
|
2620
|
-
/* @__PURE__ */
|
|
2621
|
-
] }) : /* @__PURE__ */
|
|
3136
|
+
agents.length === 0 ? /* @__PURE__ */ jsxs13("div", { className: "rounded-xl border border-dashed p-10 text-center", children: [
|
|
3137
|
+
/* @__PURE__ */ jsx18(Bot3, { className: "mx-auto h-8 w-8 text-muted-foreground/50" }),
|
|
3138
|
+
/* @__PURE__ */ jsx18("p", { className: "mt-3 text-sm text-muted-foreground", children: searchValue ? config.labels.noResults : config.labels.emptyDescription })
|
|
3139
|
+
] }) : /* @__PURE__ */ jsx18("div", { className: "grid gap-4 md:grid-cols-2 lg:grid-cols-3", children: agents.map((agent) => /* @__PURE__ */ jsxs13(
|
|
2622
3140
|
"div",
|
|
2623
3141
|
{
|
|
2624
3142
|
className: "rounded-lg border bg-card p-5 transition-colors hover:bg-muted/50 cursor-pointer",
|
|
2625
3143
|
onClick: () => onAgentClick?.(agent.agentId),
|
|
2626
3144
|
children: [
|
|
2627
|
-
/* @__PURE__ */
|
|
2628
|
-
/* @__PURE__ */
|
|
2629
|
-
/* @__PURE__ */
|
|
2630
|
-
/* @__PURE__ */
|
|
3145
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-start justify-between gap-3", children: [
|
|
3146
|
+
/* @__PURE__ */ jsxs13("div", { className: "min-w-0", children: [
|
|
3147
|
+
/* @__PURE__ */ jsx18("p", { className: "font-medium truncate", children: agent.displayName }),
|
|
3148
|
+
/* @__PURE__ */ jsx18("p", { className: "mt-1 truncate text-xs text-muted-foreground", children: agent.description ?? agent.agentId })
|
|
2631
3149
|
] }),
|
|
2632
|
-
/* @__PURE__ */
|
|
3150
|
+
/* @__PURE__ */ jsx18(Badge, { variant: "outline", className: "shrink-0", children: agent.isConfigured ? config.labels.configured : config.labels.unconfigured })
|
|
2633
3151
|
] }),
|
|
2634
|
-
/* @__PURE__ */
|
|
2635
|
-
/* @__PURE__ */
|
|
3152
|
+
/* @__PURE__ */ jsxs13("div", { className: "mt-4 grid grid-cols-2 gap-2 text-xs text-muted-foreground", children: [
|
|
3153
|
+
/* @__PURE__ */ jsxs13("span", { children: [
|
|
2636
3154
|
formatNumber4(agent.messageCount),
|
|
2637
3155
|
" messages"
|
|
2638
3156
|
] }),
|
|
2639
|
-
/* @__PURE__ */
|
|
3157
|
+
/* @__PURE__ */ jsxs13("span", { children: [
|
|
2640
3158
|
formatNumber4(agent.llmCallCount),
|
|
2641
3159
|
" LLM calls"
|
|
2642
3160
|
] }),
|
|
2643
|
-
/* @__PURE__ */
|
|
3161
|
+
/* @__PURE__ */ jsxs13("span", { children: [
|
|
2644
3162
|
formatNumber4(agent.toolCallMessageCount),
|
|
2645
3163
|
" tool calls"
|
|
2646
3164
|
] }),
|
|
2647
|
-
/* @__PURE__ */
|
|
3165
|
+
/* @__PURE__ */ jsxs13("span", { children: [
|
|
2648
3166
|
formatNumber4(agent.totalTokens),
|
|
2649
3167
|
" tokens"
|
|
2650
3168
|
] })
|
|
2651
3169
|
] }),
|
|
2652
|
-
/* @__PURE__ */
|
|
3170
|
+
/* @__PURE__ */ jsx18("p", { className: "mt-3 text-xs text-muted-foreground", children: formatDate4(agent.lastActivityAt) })
|
|
2653
3171
|
]
|
|
2654
3172
|
},
|
|
2655
3173
|
`${agent.namespace}:${agent.agentId}`
|
|
2656
3174
|
)) })
|
|
2657
3175
|
] });
|
|
2658
3176
|
};
|
|
2659
|
-
function
|
|
3177
|
+
function formatDate4(value) {
|
|
2660
3178
|
if (!value) return "No activity";
|
|
2661
3179
|
const date = new Date(value);
|
|
2662
3180
|
if (Number.isNaN(date.getTime())) return value;
|
|
@@ -2668,7 +3186,7 @@ function formatNumber4(value) {
|
|
|
2668
3186
|
|
|
2669
3187
|
// src/components/views/AgentDetailView.tsx
|
|
2670
3188
|
import { ArrowLeft as ArrowLeft3, Bot as Bot4 } from "lucide-react";
|
|
2671
|
-
import { jsx as
|
|
3189
|
+
import { jsx as jsx19, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
2672
3190
|
var AgentDetailView = ({
|
|
2673
3191
|
agentId,
|
|
2674
3192
|
config,
|
|
@@ -2677,13 +3195,13 @@ var AgentDetailView = ({
|
|
|
2677
3195
|
}) => {
|
|
2678
3196
|
const agent = agents.find((a) => a.agentId === agentId);
|
|
2679
3197
|
if (!agent) {
|
|
2680
|
-
return /* @__PURE__ */
|
|
2681
|
-
/* @__PURE__ */
|
|
3198
|
+
return /* @__PURE__ */ jsxs14("div", { className: "space-y-4 py-10 text-center", children: [
|
|
3199
|
+
/* @__PURE__ */ jsxs14("p", { className: "text-muted-foreground", children: [
|
|
2682
3200
|
"Agent not found: ",
|
|
2683
3201
|
agentId
|
|
2684
3202
|
] }),
|
|
2685
|
-
/* @__PURE__ */
|
|
2686
|
-
/* @__PURE__ */
|
|
3203
|
+
/* @__PURE__ */ jsxs14(Button, { variant: "outline", onClick: onBack, children: [
|
|
3204
|
+
/* @__PURE__ */ jsx19(ArrowLeft3, { className: "mr-2 h-4 w-4" }),
|
|
2687
3205
|
" Back"
|
|
2688
3206
|
] })
|
|
2689
3207
|
] });
|
|
@@ -2699,43 +3217,43 @@ var AgentDetailView = ({
|
|
|
2699
3217
|
{ label: "Cache Created", value: agent.cacheCreationInputTokens },
|
|
2700
3218
|
{ label: "Total Tokens", value: agent.totalTokens }
|
|
2701
3219
|
];
|
|
2702
|
-
return /* @__PURE__ */
|
|
2703
|
-
/* @__PURE__ */
|
|
2704
|
-
/* @__PURE__ */
|
|
2705
|
-
/* @__PURE__ */
|
|
2706
|
-
/* @__PURE__ */
|
|
2707
|
-
/* @__PURE__ */
|
|
2708
|
-
/* @__PURE__ */
|
|
2709
|
-
/* @__PURE__ */
|
|
2710
|
-
/* @__PURE__ */
|
|
2711
|
-
/* @__PURE__ */
|
|
3220
|
+
return /* @__PURE__ */ jsxs14("div", { className: "space-y-6", children: [
|
|
3221
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex items-start gap-4", children: [
|
|
3222
|
+
/* @__PURE__ */ jsx19(Button, { variant: "ghost", size: "icon", className: "mt-1 shrink-0", onClick: onBack, children: /* @__PURE__ */ jsx19(ArrowLeft3, { className: "h-4 w-4" }) }),
|
|
3223
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex-1 min-w-0", children: [
|
|
3224
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-3", children: [
|
|
3225
|
+
/* @__PURE__ */ jsx19("div", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary", children: /* @__PURE__ */ jsx19(Bot4, { className: "h-5 w-5" }) }),
|
|
3226
|
+
/* @__PURE__ */ jsxs14("div", { children: [
|
|
3227
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2", children: [
|
|
3228
|
+
/* @__PURE__ */ jsx19("h2", { className: "text-xl font-semibold", children: agent.displayName }),
|
|
3229
|
+
/* @__PURE__ */ jsx19(Badge, { variant: "outline", children: agent.isConfigured ? config.labels.configured : config.labels.unconfigured })
|
|
2712
3230
|
] }),
|
|
2713
|
-
agent.description && /* @__PURE__ */
|
|
3231
|
+
agent.description && /* @__PURE__ */ jsx19("p", { className: "text-sm text-muted-foreground", children: agent.description })
|
|
2714
3232
|
] })
|
|
2715
3233
|
] }),
|
|
2716
|
-
/* @__PURE__ */
|
|
2717
|
-
/* @__PURE__ */
|
|
3234
|
+
/* @__PURE__ */ jsxs14("div", { className: "mt-2 flex flex-wrap gap-4 text-xs text-muted-foreground", children: [
|
|
3235
|
+
/* @__PURE__ */ jsxs14("span", { children: [
|
|
2718
3236
|
"ID: ",
|
|
2719
3237
|
agent.agentId
|
|
2720
3238
|
] }),
|
|
2721
|
-
/* @__PURE__ */
|
|
3239
|
+
/* @__PURE__ */ jsxs14("span", { children: [
|
|
2722
3240
|
"Namespace: ",
|
|
2723
3241
|
agent.namespace
|
|
2724
3242
|
] }),
|
|
2725
|
-
agent.lastActivityAt && /* @__PURE__ */
|
|
3243
|
+
agent.lastActivityAt && /* @__PURE__ */ jsxs14("span", { children: [
|
|
2726
3244
|
"Last active: ",
|
|
2727
|
-
|
|
3245
|
+
formatDate5(agent.lastActivityAt)
|
|
2728
3246
|
] })
|
|
2729
3247
|
] })
|
|
2730
3248
|
] })
|
|
2731
3249
|
] }),
|
|
2732
|
-
/* @__PURE__ */
|
|
2733
|
-
/* @__PURE__ */
|
|
2734
|
-
/* @__PURE__ */
|
|
3250
|
+
/* @__PURE__ */ jsx19("div", { className: "grid gap-4 sm:grid-cols-3 lg:grid-cols-3", children: stats.map((stat) => /* @__PURE__ */ jsxs14("div", { className: "rounded-xl border bg-card p-5 shadow-sm", children: [
|
|
3251
|
+
/* @__PURE__ */ jsx19("p", { className: "text-sm font-medium text-muted-foreground", children: stat.label }),
|
|
3252
|
+
/* @__PURE__ */ jsx19("p", { className: "mt-2 text-2xl font-semibold tracking-tight", children: new Intl.NumberFormat().format(stat.value) })
|
|
2735
3253
|
] }, stat.label)) })
|
|
2736
3254
|
] });
|
|
2737
3255
|
};
|
|
2738
|
-
function
|
|
3256
|
+
function formatDate5(value) {
|
|
2739
3257
|
const date = new Date(value);
|
|
2740
3258
|
if (Number.isNaN(date.getTime())) return value;
|
|
2741
3259
|
return date.toLocaleString(void 0, { month: "short", day: "numeric", hour: "numeric", minute: "2-digit" });
|
|
@@ -2743,8 +3261,8 @@ function formatDate6(value) {
|
|
|
2743
3261
|
|
|
2744
3262
|
// src/components/views/CollectionItemsView.tsx
|
|
2745
3263
|
import { useCallback as useCallback5, useEffect as useEffect7, useState as useState6 } from "react";
|
|
2746
|
-
import { Loader2 as Loader23, Plus, Search as
|
|
2747
|
-
import { jsx as
|
|
3264
|
+
import { Loader2 as Loader23, Plus, Search as Search5, Database as Database3 } from "lucide-react";
|
|
3265
|
+
import { jsx as jsx20, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
2748
3266
|
var CollectionItemsView = ({
|
|
2749
3267
|
collection,
|
|
2750
3268
|
config,
|
|
@@ -2790,17 +3308,17 @@ var CollectionItemsView = ({
|
|
|
2790
3308
|
if (keys.length === 0) return "(empty)";
|
|
2791
3309
|
return keys.slice(0, 3).map((k) => `${k}: ${JSON.stringify(rest[k])?.slice(0, 30)}`).join(", ");
|
|
2792
3310
|
};
|
|
2793
|
-
return /* @__PURE__ */
|
|
2794
|
-
/* @__PURE__ */
|
|
2795
|
-
/* @__PURE__ */
|
|
2796
|
-
onCreateNew && /* @__PURE__ */
|
|
2797
|
-
/* @__PURE__ */
|
|
3311
|
+
return /* @__PURE__ */ jsxs15("div", { className: "space-y-4", children: [
|
|
3312
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between gap-4", children: [
|
|
3313
|
+
/* @__PURE__ */ jsx20("h2", { className: "text-lg font-semibold capitalize", children: collection }),
|
|
3314
|
+
onCreateNew && /* @__PURE__ */ jsxs15(Button, { size: "sm", onClick: onCreateNew, children: [
|
|
3315
|
+
/* @__PURE__ */ jsx20(Plus, { className: "mr-2 h-3 w-3" }),
|
|
2798
3316
|
" New"
|
|
2799
3317
|
] })
|
|
2800
3318
|
] }),
|
|
2801
|
-
/* @__PURE__ */
|
|
2802
|
-
/* @__PURE__ */
|
|
2803
|
-
/* @__PURE__ */
|
|
3319
|
+
/* @__PURE__ */ jsxs15("div", { className: "relative max-w-sm", children: [
|
|
3320
|
+
/* @__PURE__ */ jsx20(Search5, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
|
|
3321
|
+
/* @__PURE__ */ jsx20(
|
|
2804
3322
|
Input,
|
|
2805
3323
|
{
|
|
2806
3324
|
className: "pl-9",
|
|
@@ -2810,20 +3328,20 @@ var CollectionItemsView = ({
|
|
|
2810
3328
|
}
|
|
2811
3329
|
)
|
|
2812
3330
|
] }),
|
|
2813
|
-
error && /* @__PURE__ */
|
|
2814
|
-
isLoading ? /* @__PURE__ */
|
|
2815
|
-
/* @__PURE__ */
|
|
2816
|
-
/* @__PURE__ */
|
|
2817
|
-
] }) : /* @__PURE__ */
|
|
3331
|
+
error && /* @__PURE__ */ jsx20("div", { className: "rounded-lg border border-destructive/50 bg-destructive/10 p-3 text-sm text-destructive", children: error }),
|
|
3332
|
+
isLoading ? /* @__PURE__ */ jsx20("div", { className: "flex items-center justify-center py-20", children: /* @__PURE__ */ jsx20(Loader23, { className: "h-6 w-6 animate-spin text-muted-foreground" }) }) : items.length === 0 ? /* @__PURE__ */ jsxs15("div", { className: "rounded-xl border border-dashed p-10 text-center", children: [
|
|
3333
|
+
/* @__PURE__ */ jsx20(Database3, { className: "mx-auto h-8 w-8 text-muted-foreground/50" }),
|
|
3334
|
+
/* @__PURE__ */ jsx20("p", { className: "mt-3 text-sm text-muted-foreground", children: search ? config.labels.noResults : `No items in ${collection}` })
|
|
3335
|
+
] }) : /* @__PURE__ */ jsx20("div", { className: "space-y-2", children: items.map((item, idx) => {
|
|
2818
3336
|
const itemId = getItemId(item);
|
|
2819
|
-
return /* @__PURE__ */
|
|
3337
|
+
return /* @__PURE__ */ jsx20(
|
|
2820
3338
|
"div",
|
|
2821
3339
|
{
|
|
2822
3340
|
className: "flex items-center gap-4 rounded-lg border bg-card p-4 transition-colors hover:bg-muted/50 cursor-pointer",
|
|
2823
3341
|
onClick: () => onItemClick?.(itemId),
|
|
2824
|
-
children: /* @__PURE__ */
|
|
2825
|
-
/* @__PURE__ */
|
|
2826
|
-
/* @__PURE__ */
|
|
3342
|
+
children: /* @__PURE__ */ jsxs15("div", { className: "flex-1 min-w-0", children: [
|
|
3343
|
+
/* @__PURE__ */ jsx20("p", { className: "font-medium font-mono text-sm truncate", children: itemId }),
|
|
3344
|
+
/* @__PURE__ */ jsx20("p", { className: "mt-1 text-xs text-muted-foreground truncate", children: getItemPreview(item) })
|
|
2827
3345
|
] })
|
|
2828
3346
|
},
|
|
2829
3347
|
itemId + idx
|
|
@@ -2835,7 +3353,7 @@ var CollectionItemsView = ({
|
|
|
2835
3353
|
// src/components/views/CollectionItemDetailView.tsx
|
|
2836
3354
|
import { useCallback as useCallback6, useEffect as useEffect8, useState as useState7 } from "react";
|
|
2837
3355
|
import { ArrowLeft as ArrowLeft5, Loader2 as Loader24, Save as Save2, Trash2 } from "lucide-react";
|
|
2838
|
-
import { jsx as
|
|
3356
|
+
import { jsx as jsx21, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
2839
3357
|
var CollectionItemDetailView = ({
|
|
2840
3358
|
collection,
|
|
2841
3359
|
itemId,
|
|
@@ -2909,15 +3427,15 @@ var CollectionItemDetailView = ({
|
|
|
2909
3427
|
}
|
|
2910
3428
|
};
|
|
2911
3429
|
if (isLoading) {
|
|
2912
|
-
return /* @__PURE__ */
|
|
3430
|
+
return /* @__PURE__ */ jsx21("div", { className: "flex items-center justify-center py-20", children: /* @__PURE__ */ jsx21(Loader24, { className: "h-6 w-6 animate-spin text-muted-foreground" }) });
|
|
2913
3431
|
}
|
|
2914
|
-
return /* @__PURE__ */
|
|
2915
|
-
/* @__PURE__ */
|
|
2916
|
-
/* @__PURE__ */
|
|
2917
|
-
/* @__PURE__ */
|
|
2918
|
-
/* @__PURE__ */
|
|
2919
|
-
saveMessage && /* @__PURE__ */
|
|
2920
|
-
!isNew && /* @__PURE__ */
|
|
3432
|
+
return /* @__PURE__ */ jsxs16("div", { className: "space-y-6", children: [
|
|
3433
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-4", children: [
|
|
3434
|
+
/* @__PURE__ */ jsx21(Button, { variant: "ghost", size: "icon", onClick: onBack, children: /* @__PURE__ */ jsx21(ArrowLeft5, { className: "h-4 w-4" }) }),
|
|
3435
|
+
/* @__PURE__ */ jsx21("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsx21("h2", { className: "text-xl font-semibold truncate capitalize", children: isNew ? `New ${collection} item` : `${collection} / ${itemId}` }) }),
|
|
3436
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-2", children: [
|
|
3437
|
+
saveMessage && /* @__PURE__ */ jsx21("span", { className: "text-xs text-emerald-600", children: saveMessage }),
|
|
3438
|
+
!isNew && /* @__PURE__ */ jsxs16(
|
|
2921
3439
|
Button,
|
|
2922
3440
|
{
|
|
2923
3441
|
variant: "destructive",
|
|
@@ -2925,19 +3443,19 @@ var CollectionItemDetailView = ({
|
|
|
2925
3443
|
onClick: () => void handleDelete(),
|
|
2926
3444
|
disabled: isDeleting,
|
|
2927
3445
|
children: [
|
|
2928
|
-
isDeleting ? /* @__PURE__ */
|
|
3446
|
+
isDeleting ? /* @__PURE__ */ jsx21(Loader24, { className: "mr-2 h-3 w-3 animate-spin" }) : /* @__PURE__ */ jsx21(Trash2, { className: "mr-2 h-3 w-3" }),
|
|
2929
3447
|
"Delete"
|
|
2930
3448
|
]
|
|
2931
3449
|
}
|
|
2932
3450
|
),
|
|
2933
|
-
/* @__PURE__ */
|
|
2934
|
-
isSaving ? /* @__PURE__ */
|
|
3451
|
+
/* @__PURE__ */ jsxs16(Button, { size: "sm", onClick: () => void handleSave(), disabled: isSaving, children: [
|
|
3452
|
+
isSaving ? /* @__PURE__ */ jsx21(Loader24, { className: "mr-2 h-3 w-3 animate-spin" }) : /* @__PURE__ */ jsx21(Save2, { className: "mr-2 h-3 w-3" }),
|
|
2935
3453
|
isNew ? "Create" : "Save"
|
|
2936
3454
|
] })
|
|
2937
3455
|
] })
|
|
2938
3456
|
] }),
|
|
2939
|
-
error && /* @__PURE__ */
|
|
2940
|
-
/* @__PURE__ */
|
|
3457
|
+
error && /* @__PURE__ */ jsx21("div", { className: "rounded-lg border border-destructive/50 bg-destructive/10 p-3 text-sm text-destructive", children: error }),
|
|
3458
|
+
/* @__PURE__ */ jsx21("div", { className: "rounded-lg border bg-card", children: /* @__PURE__ */ jsx21(
|
|
2941
3459
|
"textarea",
|
|
2942
3460
|
{
|
|
2943
3461
|
className: "w-full min-h-[400px] p-4 font-mono text-sm bg-transparent resize-y focus:outline-none",
|
|
@@ -2951,8 +3469,8 @@ var CollectionItemDetailView = ({
|
|
|
2951
3469
|
|
|
2952
3470
|
// src/components/views/EventsView.tsx
|
|
2953
3471
|
import { useCallback as useCallback7, useState as useState8 } from "react";
|
|
2954
|
-
import { Activity as
|
|
2955
|
-
import { jsx as
|
|
3472
|
+
import { Activity as Activity3, Loader2 as Loader25, Search as Search6 } from "lucide-react";
|
|
3473
|
+
import { jsx as jsx22, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
2956
3474
|
var STATUS_VARIANTS = {
|
|
2957
3475
|
pending: "outline",
|
|
2958
3476
|
processing: "default",
|
|
@@ -2985,13 +3503,13 @@ var EventsView = ({ config }) => {
|
|
|
2985
3503
|
setIsLoading(false);
|
|
2986
3504
|
}
|
|
2987
3505
|
}, [threadId, config.baseUrl, config.getRequestHeaders]);
|
|
2988
|
-
return /* @__PURE__ */
|
|
2989
|
-
/* @__PURE__ */
|
|
2990
|
-
/* @__PURE__ */
|
|
2991
|
-
/* @__PURE__ */
|
|
2992
|
-
/* @__PURE__ */
|
|
2993
|
-
/* @__PURE__ */
|
|
2994
|
-
/* @__PURE__ */
|
|
3506
|
+
return /* @__PURE__ */ jsxs17("div", { className: "space-y-6", children: [
|
|
3507
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex items-end gap-3 max-w-lg", children: [
|
|
3508
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex-1", children: [
|
|
3509
|
+
/* @__PURE__ */ jsx22("label", { className: "text-sm font-medium mb-1 block", children: "Thread ID" }),
|
|
3510
|
+
/* @__PURE__ */ jsxs17("div", { className: "relative", children: [
|
|
3511
|
+
/* @__PURE__ */ jsx22(Search6, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
|
|
3512
|
+
/* @__PURE__ */ jsx22(
|
|
2995
3513
|
Input,
|
|
2996
3514
|
{
|
|
2997
3515
|
className: "pl-9",
|
|
@@ -3003,55 +3521,55 @@ var EventsView = ({ config }) => {
|
|
|
3003
3521
|
)
|
|
3004
3522
|
] })
|
|
3005
3523
|
] }),
|
|
3006
|
-
/* @__PURE__ */
|
|
3007
|
-
isLoading ? /* @__PURE__ */
|
|
3524
|
+
/* @__PURE__ */ jsxs17(Button, { onClick: () => void handleSearch(), disabled: isLoading || !threadId.trim(), children: [
|
|
3525
|
+
isLoading ? /* @__PURE__ */ jsx22(Loader25, { className: "mr-2 h-4 w-4 animate-spin" }) : null,
|
|
3008
3526
|
"Inspect"
|
|
3009
3527
|
] })
|
|
3010
3528
|
] }),
|
|
3011
|
-
error && /* @__PURE__ */
|
|
3012
|
-
!hasSearched ? /* @__PURE__ */
|
|
3013
|
-
/* @__PURE__ */
|
|
3014
|
-
/* @__PURE__ */
|
|
3015
|
-
] }) : isLoading ? /* @__PURE__ */
|
|
3016
|
-
/* @__PURE__ */
|
|
3017
|
-
/* @__PURE__ */
|
|
3018
|
-
] }) : /* @__PURE__ */
|
|
3019
|
-
/* @__PURE__ */
|
|
3020
|
-
/* @__PURE__ */
|
|
3021
|
-
/* @__PURE__ */
|
|
3022
|
-
/* @__PURE__ */
|
|
3529
|
+
error && /* @__PURE__ */ jsx22("div", { className: "rounded-lg border border-destructive/50 bg-destructive/10 p-3 text-sm text-destructive", children: error }),
|
|
3530
|
+
!hasSearched ? /* @__PURE__ */ jsxs17("div", { className: "rounded-xl border border-dashed p-10 text-center", children: [
|
|
3531
|
+
/* @__PURE__ */ jsx22(Activity3, { className: "mx-auto h-8 w-8 text-muted-foreground/50" }),
|
|
3532
|
+
/* @__PURE__ */ jsx22("p", { className: "mt-3 text-sm text-muted-foreground", children: "Enter a thread ID to inspect its next pending queue event." })
|
|
3533
|
+
] }) : isLoading ? /* @__PURE__ */ jsx22("div", { className: "flex items-center justify-center py-20", children: /* @__PURE__ */ jsx22(Loader25, { className: "h-6 w-6 animate-spin text-muted-foreground" }) }) : !event ? /* @__PURE__ */ jsxs17("div", { className: "rounded-xl border border-dashed p-10 text-center", children: [
|
|
3534
|
+
/* @__PURE__ */ jsx22(Activity3, { className: "mx-auto h-8 w-8 text-muted-foreground/50" }),
|
|
3535
|
+
/* @__PURE__ */ jsx22("p", { className: "mt-3 text-sm text-muted-foreground", children: "No pending events found for this thread." })
|
|
3536
|
+
] }) : /* @__PURE__ */ jsxs17("div", { className: "rounded-lg border bg-card p-5 space-y-4", children: [
|
|
3537
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex items-start justify-between gap-3", children: [
|
|
3538
|
+
/* @__PURE__ */ jsxs17("div", { children: [
|
|
3539
|
+
/* @__PURE__ */ jsx22("p", { className: "font-medium", children: event.eventType }),
|
|
3540
|
+
/* @__PURE__ */ jsx22("p", { className: "text-xs text-muted-foreground font-mono mt-1", children: event.id })
|
|
3023
3541
|
] }),
|
|
3024
|
-
/* @__PURE__ */
|
|
3542
|
+
/* @__PURE__ */ jsx22(Badge, { variant: STATUS_VARIANTS[event.status] ?? "outline", children: event.status })
|
|
3025
3543
|
] }),
|
|
3026
|
-
/* @__PURE__ */
|
|
3027
|
-
event.traceId && /* @__PURE__ */
|
|
3028
|
-
/* @__PURE__ */
|
|
3544
|
+
/* @__PURE__ */ jsxs17("div", { className: "grid gap-3 sm:grid-cols-2 text-sm", children: [
|
|
3545
|
+
event.traceId && /* @__PURE__ */ jsxs17("div", { children: [
|
|
3546
|
+
/* @__PURE__ */ jsx22("span", { className: "text-muted-foreground", children: "Trace:" }),
|
|
3029
3547
|
" ",
|
|
3030
|
-
/* @__PURE__ */
|
|
3548
|
+
/* @__PURE__ */ jsx22("span", { className: "font-mono text-xs", children: event.traceId })
|
|
3031
3549
|
] }),
|
|
3032
|
-
event.parentEventId && /* @__PURE__ */
|
|
3033
|
-
/* @__PURE__ */
|
|
3550
|
+
event.parentEventId && /* @__PURE__ */ jsxs17("div", { children: [
|
|
3551
|
+
/* @__PURE__ */ jsx22("span", { className: "text-muted-foreground", children: "Parent:" }),
|
|
3034
3552
|
" ",
|
|
3035
|
-
/* @__PURE__ */
|
|
3553
|
+
/* @__PURE__ */ jsx22("span", { className: "font-mono text-xs", children: event.parentEventId })
|
|
3036
3554
|
] }),
|
|
3037
|
-
event.priority != null && /* @__PURE__ */
|
|
3038
|
-
/* @__PURE__ */
|
|
3555
|
+
event.priority != null && /* @__PURE__ */ jsxs17("div", { children: [
|
|
3556
|
+
/* @__PURE__ */ jsx22("span", { className: "text-muted-foreground", children: "Priority:" }),
|
|
3039
3557
|
" ",
|
|
3040
3558
|
event.priority
|
|
3041
3559
|
] }),
|
|
3042
|
-
event.createdAt && /* @__PURE__ */
|
|
3043
|
-
/* @__PURE__ */
|
|
3560
|
+
event.createdAt && /* @__PURE__ */ jsxs17("div", { children: [
|
|
3561
|
+
/* @__PURE__ */ jsx22("span", { className: "text-muted-foreground", children: "Created:" }),
|
|
3044
3562
|
" ",
|
|
3045
3563
|
formatTimestamp2(event.createdAt)
|
|
3046
3564
|
] })
|
|
3047
3565
|
] }),
|
|
3048
|
-
event.payload != null && /* @__PURE__ */
|
|
3049
|
-
/* @__PURE__ */
|
|
3050
|
-
/* @__PURE__ */
|
|
3566
|
+
event.payload != null && /* @__PURE__ */ jsxs17("div", { children: [
|
|
3567
|
+
/* @__PURE__ */ jsx22("p", { className: "text-xs font-medium text-muted-foreground mb-1", children: "Payload" }),
|
|
3568
|
+
/* @__PURE__ */ jsx22("pre", { className: "rounded-md bg-muted p-3 text-xs overflow-auto max-h-60", children: JSON.stringify(event.payload, null, 2) })
|
|
3051
3569
|
] }),
|
|
3052
|
-
event.metadata != null && Object.keys(event.metadata).length > 0 && /* @__PURE__ */
|
|
3053
|
-
/* @__PURE__ */
|
|
3054
|
-
/* @__PURE__ */
|
|
3570
|
+
event.metadata != null && Object.keys(event.metadata).length > 0 && /* @__PURE__ */ jsxs17("div", { children: [
|
|
3571
|
+
/* @__PURE__ */ jsx22("p", { className: "text-xs font-medium text-muted-foreground mb-1", children: "Metadata" }),
|
|
3572
|
+
/* @__PURE__ */ jsx22("pre", { className: "rounded-md bg-muted p-3 text-xs overflow-auto max-h-40", children: JSON.stringify(event.metadata, null, 2) })
|
|
3055
3573
|
] })
|
|
3056
3574
|
] })
|
|
3057
3575
|
] });
|
|
@@ -3069,7 +3587,7 @@ function formatTimestamp2(value) {
|
|
|
3069
3587
|
}
|
|
3070
3588
|
|
|
3071
3589
|
// src/CopilotzAdmin.tsx
|
|
3072
|
-
import { jsx as
|
|
3590
|
+
import { jsx as jsx23, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
3073
3591
|
var CopilotzAdmin = ({
|
|
3074
3592
|
config: userConfig,
|
|
3075
3593
|
className
|
|
@@ -3161,18 +3679,18 @@ var CopilotzAdmin = ({
|
|
|
3161
3679
|
}
|
|
3162
3680
|
})();
|
|
3163
3681
|
if (admin.isLoading && !admin.overview) {
|
|
3164
|
-
return /* @__PURE__ */
|
|
3682
|
+
return /* @__PURE__ */ jsx23(Card, { className: cn("border-border", className), children: /* @__PURE__ */ jsx23(CardContent, { className: "text-muted-foreground flex items-center justify-center min-h-[200px]", children: config.labels.loading }) });
|
|
3165
3683
|
}
|
|
3166
3684
|
if (admin.error && !admin.overview) {
|
|
3167
|
-
return /* @__PURE__ */
|
|
3168
|
-
/* @__PURE__ */
|
|
3169
|
-
/* @__PURE__ */
|
|
3685
|
+
return /* @__PURE__ */ jsx23(Card, { className: cn("border-destructive/50 bg-destructive/10", className), children: /* @__PURE__ */ jsxs18(CardContent, { className: "space-y-4", children: [
|
|
3686
|
+
/* @__PURE__ */ jsx23("p", { className: "text-base font-semibold text-destructive", children: admin.error.message }),
|
|
3687
|
+
/* @__PURE__ */ jsx23(Button, { variant: "destructive", onClick: () => void admin.refresh(), children: config.labels.retry })
|
|
3170
3688
|
] }) });
|
|
3171
3689
|
}
|
|
3172
3690
|
const renderCurrentView = () => {
|
|
3173
3691
|
switch (route.page) {
|
|
3174
3692
|
case "dashboard":
|
|
3175
|
-
return /* @__PURE__ */
|
|
3693
|
+
return /* @__PURE__ */ jsx23(
|
|
3176
3694
|
DashboardView,
|
|
3177
3695
|
{
|
|
3178
3696
|
config,
|
|
@@ -3182,6 +3700,7 @@ var CopilotzAdmin = ({
|
|
|
3182
3700
|
participants: admin.participants,
|
|
3183
3701
|
agents: admin.agents,
|
|
3184
3702
|
interval: admin.filters.interval,
|
|
3703
|
+
namespace,
|
|
3185
3704
|
threadSearch,
|
|
3186
3705
|
participantSearch,
|
|
3187
3706
|
agentSearch,
|
|
@@ -3192,7 +3711,7 @@ var CopilotzAdmin = ({
|
|
|
3192
3711
|
}
|
|
3193
3712
|
);
|
|
3194
3713
|
case "threads":
|
|
3195
|
-
return /* @__PURE__ */
|
|
3714
|
+
return /* @__PURE__ */ jsx23(
|
|
3196
3715
|
ThreadsView,
|
|
3197
3716
|
{
|
|
3198
3717
|
config,
|
|
@@ -3203,9 +3722,9 @@ var CopilotzAdmin = ({
|
|
|
3203
3722
|
}
|
|
3204
3723
|
);
|
|
3205
3724
|
case "thread-detail":
|
|
3206
|
-
return route.resourceId ? /* @__PURE__ */
|
|
3725
|
+
return route.resourceId ? /* @__PURE__ */ jsx23(ThreadDetailView, { threadId: route.resourceId, config, onBack: handleBackToThreads }) : null;
|
|
3207
3726
|
case "participants":
|
|
3208
|
-
return /* @__PURE__ */
|
|
3727
|
+
return /* @__PURE__ */ jsx23(
|
|
3209
3728
|
ParticipantsView,
|
|
3210
3729
|
{
|
|
3211
3730
|
config,
|
|
@@ -3216,9 +3735,9 @@ var CopilotzAdmin = ({
|
|
|
3216
3735
|
}
|
|
3217
3736
|
);
|
|
3218
3737
|
case "participant-detail":
|
|
3219
|
-
return route.resourceId ? /* @__PURE__ */
|
|
3738
|
+
return route.resourceId ? /* @__PURE__ */ jsx23(ParticipantDetailView, { participantId: route.resourceId, config, onBack: handleBackToParticipants }) : null;
|
|
3220
3739
|
case "agents":
|
|
3221
|
-
return /* @__PURE__ */
|
|
3740
|
+
return /* @__PURE__ */ jsx23(
|
|
3222
3741
|
AgentsView,
|
|
3223
3742
|
{
|
|
3224
3743
|
config,
|
|
@@ -3229,9 +3748,9 @@ var CopilotzAdmin = ({
|
|
|
3229
3748
|
}
|
|
3230
3749
|
);
|
|
3231
3750
|
case "agent-detail":
|
|
3232
|
-
return route.resourceId ? /* @__PURE__ */
|
|
3751
|
+
return route.resourceId ? /* @__PURE__ */ jsx23(AgentDetailView, { agentId: route.resourceId, config, agents: admin.agents, onBack: handleBackToAgents }) : null;
|
|
3233
3752
|
case "collection-items":
|
|
3234
|
-
return route.collection ? /* @__PURE__ */
|
|
3753
|
+
return route.collection ? /* @__PURE__ */ jsx23(
|
|
3235
3754
|
CollectionItemsView,
|
|
3236
3755
|
{
|
|
3237
3756
|
collection: route.collection,
|
|
@@ -3242,7 +3761,7 @@ var CopilotzAdmin = ({
|
|
|
3242
3761
|
}
|
|
3243
3762
|
) : null;
|
|
3244
3763
|
case "collection-item-detail":
|
|
3245
|
-
return route.collection ? /* @__PURE__ */
|
|
3764
|
+
return route.collection ? /* @__PURE__ */ jsx23(
|
|
3246
3765
|
CollectionItemDetailView,
|
|
3247
3766
|
{
|
|
3248
3767
|
collection: route.collection,
|
|
@@ -3253,12 +3772,12 @@ var CopilotzAdmin = ({
|
|
|
3253
3772
|
}
|
|
3254
3773
|
) : null;
|
|
3255
3774
|
case "events":
|
|
3256
|
-
return /* @__PURE__ */
|
|
3775
|
+
return /* @__PURE__ */ jsx23(EventsView, { config });
|
|
3257
3776
|
default:
|
|
3258
3777
|
return null;
|
|
3259
3778
|
}
|
|
3260
3779
|
};
|
|
3261
|
-
return /* @__PURE__ */
|
|
3780
|
+
return /* @__PURE__ */ jsx23(TooltipProvider, { children: /* @__PURE__ */ jsx23(SidebarProvider, { defaultOpen: config.sidebar.defaultOpen, children: /* @__PURE__ */ jsxs18(
|
|
3262
3781
|
"div",
|
|
3263
3782
|
{
|
|
3264
3783
|
className: cn(
|
|
@@ -3266,7 +3785,7 @@ var CopilotzAdmin = ({
|
|
|
3266
3785
|
className
|
|
3267
3786
|
),
|
|
3268
3787
|
children: [
|
|
3269
|
-
/* @__PURE__ */
|
|
3788
|
+
/* @__PURE__ */ jsx23(
|
|
3270
3789
|
AdminSidebar,
|
|
3271
3790
|
{
|
|
3272
3791
|
config,
|
|
@@ -3279,8 +3798,8 @@ var CopilotzAdmin = ({
|
|
|
3279
3798
|
onNamespaceChange: setNamespace
|
|
3280
3799
|
}
|
|
3281
3800
|
),
|
|
3282
|
-
/* @__PURE__ */
|
|
3283
|
-
/* @__PURE__ */
|
|
3801
|
+
/* @__PURE__ */ jsx23(SidebarInset, { children: /* @__PURE__ */ jsxs18("div", { className: "flex flex-col h-full min-h-0", children: [
|
|
3802
|
+
/* @__PURE__ */ jsx23(
|
|
3284
3803
|
AdminHeader,
|
|
3285
3804
|
{
|
|
3286
3805
|
config,
|
|
@@ -3293,7 +3812,7 @@ var CopilotzAdmin = ({
|
|
|
3293
3812
|
isLoading: admin.isLoading
|
|
3294
3813
|
}
|
|
3295
3814
|
),
|
|
3296
|
-
/* @__PURE__ */
|
|
3815
|
+
/* @__PURE__ */ jsx23("div", { className: "flex-1 overflow-auto p-6", children: renderCurrentView() })
|
|
3297
3816
|
] }) })
|
|
3298
3817
|
]
|
|
3299
3818
|
}
|
|
@@ -3309,6 +3828,7 @@ export {
|
|
|
3309
3828
|
fetchAdminOverview,
|
|
3310
3829
|
fetchAdminParticipants,
|
|
3311
3830
|
fetchAdminThreads,
|
|
3831
|
+
fetchAdminUsage,
|
|
3312
3832
|
fetchCollectionItem,
|
|
3313
3833
|
fetchCollectionItems,
|
|
3314
3834
|
fetchCollectionNames,
|