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