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