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