@copilotz/admin 0.9.25 → 0.9.28
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 +1230 -1044
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +1262 -1060
- package/dist/index.js.map +1 -1
- package/dist/styles.css +190 -62
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -263,6 +263,7 @@ async function fetchAdminUsage(filters, options) {
|
|
|
263
263
|
interval: filters.interval,
|
|
264
264
|
metric: filters.metric,
|
|
265
265
|
groupBy: filters.groupBy,
|
|
266
|
+
attribution: filters.attribution,
|
|
266
267
|
threadId: filters.threadId,
|
|
267
268
|
participantId: filters.participantId,
|
|
268
269
|
participantType: filters.participantType,
|
|
@@ -535,6 +536,16 @@ function CardHeader({ className, ...props }) {
|
|
|
535
536
|
}
|
|
536
537
|
);
|
|
537
538
|
}
|
|
539
|
+
function CardTitle({ className, ...props }) {
|
|
540
|
+
return /* @__PURE__ */ jsx(
|
|
541
|
+
"div",
|
|
542
|
+
{
|
|
543
|
+
"data-slot": "card-title",
|
|
544
|
+
className: cn("leading-none font-semibold", className),
|
|
545
|
+
...props
|
|
546
|
+
}
|
|
547
|
+
);
|
|
548
|
+
}
|
|
538
549
|
function CardContent({ className, ...props }) {
|
|
539
550
|
return /* @__PURE__ */ jsx(
|
|
540
551
|
"div",
|
|
@@ -1420,7 +1431,7 @@ var AdminSidebar = ({
|
|
|
1420
1431
|
|
|
1421
1432
|
// src/components/layout/AdminHeader.tsx
|
|
1422
1433
|
import { RefreshCw } from "lucide-react";
|
|
1423
|
-
import {
|
|
1434
|
+
import { jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1424
1435
|
var PAGE_TITLES = {
|
|
1425
1436
|
dashboard: "Dashboard",
|
|
1426
1437
|
threads: "Threads",
|
|
@@ -1436,73 +1447,24 @@ var PAGE_TITLES = {
|
|
|
1436
1447
|
var AdminHeader = ({
|
|
1437
1448
|
config,
|
|
1438
1449
|
currentRoute,
|
|
1439
|
-
range,
|
|
1440
|
-
interval,
|
|
1441
|
-
onRangeChange,
|
|
1442
|
-
onIntervalChange,
|
|
1443
1450
|
onRefresh,
|
|
1444
|
-
isLoading
|
|
1451
|
+
isLoading,
|
|
1452
|
+
controls
|
|
1445
1453
|
}) => {
|
|
1446
1454
|
let pageTitle = config.labels[`${currentRoute.page}Title`] || PAGE_TITLES[currentRoute.page] || currentRoute.page;
|
|
1447
1455
|
if (currentRoute.page === "collection-items" && currentRoute.collection) {
|
|
1448
1456
|
pageTitle = currentRoute.collection.charAt(0).toUpperCase() + currentRoute.collection.slice(1);
|
|
1449
1457
|
}
|
|
1450
|
-
return /* @__PURE__ */ jsx10(Card, { className: "py-0 border-b rounded-none relative z-10 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/80", children: /* @__PURE__ */ jsx10(CardHeader, { className: "
|
|
1451
|
-
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-1", children: [
|
|
1458
|
+
return /* @__PURE__ */ jsx10(Card, { className: "py-0 border-b rounded-none relative z-10 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/80 shadow-none", children: /* @__PURE__ */ jsx10(CardHeader, { className: "px-3 py-2", children: /* @__PURE__ */ jsxs6("div", { className: "flex min-h-10 flex-wrap items-center gap-2", children: [
|
|
1459
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex min-w-0 items-center gap-1", children: [
|
|
1452
1460
|
/* @__PURE__ */ jsxs6(Tooltip, { children: [
|
|
1453
1461
|
/* @__PURE__ */ jsx10(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx10(SidebarTrigger, { className: "-ml-1" }) }),
|
|
1454
1462
|
/* @__PURE__ */ jsx10(TooltipContent, { children: "Toggle Sidebar" })
|
|
1455
1463
|
] }),
|
|
1456
|
-
/* @__PURE__ */ jsx10("h1", { className: "text-sm font-medium
|
|
1464
|
+
/* @__PURE__ */ jsx10("h1", { className: "ml-2 whitespace-nowrap text-sm font-medium", children: pageTitle })
|
|
1457
1465
|
] }),
|
|
1458
|
-
/* @__PURE__ */ jsx10("div", { className: "flex-1" }),
|
|
1459
|
-
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-1", children: [
|
|
1460
|
-
currentRoute.page === "dashboard" && /* @__PURE__ */ jsxs6(Fragment2, { children: [
|
|
1461
|
-
/* @__PURE__ */ jsx10(
|
|
1462
|
-
Button,
|
|
1463
|
-
{
|
|
1464
|
-
variant: range === "24h" ? "default" : "ghost",
|
|
1465
|
-
size: "sm",
|
|
1466
|
-
className: "h-7 text-xs",
|
|
1467
|
-
onClick: () => onRangeChange("24h"),
|
|
1468
|
-
children: config.labels.range24h
|
|
1469
|
-
}
|
|
1470
|
-
),
|
|
1471
|
-
/* @__PURE__ */ jsx10(
|
|
1472
|
-
Button,
|
|
1473
|
-
{
|
|
1474
|
-
variant: range === "7d" ? "default" : "ghost",
|
|
1475
|
-
size: "sm",
|
|
1476
|
-
className: "h-7 text-xs",
|
|
1477
|
-
onClick: () => onRangeChange("7d"),
|
|
1478
|
-
children: config.labels.range7d
|
|
1479
|
-
}
|
|
1480
|
-
),
|
|
1481
|
-
/* @__PURE__ */ jsx10(
|
|
1482
|
-
Button,
|
|
1483
|
-
{
|
|
1484
|
-
variant: range === "30d" ? "default" : "ghost",
|
|
1485
|
-
size: "sm",
|
|
1486
|
-
className: "h-7 text-xs",
|
|
1487
|
-
onClick: () => onRangeChange("30d"),
|
|
1488
|
-
children: config.labels.range30d
|
|
1489
|
-
}
|
|
1490
|
-
),
|
|
1491
|
-
/* @__PURE__ */ jsxs6(
|
|
1492
|
-
Select,
|
|
1493
|
-
{
|
|
1494
|
-
value: interval,
|
|
1495
|
-
onValueChange: (v) => onIntervalChange(v),
|
|
1496
|
-
children: [
|
|
1497
|
-
/* @__PURE__ */ jsx10(SelectTrigger, { className: "h-7 w-[90px] text-xs", children: /* @__PURE__ */ jsx10(SelectValue, {}) }),
|
|
1498
|
-
/* @__PURE__ */ jsxs6(SelectContent, { children: [
|
|
1499
|
-
/* @__PURE__ */ jsx10(SelectItem, { value: "hour", children: config.labels.intervalHour }),
|
|
1500
|
-
/* @__PURE__ */ jsx10(SelectItem, { value: "day", children: config.labels.intervalDay })
|
|
1501
|
-
] })
|
|
1502
|
-
]
|
|
1503
|
-
}
|
|
1504
|
-
)
|
|
1505
|
-
] }),
|
|
1466
|
+
controls && /* @__PURE__ */ jsx10("div", { className: "flex min-w-[240px] flex-1 items-center justify-end gap-2 overflow-x-auto", children: controls }),
|
|
1467
|
+
/* @__PURE__ */ jsxs6("div", { className: "ml-auto flex items-center gap-1", children: [
|
|
1506
1468
|
/* @__PURE__ */ jsxs6(Tooltip, { children: [
|
|
1507
1469
|
/* @__PURE__ */ jsx10(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx10(
|
|
1508
1470
|
Button,
|
|
@@ -1528,7 +1490,25 @@ var AdminHeader = ({
|
|
|
1528
1490
|
};
|
|
1529
1491
|
|
|
1530
1492
|
// src/components/views/DashboardView.tsx
|
|
1531
|
-
import
|
|
1493
|
+
import React6 from "react";
|
|
1494
|
+
import {
|
|
1495
|
+
Bar,
|
|
1496
|
+
BarChart,
|
|
1497
|
+
CartesianGrid,
|
|
1498
|
+
Legend,
|
|
1499
|
+
Tooltip as Tooltip2,
|
|
1500
|
+
XAxis,
|
|
1501
|
+
YAxis
|
|
1502
|
+
} from "recharts";
|
|
1503
|
+
import {
|
|
1504
|
+
Activity as Activity2,
|
|
1505
|
+
Database as Database2,
|
|
1506
|
+
Filter,
|
|
1507
|
+
Search,
|
|
1508
|
+
Sparkles,
|
|
1509
|
+
Users as Users2,
|
|
1510
|
+
Wallet
|
|
1511
|
+
} from "lucide-react";
|
|
1532
1512
|
|
|
1533
1513
|
// src/components/ui/badge.tsx
|
|
1534
1514
|
import { Slot as Slot3 } from "@radix-ui/react-slot";
|
|
@@ -1567,8 +1547,124 @@ function Badge({
|
|
|
1567
1547
|
);
|
|
1568
1548
|
}
|
|
1569
1549
|
|
|
1550
|
+
// src/components/ui/chart.tsx
|
|
1551
|
+
import * as React5 from "react";
|
|
1552
|
+
import * as RechartsPrimitive from "recharts";
|
|
1553
|
+
import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1554
|
+
var ChartContext = React5.createContext(null);
|
|
1555
|
+
function useChart() {
|
|
1556
|
+
const context = React5.useContext(ChartContext);
|
|
1557
|
+
if (!context) {
|
|
1558
|
+
throw new Error("useChart must be used within a ChartContainer");
|
|
1559
|
+
}
|
|
1560
|
+
return context;
|
|
1561
|
+
}
|
|
1562
|
+
function ChartContainer({
|
|
1563
|
+
id,
|
|
1564
|
+
className,
|
|
1565
|
+
config,
|
|
1566
|
+
children,
|
|
1567
|
+
...props
|
|
1568
|
+
}) {
|
|
1569
|
+
const uniqueId = React5.useId();
|
|
1570
|
+
const chartId = `chart-${id ?? uniqueId.replace(/:/g, "")}`;
|
|
1571
|
+
return /* @__PURE__ */ jsx12(ChartContext.Provider, { value: config, children: /* @__PURE__ */ jsxs7(
|
|
1572
|
+
"div",
|
|
1573
|
+
{
|
|
1574
|
+
"data-chart": chartId,
|
|
1575
|
+
className: cn(
|
|
1576
|
+
"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",
|
|
1577
|
+
className
|
|
1578
|
+
),
|
|
1579
|
+
...props,
|
|
1580
|
+
children: [
|
|
1581
|
+
/* @__PURE__ */ jsx12("style", { children: Object.entries(config).map(([key, item]) => {
|
|
1582
|
+
return `[data-chart=${chartId}] { --color-${key}: ${item.color}; }`;
|
|
1583
|
+
}).join("\n") }),
|
|
1584
|
+
/* @__PURE__ */ jsx12(RechartsPrimitive.ResponsiveContainer, { children })
|
|
1585
|
+
]
|
|
1586
|
+
}
|
|
1587
|
+
) });
|
|
1588
|
+
}
|
|
1589
|
+
function ChartTooltipContent({
|
|
1590
|
+
active,
|
|
1591
|
+
payload,
|
|
1592
|
+
label,
|
|
1593
|
+
className,
|
|
1594
|
+
formatter,
|
|
1595
|
+
labelFormatter
|
|
1596
|
+
}) {
|
|
1597
|
+
const config = useChart();
|
|
1598
|
+
if (!active || !payload?.length) return null;
|
|
1599
|
+
const total = payload.reduce((sum, item) => {
|
|
1600
|
+
const value = typeof item.value === "number" ? item.value : Number(item.value ?? 0);
|
|
1601
|
+
return sum + (Number.isFinite(value) ? value : 0);
|
|
1602
|
+
}, 0);
|
|
1603
|
+
return /* @__PURE__ */ jsxs7(
|
|
1604
|
+
"div",
|
|
1605
|
+
{
|
|
1606
|
+
className: cn(
|
|
1607
|
+
"min-w-44 rounded-lg border bg-popover px-3 py-2 text-popover-foreground shadow-md",
|
|
1608
|
+
className
|
|
1609
|
+
),
|
|
1610
|
+
children: [
|
|
1611
|
+
/* @__PURE__ */ jsxs7("div", { className: "mb-2 flex items-center justify-between gap-4 border-b pb-2", children: [
|
|
1612
|
+
/* @__PURE__ */ jsx12("p", { className: "text-xs font-medium text-muted-foreground", children: labelFormatter ? labelFormatter(label) : label }),
|
|
1613
|
+
/* @__PURE__ */ jsx12("p", { className: "text-xs font-semibold text-foreground", children: formatter ? formatter(total) : total })
|
|
1614
|
+
] }),
|
|
1615
|
+
/* @__PURE__ */ jsx12("div", { className: "space-y-1.5", children: payload.filter((item) => Number(item.value ?? 0) > 0).map((item) => {
|
|
1616
|
+
const key = String(item.dataKey ?? item.name ?? "");
|
|
1617
|
+
const itemConfig = config[key];
|
|
1618
|
+
const color = item.color ?? itemConfig?.color ?? "currentColor";
|
|
1619
|
+
return /* @__PURE__ */ jsxs7(
|
|
1620
|
+
"div",
|
|
1621
|
+
{
|
|
1622
|
+
className: "grid grid-cols-[0.6rem_1fr_auto] items-center gap-2",
|
|
1623
|
+
children: [
|
|
1624
|
+
/* @__PURE__ */ jsx12(
|
|
1625
|
+
"span",
|
|
1626
|
+
{
|
|
1627
|
+
className: "size-2 rounded-[2px]",
|
|
1628
|
+
style: { backgroundColor: color }
|
|
1629
|
+
}
|
|
1630
|
+
),
|
|
1631
|
+
/* @__PURE__ */ jsx12("span", { className: "max-w-48 truncate text-muted-foreground", children: itemConfig?.label ?? item.name ?? key }),
|
|
1632
|
+
/* @__PURE__ */ jsx12("span", { className: "font-medium text-foreground", children: formatter ? formatter(item.value ?? 0) : item.value })
|
|
1633
|
+
]
|
|
1634
|
+
},
|
|
1635
|
+
key
|
|
1636
|
+
);
|
|
1637
|
+
}) })
|
|
1638
|
+
]
|
|
1639
|
+
}
|
|
1640
|
+
);
|
|
1641
|
+
}
|
|
1642
|
+
function ChartLegendContent({
|
|
1643
|
+
payload,
|
|
1644
|
+
className
|
|
1645
|
+
}) {
|
|
1646
|
+
const config = useChart();
|
|
1647
|
+
if (!payload?.length) return null;
|
|
1648
|
+
return /* @__PURE__ */ jsx12("div", { className: cn("flex flex-wrap items-center gap-x-4 gap-y-2", className), children: payload.map((item) => {
|
|
1649
|
+
const key = String(item.dataKey ?? item.value ?? "");
|
|
1650
|
+
const itemConfig = config[key];
|
|
1651
|
+
return /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2", children: [
|
|
1652
|
+
/* @__PURE__ */ jsx12(
|
|
1653
|
+
"span",
|
|
1654
|
+
{
|
|
1655
|
+
className: "size-2 rounded-[2px]",
|
|
1656
|
+
style: {
|
|
1657
|
+
backgroundColor: item.color ?? itemConfig?.color ?? "currentColor"
|
|
1658
|
+
}
|
|
1659
|
+
}
|
|
1660
|
+
),
|
|
1661
|
+
/* @__PURE__ */ jsx12("span", { className: "max-w-52 truncate text-xs text-muted-foreground", children: itemConfig?.label ?? item.value ?? key })
|
|
1662
|
+
] }, key);
|
|
1663
|
+
}) });
|
|
1664
|
+
}
|
|
1665
|
+
|
|
1570
1666
|
// src/components/views/DashboardView.tsx
|
|
1571
|
-
import { Fragment as
|
|
1667
|
+
import { Fragment as Fragment2, jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1572
1668
|
var DashboardView = ({
|
|
1573
1669
|
config,
|
|
1574
1670
|
overview,
|
|
@@ -1584,172 +1680,76 @@ var DashboardView = ({
|
|
|
1584
1680
|
onParticipantSearchChange,
|
|
1585
1681
|
onAgentSearchChange,
|
|
1586
1682
|
onThreadClick,
|
|
1587
|
-
namespace
|
|
1683
|
+
namespace,
|
|
1684
|
+
setHeaderControls,
|
|
1685
|
+
setHeaderRefresh
|
|
1588
1686
|
}) => {
|
|
1589
|
-
|
|
1687
|
+
void overview;
|
|
1688
|
+
void activity;
|
|
1689
|
+
void threads;
|
|
1690
|
+
void participants;
|
|
1691
|
+
void agents;
|
|
1692
|
+
void interval;
|
|
1693
|
+
void threadSearch;
|
|
1694
|
+
void participantSearch;
|
|
1695
|
+
void agentSearch;
|
|
1696
|
+
void onThreadSearchChange;
|
|
1697
|
+
void onParticipantSearchChange;
|
|
1698
|
+
void onAgentSearchChange;
|
|
1699
|
+
void onThreadClick;
|
|
1700
|
+
if (!config.features.showOverview) {
|
|
1701
|
+
return /* @__PURE__ */ jsx13(
|
|
1702
|
+
EmptyDashboard,
|
|
1703
|
+
{
|
|
1704
|
+
description: config.labels.emptyDescription,
|
|
1705
|
+
title: config.labels.emptyTitle
|
|
1706
|
+
}
|
|
1707
|
+
);
|
|
1708
|
+
}
|
|
1709
|
+
return /* @__PURE__ */ jsx13(
|
|
1710
|
+
UsageDashboard,
|
|
1711
|
+
{
|
|
1712
|
+
config,
|
|
1713
|
+
namespace,
|
|
1714
|
+
setHeaderControls,
|
|
1715
|
+
setHeaderRefresh
|
|
1716
|
+
}
|
|
1717
|
+
);
|
|
1718
|
+
};
|
|
1719
|
+
function UsageDashboard({
|
|
1720
|
+
config,
|
|
1721
|
+
namespace,
|
|
1722
|
+
setHeaderControls,
|
|
1723
|
+
setHeaderRefresh
|
|
1724
|
+
}) {
|
|
1725
|
+
const [period, setPeriod] = React6.useState("7d");
|
|
1726
|
+
const [bucket, setBucket] = React6.useState("day");
|
|
1727
|
+
const [metricKind, setMetricKind] = React6.useState(
|
|
1590
1728
|
"cost"
|
|
1591
1729
|
);
|
|
1592
|
-
const [
|
|
1593
|
-
|
|
1730
|
+
const [dimension, setDimension] = React6.useState("total");
|
|
1731
|
+
const [groupBy, setGroupBy] = React6.useState(
|
|
1732
|
+
"participant"
|
|
1594
1733
|
);
|
|
1595
|
-
const
|
|
1596
|
-
|
|
1597
|
-
config.labels,
|
|
1598
|
-
usageMetricKind,
|
|
1599
|
-
usageDimension
|
|
1734
|
+
const [attribution, setAttribution] = React6.useState(
|
|
1735
|
+
"initiatedBy"
|
|
1600
1736
|
);
|
|
1601
|
-
const
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
{
|
|
1613
|
-
label: config.labels.participantsCard,
|
|
1614
|
-
value: overview?.participantTotals.total ?? 0,
|
|
1615
|
-
detail: `${overview?.participantTotals.agents ?? 0} agents, ${overview?.participantTotals.jobs ?? 0} jobs`
|
|
1616
|
-
},
|
|
1617
|
-
{
|
|
1618
|
-
label: llmSummaryLabel,
|
|
1619
|
-
value: llmSummaryValue,
|
|
1620
|
-
detail: `${overview?.llmTotals.totalCalls ?? 0} ${config.labels.usageCallsDetail}`,
|
|
1621
|
-
metricKind: usageMetricKind
|
|
1622
|
-
},
|
|
1623
|
-
{
|
|
1624
|
-
label: config.labels.queueCard,
|
|
1625
|
-
value: overview?.queueTotals.pending ?? 0,
|
|
1626
|
-
detail: `${overview?.queueTotals.failed ?? 0} failed`
|
|
1627
|
-
}
|
|
1628
|
-
];
|
|
1629
|
-
const isEmpty = cards.every((card) => card.value === 0) && activity.length === 0 && threads.length === 0 && participants.length === 0 && agents.length === 0;
|
|
1630
|
-
return /* @__PURE__ */ jsxs7("div", { className: "space-y-6", children: [
|
|
1631
|
-
isEmpty && /* @__PURE__ */ jsxs7("div", { className: "rounded-xl border border-dashed p-10 text-center", children: [
|
|
1632
|
-
/* @__PURE__ */ jsx12("h3", { className: "text-lg font-semibold", children: config.labels.emptyTitle }),
|
|
1633
|
-
/* @__PURE__ */ jsx12("p", { className: "mt-2 text-sm text-muted-foreground", children: config.labels.emptyDescription })
|
|
1634
|
-
] }),
|
|
1635
|
-
config.features.showOverview && /* @__PURE__ */ jsxs7("section", { className: "space-y-4", children: [
|
|
1636
|
-
/* @__PURE__ */ jsx12(SectionHeading, { title: config.labels.overviewTitle }),
|
|
1637
|
-
/* @__PURE__ */ jsx12("div", { className: "grid grid-cols-2 gap-4 md:grid-cols-3 lg:grid-cols-5", children: cards.map((card) => /* @__PURE__ */ jsxs7(
|
|
1638
|
-
"div",
|
|
1639
|
-
{
|
|
1640
|
-
className: "rounded-xl border bg-card p-5 shadow-sm",
|
|
1641
|
-
children: [
|
|
1642
|
-
/* @__PURE__ */ jsx12("p", { className: "text-sm font-medium text-muted-foreground", children: card.label }),
|
|
1643
|
-
/* @__PURE__ */ jsx12("p", { className: "mt-3 text-3xl font-semibold tracking-tight", children: formatMetricValue(
|
|
1644
|
-
card.value,
|
|
1645
|
-
card.metricKind ?? "tokens"
|
|
1646
|
-
) }),
|
|
1647
|
-
/* @__PURE__ */ jsx12("p", { className: "mt-2 text-xs text-muted-foreground", children: card.detail })
|
|
1648
|
-
]
|
|
1649
|
-
},
|
|
1650
|
-
card.label
|
|
1651
|
-
)) })
|
|
1652
|
-
] }),
|
|
1653
|
-
config.features.showOverview && /* @__PURE__ */ jsx12(
|
|
1654
|
-
UsageExplorer,
|
|
1655
|
-
{
|
|
1656
|
-
config,
|
|
1657
|
-
metricKind: usageMetricKind,
|
|
1658
|
-
namespace,
|
|
1659
|
-
onDimensionChange: setUsageDimension,
|
|
1660
|
-
onMetricKindChange: setUsageMetricKind,
|
|
1661
|
-
selectedDimension: usageDimension
|
|
1662
|
-
}
|
|
1663
|
-
),
|
|
1664
|
-
config.features.showActivity && /* @__PURE__ */ jsxs7("section", { className: "space-y-4", children: [
|
|
1665
|
-
/* @__PURE__ */ jsx12(SectionHeading, { title: config.labels.activityTitle }),
|
|
1666
|
-
/* @__PURE__ */ jsx12(
|
|
1667
|
-
ActivityChart,
|
|
1668
|
-
{
|
|
1669
|
-
interval,
|
|
1670
|
-
labels: config.labels,
|
|
1671
|
-
maxBars: config.ui.maxActivityBars,
|
|
1672
|
-
points: activity,
|
|
1673
|
-
usageDimension,
|
|
1674
|
-
usageMetricKind
|
|
1675
|
-
}
|
|
1676
|
-
)
|
|
1677
|
-
] }),
|
|
1678
|
-
/* @__PURE__ */ jsxs7("div", { className: "grid gap-6 lg:grid-cols-3", children: [
|
|
1679
|
-
config.features.showThreads && /* @__PURE__ */ jsx12(
|
|
1680
|
-
DataTable,
|
|
1681
|
-
{
|
|
1682
|
-
rows: threads,
|
|
1683
|
-
searchPlaceholder: config.labels.threadSearchPlaceholder,
|
|
1684
|
-
searchValue: threadSearch,
|
|
1685
|
-
setSearchValue: onThreadSearchChange,
|
|
1686
|
-
title: config.labels.threadsTitle,
|
|
1687
|
-
children: /* @__PURE__ */ jsx12(
|
|
1688
|
-
ThreadsTable,
|
|
1689
|
-
{
|
|
1690
|
-
rows: threads,
|
|
1691
|
-
labels: config.labels,
|
|
1692
|
-
onThreadClick
|
|
1693
|
-
}
|
|
1694
|
-
)
|
|
1695
|
-
}
|
|
1696
|
-
),
|
|
1697
|
-
config.features.showParticipants && /* @__PURE__ */ jsx12(
|
|
1698
|
-
DataTable,
|
|
1699
|
-
{
|
|
1700
|
-
rows: participants,
|
|
1701
|
-
searchPlaceholder: config.labels.participantSearchPlaceholder,
|
|
1702
|
-
searchValue: participantSearch,
|
|
1703
|
-
setSearchValue: onParticipantSearchChange,
|
|
1704
|
-
title: config.labels.participantsTitle,
|
|
1705
|
-
children: /* @__PURE__ */ jsx12(ParticipantsTable, { rows: participants, labels: config.labels })
|
|
1706
|
-
}
|
|
1707
|
-
),
|
|
1708
|
-
config.features.showAgents && /* @__PURE__ */ jsx12(
|
|
1709
|
-
DataTable,
|
|
1710
|
-
{
|
|
1711
|
-
rows: agents,
|
|
1712
|
-
searchPlaceholder: config.labels.agentSearchPlaceholder,
|
|
1713
|
-
searchValue: agentSearch,
|
|
1714
|
-
setSearchValue: onAgentSearchChange,
|
|
1715
|
-
title: config.labels.agentsTitle,
|
|
1716
|
-
children: /* @__PURE__ */ jsx12(
|
|
1717
|
-
AgentsTable,
|
|
1718
|
-
{
|
|
1719
|
-
rows: agents,
|
|
1720
|
-
labels: config.labels,
|
|
1721
|
-
usageMetricKind,
|
|
1722
|
-
usageDimension
|
|
1723
|
-
}
|
|
1724
|
-
)
|
|
1725
|
-
}
|
|
1726
|
-
)
|
|
1727
|
-
] })
|
|
1728
|
-
] });
|
|
1729
|
-
};
|
|
1730
|
-
function SectionHeading({ title }) {
|
|
1731
|
-
return /* @__PURE__ */ jsx12("h3", { className: "text-lg font-semibold tracking-tight", children: title });
|
|
1732
|
-
}
|
|
1733
|
-
function UsageExplorer(props) {
|
|
1734
|
-
const [period, setPeriod] = React5.useState("7d");
|
|
1735
|
-
const [bucket, setBucket] = React5.useState("day");
|
|
1736
|
-
const [groupBy, setGroupBy] = React5.useState("participant");
|
|
1737
|
-
const [participantType, setParticipantType] = React5.useState("all");
|
|
1738
|
-
const [threadId, setThreadId] = React5.useState("");
|
|
1739
|
-
const [participantId, setParticipantId] = React5.useState("");
|
|
1740
|
-
const [provider, setProvider] = React5.useState("");
|
|
1741
|
-
const [model, setModel] = React5.useState("");
|
|
1742
|
-
const [customFrom, setCustomFrom] = React5.useState("");
|
|
1743
|
-
const [customTo, setCustomTo] = React5.useState("");
|
|
1744
|
-
const [usage, setUsage] = React5.useState(null);
|
|
1745
|
-
const [isLoading, setIsLoading] = React5.useState(false);
|
|
1746
|
-
const [error, setError] = React5.useState(null);
|
|
1747
|
-
const range = React5.useMemo(() => getUsageRange(period, customFrom, customTo), [
|
|
1737
|
+
const [participantType, setParticipantType] = React6.useState("all");
|
|
1738
|
+
const [threadId, setThreadId] = React6.useState("");
|
|
1739
|
+
const [participantId, setParticipantId] = React6.useState("");
|
|
1740
|
+
const [provider, setProvider] = React6.useState("");
|
|
1741
|
+
const [model, setModel] = React6.useState("");
|
|
1742
|
+
const [customFrom, setCustomFrom] = React6.useState("");
|
|
1743
|
+
const [customTo, setCustomTo] = React6.useState("");
|
|
1744
|
+
const [usage, setUsage] = React6.useState(null);
|
|
1745
|
+
const [isLoading, setIsLoading] = React6.useState(false);
|
|
1746
|
+
const [error, setError] = React6.useState(null);
|
|
1747
|
+
const range = React6.useMemo(() => getUsageRange(period, customFrom, customTo), [
|
|
1748
1748
|
customFrom,
|
|
1749
1749
|
customTo,
|
|
1750
1750
|
period
|
|
1751
1751
|
]);
|
|
1752
|
-
const loadUsage =
|
|
1752
|
+
const loadUsage = React6.useCallback(async () => {
|
|
1753
1753
|
setIsLoading(true);
|
|
1754
1754
|
setError(null);
|
|
1755
1755
|
try {
|
|
@@ -1757,17 +1757,18 @@ function UsageExplorer(props) {
|
|
|
1757
1757
|
from: range.from,
|
|
1758
1758
|
to: range.to,
|
|
1759
1759
|
interval: bucket,
|
|
1760
|
-
metric:
|
|
1760
|
+
metric: metricKind,
|
|
1761
1761
|
groupBy,
|
|
1762
|
-
|
|
1762
|
+
attribution,
|
|
1763
|
+
namespace: namespace || void 0,
|
|
1763
1764
|
participantType,
|
|
1764
1765
|
threadId: emptyToUndefined(threadId),
|
|
1765
1766
|
participantId: emptyToUndefined(participantId),
|
|
1766
1767
|
provider: emptyToUndefined(provider),
|
|
1767
1768
|
model: emptyToUndefined(model)
|
|
1768
1769
|
}, {
|
|
1769
|
-
baseUrl:
|
|
1770
|
-
getRequestHeaders:
|
|
1770
|
+
baseUrl: config.baseUrl,
|
|
1771
|
+
getRequestHeaders: config.getRequestHeaders
|
|
1771
1772
|
});
|
|
1772
1773
|
setUsage(next);
|
|
1773
1774
|
} catch (err) {
|
|
@@ -1777,505 +1778,659 @@ function UsageExplorer(props) {
|
|
|
1777
1778
|
setIsLoading(false);
|
|
1778
1779
|
}
|
|
1779
1780
|
}, [
|
|
1781
|
+
attribution,
|
|
1780
1782
|
bucket,
|
|
1783
|
+
config.baseUrl,
|
|
1784
|
+
config.getRequestHeaders,
|
|
1781
1785
|
groupBy,
|
|
1786
|
+
metricKind,
|
|
1782
1787
|
model,
|
|
1788
|
+
namespace,
|
|
1783
1789
|
participantId,
|
|
1784
1790
|
participantType,
|
|
1785
|
-
props.config.baseUrl,
|
|
1786
|
-
props.config.getRequestHeaders,
|
|
1787
|
-
props.metricKind,
|
|
1788
|
-
props.namespace,
|
|
1789
1791
|
provider,
|
|
1790
1792
|
range.from,
|
|
1791
1793
|
range.to,
|
|
1792
1794
|
threadId
|
|
1793
1795
|
]);
|
|
1794
|
-
|
|
1796
|
+
React6.useEffect(() => {
|
|
1795
1797
|
void loadUsage();
|
|
1796
1798
|
}, [loadUsage]);
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1799
|
+
const points = usage?.points ?? [];
|
|
1800
|
+
const totals = usage?.totals ?? EMPTY_TOTALS;
|
|
1801
|
+
const chartState = React6.useMemo(() => buildChartState(points, metricKind, dimension, bucket), [
|
|
1802
|
+
bucket,
|
|
1803
|
+
dimension,
|
|
1804
|
+
metricKind,
|
|
1805
|
+
points
|
|
1806
|
+
]);
|
|
1807
|
+
const groupedRows = React6.useMemo(() => aggregateUsageRows(points, metricKind, dimension), [
|
|
1808
|
+
dimension,
|
|
1809
|
+
metricKind,
|
|
1810
|
+
points
|
|
1811
|
+
]);
|
|
1812
|
+
const activeFilterCount = [
|
|
1813
|
+
participantType !== "all" ? participantType : "",
|
|
1814
|
+
threadId,
|
|
1815
|
+
participantId,
|
|
1816
|
+
provider,
|
|
1817
|
+
model,
|
|
1818
|
+
period === "custom" ? customFrom : "",
|
|
1819
|
+
period === "custom" ? customTo : ""
|
|
1820
|
+
].filter((value) => value.trim().length > 0).length;
|
|
1821
|
+
const clearFilters = React6.useCallback(() => {
|
|
1822
|
+
setParticipantType("all");
|
|
1823
|
+
setThreadId("");
|
|
1824
|
+
setParticipantId("");
|
|
1825
|
+
setProvider("");
|
|
1826
|
+
setModel("");
|
|
1827
|
+
setCustomFrom("");
|
|
1828
|
+
setCustomTo("");
|
|
1829
|
+
}, []);
|
|
1830
|
+
const headerControls = React6.useMemo(() => /* @__PURE__ */ jsx13(
|
|
1831
|
+
DashboardHeaderControls,
|
|
1832
|
+
{
|
|
1833
|
+
attribution,
|
|
1834
|
+
bucket,
|
|
1835
|
+
config,
|
|
1836
|
+
dimension,
|
|
1837
|
+
groupBy,
|
|
1838
|
+
metricKind,
|
|
1839
|
+
period,
|
|
1840
|
+
setAttribution,
|
|
1841
|
+
setBucket,
|
|
1842
|
+
setDimension,
|
|
1843
|
+
setGroupBy,
|
|
1844
|
+
setMetricKind,
|
|
1845
|
+
setPeriod
|
|
1846
|
+
}
|
|
1847
|
+
), [
|
|
1848
|
+
attribution,
|
|
1849
|
+
bucket,
|
|
1850
|
+
config,
|
|
1851
|
+
dimension,
|
|
1852
|
+
groupBy,
|
|
1853
|
+
metricKind,
|
|
1854
|
+
period
|
|
1855
|
+
]);
|
|
1856
|
+
React6.useEffect(() => {
|
|
1857
|
+
setHeaderControls?.(headerControls);
|
|
1858
|
+
return () => setHeaderControls?.(null);
|
|
1859
|
+
}, [headerControls, setHeaderControls]);
|
|
1860
|
+
React6.useEffect(() => {
|
|
1861
|
+
setHeaderRefresh?.(() => () => {
|
|
1862
|
+
void loadUsage();
|
|
1863
|
+
});
|
|
1864
|
+
return () => setHeaderRefresh?.(null);
|
|
1865
|
+
}, [loadUsage, setHeaderRefresh]);
|
|
1866
|
+
return /* @__PURE__ */ jsxs8("div", { className: "grid h-full min-h-0 grid-rows-[auto_minmax(0,4fr)_minmax(0,5fr)] gap-3", children: [
|
|
1867
|
+
/* @__PURE__ */ jsxs8("div", { className: "space-y-3", children: [
|
|
1868
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex flex-col gap-3 xl:flex-row xl:items-end xl:justify-between", children: [
|
|
1869
|
+
/* @__PURE__ */ jsxs8("div", { className: "min-w-0", children: [
|
|
1870
|
+
/* @__PURE__ */ jsx13("h2", { className: "text-xl font-semibold tracking-tight", children: config.labels.llmUsageTitle }),
|
|
1871
|
+
/* @__PURE__ */ jsxs8("div", { className: "mt-1 flex flex-wrap items-center gap-2", children: [
|
|
1872
|
+
/* @__PURE__ */ jsx13(Badge, { variant: "outline", children: formatUsageRangeLabel(period, range) }),
|
|
1873
|
+
/* @__PURE__ */ jsx13(Badge, { variant: "secondary", children: getGroupByLabel(groupBy) }),
|
|
1874
|
+
groupBy === "participant" && /* @__PURE__ */ jsx13(Badge, { variant: "outline", children: attribution === "initiatedBy" ? "Initiated by sender" : "Generated by caller" }),
|
|
1875
|
+
isLoading && /* @__PURE__ */ jsx13(Badge, { variant: "outline", children: config.labels.loading })
|
|
1876
|
+
] })
|
|
1877
|
+
] }),
|
|
1878
|
+
/* @__PURE__ */ jsx13(
|
|
1879
|
+
InlineFilters,
|
|
1860
1880
|
{
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1881
|
+
activeFilterCount,
|
|
1882
|
+
clearFilters,
|
|
1883
|
+
customFrom,
|
|
1884
|
+
customTo,
|
|
1885
|
+
model,
|
|
1886
|
+
participantId,
|
|
1887
|
+
participantType,
|
|
1888
|
+
period,
|
|
1889
|
+
provider,
|
|
1890
|
+
setCustomFrom,
|
|
1891
|
+
setCustomTo,
|
|
1892
|
+
setModel,
|
|
1893
|
+
setParticipantId,
|
|
1894
|
+
setParticipantType,
|
|
1895
|
+
setProvider,
|
|
1896
|
+
setThreadId,
|
|
1897
|
+
threadId
|
|
1868
1898
|
}
|
|
1869
1899
|
)
|
|
1870
|
-
] })
|
|
1871
|
-
] }),
|
|
1872
|
-
/* @__PURE__ */ jsx12("div", { className: "rounded-xl border bg-card p-5 shadow-sm", children: /* @__PURE__ */ jsxs7("div", { className: "grid gap-3 md:grid-cols-2 xl:grid-cols-6", children: [
|
|
1873
|
-
period === "custom" && /* @__PURE__ */ jsxs7(Fragment3, { children: [
|
|
1874
|
-
/* @__PURE__ */ jsx12(FilterInput, { label: "From", type: "datetime-local", value: customFrom, onChange: setCustomFrom }),
|
|
1875
|
-
/* @__PURE__ */ jsx12(FilterInput, { label: "To", type: "datetime-local", value: customTo, onChange: setCustomTo })
|
|
1876
1900
|
] }),
|
|
1877
|
-
/* @__PURE__ */
|
|
1878
|
-
|
|
1901
|
+
/* @__PURE__ */ jsx13(
|
|
1902
|
+
UsageSummary,
|
|
1879
1903
|
{
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
onValueChange: (value) => setParticipantType(value),
|
|
1883
|
-
options: [
|
|
1884
|
-
["all", "All"],
|
|
1885
|
-
["human", "Human"],
|
|
1886
|
-
["agent", "Agent"],
|
|
1887
|
-
["job", "Job"]
|
|
1888
|
-
]
|
|
1904
|
+
labels: config.labels,
|
|
1905
|
+
totals
|
|
1889
1906
|
}
|
|
1890
|
-
)
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
/* @__PURE__ */
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1907
|
+
)
|
|
1908
|
+
] }),
|
|
1909
|
+
/* @__PURE__ */ jsxs8(Card, { className: "min-h-0 gap-2 overflow-hidden py-3", children: [
|
|
1910
|
+
/* @__PURE__ */ jsx13(CardHeader, { className: "px-4", children: /* @__PURE__ */ jsx13("div", { className: "flex flex-col gap-2 md:flex-row md:items-start md:justify-between", children: /* @__PURE__ */ jsxs8("div", { children: [
|
|
1911
|
+
/* @__PURE__ */ jsx13(CardTitle, { className: "text-base", children: getUsageSummaryLabel(config.labels, metricKind, dimension) }),
|
|
1912
|
+
/* @__PURE__ */ jsxs8("p", { className: "mt-1 text-sm text-muted-foreground", children: [
|
|
1913
|
+
formatMetricValue(
|
|
1914
|
+
getUsageTotalValue(totals, metricKind, dimension),
|
|
1915
|
+
metricKind
|
|
1916
|
+
),
|
|
1917
|
+
" ",
|
|
1918
|
+
"across ",
|
|
1919
|
+
formatNumber(totals.totalCalls),
|
|
1920
|
+
" calls"
|
|
1921
|
+
] })
|
|
1922
|
+
] }) }) }),
|
|
1923
|
+
/* @__PURE__ */ jsx13(CardContent, { className: "min-h-0 flex-1 px-2 lg:px-4", children: error ? /* @__PURE__ */ jsx13("div", { className: "rounded-lg border border-destructive/30 bg-destructive/10 p-4 text-sm text-destructive", children: error }) : chartState.data.length === 0 ? /* @__PURE__ */ jsx13(
|
|
1924
|
+
EmptyDashboard,
|
|
1925
|
+
{
|
|
1926
|
+
description: config.labels.noResults,
|
|
1927
|
+
title: "No usage"
|
|
1928
|
+
}
|
|
1929
|
+
) : /* @__PURE__ */ jsx13(
|
|
1930
|
+
UsageChart,
|
|
1897
1931
|
{
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
disabled: isLoading,
|
|
1901
|
-
variant: "outline",
|
|
1902
|
-
children: props.config.labels.refresh
|
|
1932
|
+
chartState,
|
|
1933
|
+
metricKind
|
|
1903
1934
|
}
|
|
1904
1935
|
) })
|
|
1905
|
-
] })
|
|
1906
|
-
/* @__PURE__ */
|
|
1907
|
-
UsageChart,
|
|
1908
|
-
{
|
|
1909
|
-
labels: props.config.labels,
|
|
1910
|
-
metricKind: props.metricKind,
|
|
1911
|
-
dimension: props.selectedDimension,
|
|
1912
|
-
points: usage?.points ?? [],
|
|
1913
|
-
bucket,
|
|
1914
|
-
isLoading,
|
|
1915
|
-
error
|
|
1916
|
-
}
|
|
1917
|
-
),
|
|
1918
|
-
/* @__PURE__ */ jsx12(
|
|
1936
|
+
] }),
|
|
1937
|
+
/* @__PURE__ */ jsx13(
|
|
1919
1938
|
UsageTable,
|
|
1920
1939
|
{
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1940
|
+
dimension,
|
|
1941
|
+
groupBy,
|
|
1942
|
+
labels: config.labels,
|
|
1943
|
+
metricKind,
|
|
1944
|
+
onRowFilter: (row) => {
|
|
1945
|
+
if (groupBy === "thread") setThreadId(row.groupKey);
|
|
1946
|
+
if (groupBy === "participant") setParticipantId(row.groupKey);
|
|
1947
|
+
if (groupBy === "provider") setProvider(row.groupKey);
|
|
1948
|
+
if (groupBy === "model") setModel(row.groupKey);
|
|
1949
|
+
},
|
|
1950
|
+
rows: groupedRows,
|
|
1951
|
+
totals
|
|
1926
1952
|
}
|
|
1927
1953
|
)
|
|
1928
1954
|
] });
|
|
1929
1955
|
}
|
|
1930
|
-
function
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
}
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
{
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1956
|
+
function UsageSummary({
|
|
1957
|
+
labels,
|
|
1958
|
+
totals
|
|
1959
|
+
}) {
|
|
1960
|
+
const summary = [
|
|
1961
|
+
{
|
|
1962
|
+
label: labels.usageMetricCost,
|
|
1963
|
+
value: formatMetricValue(totals.totalCostUsd, "cost"),
|
|
1964
|
+
detail: `${formatNumber(totals.totalCalls)} ${labels.usageCallsDetail}`,
|
|
1965
|
+
icon: Wallet
|
|
1966
|
+
},
|
|
1967
|
+
{
|
|
1968
|
+
label: labels.usageMetricTokens,
|
|
1969
|
+
value: formatMetricValue(totals.totalTokens, "tokens"),
|
|
1970
|
+
detail: `${formatMetricValue(totals.inputTokens, "tokens")} input`,
|
|
1971
|
+
icon: Activity2
|
|
1972
|
+
},
|
|
1973
|
+
{
|
|
1974
|
+
label: "Calls",
|
|
1975
|
+
value: formatMetricValue(totals.totalCalls, "calls"),
|
|
1976
|
+
detail: totals.totalCalls > 0 ? `${formatMetricValue(totals.totalCostUsd / totals.totalCalls, "cost")} avg` : "No calls",
|
|
1977
|
+
icon: Sparkles
|
|
1978
|
+
}
|
|
1979
|
+
];
|
|
1980
|
+
return /* @__PURE__ */ jsx13("div", { className: "grid gap-2 md:grid-cols-3", children: summary.map((item) => /* @__PURE__ */ jsx13(Card, { className: "gap-0 rounded-lg py-2 shadow-xs", children: /* @__PURE__ */ jsx13(CardContent, { className: "px-3", children: /* @__PURE__ */ jsxs8("div", { className: "flex items-center justify-between gap-3", children: [
|
|
1981
|
+
/* @__PURE__ */ jsxs8("div", { className: "min-w-0", children: [
|
|
1982
|
+
/* @__PURE__ */ jsx13("p", { className: "truncate text-xs text-muted-foreground", children: item.label }),
|
|
1983
|
+
/* @__PURE__ */ jsx13("p", { className: "truncate text-lg font-semibold tracking-tight", children: item.value }),
|
|
1984
|
+
/* @__PURE__ */ jsx13("p", { className: "truncate text-[11px] text-muted-foreground", children: item.detail })
|
|
1985
|
+
] }),
|
|
1986
|
+
/* @__PURE__ */ jsx13("div", { className: "rounded-md border bg-muted/50 p-1.5 text-muted-foreground", children: /* @__PURE__ */ jsx13(item.icon, { className: "size-4" }) })
|
|
1987
|
+
] }) }) }, item.label)) });
|
|
1952
1988
|
}
|
|
1953
|
-
function UsageChart(
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
),
|
|
1965
|
-
1
|
|
1966
|
-
);
|
|
1967
|
-
return /* @__PURE__ */ jsx12("div", { className: "rounded-xl border bg-card p-5 shadow-sm", children: props.error ? /* @__PURE__ */ jsx12("p", { className: "text-sm text-destructive", children: props.error }) : props.isLoading && props.points.length === 0 ? /* @__PURE__ */ jsx12("p", { className: "text-sm text-muted-foreground", children: props.labels.loading }) : visibleBuckets.length === 0 ? /* @__PURE__ */ jsx12("p", { className: "text-sm text-muted-foreground", children: props.labels.noResults }) : /* @__PURE__ */ jsxs7("div", { className: "space-y-4", children: [
|
|
1968
|
-
/* @__PURE__ */ jsx12("div", { className: "flex min-h-56 items-end gap-2", children: visibleBuckets.map((bucket) => {
|
|
1969
|
-
const bucketTotal = bucket.points.reduce((sum, point) => sum + getUsagePointValue(point, props.metricKind, props.dimension), 0);
|
|
1970
|
-
return /* @__PURE__ */ jsxs7("div", { className: "flex min-w-0 flex-1 flex-col items-center gap-2", children: [
|
|
1971
|
-
/* @__PURE__ */ jsx12("div", { className: "flex h-40 w-full items-end rounded-lg bg-muted px-1 pb-1", children: /* @__PURE__ */ jsx12(
|
|
1972
|
-
"div",
|
|
1973
|
-
{
|
|
1974
|
-
className: "flex w-full flex-col-reverse overflow-hidden rounded-md",
|
|
1975
|
-
style: {
|
|
1976
|
-
height: `${Math.max(bucketTotal / maxBucketValue * 100, 6)}%`
|
|
1977
|
-
},
|
|
1978
|
-
children: groups.map((group, index) => {
|
|
1979
|
-
const point = bucket.points.find((item) => item.groupKey === group.key);
|
|
1980
|
-
const value = point ? getUsagePointValue(point, props.metricKind, props.dimension) : 0;
|
|
1981
|
-
if (value <= 0 || bucketTotal <= 0) return null;
|
|
1982
|
-
return /* @__PURE__ */ jsx12(
|
|
1983
|
-
"div",
|
|
1984
|
-
{
|
|
1985
|
-
title: `${group.label}: ${formatMetricValue(value, props.metricKind)}`,
|
|
1986
|
-
style: {
|
|
1987
|
-
height: `${value / bucketTotal * 100}%`,
|
|
1988
|
-
backgroundColor: USAGE_CHART_COLORS[index % USAGE_CHART_COLORS.length]
|
|
1989
|
-
}
|
|
1990
|
-
},
|
|
1991
|
-
group.key
|
|
1992
|
-
);
|
|
1993
|
-
})
|
|
1994
|
-
}
|
|
1995
|
-
) }),
|
|
1996
|
-
/* @__PURE__ */ jsxs7("div", { className: "text-center", children: [
|
|
1997
|
-
/* @__PURE__ */ jsx12("p", { className: "text-xs font-medium", children: formatUsageBucket(bucket.bucket, props.bucket) }),
|
|
1998
|
-
/* @__PURE__ */ jsx12("p", { className: "text-[11px] text-muted-foreground", children: formatMetricValue(bucketTotal, props.metricKind) })
|
|
1999
|
-
] })
|
|
2000
|
-
] }, bucket.bucket);
|
|
2001
|
-
}) }),
|
|
2002
|
-
/* @__PURE__ */ jsx12("div", { className: "flex flex-wrap gap-3", children: groups.map((group, index) => /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2 text-xs", children: [
|
|
2003
|
-
/* @__PURE__ */ jsx12(
|
|
2004
|
-
"span",
|
|
1989
|
+
function UsageChart({
|
|
1990
|
+
chartState,
|
|
1991
|
+
metricKind
|
|
1992
|
+
}) {
|
|
1993
|
+
return /* @__PURE__ */ jsx13(
|
|
1994
|
+
ChartContainer,
|
|
1995
|
+
{
|
|
1996
|
+
className: "h-full min-h-[220px] w-full",
|
|
1997
|
+
config: chartState.config,
|
|
1998
|
+
children: /* @__PURE__ */ jsxs8(
|
|
1999
|
+
BarChart,
|
|
2005
2000
|
{
|
|
2006
|
-
|
|
2007
|
-
|
|
2001
|
+
accessibilityLayer: true,
|
|
2002
|
+
data: chartState.data,
|
|
2003
|
+
margin: { left: 8, right: 8, top: 12 },
|
|
2004
|
+
children: [
|
|
2005
|
+
/* @__PURE__ */ jsx13(CartesianGrid, { vertical: false }),
|
|
2006
|
+
/* @__PURE__ */ jsx13(
|
|
2007
|
+
XAxis,
|
|
2008
|
+
{
|
|
2009
|
+
axisLine: false,
|
|
2010
|
+
dataKey: "label",
|
|
2011
|
+
tickLine: false,
|
|
2012
|
+
tickMargin: 10
|
|
2013
|
+
}
|
|
2014
|
+
),
|
|
2015
|
+
/* @__PURE__ */ jsx13(
|
|
2016
|
+
YAxis,
|
|
2017
|
+
{
|
|
2018
|
+
axisLine: false,
|
|
2019
|
+
tickFormatter: (value) => formatCompactMetric(value, metricKind),
|
|
2020
|
+
tickLine: false,
|
|
2021
|
+
width: 60
|
|
2022
|
+
}
|
|
2023
|
+
),
|
|
2024
|
+
/* @__PURE__ */ jsx13(
|
|
2025
|
+
Tooltip2,
|
|
2026
|
+
{
|
|
2027
|
+
content: /* @__PURE__ */ jsx13(
|
|
2028
|
+
ChartTooltipContent,
|
|
2029
|
+
{
|
|
2030
|
+
formatter: (value) => formatMetricValue(Number(value), metricKind),
|
|
2031
|
+
labelFormatter: (value) => String(value ?? "")
|
|
2032
|
+
}
|
|
2033
|
+
),
|
|
2034
|
+
cursor: false
|
|
2035
|
+
}
|
|
2036
|
+
),
|
|
2037
|
+
/* @__PURE__ */ jsx13(
|
|
2038
|
+
Legend,
|
|
2039
|
+
{
|
|
2040
|
+
content: /* @__PURE__ */ jsx13(ChartLegendContent, { className: "justify-center pt-3" })
|
|
2041
|
+
}
|
|
2042
|
+
),
|
|
2043
|
+
chartState.series.map((series) => /* @__PURE__ */ jsx13(
|
|
2044
|
+
Bar,
|
|
2045
|
+
{
|
|
2046
|
+
dataKey: series.id,
|
|
2047
|
+
fill: `var(--color-${series.id})`,
|
|
2048
|
+
radius: [4, 4, 0, 0],
|
|
2049
|
+
stackId: "usage"
|
|
2050
|
+
},
|
|
2051
|
+
series.id
|
|
2052
|
+
))
|
|
2053
|
+
]
|
|
2008
2054
|
}
|
|
2009
|
-
),
|
|
2010
|
-
/* @__PURE__ */ jsx12("span", { className: "max-w-48 truncate text-muted-foreground", children: group.label })
|
|
2011
|
-
] }, group.key)) })
|
|
2012
|
-
] }) });
|
|
2013
|
-
}
|
|
2014
|
-
function UsageTable(props) {
|
|
2015
|
-
const rows = props.rows.slice(0, 40);
|
|
2016
|
-
return /* @__PURE__ */ jsxs7("div", { className: "rounded-xl border bg-card p-5 shadow-sm", children: [
|
|
2017
|
-
/* @__PURE__ */ jsxs7("div", { className: "mb-4 flex items-center justify-between gap-3", children: [
|
|
2018
|
-
/* @__PURE__ */ jsx12(SectionHeading, { title: "Usage detail" }),
|
|
2019
|
-
props.isLoading && /* @__PURE__ */ jsx12(Badge, { variant: "outline", children: props.labels.loading })
|
|
2020
|
-
] }),
|
|
2021
|
-
rows.length === 0 ? /* @__PURE__ */ jsx12("p", { className: "text-sm text-muted-foreground", children: props.labels.noResults }) : /* @__PURE__ */ jsx12("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxs7("table", { className: "w-full min-w-[720px] text-sm", children: [
|
|
2022
|
-
/* @__PURE__ */ jsx12("thead", { children: /* @__PURE__ */ jsxs7("tr", { className: "border-b text-left text-xs uppercase tracking-[0.14em] text-muted-foreground", children: [
|
|
2023
|
-
/* @__PURE__ */ jsx12("th", { className: "py-2 pr-4 font-medium", children: "Interval" }),
|
|
2024
|
-
/* @__PURE__ */ jsx12("th", { className: "py-2 pr-4 font-medium", children: "Group" }),
|
|
2025
|
-
/* @__PURE__ */ jsx12("th", { className: "py-2 pr-4 text-right font-medium", children: "Input" }),
|
|
2026
|
-
/* @__PURE__ */ jsx12("th", { className: "py-2 pr-4 text-right font-medium", children: "Output" }),
|
|
2027
|
-
/* @__PURE__ */ jsx12("th", { className: "py-2 pr-4 text-right font-medium", children: "Reasoning" }),
|
|
2028
|
-
/* @__PURE__ */ jsx12("th", { className: "py-2 pr-4 text-right font-medium", children: "Cache read" }),
|
|
2029
|
-
/* @__PURE__ */ jsx12("th", { className: "py-2 pr-4 text-right font-medium", children: "Cache write" }),
|
|
2030
|
-
/* @__PURE__ */ jsx12("th", { className: "py-2 text-right font-medium", children: getUsageSummaryLabel(props.labels, props.metricKind, props.dimension) })
|
|
2031
|
-
] }) }),
|
|
2032
|
-
/* @__PURE__ */ jsx12("tbody", { children: rows.map((row) => /* @__PURE__ */ jsxs7("tr", { className: "border-b last:border-0", children: [
|
|
2033
|
-
/* @__PURE__ */ jsx12("td", { className: "py-2 pr-4 text-muted-foreground", children: formatDate(row.bucket) }),
|
|
2034
|
-
/* @__PURE__ */ jsx12("td", { className: "max-w-72 truncate py-2 pr-4 font-medium", children: row.groupLabel }),
|
|
2035
|
-
/* @__PURE__ */ jsx12("td", { className: "py-2 pr-4 text-right", children: formatMetricValue(getUsagePointValue(row, props.metricKind, "input"), props.metricKind) }),
|
|
2036
|
-
/* @__PURE__ */ jsx12("td", { className: "py-2 pr-4 text-right", children: formatMetricValue(getUsagePointValue(row, props.metricKind, "output"), props.metricKind) }),
|
|
2037
|
-
/* @__PURE__ */ jsx12("td", { className: "py-2 pr-4 text-right", children: formatMetricValue(getUsagePointValue(row, props.metricKind, "reasoning"), props.metricKind) }),
|
|
2038
|
-
/* @__PURE__ */ jsx12("td", { className: "py-2 pr-4 text-right", children: formatMetricValue(getUsagePointValue(row, props.metricKind, "cacheRead"), props.metricKind) }),
|
|
2039
|
-
/* @__PURE__ */ jsx12("td", { className: "py-2 pr-4 text-right", children: formatMetricValue(getUsagePointValue(row, props.metricKind, "cacheWrite"), props.metricKind) }),
|
|
2040
|
-
/* @__PURE__ */ jsx12("td", { className: "py-2 text-right font-medium", children: formatMetricValue(getUsagePointValue(row, props.metricKind, props.dimension), props.metricKind) })
|
|
2041
|
-
] }, `${row.bucket}:${row.groupKey}`)) })
|
|
2042
|
-
] }) })
|
|
2043
|
-
] });
|
|
2044
|
-
}
|
|
2045
|
-
function ActivityChart(props) {
|
|
2046
|
-
const trimmedPoints = props.points.slice(-props.maxBars);
|
|
2047
|
-
const maxUsageValue = Math.max(
|
|
2048
|
-
...trimmedPoints.map(
|
|
2049
|
-
(point) => getActivityUsageValue(
|
|
2050
|
-
point,
|
|
2051
|
-
props.usageMetricKind,
|
|
2052
|
-
props.usageDimension
|
|
2053
2055
|
)
|
|
2054
|
-
|
|
2055
|
-
1
|
|
2056
|
+
}
|
|
2056
2057
|
);
|
|
2057
|
-
return /* @__PURE__ */ jsx12("div", { className: "rounded-xl border bg-card p-5 shadow-sm", children: trimmedPoints.length === 0 ? /* @__PURE__ */ jsx12("p", { className: "text-sm text-muted-foreground", children: props.labels.noResults }) : /* @__PURE__ */ jsx12("div", { className: "flex min-h-48 items-end gap-2", children: trimmedPoints.map((point) => {
|
|
2058
|
-
const usageValue = getActivityUsageValue(
|
|
2059
|
-
point,
|
|
2060
|
-
props.usageMetricKind,
|
|
2061
|
-
props.usageDimension
|
|
2062
|
-
);
|
|
2063
|
-
return /* @__PURE__ */ jsxs7(
|
|
2064
|
-
"div",
|
|
2065
|
-
{
|
|
2066
|
-
className: "flex min-w-0 flex-1 flex-col items-center gap-2",
|
|
2067
|
-
children: [
|
|
2068
|
-
/* @__PURE__ */ jsx12("div", { className: "flex h-36 w-full items-end rounded-lg bg-muted px-1 pb-1", children: /* @__PURE__ */ jsx12(
|
|
2069
|
-
"div",
|
|
2070
|
-
{
|
|
2071
|
-
className: "w-full rounded-md bg-primary transition-all",
|
|
2072
|
-
style: {
|
|
2073
|
-
height: `${Math.max(usageValue / maxUsageValue * 100, 8)}%`
|
|
2074
|
-
}
|
|
2075
|
-
}
|
|
2076
|
-
) }),
|
|
2077
|
-
/* @__PURE__ */ jsxs7("div", { className: "text-center", children: [
|
|
2078
|
-
/* @__PURE__ */ jsx12("p", { className: "text-xs font-medium", children: formatBucket(point.bucket, props.interval) }),
|
|
2079
|
-
/* @__PURE__ */ jsx12("p", { className: "text-[11px] text-muted-foreground", children: formatMetricValue(usageValue, props.usageMetricKind) }),
|
|
2080
|
-
/* @__PURE__ */ jsxs7("p", { className: "text-[11px] text-muted-foreground", children: [
|
|
2081
|
-
formatNumber(point.totalCalls),
|
|
2082
|
-
" ",
|
|
2083
|
-
props.labels.usageCallsDetail
|
|
2084
|
-
] })
|
|
2085
|
-
] })
|
|
2086
|
-
]
|
|
2087
|
-
},
|
|
2088
|
-
point.bucket
|
|
2089
|
-
);
|
|
2090
|
-
}) }) });
|
|
2091
2058
|
}
|
|
2092
|
-
function
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
/* @__PURE__ */ jsx12(SectionHeading, { title: props.title }),
|
|
2096
|
-
/* @__PURE__ */ jsx12(
|
|
2097
|
-
Input,
|
|
2098
|
-
{
|
|
2099
|
-
className: "h-8 w-full max-w-44",
|
|
2100
|
-
onChange: (event) => props.setSearchValue(event.target.value),
|
|
2101
|
-
placeholder: props.searchPlaceholder,
|
|
2102
|
-
value: props.searchValue
|
|
2103
|
-
}
|
|
2104
|
-
)
|
|
2105
|
-
] }),
|
|
2106
|
-
props.rows.length === 0 ? /* @__PURE__ */ jsx12("p", { className: "text-sm text-muted-foreground", children: "No results" }) : props.children
|
|
2107
|
-
] });
|
|
2108
|
-
}
|
|
2109
|
-
function ThreadsTable({
|
|
2110
|
-
rows,
|
|
2059
|
+
function UsageTable({
|
|
2060
|
+
dimension,
|
|
2061
|
+
groupBy,
|
|
2111
2062
|
labels,
|
|
2112
|
-
|
|
2063
|
+
metricKind,
|
|
2064
|
+
onRowFilter,
|
|
2065
|
+
rows,
|
|
2066
|
+
totals
|
|
2113
2067
|
}) {
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2068
|
+
const totalValue = getUsageTotalValue(totals, metricKind, dimension);
|
|
2069
|
+
const filterable = groupBy !== "namespace";
|
|
2070
|
+
return /* @__PURE__ */ jsxs8(Card, { className: "min-h-0 gap-2 overflow-hidden py-3", children: [
|
|
2071
|
+
/* @__PURE__ */ jsx13(CardHeader, { className: "px-4", children: /* @__PURE__ */ jsxs8("div", { className: "flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between", children: [
|
|
2072
|
+
/* @__PURE__ */ jsx13(CardTitle, { className: "text-base", children: "Usage detail" }),
|
|
2073
|
+
/* @__PURE__ */ jsxs8(Badge, { variant: "outline", children: [
|
|
2074
|
+
formatNumber(rows.length),
|
|
2075
|
+
" ",
|
|
2076
|
+
getGroupByLabel(groupBy).toLowerCase()
|
|
2077
|
+
] })
|
|
2078
|
+
] }) }),
|
|
2079
|
+
/* @__PURE__ */ jsx13(CardContent, { className: "min-h-0 flex-1 overflow-hidden px-0", children: rows.length === 0 ? /* @__PURE__ */ jsx13("p", { className: "px-5 py-4 text-sm text-muted-foreground", children: labels.noResults }) : /* @__PURE__ */ jsx13("div", { className: "h-full overflow-auto", children: /* @__PURE__ */ jsxs8("table", { className: "w-full min-w-[940px] text-sm", children: [
|
|
2080
|
+
/* @__PURE__ */ jsx13("thead", { className: "sticky top-0 z-10 bg-card", children: /* @__PURE__ */ jsxs8("tr", { className: "border-b text-left text-xs uppercase tracking-[0.12em] text-muted-foreground", children: [
|
|
2081
|
+
/* @__PURE__ */ jsx13("th", { className: "px-5 py-2.5 font-medium", children: getGroupByLabel(groupBy) }),
|
|
2082
|
+
/* @__PURE__ */ jsx13("th", { className: "px-3 py-2.5 text-right font-medium", children: getUsageSummaryLabel(labels, metricKind, dimension) }),
|
|
2083
|
+
/* @__PURE__ */ jsx13("th", { className: "px-3 py-2.5 text-right font-medium", children: "Share" }),
|
|
2084
|
+
/* @__PURE__ */ jsx13("th", { className: "px-3 py-2.5 text-right font-medium", children: "Calls" }),
|
|
2085
|
+
/* @__PURE__ */ jsx13("th", { className: "px-3 py-2.5 text-right font-medium", children: "Input" }),
|
|
2086
|
+
/* @__PURE__ */ jsx13("th", { className: "px-3 py-2.5 text-right font-medium", children: "Output" }),
|
|
2087
|
+
/* @__PURE__ */ jsx13("th", { className: "px-3 py-2.5 text-right font-medium", children: "Reasoning" }),
|
|
2088
|
+
/* @__PURE__ */ jsx13("th", { className: "px-3 py-2.5 text-right font-medium", children: "Cache read" }),
|
|
2089
|
+
/* @__PURE__ */ jsx13("th", { className: "px-5 py-2.5 text-right font-medium", children: "Avg/call" })
|
|
2090
|
+
] }) }),
|
|
2091
|
+
/* @__PURE__ */ jsx13("tbody", { children: rows.slice(0, 60).map((row) => {
|
|
2092
|
+
const share = totalValue > 0 ? row.value / totalValue : 0;
|
|
2093
|
+
return /* @__PURE__ */ jsxs8(
|
|
2094
|
+
"tr",
|
|
2095
|
+
{
|
|
2096
|
+
className: cn(
|
|
2097
|
+
"border-b last:border-0",
|
|
2098
|
+
filterable && "cursor-pointer transition-colors hover:bg-muted/50"
|
|
2099
|
+
),
|
|
2100
|
+
onClick: () => filterable && onRowFilter(row),
|
|
2101
|
+
children: [
|
|
2102
|
+
/* @__PURE__ */ jsxs8("td", { className: "px-5 py-3", children: [
|
|
2103
|
+
/* @__PURE__ */ jsx13("div", { className: "max-w-80 truncate font-medium", children: row.groupLabel }),
|
|
2104
|
+
row.groupKey !== row.groupLabel && /* @__PURE__ */ jsx13("div", { className: "mt-0.5 max-w-80 truncate text-xs text-muted-foreground", children: row.groupKey })
|
|
2105
|
+
] }),
|
|
2106
|
+
/* @__PURE__ */ jsx13("td", { className: "px-3 py-3 text-right font-medium", children: formatMetricValue(row.value, metricKind) }),
|
|
2107
|
+
/* @__PURE__ */ jsx13("td", { className: "px-3 py-3 text-right", children: formatPercent(share) }),
|
|
2108
|
+
/* @__PURE__ */ jsx13("td", { className: "px-3 py-3 text-right", children: formatNumber(row.totalCalls) }),
|
|
2109
|
+
/* @__PURE__ */ jsx13("td", { className: "px-3 py-3 text-right", children: formatMetricValue(
|
|
2110
|
+
getUsageTotalValue(row, metricKind, "input"),
|
|
2111
|
+
metricKind
|
|
2112
|
+
) }),
|
|
2113
|
+
/* @__PURE__ */ jsx13("td", { className: "px-3 py-3 text-right", children: formatMetricValue(
|
|
2114
|
+
getUsageTotalValue(row, metricKind, "output"),
|
|
2115
|
+
metricKind
|
|
2116
|
+
) }),
|
|
2117
|
+
/* @__PURE__ */ jsx13("td", { className: "px-3 py-3 text-right", children: formatMetricValue(
|
|
2118
|
+
getUsageTotalValue(row, metricKind, "reasoning"),
|
|
2119
|
+
metricKind
|
|
2120
|
+
) }),
|
|
2121
|
+
/* @__PURE__ */ jsx13("td", { className: "px-3 py-3 text-right", children: formatMetricValue(
|
|
2122
|
+
getUsageTotalValue(row, metricKind, "cacheRead"),
|
|
2123
|
+
metricKind
|
|
2124
|
+
) }),
|
|
2125
|
+
/* @__PURE__ */ jsx13("td", { className: "px-5 py-3 text-right", children: formatMetricValue(
|
|
2126
|
+
row.totalCalls > 0 ? row.value / row.totalCalls : 0,
|
|
2127
|
+
metricKind
|
|
2128
|
+
) })
|
|
2129
|
+
]
|
|
2130
|
+
},
|
|
2131
|
+
row.groupKey
|
|
2132
|
+
);
|
|
2133
|
+
}) })
|
|
2134
|
+
] }) }) })
|
|
2135
|
+
] });
|
|
2151
2136
|
}
|
|
2152
|
-
function
|
|
2153
|
-
|
|
2154
|
-
|
|
2137
|
+
function DashboardHeaderControls({
|
|
2138
|
+
attribution,
|
|
2139
|
+
bucket,
|
|
2140
|
+
config,
|
|
2141
|
+
dimension,
|
|
2142
|
+
groupBy,
|
|
2143
|
+
metricKind,
|
|
2144
|
+
period,
|
|
2145
|
+
setAttribution,
|
|
2146
|
+
setBucket,
|
|
2147
|
+
setDimension,
|
|
2148
|
+
setGroupBy,
|
|
2149
|
+
setMetricKind,
|
|
2150
|
+
setPeriod
|
|
2155
2151
|
}) {
|
|
2156
|
-
return /* @__PURE__ */
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
]
|
|
2166
|
-
|
|
2167
|
-
]
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2152
|
+
return /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-1.5", children: [
|
|
2153
|
+
/* @__PURE__ */ jsx13(
|
|
2154
|
+
HeaderSelect,
|
|
2155
|
+
{
|
|
2156
|
+
label: "Period",
|
|
2157
|
+
onValueChange: (value) => setPeriod(value),
|
|
2158
|
+
options: [
|
|
2159
|
+
["24h", config.labels.range24h],
|
|
2160
|
+
["7d", config.labels.range7d],
|
|
2161
|
+
["30d", config.labels.range30d],
|
|
2162
|
+
["custom", "Custom"]
|
|
2163
|
+
],
|
|
2164
|
+
value: period,
|
|
2165
|
+
width: "w-[86px]"
|
|
2166
|
+
}
|
|
2167
|
+
),
|
|
2168
|
+
/* @__PURE__ */ jsx13(
|
|
2169
|
+
HeaderSelect,
|
|
2170
|
+
{
|
|
2171
|
+
label: "Bucket",
|
|
2172
|
+
onValueChange: (value) => setBucket(value),
|
|
2173
|
+
options: [
|
|
2174
|
+
["minute", "Minute"],
|
|
2175
|
+
["hour", "Hour"],
|
|
2176
|
+
["day", "Day"],
|
|
2177
|
+
["week", "Week"],
|
|
2178
|
+
["month", "Month"]
|
|
2179
|
+
],
|
|
2180
|
+
value: bucket,
|
|
2181
|
+
width: "w-[92px]"
|
|
2182
|
+
}
|
|
2183
|
+
),
|
|
2184
|
+
/* @__PURE__ */ jsx13(
|
|
2185
|
+
HeaderSelect,
|
|
2186
|
+
{
|
|
2187
|
+
label: config.labels.usageMetricLabel,
|
|
2188
|
+
onValueChange: (value) => setMetricKind(value),
|
|
2189
|
+
options: [
|
|
2190
|
+
["cost", config.labels.usageMetricCost],
|
|
2191
|
+
["tokens", config.labels.usageMetricTokens],
|
|
2192
|
+
["calls", "Calls"]
|
|
2193
|
+
],
|
|
2194
|
+
value: metricKind,
|
|
2195
|
+
width: "w-[94px]"
|
|
2196
|
+
}
|
|
2197
|
+
),
|
|
2198
|
+
/* @__PURE__ */ jsx13(
|
|
2199
|
+
HeaderSelect,
|
|
2200
|
+
{
|
|
2201
|
+
label: "Group",
|
|
2202
|
+
onValueChange: (value) => setGroupBy(value),
|
|
2203
|
+
options: [
|
|
2204
|
+
["participant", "Participant"],
|
|
2205
|
+
["thread", "Thread"],
|
|
2206
|
+
["namespace", "Namespace"],
|
|
2207
|
+
["provider", "Provider"],
|
|
2208
|
+
["model", "Model"]
|
|
2209
|
+
],
|
|
2210
|
+
value: groupBy,
|
|
2211
|
+
width: "w-[128px]"
|
|
2212
|
+
}
|
|
2213
|
+
),
|
|
2214
|
+
/* @__PURE__ */ jsx13(
|
|
2215
|
+
HeaderSelect,
|
|
2216
|
+
{
|
|
2217
|
+
label: "Attribution",
|
|
2218
|
+
onValueChange: (value) => setAttribution(value),
|
|
2219
|
+
options: [
|
|
2220
|
+
["initiatedBy", "Initiated by"],
|
|
2221
|
+
["generatedBy", "Generated by"]
|
|
2222
|
+
],
|
|
2223
|
+
value: attribution,
|
|
2224
|
+
width: "w-[132px]"
|
|
2225
|
+
}
|
|
2226
|
+
),
|
|
2227
|
+
/* @__PURE__ */ jsx13(
|
|
2228
|
+
HeaderSelect,
|
|
2229
|
+
{
|
|
2230
|
+
label: config.labels.usageDimensionLabel,
|
|
2231
|
+
onValueChange: (value) => setDimension(value),
|
|
2232
|
+
options: USAGE_DIMENSIONS.map((nextDimension) => [
|
|
2233
|
+
nextDimension,
|
|
2234
|
+
getUsageDimensionLabel(config.labels, nextDimension)
|
|
2235
|
+
]),
|
|
2236
|
+
value: dimension,
|
|
2237
|
+
width: "w-[116px]"
|
|
2238
|
+
}
|
|
2239
|
+
)
|
|
2240
|
+
] });
|
|
2183
2241
|
}
|
|
2184
|
-
function
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2242
|
+
function InlineFilters({
|
|
2243
|
+
activeFilterCount,
|
|
2244
|
+
clearFilters,
|
|
2245
|
+
customFrom,
|
|
2246
|
+
customTo,
|
|
2247
|
+
model,
|
|
2248
|
+
participantId,
|
|
2249
|
+
participantType,
|
|
2250
|
+
period,
|
|
2251
|
+
provider,
|
|
2252
|
+
setCustomFrom,
|
|
2253
|
+
setCustomTo,
|
|
2254
|
+
setModel,
|
|
2255
|
+
setParticipantId,
|
|
2256
|
+
setParticipantType,
|
|
2257
|
+
setProvider,
|
|
2258
|
+
setThreadId,
|
|
2259
|
+
threadId
|
|
2189
2260
|
}) {
|
|
2190
|
-
return /* @__PURE__ */
|
|
2191
|
-
"div",
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
children:
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2261
|
+
return /* @__PURE__ */ jsxs8("div", { className: "flex max-w-full flex-wrap items-end justify-end gap-2", children: [
|
|
2262
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2 pb-1 text-xs font-medium text-muted-foreground", children: [
|
|
2263
|
+
/* @__PURE__ */ jsx13(Filter, { className: "size-3.5" }),
|
|
2264
|
+
/* @__PURE__ */ jsx13("span", { children: "Filters" }),
|
|
2265
|
+
activeFilterCount > 0 && /* @__PURE__ */ jsx13(Badge, { variant: "secondary", children: activeFilterCount })
|
|
2266
|
+
] }),
|
|
2267
|
+
period === "custom" && /* @__PURE__ */ jsxs8(Fragment2, { children: [
|
|
2268
|
+
/* @__PURE__ */ jsx13(
|
|
2269
|
+
FilterInput,
|
|
2270
|
+
{
|
|
2271
|
+
compact: true,
|
|
2272
|
+
label: "From",
|
|
2273
|
+
onChange: setCustomFrom,
|
|
2274
|
+
type: "datetime-local",
|
|
2275
|
+
value: customFrom
|
|
2276
|
+
}
|
|
2277
|
+
),
|
|
2278
|
+
/* @__PURE__ */ jsx13(
|
|
2279
|
+
FilterInput,
|
|
2280
|
+
{
|
|
2281
|
+
compact: true,
|
|
2282
|
+
label: "To",
|
|
2283
|
+
onChange: setCustomTo,
|
|
2284
|
+
type: "datetime-local",
|
|
2285
|
+
value: customTo
|
|
2286
|
+
}
|
|
2287
|
+
)
|
|
2288
|
+
] }),
|
|
2289
|
+
/* @__PURE__ */ jsx13(
|
|
2290
|
+
UsageSelect,
|
|
2291
|
+
{
|
|
2292
|
+
compact: true,
|
|
2293
|
+
label: "Type",
|
|
2294
|
+
onValueChange: (value) => setParticipantType(value),
|
|
2295
|
+
options: [
|
|
2296
|
+
["all", "All"],
|
|
2297
|
+
["human", "Human"],
|
|
2298
|
+
["agent", "Agent"],
|
|
2299
|
+
["job", "Job"]
|
|
2300
|
+
],
|
|
2301
|
+
value: participantType
|
|
2302
|
+
}
|
|
2303
|
+
),
|
|
2304
|
+
/* @__PURE__ */ jsx13(
|
|
2305
|
+
FilterInput,
|
|
2306
|
+
{
|
|
2307
|
+
compact: true,
|
|
2308
|
+
icon: /* @__PURE__ */ jsx13(Search, { className: "size-3.5" }),
|
|
2309
|
+
label: "Thread",
|
|
2310
|
+
onChange: setThreadId,
|
|
2311
|
+
value: threadId
|
|
2312
|
+
}
|
|
2313
|
+
),
|
|
2314
|
+
/* @__PURE__ */ jsx13(
|
|
2315
|
+
FilterInput,
|
|
2316
|
+
{
|
|
2317
|
+
compact: true,
|
|
2318
|
+
icon: /* @__PURE__ */ jsx13(Users2, { className: "size-3.5" }),
|
|
2319
|
+
label: "Participant",
|
|
2320
|
+
onChange: setParticipantId,
|
|
2321
|
+
value: participantId
|
|
2322
|
+
}
|
|
2323
|
+
),
|
|
2324
|
+
/* @__PURE__ */ jsx13(
|
|
2325
|
+
FilterInput,
|
|
2326
|
+
{
|
|
2327
|
+
compact: true,
|
|
2328
|
+
icon: /* @__PURE__ */ jsx13(Database2, { className: "size-3.5" }),
|
|
2329
|
+
label: "Provider",
|
|
2330
|
+
onChange: setProvider,
|
|
2331
|
+
value: provider
|
|
2332
|
+
}
|
|
2333
|
+
),
|
|
2334
|
+
/* @__PURE__ */ jsx13(
|
|
2335
|
+
FilterInput,
|
|
2336
|
+
{
|
|
2337
|
+
compact: true,
|
|
2338
|
+
icon: /* @__PURE__ */ jsx13(Sparkles, { className: "size-3.5" }),
|
|
2339
|
+
label: "Model",
|
|
2340
|
+
onChange: setModel,
|
|
2341
|
+
value: model
|
|
2342
|
+
}
|
|
2343
|
+
),
|
|
2344
|
+
activeFilterCount > 0 && /* @__PURE__ */ jsx13(
|
|
2345
|
+
Button,
|
|
2346
|
+
{
|
|
2347
|
+
className: "h-8",
|
|
2348
|
+
onClick: clearFilters,
|
|
2349
|
+
size: "sm",
|
|
2350
|
+
variant: "ghost",
|
|
2351
|
+
children: "Clear"
|
|
2352
|
+
}
|
|
2353
|
+
)
|
|
2354
|
+
] });
|
|
2230
2355
|
}
|
|
2231
|
-
function
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2356
|
+
function HeaderSelect(props) {
|
|
2357
|
+
return /* @__PURE__ */ jsxs8(Select, { value: props.value, onValueChange: props.onValueChange, children: [
|
|
2358
|
+
/* @__PURE__ */ jsx13(
|
|
2359
|
+
SelectTrigger,
|
|
2360
|
+
{
|
|
2361
|
+
"aria-label": props.label,
|
|
2362
|
+
className: cn("h-8 bg-background text-xs", props.width),
|
|
2363
|
+
children: /* @__PURE__ */ jsx13(SelectValue, {})
|
|
2364
|
+
}
|
|
2365
|
+
),
|
|
2366
|
+
/* @__PURE__ */ jsx13(SelectContent, { children: props.options.map(([value, label]) => /* @__PURE__ */ jsx13(SelectItem, { value, children: label }, value)) })
|
|
2367
|
+
] });
|
|
2242
2368
|
}
|
|
2243
|
-
function
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
month: "short",
|
|
2262
|
-
day: "numeric"
|
|
2263
|
-
});
|
|
2369
|
+
function UsageSelect(props) {
|
|
2370
|
+
return /* @__PURE__ */ jsxs8("label", { className: cn("space-y-1", props.compact && "w-[116px]"), children: [
|
|
2371
|
+
/* @__PURE__ */ jsx13("span", { className: "sr-only", children: props.label }),
|
|
2372
|
+
/* @__PURE__ */ jsxs8(Select, { value: props.value, onValueChange: props.onValueChange, children: [
|
|
2373
|
+
/* @__PURE__ */ jsx13(
|
|
2374
|
+
SelectTrigger,
|
|
2375
|
+
{
|
|
2376
|
+
"aria-label": props.label,
|
|
2377
|
+
className: cn(
|
|
2378
|
+
"w-full min-w-0 bg-background",
|
|
2379
|
+
props.compact ? "h-8 text-xs" : "h-9"
|
|
2380
|
+
),
|
|
2381
|
+
children: /* @__PURE__ */ jsx13(SelectValue, {})
|
|
2382
|
+
}
|
|
2383
|
+
),
|
|
2384
|
+
/* @__PURE__ */ jsx13(SelectContent, { children: props.options.map(([value, label]) => /* @__PURE__ */ jsx13(SelectItem, { value, children: label }, value)) })
|
|
2385
|
+
] })
|
|
2386
|
+
] });
|
|
2264
2387
|
}
|
|
2265
|
-
function
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2388
|
+
function FilterInput(props) {
|
|
2389
|
+
return /* @__PURE__ */ jsxs8("label", { className: cn("space-y-1", props.compact && "w-[150px]"), children: [
|
|
2390
|
+
/* @__PURE__ */ jsx13("span", { className: "sr-only", children: props.label }),
|
|
2391
|
+
/* @__PURE__ */ jsxs8("div", { className: "relative", children: [
|
|
2392
|
+
props.icon && /* @__PURE__ */ jsx13("span", { className: "pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground", children: props.icon }),
|
|
2393
|
+
/* @__PURE__ */ jsx13(
|
|
2394
|
+
Input,
|
|
2395
|
+
{
|
|
2396
|
+
"aria-label": props.label,
|
|
2397
|
+
className: cn(
|
|
2398
|
+
"bg-background",
|
|
2399
|
+
props.compact ? "h-8 text-xs" : "h-9",
|
|
2400
|
+
props.icon && "pl-8"
|
|
2401
|
+
),
|
|
2402
|
+
onChange: (event) => props.onChange(event.target.value),
|
|
2403
|
+
type: props.type ?? "text",
|
|
2404
|
+
value: props.value
|
|
2405
|
+
}
|
|
2406
|
+
)
|
|
2407
|
+
] })
|
|
2408
|
+
] });
|
|
2275
2409
|
}
|
|
2276
|
-
function
|
|
2277
|
-
|
|
2410
|
+
function EmptyDashboard({
|
|
2411
|
+
description,
|
|
2412
|
+
title
|
|
2413
|
+
}) {
|
|
2414
|
+
return /* @__PURE__ */ jsxs8("div", { className: "rounded-lg border border-dashed bg-muted/20 p-8 text-center", children: [
|
|
2415
|
+
/* @__PURE__ */ jsx13("h3", { className: "text-base font-semibold", children: title }),
|
|
2416
|
+
/* @__PURE__ */ jsx13("p", { className: "mt-2 text-sm text-muted-foreground", children: description })
|
|
2417
|
+
] });
|
|
2278
2418
|
}
|
|
2419
|
+
var EMPTY_TOTALS = {
|
|
2420
|
+
inputTokens: 0,
|
|
2421
|
+
outputTokens: 0,
|
|
2422
|
+
reasoningTokens: 0,
|
|
2423
|
+
cacheReadInputTokens: 0,
|
|
2424
|
+
cacheCreationInputTokens: 0,
|
|
2425
|
+
totalTokens: 0,
|
|
2426
|
+
inputCostUsd: 0,
|
|
2427
|
+
outputCostUsd: 0,
|
|
2428
|
+
reasoningCostUsd: 0,
|
|
2429
|
+
cacheReadInputCostUsd: 0,
|
|
2430
|
+
cacheCreationInputCostUsd: 0,
|
|
2431
|
+
totalCostUsd: 0,
|
|
2432
|
+
totalCalls: 0
|
|
2433
|
+
};
|
|
2279
2434
|
var USAGE_DIMENSIONS = [
|
|
2280
2435
|
"total",
|
|
2281
2436
|
"input",
|
|
@@ -2292,27 +2447,43 @@ var USAGE_CHART_COLORS = [
|
|
|
2292
2447
|
"hsl(var(--chart-5, 346 77% 49%))",
|
|
2293
2448
|
"hsl(var(--muted-foreground))"
|
|
2294
2449
|
];
|
|
2295
|
-
function
|
|
2296
|
-
const
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2450
|
+
function buildChartState(points, metricKind, dimension, interval) {
|
|
2451
|
+
const topGroups = topUsageGroups(points, metricKind, dimension);
|
|
2452
|
+
const groupIdByKey = new Map(topGroups.map((group, index) => [
|
|
2453
|
+
group.key,
|
|
2454
|
+
`series${index + 1}`
|
|
2455
|
+
]));
|
|
2456
|
+
const series = topGroups.map((group, index) => ({
|
|
2457
|
+
color: USAGE_CHART_COLORS[index % USAGE_CHART_COLORS.length],
|
|
2458
|
+
id: groupIdByKey.get(group.key) ?? `series${index + 1}`,
|
|
2459
|
+
key: group.key,
|
|
2460
|
+
label: group.label
|
|
2461
|
+
}));
|
|
2462
|
+
const config = Object.fromEntries(
|
|
2463
|
+
series.map((item) => [item.id, {
|
|
2464
|
+
color: item.color,
|
|
2465
|
+
label: item.label
|
|
2466
|
+
}])
|
|
2467
|
+
);
|
|
2468
|
+
const buckets = buildUsageBuckets(points);
|
|
2469
|
+
const data = buckets.map((bucket) => {
|
|
2470
|
+
const row = {
|
|
2471
|
+
bucket: bucket.bucket,
|
|
2472
|
+
label: formatUsageBucket(bucket.bucket, interval)
|
|
2304
2473
|
};
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
}
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2474
|
+
for (const item of series) row[item.id] = 0;
|
|
2475
|
+
for (const point of bucket.points) {
|
|
2476
|
+
const seriesId = groupIdByKey.get(point.groupKey);
|
|
2477
|
+
if (!seriesId) continue;
|
|
2478
|
+
row[seriesId] = Number(row[seriesId] ?? 0) + getUsageTotalValue(point, metricKind, dimension);
|
|
2479
|
+
}
|
|
2480
|
+
return row;
|
|
2481
|
+
});
|
|
2482
|
+
return {
|
|
2483
|
+
config,
|
|
2484
|
+
data,
|
|
2485
|
+
series
|
|
2486
|
+
};
|
|
2316
2487
|
}
|
|
2317
2488
|
function buildUsageBuckets(points) {
|
|
2318
2489
|
const byBucket = /* @__PURE__ */ new Map();
|
|
@@ -2321,7 +2492,39 @@ function buildUsageBuckets(points) {
|
|
|
2321
2492
|
rows.push(point);
|
|
2322
2493
|
byBucket.set(point.bucket, rows);
|
|
2323
2494
|
}
|
|
2324
|
-
return Array.from(byBucket.entries()).map(([bucket, bucketPoints]) => ({ bucket, points: bucketPoints })).sort(
|
|
2495
|
+
return Array.from(byBucket.entries()).map(([bucket, bucketPoints]) => ({ bucket, points: bucketPoints })).sort(
|
|
2496
|
+
(a, b) => new Date(a.bucket).getTime() - new Date(b.bucket).getTime()
|
|
2497
|
+
);
|
|
2498
|
+
}
|
|
2499
|
+
function aggregateUsageRows(points, metricKind, dimension) {
|
|
2500
|
+
const totals = /* @__PURE__ */ new Map();
|
|
2501
|
+
for (const point of points) {
|
|
2502
|
+
const existing = totals.get(point.groupKey) ?? {
|
|
2503
|
+
...EMPTY_TOTALS,
|
|
2504
|
+
groupKey: point.groupKey,
|
|
2505
|
+
groupLabel: point.groupLabel,
|
|
2506
|
+
value: 0
|
|
2507
|
+
};
|
|
2508
|
+
addUsageTotals(existing, point);
|
|
2509
|
+
existing.value = getUsageTotalValue(existing, metricKind, dimension);
|
|
2510
|
+
totals.set(point.groupKey, existing);
|
|
2511
|
+
}
|
|
2512
|
+
return Array.from(totals.values()).sort((a, b) => b.value - a.value);
|
|
2513
|
+
}
|
|
2514
|
+
function addUsageTotals(target, source) {
|
|
2515
|
+
target.inputTokens += source.inputTokens;
|
|
2516
|
+
target.outputTokens += source.outputTokens;
|
|
2517
|
+
target.reasoningTokens += source.reasoningTokens;
|
|
2518
|
+
target.cacheReadInputTokens += source.cacheReadInputTokens;
|
|
2519
|
+
target.cacheCreationInputTokens += source.cacheCreationInputTokens;
|
|
2520
|
+
target.totalTokens += source.totalTokens;
|
|
2521
|
+
target.inputCostUsd += source.inputCostUsd;
|
|
2522
|
+
target.outputCostUsd += source.outputCostUsd;
|
|
2523
|
+
target.reasoningCostUsd += source.reasoningCostUsd;
|
|
2524
|
+
target.cacheReadInputCostUsd += source.cacheReadInputCostUsd;
|
|
2525
|
+
target.cacheCreationInputCostUsd += source.cacheCreationInputCostUsd;
|
|
2526
|
+
target.totalCostUsd += source.totalCostUsd;
|
|
2527
|
+
target.totalCalls += source.totalCalls;
|
|
2325
2528
|
}
|
|
2326
2529
|
function topUsageGroups(points, metricKind, dimension) {
|
|
2327
2530
|
const totals = /* @__PURE__ */ new Map();
|
|
@@ -2331,11 +2534,33 @@ function topUsageGroups(points, metricKind, dimension) {
|
|
|
2331
2534
|
label: point.groupLabel,
|
|
2332
2535
|
value: 0
|
|
2333
2536
|
};
|
|
2334
|
-
existing.value +=
|
|
2537
|
+
existing.value += getUsageTotalValue(point, metricKind, dimension);
|
|
2335
2538
|
totals.set(point.groupKey, existing);
|
|
2336
2539
|
}
|
|
2337
2540
|
return Array.from(totals.values()).sort((a, b) => b.value - a.value).slice(0, 6);
|
|
2338
2541
|
}
|
|
2542
|
+
function getUsageRange(period, customFrom, customTo) {
|
|
2543
|
+
if (period === "custom") {
|
|
2544
|
+
return {
|
|
2545
|
+
from: customFrom ? new Date(customFrom).toISOString() : void 0,
|
|
2546
|
+
to: customTo ? new Date(customTo).toISOString() : void 0
|
|
2547
|
+
};
|
|
2548
|
+
}
|
|
2549
|
+
const to = /* @__PURE__ */ new Date();
|
|
2550
|
+
const from = new Date(to);
|
|
2551
|
+
if (period === "24h") {
|
|
2552
|
+
from.setHours(from.getHours() - 24);
|
|
2553
|
+
} else if (period === "30d") {
|
|
2554
|
+
from.setDate(from.getDate() - 30);
|
|
2555
|
+
} else {
|
|
2556
|
+
from.setDate(from.getDate() - 7);
|
|
2557
|
+
}
|
|
2558
|
+
return { from: from.toISOString(), to: to.toISOString() };
|
|
2559
|
+
}
|
|
2560
|
+
function emptyToUndefined(value) {
|
|
2561
|
+
const trimmed = value.trim();
|
|
2562
|
+
return trimmed.length > 0 ? trimmed : void 0;
|
|
2563
|
+
}
|
|
2339
2564
|
function getUsageDimensionLabel(labels, dimension) {
|
|
2340
2565
|
switch (dimension) {
|
|
2341
2566
|
case "input":
|
|
@@ -2357,146 +2582,100 @@ function getUsageSummaryLabel(labels, metricKind, dimension) {
|
|
|
2357
2582
|
const metricLabel = metricKind === "cost" ? labels.usageMetricCost : metricKind === "calls" ? "Calls" : labels.usageMetricTokens;
|
|
2358
2583
|
return `${getUsageDimensionLabel(labels, dimension)} ${metricLabel}`;
|
|
2359
2584
|
}
|
|
2360
|
-
function
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
case "cacheRead":
|
|
2372
|
-
return llmTotals.cacheReadInputCostUsd;
|
|
2373
|
-
case "cacheWrite":
|
|
2374
|
-
return llmTotals.cacheCreationInputCostUsd;
|
|
2375
|
-
case "total":
|
|
2376
|
-
default:
|
|
2377
|
-
return llmTotals.totalCostUsd;
|
|
2378
|
-
}
|
|
2379
|
-
}
|
|
2380
|
-
switch (dimension) {
|
|
2381
|
-
case "input":
|
|
2382
|
-
return llmTotals.inputTokens;
|
|
2383
|
-
case "output":
|
|
2384
|
-
return llmTotals.outputTokens;
|
|
2385
|
-
case "reasoning":
|
|
2386
|
-
return llmTotals.reasoningTokens;
|
|
2387
|
-
case "cacheRead":
|
|
2388
|
-
return llmTotals.cacheReadInputTokens;
|
|
2389
|
-
case "cacheWrite":
|
|
2390
|
-
return llmTotals.cacheCreationInputTokens;
|
|
2391
|
-
case "total":
|
|
2585
|
+
function getGroupByLabel(groupBy) {
|
|
2586
|
+
switch (groupBy) {
|
|
2587
|
+
case "thread":
|
|
2588
|
+
return "Thread";
|
|
2589
|
+
case "namespace":
|
|
2590
|
+
return "Namespace";
|
|
2591
|
+
case "provider":
|
|
2592
|
+
return "Provider";
|
|
2593
|
+
case "model":
|
|
2594
|
+
return "Model";
|
|
2595
|
+
case "participant":
|
|
2392
2596
|
default:
|
|
2393
|
-
return
|
|
2597
|
+
return "Participant";
|
|
2394
2598
|
}
|
|
2395
2599
|
}
|
|
2396
|
-
function
|
|
2600
|
+
function getUsageTotalValue(totals, metricKind, dimension) {
|
|
2601
|
+
if (metricKind === "calls") return totals.totalCalls;
|
|
2397
2602
|
if (metricKind === "cost") {
|
|
2398
2603
|
switch (dimension) {
|
|
2399
2604
|
case "input":
|
|
2400
|
-
return
|
|
2605
|
+
return totals.inputCostUsd;
|
|
2401
2606
|
case "output":
|
|
2402
|
-
return
|
|
2607
|
+
return totals.outputCostUsd;
|
|
2403
2608
|
case "reasoning":
|
|
2404
|
-
return
|
|
2609
|
+
return totals.reasoningCostUsd;
|
|
2405
2610
|
case "cacheRead":
|
|
2406
|
-
return
|
|
2611
|
+
return totals.cacheReadInputCostUsd;
|
|
2407
2612
|
case "cacheWrite":
|
|
2408
|
-
return
|
|
2613
|
+
return totals.cacheCreationInputCostUsd;
|
|
2409
2614
|
case "total":
|
|
2410
2615
|
default:
|
|
2411
|
-
return
|
|
2616
|
+
return totals.totalCostUsd;
|
|
2412
2617
|
}
|
|
2413
2618
|
}
|
|
2414
|
-
if (metricKind === "calls") return agent.llmCallCount;
|
|
2415
2619
|
switch (dimension) {
|
|
2416
2620
|
case "input":
|
|
2417
|
-
return
|
|
2621
|
+
return totals.inputTokens;
|
|
2418
2622
|
case "output":
|
|
2419
|
-
return
|
|
2623
|
+
return totals.outputTokens;
|
|
2420
2624
|
case "reasoning":
|
|
2421
|
-
return
|
|
2625
|
+
return totals.reasoningTokens;
|
|
2422
2626
|
case "cacheRead":
|
|
2423
|
-
return
|
|
2627
|
+
return totals.cacheReadInputTokens;
|
|
2424
2628
|
case "cacheWrite":
|
|
2425
|
-
return
|
|
2629
|
+
return totals.cacheCreationInputTokens;
|
|
2426
2630
|
case "total":
|
|
2427
2631
|
default:
|
|
2428
|
-
return
|
|
2632
|
+
return totals.totalTokens;
|
|
2429
2633
|
}
|
|
2430
2634
|
}
|
|
2431
|
-
function
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
return point.cacheReadInputCostUsd;
|
|
2442
|
-
case "cacheWrite":
|
|
2443
|
-
return point.cacheCreationInputCostUsd;
|
|
2444
|
-
case "total":
|
|
2445
|
-
default:
|
|
2446
|
-
return point.totalCostUsd;
|
|
2447
|
-
}
|
|
2635
|
+
function formatUsageBucket(bucket, interval) {
|
|
2636
|
+
const date = new Date(bucket);
|
|
2637
|
+
if (Number.isNaN(date.getTime())) return bucket;
|
|
2638
|
+
if (interval === "minute" || interval === "hour") {
|
|
2639
|
+
return date.toLocaleString(void 0, {
|
|
2640
|
+
month: "short",
|
|
2641
|
+
day: "numeric",
|
|
2642
|
+
hour: "numeric",
|
|
2643
|
+
minute: interval === "minute" ? "2-digit" : void 0
|
|
2644
|
+
});
|
|
2448
2645
|
}
|
|
2449
|
-
if (
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
return point.outputTokens;
|
|
2455
|
-
case "reasoning":
|
|
2456
|
-
return point.reasoningTokens;
|
|
2457
|
-
case "cacheRead":
|
|
2458
|
-
return point.cacheReadInputTokens;
|
|
2459
|
-
case "cacheWrite":
|
|
2460
|
-
return point.cacheCreationInputTokens;
|
|
2461
|
-
case "total":
|
|
2462
|
-
default:
|
|
2463
|
-
return point.totalTokens;
|
|
2646
|
+
if (interval === "month") {
|
|
2647
|
+
return date.toLocaleDateString(void 0, {
|
|
2648
|
+
month: "short",
|
|
2649
|
+
year: "numeric"
|
|
2650
|
+
});
|
|
2464
2651
|
}
|
|
2652
|
+
return date.toLocaleDateString(void 0, {
|
|
2653
|
+
month: "short",
|
|
2654
|
+
day: "numeric"
|
|
2655
|
+
});
|
|
2465
2656
|
}
|
|
2466
|
-
function
|
|
2467
|
-
if (
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
case "output":
|
|
2489
|
-
return point.outputTokens;
|
|
2490
|
-
case "reasoning":
|
|
2491
|
-
return point.reasoningTokens;
|
|
2492
|
-
case "cacheRead":
|
|
2493
|
-
return point.cacheReadInputTokens;
|
|
2494
|
-
case "cacheWrite":
|
|
2495
|
-
return point.cacheCreationInputTokens;
|
|
2496
|
-
case "total":
|
|
2497
|
-
default:
|
|
2498
|
-
return point.totalTokens;
|
|
2499
|
-
}
|
|
2657
|
+
function formatUsageRangeLabel(period, range) {
|
|
2658
|
+
if (period !== "custom") return period;
|
|
2659
|
+
if (!range.from && !range.to) return "Custom";
|
|
2660
|
+
return `${formatShortDate(range.from)} - ${formatShortDate(range.to)}`;
|
|
2661
|
+
}
|
|
2662
|
+
function formatShortDate(value) {
|
|
2663
|
+
if (!value) return "Open";
|
|
2664
|
+
const date = new Date(value);
|
|
2665
|
+
if (Number.isNaN(date.getTime())) return value;
|
|
2666
|
+
return date.toLocaleDateString(void 0, {
|
|
2667
|
+
month: "short",
|
|
2668
|
+
day: "numeric"
|
|
2669
|
+
});
|
|
2670
|
+
}
|
|
2671
|
+
function formatNumber(value) {
|
|
2672
|
+
return new Intl.NumberFormat().format(value);
|
|
2673
|
+
}
|
|
2674
|
+
function formatPercent(value) {
|
|
2675
|
+
return new Intl.NumberFormat(void 0, {
|
|
2676
|
+
maximumFractionDigits: 1,
|
|
2677
|
+
style: "percent"
|
|
2678
|
+
}).format(value);
|
|
2500
2679
|
}
|
|
2501
2680
|
function formatMetricValue(value, metricKind) {
|
|
2502
2681
|
if (metricKind === "cost") {
|
|
@@ -2511,10 +2690,26 @@ function formatMetricValue(value, metricKind) {
|
|
|
2511
2690
|
}
|
|
2512
2691
|
return formatNumber(value);
|
|
2513
2692
|
}
|
|
2693
|
+
function formatCompactMetric(value, metricKind) {
|
|
2694
|
+
if (metricKind === "cost") {
|
|
2695
|
+
return new Intl.NumberFormat(void 0, {
|
|
2696
|
+
compactDisplay: "short",
|
|
2697
|
+
currency: "USD",
|
|
2698
|
+
maximumFractionDigits: 1,
|
|
2699
|
+
notation: "compact",
|
|
2700
|
+
style: "currency"
|
|
2701
|
+
}).format(value);
|
|
2702
|
+
}
|
|
2703
|
+
return new Intl.NumberFormat(void 0, {
|
|
2704
|
+
compactDisplay: "short",
|
|
2705
|
+
maximumFractionDigits: 1,
|
|
2706
|
+
notation: "compact"
|
|
2707
|
+
}).format(value);
|
|
2708
|
+
}
|
|
2514
2709
|
|
|
2515
2710
|
// src/components/views/ThreadsView.tsx
|
|
2516
|
-
import { Search, MessageSquare as MessageSquare2 } from "lucide-react";
|
|
2517
|
-
import { jsx as
|
|
2711
|
+
import { Search as Search2, MessageSquare as MessageSquare2 } from "lucide-react";
|
|
2712
|
+
import { jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2518
2713
|
var ThreadsView = ({
|
|
2519
2714
|
config,
|
|
2520
2715
|
threads,
|
|
@@ -2522,10 +2717,10 @@ var ThreadsView = ({
|
|
|
2522
2717
|
onSearchChange,
|
|
2523
2718
|
onThreadClick
|
|
2524
2719
|
}) => {
|
|
2525
|
-
return /* @__PURE__ */
|
|
2526
|
-
/* @__PURE__ */
|
|
2527
|
-
/* @__PURE__ */
|
|
2528
|
-
/* @__PURE__ */
|
|
2720
|
+
return /* @__PURE__ */ jsxs9("div", { className: "space-y-4", children: [
|
|
2721
|
+
/* @__PURE__ */ jsxs9("div", { className: "relative max-w-sm", children: [
|
|
2722
|
+
/* @__PURE__ */ jsx14(Search2, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
|
|
2723
|
+
/* @__PURE__ */ jsx14(
|
|
2529
2724
|
Input,
|
|
2530
2725
|
{
|
|
2531
2726
|
className: "pl-9",
|
|
@@ -2535,19 +2730,19 @@ var ThreadsView = ({
|
|
|
2535
2730
|
}
|
|
2536
2731
|
)
|
|
2537
2732
|
] }),
|
|
2538
|
-
threads.length === 0 ? /* @__PURE__ */
|
|
2539
|
-
/* @__PURE__ */
|
|
2540
|
-
/* @__PURE__ */
|
|
2541
|
-
] }) : /* @__PURE__ */
|
|
2733
|
+
threads.length === 0 ? /* @__PURE__ */ jsxs9("div", { className: "rounded-xl border border-dashed p-10 text-center", children: [
|
|
2734
|
+
/* @__PURE__ */ jsx14(MessageSquare2, { className: "mx-auto h-8 w-8 text-muted-foreground/50" }),
|
|
2735
|
+
/* @__PURE__ */ jsx14("p", { className: "mt-3 text-sm text-muted-foreground", children: searchValue ? config.labels.noResults : config.labels.emptyDescription })
|
|
2736
|
+
] }) : /* @__PURE__ */ jsx14("div", { className: "space-y-2", children: threads.map((thread) => /* @__PURE__ */ jsxs9(
|
|
2542
2737
|
"div",
|
|
2543
2738
|
{
|
|
2544
2739
|
className: "flex items-center gap-4 rounded-lg border bg-card p-4 transition-colors hover:bg-muted/50 cursor-pointer",
|
|
2545
2740
|
onClick: () => onThreadClick?.(thread.threadId),
|
|
2546
2741
|
children: [
|
|
2547
|
-
/* @__PURE__ */
|
|
2548
|
-
/* @__PURE__ */
|
|
2549
|
-
/* @__PURE__ */
|
|
2550
|
-
/* @__PURE__ */
|
|
2742
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex-1 min-w-0", children: [
|
|
2743
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2", children: [
|
|
2744
|
+
/* @__PURE__ */ jsx14("p", { className: "font-medium truncate", children: thread.name }),
|
|
2745
|
+
/* @__PURE__ */ jsx14(
|
|
2551
2746
|
Badge,
|
|
2552
2747
|
{
|
|
2553
2748
|
variant: thread.status === "archived" ? "secondary" : "default",
|
|
@@ -2556,18 +2751,18 @@ var ThreadsView = ({
|
|
|
2556
2751
|
}
|
|
2557
2752
|
)
|
|
2558
2753
|
] }),
|
|
2559
|
-
/* @__PURE__ */
|
|
2754
|
+
/* @__PURE__ */ jsx14("p", { className: "mt-1 text-sm text-muted-foreground truncate", children: thread.summary ?? thread.lastMessagePreview ?? "No summary yet" })
|
|
2560
2755
|
] }),
|
|
2561
|
-
/* @__PURE__ */
|
|
2562
|
-
/* @__PURE__ */
|
|
2756
|
+
/* @__PURE__ */ jsxs9("div", { className: "text-right text-xs text-muted-foreground shrink-0 space-y-1", children: [
|
|
2757
|
+
/* @__PURE__ */ jsxs9("p", { children: [
|
|
2563
2758
|
formatNumber2(thread.messageCount),
|
|
2564
2759
|
" messages"
|
|
2565
2760
|
] }),
|
|
2566
|
-
/* @__PURE__ */
|
|
2761
|
+
/* @__PURE__ */ jsxs9("p", { children: [
|
|
2567
2762
|
thread.participantIds.length,
|
|
2568
2763
|
" participants"
|
|
2569
2764
|
] }),
|
|
2570
|
-
/* @__PURE__ */
|
|
2765
|
+
/* @__PURE__ */ jsx14("p", { children: formatDate(thread.lastActivityAt) })
|
|
2571
2766
|
] })
|
|
2572
2767
|
]
|
|
2573
2768
|
},
|
|
@@ -2575,7 +2770,7 @@ var ThreadsView = ({
|
|
|
2575
2770
|
)) })
|
|
2576
2771
|
] });
|
|
2577
2772
|
};
|
|
2578
|
-
function
|
|
2773
|
+
function formatDate(value) {
|
|
2579
2774
|
if (!value) return "No activity";
|
|
2580
2775
|
const date = new Date(value);
|
|
2581
2776
|
if (Number.isNaN(date.getTime())) return value;
|
|
@@ -2601,7 +2796,7 @@ import {
|
|
|
2601
2796
|
Wrench,
|
|
2602
2797
|
Cpu
|
|
2603
2798
|
} from "lucide-react";
|
|
2604
|
-
import { jsx as
|
|
2799
|
+
import { jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2605
2800
|
var MESSAGES_PAGE_SIZE = 50;
|
|
2606
2801
|
var ThreadDetailView = ({
|
|
2607
2802
|
threadId,
|
|
@@ -2659,36 +2854,36 @@ var ThreadDetailView = ({
|
|
|
2659
2854
|
}
|
|
2660
2855
|
}, [threadId, pageInfo, isLoadingMore, config.baseUrl, config.getRequestHeaders]);
|
|
2661
2856
|
if (isLoading) {
|
|
2662
|
-
return /* @__PURE__ */
|
|
2857
|
+
return /* @__PURE__ */ jsx15("div", { className: "flex items-center justify-center py-20", children: /* @__PURE__ */ jsx15(Loader2, { className: "h-6 w-6 animate-spin text-muted-foreground" }) });
|
|
2663
2858
|
}
|
|
2664
2859
|
if (error) {
|
|
2665
|
-
return /* @__PURE__ */
|
|
2666
|
-
/* @__PURE__ */
|
|
2667
|
-
/* @__PURE__ */
|
|
2668
|
-
/* @__PURE__ */
|
|
2669
|
-
/* @__PURE__ */
|
|
2860
|
+
return /* @__PURE__ */ jsxs10("div", { className: "space-y-4 py-10 text-center", children: [
|
|
2861
|
+
/* @__PURE__ */ jsx15("p", { className: "text-destructive font-medium", children: error.message }),
|
|
2862
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex justify-center gap-2", children: [
|
|
2863
|
+
/* @__PURE__ */ jsxs10(Button, { variant: "outline", onClick: onBack, children: [
|
|
2864
|
+
/* @__PURE__ */ jsx15(ArrowLeft, { className: "mr-2 h-4 w-4" }),
|
|
2670
2865
|
"Back"
|
|
2671
2866
|
] }),
|
|
2672
|
-
/* @__PURE__ */
|
|
2867
|
+
/* @__PURE__ */ jsx15(Button, { variant: "destructive", onClick: () => void loadInitial(), children: config.labels.retry })
|
|
2673
2868
|
] })
|
|
2674
2869
|
] });
|
|
2675
2870
|
}
|
|
2676
|
-
return /* @__PURE__ */
|
|
2677
|
-
/* @__PURE__ */
|
|
2678
|
-
/* @__PURE__ */
|
|
2871
|
+
return /* @__PURE__ */ jsxs10("div", { className: "space-y-6", children: [
|
|
2872
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex items-start gap-4", children: [
|
|
2873
|
+
/* @__PURE__ */ jsx15(
|
|
2679
2874
|
Button,
|
|
2680
2875
|
{
|
|
2681
2876
|
variant: "ghost",
|
|
2682
2877
|
size: "icon",
|
|
2683
2878
|
className: "mt-1 shrink-0",
|
|
2684
2879
|
onClick: onBack,
|
|
2685
|
-
children: /* @__PURE__ */
|
|
2880
|
+
children: /* @__PURE__ */ jsx15(ArrowLeft, { className: "h-4 w-4" })
|
|
2686
2881
|
}
|
|
2687
2882
|
),
|
|
2688
|
-
/* @__PURE__ */
|
|
2689
|
-
/* @__PURE__ */
|
|
2690
|
-
/* @__PURE__ */
|
|
2691
|
-
/* @__PURE__ */
|
|
2883
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex-1 min-w-0", children: [
|
|
2884
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-2", children: [
|
|
2885
|
+
/* @__PURE__ */ jsx15("h2", { className: "text-xl font-semibold truncate", children: thread?.name ?? threadId }),
|
|
2886
|
+
/* @__PURE__ */ jsx15(
|
|
2692
2887
|
Badge,
|
|
2693
2888
|
{
|
|
2694
2889
|
variant: thread?.status === "archived" ? "secondary" : "default",
|
|
@@ -2696,31 +2891,31 @@ var ThreadDetailView = ({
|
|
|
2696
2891
|
}
|
|
2697
2892
|
)
|
|
2698
2893
|
] }),
|
|
2699
|
-
thread?.summary && /* @__PURE__ */
|
|
2700
|
-
/* @__PURE__ */
|
|
2701
|
-
thread?.createdAt && /* @__PURE__ */
|
|
2894
|
+
thread?.summary && /* @__PURE__ */ jsx15("p", { className: "mt-1 text-sm text-muted-foreground", children: thread.summary }),
|
|
2895
|
+
/* @__PURE__ */ jsxs10("div", { className: "mt-2 flex flex-wrap gap-4 text-xs text-muted-foreground", children: [
|
|
2896
|
+
thread?.createdAt && /* @__PURE__ */ jsxs10("span", { children: [
|
|
2702
2897
|
"Created ",
|
|
2703
|
-
|
|
2898
|
+
formatDate2(thread.createdAt)
|
|
2704
2899
|
] }),
|
|
2705
|
-
thread?.updatedAt && /* @__PURE__ */
|
|
2900
|
+
thread?.updatedAt && /* @__PURE__ */ jsxs10("span", { children: [
|
|
2706
2901
|
"Updated ",
|
|
2707
|
-
|
|
2902
|
+
formatDate2(thread.updatedAt)
|
|
2708
2903
|
] }),
|
|
2709
|
-
thread?.participants && /* @__PURE__ */
|
|
2904
|
+
thread?.participants && /* @__PURE__ */ jsxs10("span", { children: [
|
|
2710
2905
|
thread.participants.length,
|
|
2711
2906
|
" participants"
|
|
2712
2907
|
] })
|
|
2713
2908
|
] })
|
|
2714
2909
|
] })
|
|
2715
2910
|
] }),
|
|
2716
|
-
/* @__PURE__ */
|
|
2717
|
-
/* @__PURE__ */
|
|
2911
|
+
/* @__PURE__ */ jsxs10("div", { className: "space-y-1", children: [
|
|
2912
|
+
/* @__PURE__ */ jsx15("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ jsxs10("h3", { className: "text-sm font-medium text-muted-foreground", children: [
|
|
2718
2913
|
"Messages (",
|
|
2719
2914
|
messages.length,
|
|
2720
2915
|
pageInfo?.hasMoreBefore ? "+" : "",
|
|
2721
2916
|
")"
|
|
2722
2917
|
] }) }),
|
|
2723
|
-
pageInfo?.hasMoreBefore && /* @__PURE__ */
|
|
2918
|
+
pageInfo?.hasMoreBefore && /* @__PURE__ */ jsx15("div", { className: "flex justify-center py-2", children: /* @__PURE__ */ jsxs10(
|
|
2724
2919
|
Button,
|
|
2725
2920
|
{
|
|
2726
2921
|
variant: "ghost",
|
|
@@ -2728,12 +2923,12 @@ var ThreadDetailView = ({
|
|
|
2728
2923
|
onClick: () => void loadMore(),
|
|
2729
2924
|
disabled: isLoadingMore,
|
|
2730
2925
|
children: [
|
|
2731
|
-
isLoadingMore ? /* @__PURE__ */
|
|
2926
|
+
isLoadingMore ? /* @__PURE__ */ jsx15(Loader2, { className: "mr-2 h-3 w-3 animate-spin" }) : /* @__PURE__ */ jsx15(ChevronUp2, { className: "mr-2 h-3 w-3" }),
|
|
2732
2927
|
"Load older messages"
|
|
2733
2928
|
]
|
|
2734
2929
|
}
|
|
2735
2930
|
) }),
|
|
2736
|
-
/* @__PURE__ */
|
|
2931
|
+
/* @__PURE__ */ jsx15("div", { className: "rounded-lg border bg-card", children: messages.length === 0 ? /* @__PURE__ */ jsx15("p", { className: "p-6 text-center text-sm text-muted-foreground", children: "No messages in this thread yet." }) : /* @__PURE__ */ jsx15("div", { className: "divide-y", children: messages.map((message) => /* @__PURE__ */ jsx15(MessageRow, { message }, message.id)) }) })
|
|
2737
2932
|
] })
|
|
2738
2933
|
] });
|
|
2739
2934
|
};
|
|
@@ -2741,43 +2936,43 @@ function MessageRow({ message }) {
|
|
|
2741
2936
|
const [expanded, setExpanded] = useState4(false);
|
|
2742
2937
|
const hasToolCalls = Array.isArray(message.toolCalls) && message.toolCalls.length > 0;
|
|
2743
2938
|
const hasReasoning = !!message.reasoning;
|
|
2744
|
-
return /* @__PURE__ */
|
|
2745
|
-
/* @__PURE__ */
|
|
2746
|
-
/* @__PURE__ */
|
|
2747
|
-
/* @__PURE__ */
|
|
2748
|
-
/* @__PURE__ */
|
|
2749
|
-
/* @__PURE__ */
|
|
2750
|
-
message.createdAt && /* @__PURE__ */
|
|
2939
|
+
return /* @__PURE__ */ jsx15("div", { className: "px-4 py-3", children: /* @__PURE__ */ jsxs10("div", { className: "flex items-start gap-3", children: [
|
|
2940
|
+
/* @__PURE__ */ jsx15(SenderIcon, { senderType: message.senderType }),
|
|
2941
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex-1 min-w-0", children: [
|
|
2942
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-2 text-xs", children: [
|
|
2943
|
+
/* @__PURE__ */ jsx15("span", { className: "font-medium", children: message.senderId ?? message.senderUserId ?? message.senderType }),
|
|
2944
|
+
/* @__PURE__ */ jsx15(Badge, { variant: "outline", className: "text-[10px] px-1.5 py-0", children: message.senderType }),
|
|
2945
|
+
message.createdAt && /* @__PURE__ */ jsx15("span", { className: "text-muted-foreground", children: formatTimestamp(message.createdAt) })
|
|
2751
2946
|
] }),
|
|
2752
|
-
message.content && /* @__PURE__ */
|
|
2753
|
-
(hasToolCalls || hasReasoning) && /* @__PURE__ */
|
|
2754
|
-
hasToolCalls && /* @__PURE__ */
|
|
2947
|
+
message.content && /* @__PURE__ */ jsx15("p", { className: "mt-1 text-sm whitespace-pre-wrap break-words", children: message.content }),
|
|
2948
|
+
(hasToolCalls || hasReasoning) && /* @__PURE__ */ jsxs10("div", { className: "mt-2 space-y-2", children: [
|
|
2949
|
+
hasToolCalls && /* @__PURE__ */ jsxs10(
|
|
2755
2950
|
"button",
|
|
2756
2951
|
{
|
|
2757
2952
|
type: "button",
|
|
2758
2953
|
onClick: () => setExpanded(!expanded),
|
|
2759
2954
|
className: "inline-flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground transition-colors",
|
|
2760
2955
|
children: [
|
|
2761
|
-
/* @__PURE__ */
|
|
2956
|
+
/* @__PURE__ */ jsx15(Wrench, { className: "h-3 w-3" }),
|
|
2762
2957
|
message.toolCalls.length,
|
|
2763
2958
|
" tool call",
|
|
2764
2959
|
message.toolCalls.length > 1 ? "s" : ""
|
|
2765
2960
|
]
|
|
2766
2961
|
}
|
|
2767
2962
|
),
|
|
2768
|
-
hasReasoning && /* @__PURE__ */
|
|
2963
|
+
hasReasoning && /* @__PURE__ */ jsxs10(
|
|
2769
2964
|
"button",
|
|
2770
2965
|
{
|
|
2771
2966
|
type: "button",
|
|
2772
2967
|
onClick: () => setExpanded(!expanded),
|
|
2773
2968
|
className: "inline-flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground transition-colors",
|
|
2774
2969
|
children: [
|
|
2775
|
-
/* @__PURE__ */
|
|
2970
|
+
/* @__PURE__ */ jsx15(Cpu, { className: "h-3 w-3" }),
|
|
2776
2971
|
"Reasoning"
|
|
2777
2972
|
]
|
|
2778
2973
|
}
|
|
2779
2974
|
),
|
|
2780
|
-
expanded && /* @__PURE__ */
|
|
2975
|
+
expanded && /* @__PURE__ */ jsx15("pre", { className: "mt-2 rounded-md bg-muted p-3 text-xs overflow-auto max-h-60", children: JSON.stringify(
|
|
2781
2976
|
{
|
|
2782
2977
|
...hasToolCalls ? { toolCalls: message.toolCalls } : {},
|
|
2783
2978
|
...hasReasoning ? { reasoning: message.reasoning } : {}
|
|
@@ -2793,16 +2988,16 @@ function SenderIcon({ senderType }) {
|
|
|
2793
2988
|
const base = "flex h-7 w-7 shrink-0 items-center justify-center rounded-full";
|
|
2794
2989
|
switch (senderType) {
|
|
2795
2990
|
case "agent":
|
|
2796
|
-
return /* @__PURE__ */
|
|
2991
|
+
return /* @__PURE__ */ jsx15("div", { className: cn(base, "bg-primary/10 text-primary"), children: /* @__PURE__ */ jsx15(Bot2, { className: "h-3.5 w-3.5" }) });
|
|
2797
2992
|
case "user":
|
|
2798
|
-
return /* @__PURE__ */
|
|
2993
|
+
return /* @__PURE__ */ jsx15("div", { className: cn(base, "bg-secondary text-secondary-foreground"), children: /* @__PURE__ */ jsx15(User, { className: "h-3.5 w-3.5" }) });
|
|
2799
2994
|
case "tool":
|
|
2800
|
-
return /* @__PURE__ */
|
|
2995
|
+
return /* @__PURE__ */ jsx15("div", { className: cn(base, "bg-muted text-muted-foreground"), children: /* @__PURE__ */ jsx15(Wrench, { className: "h-3.5 w-3.5" }) });
|
|
2801
2996
|
default:
|
|
2802
|
-
return /* @__PURE__ */
|
|
2997
|
+
return /* @__PURE__ */ jsx15("div", { className: cn(base, "bg-muted text-muted-foreground"), children: /* @__PURE__ */ jsx15(Cpu, { className: "h-3.5 w-3.5" }) });
|
|
2803
2998
|
}
|
|
2804
2999
|
}
|
|
2805
|
-
function
|
|
3000
|
+
function formatDate2(value) {
|
|
2806
3001
|
const date = new Date(value);
|
|
2807
3002
|
if (Number.isNaN(date.getTime())) return value;
|
|
2808
3003
|
return date.toLocaleDateString(void 0, {
|
|
@@ -2824,8 +3019,8 @@ function formatTimestamp(value) {
|
|
|
2824
3019
|
}
|
|
2825
3020
|
|
|
2826
3021
|
// src/components/views/ParticipantsView.tsx
|
|
2827
|
-
import { Search as
|
|
2828
|
-
import { jsx as
|
|
3022
|
+
import { Search as Search3, Users as Users3 } from "lucide-react";
|
|
3023
|
+
import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2829
3024
|
var ParticipantsView = ({
|
|
2830
3025
|
config,
|
|
2831
3026
|
participants,
|
|
@@ -2833,10 +3028,10 @@ var ParticipantsView = ({
|
|
|
2833
3028
|
onSearchChange,
|
|
2834
3029
|
onParticipantClick
|
|
2835
3030
|
}) => {
|
|
2836
|
-
return /* @__PURE__ */
|
|
2837
|
-
/* @__PURE__ */
|
|
2838
|
-
/* @__PURE__ */
|
|
2839
|
-
/* @__PURE__ */
|
|
3031
|
+
return /* @__PURE__ */ jsxs11("div", { className: "space-y-4", children: [
|
|
3032
|
+
/* @__PURE__ */ jsxs11("div", { className: "relative max-w-sm", children: [
|
|
3033
|
+
/* @__PURE__ */ jsx16(Search3, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
|
|
3034
|
+
/* @__PURE__ */ jsx16(
|
|
2840
3035
|
Input,
|
|
2841
3036
|
{
|
|
2842
3037
|
className: "pl-9",
|
|
@@ -2846,33 +3041,33 @@ var ParticipantsView = ({
|
|
|
2846
3041
|
}
|
|
2847
3042
|
)
|
|
2848
3043
|
] }),
|
|
2849
|
-
participants.length === 0 ? /* @__PURE__ */
|
|
2850
|
-
/* @__PURE__ */
|
|
2851
|
-
/* @__PURE__ */
|
|
2852
|
-
] }) : /* @__PURE__ */
|
|
3044
|
+
participants.length === 0 ? /* @__PURE__ */ jsxs11("div", { className: "rounded-xl border border-dashed p-10 text-center", children: [
|
|
3045
|
+
/* @__PURE__ */ jsx16(Users3, { className: "mx-auto h-8 w-8 text-muted-foreground/50" }),
|
|
3046
|
+
/* @__PURE__ */ jsx16("p", { className: "mt-3 text-sm text-muted-foreground", children: searchValue ? config.labels.noResults : config.labels.emptyDescription })
|
|
3047
|
+
] }) : /* @__PURE__ */ jsx16("div", { className: "space-y-2", children: participants.map((p) => /* @__PURE__ */ jsxs11(
|
|
2853
3048
|
"div",
|
|
2854
3049
|
{
|
|
2855
3050
|
className: "flex items-center gap-4 rounded-lg border bg-card p-4 transition-colors hover:bg-muted/50 cursor-pointer",
|
|
2856
3051
|
onClick: () => onParticipantClick?.(p.externalId),
|
|
2857
3052
|
children: [
|
|
2858
|
-
/* @__PURE__ */
|
|
2859
|
-
/* @__PURE__ */
|
|
2860
|
-
/* @__PURE__ */
|
|
2861
|
-
/* @__PURE__ */
|
|
2862
|
-
/* @__PURE__ */
|
|
3053
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex-1 min-w-0", children: [
|
|
3054
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2", children: [
|
|
3055
|
+
/* @__PURE__ */ jsx16("p", { className: "font-medium truncate", children: p.displayName }),
|
|
3056
|
+
/* @__PURE__ */ jsx16(Badge, { variant: "outline", className: "shrink-0 text-xs", children: p.participantType }),
|
|
3057
|
+
/* @__PURE__ */ jsx16(Badge, { variant: p.isGlobal ? "default" : "secondary", className: "shrink-0 text-xs", children: p.isGlobal ? config.labels.scopeGlobal : config.labels.scopeScoped })
|
|
2863
3058
|
] }),
|
|
2864
|
-
/* @__PURE__ */
|
|
3059
|
+
/* @__PURE__ */ jsx16("p", { className: "mt-1 text-xs text-muted-foreground", children: p.externalId })
|
|
2865
3060
|
] }),
|
|
2866
|
-
/* @__PURE__ */
|
|
2867
|
-
/* @__PURE__ */
|
|
3061
|
+
/* @__PURE__ */ jsxs11("div", { className: "text-right text-xs text-muted-foreground shrink-0 space-y-1", children: [
|
|
3062
|
+
/* @__PURE__ */ jsxs11("p", { children: [
|
|
2868
3063
|
formatNumber3(p.messageCount),
|
|
2869
3064
|
" messages"
|
|
2870
3065
|
] }),
|
|
2871
|
-
/* @__PURE__ */
|
|
3066
|
+
/* @__PURE__ */ jsxs11("p", { children: [
|
|
2872
3067
|
formatNumber3(p.threadCount),
|
|
2873
3068
|
" threads"
|
|
2874
3069
|
] }),
|
|
2875
|
-
/* @__PURE__ */
|
|
3070
|
+
/* @__PURE__ */ jsx16("p", { children: formatDate3(p.lastActivityAt) })
|
|
2876
3071
|
] })
|
|
2877
3072
|
]
|
|
2878
3073
|
},
|
|
@@ -2880,7 +3075,7 @@ var ParticipantsView = ({
|
|
|
2880
3075
|
)) })
|
|
2881
3076
|
] });
|
|
2882
3077
|
};
|
|
2883
|
-
function
|
|
3078
|
+
function formatDate3(value) {
|
|
2884
3079
|
if (!value) return "No activity";
|
|
2885
3080
|
const date = new Date(value);
|
|
2886
3081
|
if (Number.isNaN(date.getTime())) return value;
|
|
@@ -2893,7 +3088,7 @@ function formatNumber3(value) {
|
|
|
2893
3088
|
// src/components/views/ParticipantDetailView.tsx
|
|
2894
3089
|
import { useCallback as useCallback4, useEffect as useEffect6, useState as useState5 } from "react";
|
|
2895
3090
|
import { ArrowLeft as ArrowLeft2, Loader2 as Loader22, Save } from "lucide-react";
|
|
2896
|
-
import { jsx as
|
|
3091
|
+
import { jsx as jsx17, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2897
3092
|
var ParticipantDetailView = ({
|
|
2898
3093
|
participantId,
|
|
2899
3094
|
config,
|
|
@@ -2943,25 +3138,25 @@ var ParticipantDetailView = ({
|
|
|
2943
3138
|
}
|
|
2944
3139
|
};
|
|
2945
3140
|
if (isLoading) {
|
|
2946
|
-
return /* @__PURE__ */
|
|
3141
|
+
return /* @__PURE__ */ jsx17("div", { className: "flex items-center justify-center py-20", children: /* @__PURE__ */ jsx17(Loader22, { className: "h-6 w-6 animate-spin text-muted-foreground" }) });
|
|
2947
3142
|
}
|
|
2948
|
-
return /* @__PURE__ */
|
|
2949
|
-
/* @__PURE__ */
|
|
2950
|
-
/* @__PURE__ */
|
|
2951
|
-
/* @__PURE__ */
|
|
2952
|
-
/* @__PURE__ */
|
|
2953
|
-
/* @__PURE__ */
|
|
3143
|
+
return /* @__PURE__ */ jsxs12("div", { className: "space-y-6", children: [
|
|
3144
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-4", children: [
|
|
3145
|
+
/* @__PURE__ */ jsx17(Button, { variant: "ghost", size: "icon", onClick: onBack, children: /* @__PURE__ */ jsx17(ArrowLeft2, { className: "h-4 w-4" }) }),
|
|
3146
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex-1 min-w-0", children: [
|
|
3147
|
+
/* @__PURE__ */ jsx17("h2", { className: "text-xl font-semibold truncate", children: participantId }),
|
|
3148
|
+
/* @__PURE__ */ jsx17("p", { className: "text-sm text-muted-foreground", children: "Participant Detail" })
|
|
2954
3149
|
] }),
|
|
2955
|
-
/* @__PURE__ */
|
|
2956
|
-
saveMessage && /* @__PURE__ */
|
|
2957
|
-
/* @__PURE__ */
|
|
2958
|
-
isSaving ? /* @__PURE__ */
|
|
3150
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2", children: [
|
|
3151
|
+
saveMessage && /* @__PURE__ */ jsx17("span", { className: "text-xs text-emerald-600", children: saveMessage }),
|
|
3152
|
+
/* @__PURE__ */ jsxs12(Button, { size: "sm", onClick: () => void handleSave(), disabled: isSaving, children: [
|
|
3153
|
+
isSaving ? /* @__PURE__ */ jsx17(Loader22, { className: "mr-2 h-3 w-3 animate-spin" }) : /* @__PURE__ */ jsx17(Save, { className: "mr-2 h-3 w-3" }),
|
|
2959
3154
|
"Save"
|
|
2960
3155
|
] })
|
|
2961
3156
|
] })
|
|
2962
3157
|
] }),
|
|
2963
|
-
error && /* @__PURE__ */
|
|
2964
|
-
/* @__PURE__ */
|
|
3158
|
+
error && /* @__PURE__ */ jsx17("div", { className: "rounded-lg border border-destructive/50 bg-destructive/10 p-3 text-sm text-destructive", children: error }),
|
|
3159
|
+
/* @__PURE__ */ jsx17("div", { className: "rounded-lg border bg-card", children: /* @__PURE__ */ jsx17(
|
|
2965
3160
|
"textarea",
|
|
2966
3161
|
{
|
|
2967
3162
|
className: "w-full min-h-[400px] p-4 font-mono text-sm bg-transparent resize-y focus:outline-none",
|
|
@@ -2974,8 +3169,8 @@ var ParticipantDetailView = ({
|
|
|
2974
3169
|
};
|
|
2975
3170
|
|
|
2976
3171
|
// src/components/views/AgentsView.tsx
|
|
2977
|
-
import { Search as
|
|
2978
|
-
import { jsx as
|
|
3172
|
+
import { Search as Search4, Bot as Bot3 } from "lucide-react";
|
|
3173
|
+
import { jsx as jsx18, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
2979
3174
|
var AgentsView = ({
|
|
2980
3175
|
config,
|
|
2981
3176
|
agents,
|
|
@@ -2983,10 +3178,10 @@ var AgentsView = ({
|
|
|
2983
3178
|
onSearchChange,
|
|
2984
3179
|
onAgentClick
|
|
2985
3180
|
}) => {
|
|
2986
|
-
return /* @__PURE__ */
|
|
2987
|
-
/* @__PURE__ */
|
|
2988
|
-
/* @__PURE__ */
|
|
2989
|
-
/* @__PURE__ */
|
|
3181
|
+
return /* @__PURE__ */ jsxs13("div", { className: "space-y-4", children: [
|
|
3182
|
+
/* @__PURE__ */ jsxs13("div", { className: "relative max-w-sm", children: [
|
|
3183
|
+
/* @__PURE__ */ jsx18(Search4, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
|
|
3184
|
+
/* @__PURE__ */ jsx18(
|
|
2990
3185
|
Input,
|
|
2991
3186
|
{
|
|
2992
3187
|
className: "pl-9",
|
|
@@ -2996,48 +3191,48 @@ var AgentsView = ({
|
|
|
2996
3191
|
}
|
|
2997
3192
|
)
|
|
2998
3193
|
] }),
|
|
2999
|
-
agents.length === 0 ? /* @__PURE__ */
|
|
3000
|
-
/* @__PURE__ */
|
|
3001
|
-
/* @__PURE__ */
|
|
3002
|
-
] }) : /* @__PURE__ */
|
|
3194
|
+
agents.length === 0 ? /* @__PURE__ */ jsxs13("div", { className: "rounded-xl border border-dashed p-10 text-center", children: [
|
|
3195
|
+
/* @__PURE__ */ jsx18(Bot3, { className: "mx-auto h-8 w-8 text-muted-foreground/50" }),
|
|
3196
|
+
/* @__PURE__ */ jsx18("p", { className: "mt-3 text-sm text-muted-foreground", children: searchValue ? config.labels.noResults : config.labels.emptyDescription })
|
|
3197
|
+
] }) : /* @__PURE__ */ jsx18("div", { className: "grid gap-4 md:grid-cols-2 lg:grid-cols-3", children: agents.map((agent) => /* @__PURE__ */ jsxs13(
|
|
3003
3198
|
"div",
|
|
3004
3199
|
{
|
|
3005
3200
|
className: "rounded-lg border bg-card p-5 transition-colors hover:bg-muted/50 cursor-pointer",
|
|
3006
3201
|
onClick: () => onAgentClick?.(agent.agentId),
|
|
3007
3202
|
children: [
|
|
3008
|
-
/* @__PURE__ */
|
|
3009
|
-
/* @__PURE__ */
|
|
3010
|
-
/* @__PURE__ */
|
|
3011
|
-
/* @__PURE__ */
|
|
3203
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-start justify-between gap-3", children: [
|
|
3204
|
+
/* @__PURE__ */ jsxs13("div", { className: "min-w-0", children: [
|
|
3205
|
+
/* @__PURE__ */ jsx18("p", { className: "font-medium truncate", children: agent.displayName }),
|
|
3206
|
+
/* @__PURE__ */ jsx18("p", { className: "mt-1 truncate text-xs text-muted-foreground", children: agent.description ?? agent.agentId })
|
|
3012
3207
|
] }),
|
|
3013
|
-
/* @__PURE__ */
|
|
3208
|
+
/* @__PURE__ */ jsx18(Badge, { variant: "outline", className: "shrink-0", children: agent.isConfigured ? config.labels.configured : config.labels.unconfigured })
|
|
3014
3209
|
] }),
|
|
3015
|
-
/* @__PURE__ */
|
|
3016
|
-
/* @__PURE__ */
|
|
3210
|
+
/* @__PURE__ */ jsxs13("div", { className: "mt-4 grid grid-cols-2 gap-2 text-xs text-muted-foreground", children: [
|
|
3211
|
+
/* @__PURE__ */ jsxs13("span", { children: [
|
|
3017
3212
|
formatNumber4(agent.messageCount),
|
|
3018
3213
|
" messages"
|
|
3019
3214
|
] }),
|
|
3020
|
-
/* @__PURE__ */
|
|
3215
|
+
/* @__PURE__ */ jsxs13("span", { children: [
|
|
3021
3216
|
formatNumber4(agent.llmCallCount),
|
|
3022
3217
|
" LLM calls"
|
|
3023
3218
|
] }),
|
|
3024
|
-
/* @__PURE__ */
|
|
3219
|
+
/* @__PURE__ */ jsxs13("span", { children: [
|
|
3025
3220
|
formatNumber4(agent.toolCallMessageCount),
|
|
3026
3221
|
" tool calls"
|
|
3027
3222
|
] }),
|
|
3028
|
-
/* @__PURE__ */
|
|
3223
|
+
/* @__PURE__ */ jsxs13("span", { children: [
|
|
3029
3224
|
formatNumber4(agent.totalTokens),
|
|
3030
3225
|
" tokens"
|
|
3031
3226
|
] })
|
|
3032
3227
|
] }),
|
|
3033
|
-
/* @__PURE__ */
|
|
3228
|
+
/* @__PURE__ */ jsx18("p", { className: "mt-3 text-xs text-muted-foreground", children: formatDate4(agent.lastActivityAt) })
|
|
3034
3229
|
]
|
|
3035
3230
|
},
|
|
3036
3231
|
`${agent.namespace}:${agent.agentId}`
|
|
3037
3232
|
)) })
|
|
3038
3233
|
] });
|
|
3039
3234
|
};
|
|
3040
|
-
function
|
|
3235
|
+
function formatDate4(value) {
|
|
3041
3236
|
if (!value) return "No activity";
|
|
3042
3237
|
const date = new Date(value);
|
|
3043
3238
|
if (Number.isNaN(date.getTime())) return value;
|
|
@@ -3049,7 +3244,7 @@ function formatNumber4(value) {
|
|
|
3049
3244
|
|
|
3050
3245
|
// src/components/views/AgentDetailView.tsx
|
|
3051
3246
|
import { ArrowLeft as ArrowLeft3, Bot as Bot4 } from "lucide-react";
|
|
3052
|
-
import { jsx as
|
|
3247
|
+
import { jsx as jsx19, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
3053
3248
|
var AgentDetailView = ({
|
|
3054
3249
|
agentId,
|
|
3055
3250
|
config,
|
|
@@ -3058,13 +3253,13 @@ var AgentDetailView = ({
|
|
|
3058
3253
|
}) => {
|
|
3059
3254
|
const agent = agents.find((a) => a.agentId === agentId);
|
|
3060
3255
|
if (!agent) {
|
|
3061
|
-
return /* @__PURE__ */
|
|
3062
|
-
/* @__PURE__ */
|
|
3256
|
+
return /* @__PURE__ */ jsxs14("div", { className: "space-y-4 py-10 text-center", children: [
|
|
3257
|
+
/* @__PURE__ */ jsxs14("p", { className: "text-muted-foreground", children: [
|
|
3063
3258
|
"Agent not found: ",
|
|
3064
3259
|
agentId
|
|
3065
3260
|
] }),
|
|
3066
|
-
/* @__PURE__ */
|
|
3067
|
-
/* @__PURE__ */
|
|
3261
|
+
/* @__PURE__ */ jsxs14(Button, { variant: "outline", onClick: onBack, children: [
|
|
3262
|
+
/* @__PURE__ */ jsx19(ArrowLeft3, { className: "mr-2 h-4 w-4" }),
|
|
3068
3263
|
" Back"
|
|
3069
3264
|
] })
|
|
3070
3265
|
] });
|
|
@@ -3080,43 +3275,43 @@ var AgentDetailView = ({
|
|
|
3080
3275
|
{ label: "Cache Created", value: agent.cacheCreationInputTokens },
|
|
3081
3276
|
{ label: "Total Tokens", value: agent.totalTokens }
|
|
3082
3277
|
];
|
|
3083
|
-
return /* @__PURE__ */
|
|
3084
|
-
/* @__PURE__ */
|
|
3085
|
-
/* @__PURE__ */
|
|
3086
|
-
/* @__PURE__ */
|
|
3087
|
-
/* @__PURE__ */
|
|
3088
|
-
/* @__PURE__ */
|
|
3089
|
-
/* @__PURE__ */
|
|
3090
|
-
/* @__PURE__ */
|
|
3091
|
-
/* @__PURE__ */
|
|
3092
|
-
/* @__PURE__ */
|
|
3278
|
+
return /* @__PURE__ */ jsxs14("div", { className: "space-y-6", children: [
|
|
3279
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex items-start gap-4", children: [
|
|
3280
|
+
/* @__PURE__ */ jsx19(Button, { variant: "ghost", size: "icon", className: "mt-1 shrink-0", onClick: onBack, children: /* @__PURE__ */ jsx19(ArrowLeft3, { className: "h-4 w-4" }) }),
|
|
3281
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex-1 min-w-0", children: [
|
|
3282
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-3", children: [
|
|
3283
|
+
/* @__PURE__ */ jsx19("div", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary", children: /* @__PURE__ */ jsx19(Bot4, { className: "h-5 w-5" }) }),
|
|
3284
|
+
/* @__PURE__ */ jsxs14("div", { children: [
|
|
3285
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2", children: [
|
|
3286
|
+
/* @__PURE__ */ jsx19("h2", { className: "text-xl font-semibold", children: agent.displayName }),
|
|
3287
|
+
/* @__PURE__ */ jsx19(Badge, { variant: "outline", children: agent.isConfigured ? config.labels.configured : config.labels.unconfigured })
|
|
3093
3288
|
] }),
|
|
3094
|
-
agent.description && /* @__PURE__ */
|
|
3289
|
+
agent.description && /* @__PURE__ */ jsx19("p", { className: "text-sm text-muted-foreground", children: agent.description })
|
|
3095
3290
|
] })
|
|
3096
3291
|
] }),
|
|
3097
|
-
/* @__PURE__ */
|
|
3098
|
-
/* @__PURE__ */
|
|
3292
|
+
/* @__PURE__ */ jsxs14("div", { className: "mt-2 flex flex-wrap gap-4 text-xs text-muted-foreground", children: [
|
|
3293
|
+
/* @__PURE__ */ jsxs14("span", { children: [
|
|
3099
3294
|
"ID: ",
|
|
3100
3295
|
agent.agentId
|
|
3101
3296
|
] }),
|
|
3102
|
-
/* @__PURE__ */
|
|
3297
|
+
/* @__PURE__ */ jsxs14("span", { children: [
|
|
3103
3298
|
"Namespace: ",
|
|
3104
3299
|
agent.namespace
|
|
3105
3300
|
] }),
|
|
3106
|
-
agent.lastActivityAt && /* @__PURE__ */
|
|
3301
|
+
agent.lastActivityAt && /* @__PURE__ */ jsxs14("span", { children: [
|
|
3107
3302
|
"Last active: ",
|
|
3108
|
-
|
|
3303
|
+
formatDate5(agent.lastActivityAt)
|
|
3109
3304
|
] })
|
|
3110
3305
|
] })
|
|
3111
3306
|
] })
|
|
3112
3307
|
] }),
|
|
3113
|
-
/* @__PURE__ */
|
|
3114
|
-
/* @__PURE__ */
|
|
3115
|
-
/* @__PURE__ */
|
|
3308
|
+
/* @__PURE__ */ jsx19("div", { className: "grid gap-4 sm:grid-cols-3 lg:grid-cols-3", children: stats.map((stat) => /* @__PURE__ */ jsxs14("div", { className: "rounded-xl border bg-card p-5 shadow-sm", children: [
|
|
3309
|
+
/* @__PURE__ */ jsx19("p", { className: "text-sm font-medium text-muted-foreground", children: stat.label }),
|
|
3310
|
+
/* @__PURE__ */ jsx19("p", { className: "mt-2 text-2xl font-semibold tracking-tight", children: new Intl.NumberFormat().format(stat.value) })
|
|
3116
3311
|
] }, stat.label)) })
|
|
3117
3312
|
] });
|
|
3118
3313
|
};
|
|
3119
|
-
function
|
|
3314
|
+
function formatDate5(value) {
|
|
3120
3315
|
const date = new Date(value);
|
|
3121
3316
|
if (Number.isNaN(date.getTime())) return value;
|
|
3122
3317
|
return date.toLocaleString(void 0, { month: "short", day: "numeric", hour: "numeric", minute: "2-digit" });
|
|
@@ -3124,8 +3319,8 @@ function formatDate6(value) {
|
|
|
3124
3319
|
|
|
3125
3320
|
// src/components/views/CollectionItemsView.tsx
|
|
3126
3321
|
import { useCallback as useCallback5, useEffect as useEffect7, useState as useState6 } from "react";
|
|
3127
|
-
import { Loader2 as Loader23, Plus, Search as
|
|
3128
|
-
import { jsx as
|
|
3322
|
+
import { Loader2 as Loader23, Plus, Search as Search5, Database as Database3 } from "lucide-react";
|
|
3323
|
+
import { jsx as jsx20, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
3129
3324
|
var CollectionItemsView = ({
|
|
3130
3325
|
collection,
|
|
3131
3326
|
config,
|
|
@@ -3171,17 +3366,17 @@ var CollectionItemsView = ({
|
|
|
3171
3366
|
if (keys.length === 0) return "(empty)";
|
|
3172
3367
|
return keys.slice(0, 3).map((k) => `${k}: ${JSON.stringify(rest[k])?.slice(0, 30)}`).join(", ");
|
|
3173
3368
|
};
|
|
3174
|
-
return /* @__PURE__ */
|
|
3175
|
-
/* @__PURE__ */
|
|
3176
|
-
/* @__PURE__ */
|
|
3177
|
-
onCreateNew && /* @__PURE__ */
|
|
3178
|
-
/* @__PURE__ */
|
|
3369
|
+
return /* @__PURE__ */ jsxs15("div", { className: "space-y-4", children: [
|
|
3370
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between gap-4", children: [
|
|
3371
|
+
/* @__PURE__ */ jsx20("h2", { className: "text-lg font-semibold capitalize", children: collection }),
|
|
3372
|
+
onCreateNew && /* @__PURE__ */ jsxs15(Button, { size: "sm", onClick: onCreateNew, children: [
|
|
3373
|
+
/* @__PURE__ */ jsx20(Plus, { className: "mr-2 h-3 w-3" }),
|
|
3179
3374
|
" New"
|
|
3180
3375
|
] })
|
|
3181
3376
|
] }),
|
|
3182
|
-
/* @__PURE__ */
|
|
3183
|
-
/* @__PURE__ */
|
|
3184
|
-
/* @__PURE__ */
|
|
3377
|
+
/* @__PURE__ */ jsxs15("div", { className: "relative max-w-sm", children: [
|
|
3378
|
+
/* @__PURE__ */ jsx20(Search5, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
|
|
3379
|
+
/* @__PURE__ */ jsx20(
|
|
3185
3380
|
Input,
|
|
3186
3381
|
{
|
|
3187
3382
|
className: "pl-9",
|
|
@@ -3191,20 +3386,20 @@ var CollectionItemsView = ({
|
|
|
3191
3386
|
}
|
|
3192
3387
|
)
|
|
3193
3388
|
] }),
|
|
3194
|
-
error && /* @__PURE__ */
|
|
3195
|
-
isLoading ? /* @__PURE__ */
|
|
3196
|
-
/* @__PURE__ */
|
|
3197
|
-
/* @__PURE__ */
|
|
3198
|
-
] }) : /* @__PURE__ */
|
|
3389
|
+
error && /* @__PURE__ */ jsx20("div", { className: "rounded-lg border border-destructive/50 bg-destructive/10 p-3 text-sm text-destructive", children: error }),
|
|
3390
|
+
isLoading ? /* @__PURE__ */ jsx20("div", { className: "flex items-center justify-center py-20", children: /* @__PURE__ */ jsx20(Loader23, { className: "h-6 w-6 animate-spin text-muted-foreground" }) }) : items.length === 0 ? /* @__PURE__ */ jsxs15("div", { className: "rounded-xl border border-dashed p-10 text-center", children: [
|
|
3391
|
+
/* @__PURE__ */ jsx20(Database3, { className: "mx-auto h-8 w-8 text-muted-foreground/50" }),
|
|
3392
|
+
/* @__PURE__ */ jsx20("p", { className: "mt-3 text-sm text-muted-foreground", children: search ? config.labels.noResults : `No items in ${collection}` })
|
|
3393
|
+
] }) : /* @__PURE__ */ jsx20("div", { className: "space-y-2", children: items.map((item, idx) => {
|
|
3199
3394
|
const itemId = getItemId(item);
|
|
3200
|
-
return /* @__PURE__ */
|
|
3395
|
+
return /* @__PURE__ */ jsx20(
|
|
3201
3396
|
"div",
|
|
3202
3397
|
{
|
|
3203
3398
|
className: "flex items-center gap-4 rounded-lg border bg-card p-4 transition-colors hover:bg-muted/50 cursor-pointer",
|
|
3204
3399
|
onClick: () => onItemClick?.(itemId),
|
|
3205
|
-
children: /* @__PURE__ */
|
|
3206
|
-
/* @__PURE__ */
|
|
3207
|
-
/* @__PURE__ */
|
|
3400
|
+
children: /* @__PURE__ */ jsxs15("div", { className: "flex-1 min-w-0", children: [
|
|
3401
|
+
/* @__PURE__ */ jsx20("p", { className: "font-medium font-mono text-sm truncate", children: itemId }),
|
|
3402
|
+
/* @__PURE__ */ jsx20("p", { className: "mt-1 text-xs text-muted-foreground truncate", children: getItemPreview(item) })
|
|
3208
3403
|
] })
|
|
3209
3404
|
},
|
|
3210
3405
|
itemId + idx
|
|
@@ -3216,7 +3411,7 @@ var CollectionItemsView = ({
|
|
|
3216
3411
|
// src/components/views/CollectionItemDetailView.tsx
|
|
3217
3412
|
import { useCallback as useCallback6, useEffect as useEffect8, useState as useState7 } from "react";
|
|
3218
3413
|
import { ArrowLeft as ArrowLeft5, Loader2 as Loader24, Save as Save2, Trash2 } from "lucide-react";
|
|
3219
|
-
import { jsx as
|
|
3414
|
+
import { jsx as jsx21, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
3220
3415
|
var CollectionItemDetailView = ({
|
|
3221
3416
|
collection,
|
|
3222
3417
|
itemId,
|
|
@@ -3290,15 +3485,15 @@ var CollectionItemDetailView = ({
|
|
|
3290
3485
|
}
|
|
3291
3486
|
};
|
|
3292
3487
|
if (isLoading) {
|
|
3293
|
-
return /* @__PURE__ */
|
|
3488
|
+
return /* @__PURE__ */ jsx21("div", { className: "flex items-center justify-center py-20", children: /* @__PURE__ */ jsx21(Loader24, { className: "h-6 w-6 animate-spin text-muted-foreground" }) });
|
|
3294
3489
|
}
|
|
3295
|
-
return /* @__PURE__ */
|
|
3296
|
-
/* @__PURE__ */
|
|
3297
|
-
/* @__PURE__ */
|
|
3298
|
-
/* @__PURE__ */
|
|
3299
|
-
/* @__PURE__ */
|
|
3300
|
-
saveMessage && /* @__PURE__ */
|
|
3301
|
-
!isNew && /* @__PURE__ */
|
|
3490
|
+
return /* @__PURE__ */ jsxs16("div", { className: "space-y-6", children: [
|
|
3491
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-4", children: [
|
|
3492
|
+
/* @__PURE__ */ jsx21(Button, { variant: "ghost", size: "icon", onClick: onBack, children: /* @__PURE__ */ jsx21(ArrowLeft5, { className: "h-4 w-4" }) }),
|
|
3493
|
+
/* @__PURE__ */ jsx21("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsx21("h2", { className: "text-xl font-semibold truncate capitalize", children: isNew ? `New ${collection} item` : `${collection} / ${itemId}` }) }),
|
|
3494
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-2", children: [
|
|
3495
|
+
saveMessage && /* @__PURE__ */ jsx21("span", { className: "text-xs text-emerald-600", children: saveMessage }),
|
|
3496
|
+
!isNew && /* @__PURE__ */ jsxs16(
|
|
3302
3497
|
Button,
|
|
3303
3498
|
{
|
|
3304
3499
|
variant: "destructive",
|
|
@@ -3306,19 +3501,19 @@ var CollectionItemDetailView = ({
|
|
|
3306
3501
|
onClick: () => void handleDelete(),
|
|
3307
3502
|
disabled: isDeleting,
|
|
3308
3503
|
children: [
|
|
3309
|
-
isDeleting ? /* @__PURE__ */
|
|
3504
|
+
isDeleting ? /* @__PURE__ */ jsx21(Loader24, { className: "mr-2 h-3 w-3 animate-spin" }) : /* @__PURE__ */ jsx21(Trash2, { className: "mr-2 h-3 w-3" }),
|
|
3310
3505
|
"Delete"
|
|
3311
3506
|
]
|
|
3312
3507
|
}
|
|
3313
3508
|
),
|
|
3314
|
-
/* @__PURE__ */
|
|
3315
|
-
isSaving ? /* @__PURE__ */
|
|
3509
|
+
/* @__PURE__ */ jsxs16(Button, { size: "sm", onClick: () => void handleSave(), disabled: isSaving, children: [
|
|
3510
|
+
isSaving ? /* @__PURE__ */ jsx21(Loader24, { className: "mr-2 h-3 w-3 animate-spin" }) : /* @__PURE__ */ jsx21(Save2, { className: "mr-2 h-3 w-3" }),
|
|
3316
3511
|
isNew ? "Create" : "Save"
|
|
3317
3512
|
] })
|
|
3318
3513
|
] })
|
|
3319
3514
|
] }),
|
|
3320
|
-
error && /* @__PURE__ */
|
|
3321
|
-
/* @__PURE__ */
|
|
3515
|
+
error && /* @__PURE__ */ jsx21("div", { className: "rounded-lg border border-destructive/50 bg-destructive/10 p-3 text-sm text-destructive", children: error }),
|
|
3516
|
+
/* @__PURE__ */ jsx21("div", { className: "rounded-lg border bg-card", children: /* @__PURE__ */ jsx21(
|
|
3322
3517
|
"textarea",
|
|
3323
3518
|
{
|
|
3324
3519
|
className: "w-full min-h-[400px] p-4 font-mono text-sm bg-transparent resize-y focus:outline-none",
|
|
@@ -3332,8 +3527,8 @@ var CollectionItemDetailView = ({
|
|
|
3332
3527
|
|
|
3333
3528
|
// src/components/views/EventsView.tsx
|
|
3334
3529
|
import { useCallback as useCallback7, useState as useState8 } from "react";
|
|
3335
|
-
import { Activity as
|
|
3336
|
-
import { jsx as
|
|
3530
|
+
import { Activity as Activity3, Loader2 as Loader25, Search as Search6 } from "lucide-react";
|
|
3531
|
+
import { jsx as jsx22, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
3337
3532
|
var STATUS_VARIANTS = {
|
|
3338
3533
|
pending: "outline",
|
|
3339
3534
|
processing: "default",
|
|
@@ -3366,13 +3561,13 @@ var EventsView = ({ config }) => {
|
|
|
3366
3561
|
setIsLoading(false);
|
|
3367
3562
|
}
|
|
3368
3563
|
}, [threadId, config.baseUrl, config.getRequestHeaders]);
|
|
3369
|
-
return /* @__PURE__ */
|
|
3370
|
-
/* @__PURE__ */
|
|
3371
|
-
/* @__PURE__ */
|
|
3372
|
-
/* @__PURE__ */
|
|
3373
|
-
/* @__PURE__ */
|
|
3374
|
-
/* @__PURE__ */
|
|
3375
|
-
/* @__PURE__ */
|
|
3564
|
+
return /* @__PURE__ */ jsxs17("div", { className: "space-y-6", children: [
|
|
3565
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex items-end gap-3 max-w-lg", children: [
|
|
3566
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex-1", children: [
|
|
3567
|
+
/* @__PURE__ */ jsx22("label", { className: "text-sm font-medium mb-1 block", children: "Thread ID" }),
|
|
3568
|
+
/* @__PURE__ */ jsxs17("div", { className: "relative", children: [
|
|
3569
|
+
/* @__PURE__ */ jsx22(Search6, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
|
|
3570
|
+
/* @__PURE__ */ jsx22(
|
|
3376
3571
|
Input,
|
|
3377
3572
|
{
|
|
3378
3573
|
className: "pl-9",
|
|
@@ -3384,55 +3579,55 @@ var EventsView = ({ config }) => {
|
|
|
3384
3579
|
)
|
|
3385
3580
|
] })
|
|
3386
3581
|
] }),
|
|
3387
|
-
/* @__PURE__ */
|
|
3388
|
-
isLoading ? /* @__PURE__ */
|
|
3582
|
+
/* @__PURE__ */ jsxs17(Button, { onClick: () => void handleSearch(), disabled: isLoading || !threadId.trim(), children: [
|
|
3583
|
+
isLoading ? /* @__PURE__ */ jsx22(Loader25, { className: "mr-2 h-4 w-4 animate-spin" }) : null,
|
|
3389
3584
|
"Inspect"
|
|
3390
3585
|
] })
|
|
3391
3586
|
] }),
|
|
3392
|
-
error && /* @__PURE__ */
|
|
3393
|
-
!hasSearched ? /* @__PURE__ */
|
|
3394
|
-
/* @__PURE__ */
|
|
3395
|
-
/* @__PURE__ */
|
|
3396
|
-
] }) : isLoading ? /* @__PURE__ */
|
|
3397
|
-
/* @__PURE__ */
|
|
3398
|
-
/* @__PURE__ */
|
|
3399
|
-
] }) : /* @__PURE__ */
|
|
3400
|
-
/* @__PURE__ */
|
|
3401
|
-
/* @__PURE__ */
|
|
3402
|
-
/* @__PURE__ */
|
|
3403
|
-
/* @__PURE__ */
|
|
3587
|
+
error && /* @__PURE__ */ jsx22("div", { className: "rounded-lg border border-destructive/50 bg-destructive/10 p-3 text-sm text-destructive", children: error }),
|
|
3588
|
+
!hasSearched ? /* @__PURE__ */ jsxs17("div", { className: "rounded-xl border border-dashed p-10 text-center", children: [
|
|
3589
|
+
/* @__PURE__ */ jsx22(Activity3, { className: "mx-auto h-8 w-8 text-muted-foreground/50" }),
|
|
3590
|
+
/* @__PURE__ */ jsx22("p", { className: "mt-3 text-sm text-muted-foreground", children: "Enter a thread ID to inspect its next pending queue event." })
|
|
3591
|
+
] }) : isLoading ? /* @__PURE__ */ jsx22("div", { className: "flex items-center justify-center py-20", children: /* @__PURE__ */ jsx22(Loader25, { className: "h-6 w-6 animate-spin text-muted-foreground" }) }) : !event ? /* @__PURE__ */ jsxs17("div", { className: "rounded-xl border border-dashed p-10 text-center", children: [
|
|
3592
|
+
/* @__PURE__ */ jsx22(Activity3, { className: "mx-auto h-8 w-8 text-muted-foreground/50" }),
|
|
3593
|
+
/* @__PURE__ */ jsx22("p", { className: "mt-3 text-sm text-muted-foreground", children: "No pending events found for this thread." })
|
|
3594
|
+
] }) : /* @__PURE__ */ jsxs17("div", { className: "rounded-lg border bg-card p-5 space-y-4", children: [
|
|
3595
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex items-start justify-between gap-3", children: [
|
|
3596
|
+
/* @__PURE__ */ jsxs17("div", { children: [
|
|
3597
|
+
/* @__PURE__ */ jsx22("p", { className: "font-medium", children: event.eventType }),
|
|
3598
|
+
/* @__PURE__ */ jsx22("p", { className: "text-xs text-muted-foreground font-mono mt-1", children: event.id })
|
|
3404
3599
|
] }),
|
|
3405
|
-
/* @__PURE__ */
|
|
3600
|
+
/* @__PURE__ */ jsx22(Badge, { variant: STATUS_VARIANTS[event.status] ?? "outline", children: event.status })
|
|
3406
3601
|
] }),
|
|
3407
|
-
/* @__PURE__ */
|
|
3408
|
-
event.traceId && /* @__PURE__ */
|
|
3409
|
-
/* @__PURE__ */
|
|
3602
|
+
/* @__PURE__ */ jsxs17("div", { className: "grid gap-3 sm:grid-cols-2 text-sm", children: [
|
|
3603
|
+
event.traceId && /* @__PURE__ */ jsxs17("div", { children: [
|
|
3604
|
+
/* @__PURE__ */ jsx22("span", { className: "text-muted-foreground", children: "Trace:" }),
|
|
3410
3605
|
" ",
|
|
3411
|
-
/* @__PURE__ */
|
|
3606
|
+
/* @__PURE__ */ jsx22("span", { className: "font-mono text-xs", children: event.traceId })
|
|
3412
3607
|
] }),
|
|
3413
|
-
event.parentEventId && /* @__PURE__ */
|
|
3414
|
-
/* @__PURE__ */
|
|
3608
|
+
event.parentEventId && /* @__PURE__ */ jsxs17("div", { children: [
|
|
3609
|
+
/* @__PURE__ */ jsx22("span", { className: "text-muted-foreground", children: "Parent:" }),
|
|
3415
3610
|
" ",
|
|
3416
|
-
/* @__PURE__ */
|
|
3611
|
+
/* @__PURE__ */ jsx22("span", { className: "font-mono text-xs", children: event.parentEventId })
|
|
3417
3612
|
] }),
|
|
3418
|
-
event.priority != null && /* @__PURE__ */
|
|
3419
|
-
/* @__PURE__ */
|
|
3613
|
+
event.priority != null && /* @__PURE__ */ jsxs17("div", { children: [
|
|
3614
|
+
/* @__PURE__ */ jsx22("span", { className: "text-muted-foreground", children: "Priority:" }),
|
|
3420
3615
|
" ",
|
|
3421
3616
|
event.priority
|
|
3422
3617
|
] }),
|
|
3423
|
-
event.createdAt && /* @__PURE__ */
|
|
3424
|
-
/* @__PURE__ */
|
|
3618
|
+
event.createdAt && /* @__PURE__ */ jsxs17("div", { children: [
|
|
3619
|
+
/* @__PURE__ */ jsx22("span", { className: "text-muted-foreground", children: "Created:" }),
|
|
3425
3620
|
" ",
|
|
3426
3621
|
formatTimestamp2(event.createdAt)
|
|
3427
3622
|
] })
|
|
3428
3623
|
] }),
|
|
3429
|
-
event.payload != null && /* @__PURE__ */
|
|
3430
|
-
/* @__PURE__ */
|
|
3431
|
-
/* @__PURE__ */
|
|
3624
|
+
event.payload != null && /* @__PURE__ */ jsxs17("div", { children: [
|
|
3625
|
+
/* @__PURE__ */ jsx22("p", { className: "text-xs font-medium text-muted-foreground mb-1", children: "Payload" }),
|
|
3626
|
+
/* @__PURE__ */ jsx22("pre", { className: "rounded-md bg-muted p-3 text-xs overflow-auto max-h-60", children: JSON.stringify(event.payload, null, 2) })
|
|
3432
3627
|
] }),
|
|
3433
|
-
event.metadata != null && Object.keys(event.metadata).length > 0 && /* @__PURE__ */
|
|
3434
|
-
/* @__PURE__ */
|
|
3435
|
-
/* @__PURE__ */
|
|
3628
|
+
event.metadata != null && Object.keys(event.metadata).length > 0 && /* @__PURE__ */ jsxs17("div", { children: [
|
|
3629
|
+
/* @__PURE__ */ jsx22("p", { className: "text-xs font-medium text-muted-foreground mb-1", children: "Metadata" }),
|
|
3630
|
+
/* @__PURE__ */ jsx22("pre", { className: "rounded-md bg-muted p-3 text-xs overflow-auto max-h-40", children: JSON.stringify(event.metadata, null, 2) })
|
|
3436
3631
|
] })
|
|
3437
3632
|
] })
|
|
3438
3633
|
] });
|
|
@@ -3450,7 +3645,7 @@ function formatTimestamp2(value) {
|
|
|
3450
3645
|
}
|
|
3451
3646
|
|
|
3452
3647
|
// src/CopilotzAdmin.tsx
|
|
3453
|
-
import { jsx as
|
|
3648
|
+
import { jsx as jsx23, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
3454
3649
|
var CopilotzAdmin = ({
|
|
3455
3650
|
config: userConfig,
|
|
3456
3651
|
className
|
|
@@ -3462,6 +3657,8 @@ var CopilotzAdmin = ({
|
|
|
3462
3657
|
const [route, setRoute] = useState9({ page: config.defaultPage });
|
|
3463
3658
|
const [namespace, setNamespace] = useState9(config.namespace);
|
|
3464
3659
|
const [collections, setCollections] = useState9([]);
|
|
3660
|
+
const [headerControls, setHeaderControls] = useState9(null);
|
|
3661
|
+
const [headerRefresh, setHeaderRefresh] = useState9(null);
|
|
3465
3662
|
const [threadSearch, setThreadSearch] = useState9("");
|
|
3466
3663
|
const [participantSearch, setParticipantSearch] = useState9("");
|
|
3467
3664
|
const [agentSearch, setAgentSearch] = useState9("");
|
|
@@ -3542,18 +3739,18 @@ var CopilotzAdmin = ({
|
|
|
3542
3739
|
}
|
|
3543
3740
|
})();
|
|
3544
3741
|
if (admin.isLoading && !admin.overview) {
|
|
3545
|
-
return /* @__PURE__ */
|
|
3742
|
+
return /* @__PURE__ */ jsx23(Card, { className: cn("border-border", className), children: /* @__PURE__ */ jsx23(CardContent, { className: "text-muted-foreground flex items-center justify-center min-h-[200px]", children: config.labels.loading }) });
|
|
3546
3743
|
}
|
|
3547
3744
|
if (admin.error && !admin.overview) {
|
|
3548
|
-
return /* @__PURE__ */
|
|
3549
|
-
/* @__PURE__ */
|
|
3550
|
-
/* @__PURE__ */
|
|
3745
|
+
return /* @__PURE__ */ jsx23(Card, { className: cn("border-destructive/50 bg-destructive/10", className), children: /* @__PURE__ */ jsxs18(CardContent, { className: "space-y-4", children: [
|
|
3746
|
+
/* @__PURE__ */ jsx23("p", { className: "text-base font-semibold text-destructive", children: admin.error.message }),
|
|
3747
|
+
/* @__PURE__ */ jsx23(Button, { variant: "destructive", onClick: () => void admin.refresh(), children: config.labels.retry })
|
|
3551
3748
|
] }) });
|
|
3552
3749
|
}
|
|
3553
3750
|
const renderCurrentView = () => {
|
|
3554
3751
|
switch (route.page) {
|
|
3555
3752
|
case "dashboard":
|
|
3556
|
-
return /* @__PURE__ */
|
|
3753
|
+
return /* @__PURE__ */ jsx23(
|
|
3557
3754
|
DashboardView,
|
|
3558
3755
|
{
|
|
3559
3756
|
config,
|
|
@@ -3570,11 +3767,13 @@ var CopilotzAdmin = ({
|
|
|
3570
3767
|
onThreadSearchChange: setThreadSearch,
|
|
3571
3768
|
onParticipantSearchChange: setParticipantSearch,
|
|
3572
3769
|
onAgentSearchChange: setAgentSearch,
|
|
3573
|
-
onThreadClick: handleThreadClick
|
|
3770
|
+
onThreadClick: handleThreadClick,
|
|
3771
|
+
setHeaderControls,
|
|
3772
|
+
setHeaderRefresh
|
|
3574
3773
|
}
|
|
3575
3774
|
);
|
|
3576
3775
|
case "threads":
|
|
3577
|
-
return /* @__PURE__ */
|
|
3776
|
+
return /* @__PURE__ */ jsx23(
|
|
3578
3777
|
ThreadsView,
|
|
3579
3778
|
{
|
|
3580
3779
|
config,
|
|
@@ -3585,9 +3784,9 @@ var CopilotzAdmin = ({
|
|
|
3585
3784
|
}
|
|
3586
3785
|
);
|
|
3587
3786
|
case "thread-detail":
|
|
3588
|
-
return route.resourceId ? /* @__PURE__ */
|
|
3787
|
+
return route.resourceId ? /* @__PURE__ */ jsx23(ThreadDetailView, { threadId: route.resourceId, config, onBack: handleBackToThreads }) : null;
|
|
3589
3788
|
case "participants":
|
|
3590
|
-
return /* @__PURE__ */
|
|
3789
|
+
return /* @__PURE__ */ jsx23(
|
|
3591
3790
|
ParticipantsView,
|
|
3592
3791
|
{
|
|
3593
3792
|
config,
|
|
@@ -3598,9 +3797,9 @@ var CopilotzAdmin = ({
|
|
|
3598
3797
|
}
|
|
3599
3798
|
);
|
|
3600
3799
|
case "participant-detail":
|
|
3601
|
-
return route.resourceId ? /* @__PURE__ */
|
|
3800
|
+
return route.resourceId ? /* @__PURE__ */ jsx23(ParticipantDetailView, { participantId: route.resourceId, config, onBack: handleBackToParticipants }) : null;
|
|
3602
3801
|
case "agents":
|
|
3603
|
-
return /* @__PURE__ */
|
|
3802
|
+
return /* @__PURE__ */ jsx23(
|
|
3604
3803
|
AgentsView,
|
|
3605
3804
|
{
|
|
3606
3805
|
config,
|
|
@@ -3611,9 +3810,9 @@ var CopilotzAdmin = ({
|
|
|
3611
3810
|
}
|
|
3612
3811
|
);
|
|
3613
3812
|
case "agent-detail":
|
|
3614
|
-
return route.resourceId ? /* @__PURE__ */
|
|
3813
|
+
return route.resourceId ? /* @__PURE__ */ jsx23(AgentDetailView, { agentId: route.resourceId, config, agents: admin.agents, onBack: handleBackToAgents }) : null;
|
|
3615
3814
|
case "collection-items":
|
|
3616
|
-
return route.collection ? /* @__PURE__ */
|
|
3815
|
+
return route.collection ? /* @__PURE__ */ jsx23(
|
|
3617
3816
|
CollectionItemsView,
|
|
3618
3817
|
{
|
|
3619
3818
|
collection: route.collection,
|
|
@@ -3624,7 +3823,7 @@ var CopilotzAdmin = ({
|
|
|
3624
3823
|
}
|
|
3625
3824
|
) : null;
|
|
3626
3825
|
case "collection-item-detail":
|
|
3627
|
-
return route.collection ? /* @__PURE__ */
|
|
3826
|
+
return route.collection ? /* @__PURE__ */ jsx23(
|
|
3628
3827
|
CollectionItemDetailView,
|
|
3629
3828
|
{
|
|
3630
3829
|
collection: route.collection,
|
|
@@ -3635,12 +3834,12 @@ var CopilotzAdmin = ({
|
|
|
3635
3834
|
}
|
|
3636
3835
|
) : null;
|
|
3637
3836
|
case "events":
|
|
3638
|
-
return /* @__PURE__ */
|
|
3837
|
+
return /* @__PURE__ */ jsx23(EventsView, { config });
|
|
3639
3838
|
default:
|
|
3640
3839
|
return null;
|
|
3641
3840
|
}
|
|
3642
3841
|
};
|
|
3643
|
-
return /* @__PURE__ */
|
|
3842
|
+
return /* @__PURE__ */ jsx23(TooltipProvider, { children: /* @__PURE__ */ jsx23(SidebarProvider, { defaultOpen: config.sidebar.defaultOpen, children: /* @__PURE__ */ jsxs18(
|
|
3644
3843
|
"div",
|
|
3645
3844
|
{
|
|
3646
3845
|
className: cn(
|
|
@@ -3648,7 +3847,7 @@ var CopilotzAdmin = ({
|
|
|
3648
3847
|
className
|
|
3649
3848
|
),
|
|
3650
3849
|
children: [
|
|
3651
|
-
/* @__PURE__ */
|
|
3850
|
+
/* @__PURE__ */ jsx23(
|
|
3652
3851
|
AdminSidebar,
|
|
3653
3852
|
{
|
|
3654
3853
|
config,
|
|
@@ -3661,21 +3860,24 @@ var CopilotzAdmin = ({
|
|
|
3661
3860
|
onNamespaceChange: setNamespace
|
|
3662
3861
|
}
|
|
3663
3862
|
),
|
|
3664
|
-
/* @__PURE__ */
|
|
3665
|
-
/* @__PURE__ */
|
|
3863
|
+
/* @__PURE__ */ jsx23(SidebarInset, { children: /* @__PURE__ */ jsxs18("div", { className: "flex flex-col h-full min-h-0", children: [
|
|
3864
|
+
/* @__PURE__ */ jsx23(
|
|
3666
3865
|
AdminHeader,
|
|
3667
3866
|
{
|
|
3668
3867
|
config,
|
|
3669
3868
|
currentRoute: route,
|
|
3670
|
-
|
|
3671
|
-
|
|
3672
|
-
|
|
3673
|
-
|
|
3674
|
-
|
|
3675
|
-
|
|
3869
|
+
onRefresh: () => {
|
|
3870
|
+
if (route.page === "dashboard" && headerRefresh) {
|
|
3871
|
+
headerRefresh();
|
|
3872
|
+
return;
|
|
3873
|
+
}
|
|
3874
|
+
void admin.refresh();
|
|
3875
|
+
},
|
|
3876
|
+
isLoading: admin.isLoading,
|
|
3877
|
+
controls: route.page === "dashboard" ? headerControls : null
|
|
3676
3878
|
}
|
|
3677
3879
|
),
|
|
3678
|
-
/* @__PURE__ */
|
|
3880
|
+
/* @__PURE__ */ jsx23("div", { className: "flex-1 overflow-auto p-4", children: renderCurrentView() })
|
|
3679
3881
|
] }) })
|
|
3680
3882
|
]
|
|
3681
3883
|
}
|