@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.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 React5 from "react";
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 jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
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
- const [usageMetricKind, setUsageMetricKind] = React5.useState(
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 [usageDimension, setUsageDimension] = React5.useState(
1593
- "total"
1774
+ const [dimension, setDimension] = React6.useState("total");
1775
+ const [groupBy, setGroupBy] = React6.useState(
1776
+ "participant"
1594
1777
  );
1595
- const llmSummaryValue = overview ? getOverviewUsageValue(overview, usageMetricKind, usageDimension) : 0;
1596
- const llmSummaryLabel = getUsageSummaryLabel(
1597
- config.labels,
1598
- usageMetricKind,
1599
- usageDimension
1778
+ const [attribution, setAttribution] = React6.useState(
1779
+ "initiatedBy"
1600
1780
  );
1601
- const cards = [
1602
- {
1603
- label: config.labels.messagesCard,
1604
- value: overview?.messageTotals.total ?? 0,
1605
- detail: `${overview?.messageTotals.toolCallMessages ?? 0} tool-call messages`
1606
- },
1607
- {
1608
- label: config.labels.activeThreadsCard,
1609
- value: overview?.threadTotals.active ?? 0,
1610
- detail: `${overview?.threadTotals.total ?? 0} total threads`
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 = React5.useCallback(async () => {
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: props.metricKind,
1804
+ metric: metricKind,
1761
1805
  groupBy,
1762
- namespace: props.namespace || void 0,
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: props.config.baseUrl,
1770
- getRequestHeaders: props.config.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
- React5.useEffect(() => {
1840
+ React6.useEffect(() => {
1795
1841
  void loadUsage();
1796
1842
  }, [loadUsage]);
1797
- return /* @__PURE__ */ jsxs7("section", { className: "space-y-4", children: [
1798
- /* @__PURE__ */ jsxs7("div", { className: "flex flex-col gap-3 lg:flex-row lg:items-end lg:justify-between", children: [
1799
- /* @__PURE__ */ jsx12(SectionHeading, { title: props.config.labels.llmUsageTitle }),
1800
- /* @__PURE__ */ jsxs7("div", { className: "grid gap-3 sm:grid-cols-2 lg:grid-cols-5", children: [
1801
- /* @__PURE__ */ jsx12(
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", props.config.labels.range24h],
1809
- ["7d", props.config.labels.range7d],
1810
- ["30d", props.config.labels.range30d],
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__ */ jsx12(
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__ */ jsx12(
1930
+ /* @__PURE__ */ jsx13(
1831
1931
  UsageSelect,
1832
1932
  {
1833
- label: props.config.labels.usageMetricLabel,
1834
- value: props.metricKind,
1835
- onValueChange: (value) => props.onMetricKindChange(value),
1933
+ label: config.labels.usageMetricLabel,
1934
+ onValueChange: (value) => setMetricKind(value),
1836
1935
  options: [
1837
- ["cost", props.config.labels.usageMetricCost],
1838
- ["tokens", props.config.labels.usageMetricTokens],
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__ */ jsx12(
1943
+ /* @__PURE__ */ jsx13(
1844
1944
  UsageSelect,
1845
1945
  {
1846
- label: "Group by",
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__ */ jsx12(
1970
+ /* @__PURE__ */ jsx13(
1859
1971
  UsageSelect,
1860
1972
  {
1861
- label: props.config.labels.usageDimensionLabel,
1862
- value: props.selectedDimension,
1863
- onValueChange: (value) => props.onDimensionChange(value),
1864
- options: USAGE_DIMENSIONS.map((dimension) => [
1865
- dimension,
1866
- getUsageDimensionLabel(props.config.labels, dimension)
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__ */ jsx12(
1878
- UsageSelect,
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
- label: "Participant type",
1881
- value: participantType,
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
- /* @__PURE__ */ jsx12(FilterInput, { label: "Thread", value: threadId, onChange: setThreadId }),
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
- className: "h-9 w-full",
1899
- onClick: () => void loadUsage(),
1900
- disabled: isLoading,
1901
- variant: "outline",
1902
- children: props.config.labels.refresh
2110
+ chartState,
2111
+ metricKind
1903
2112
  }
1904
2113
  ) })
1905
- ] }) }),
1906
- /* @__PURE__ */ jsx12(
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
- labels: props.config.labels,
1922
- metricKind: props.metricKind,
1923
- dimension: props.selectedDimension,
1924
- rows: usage?.rows ?? [],
1925
- isLoading
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__ */ jsxs7("div", { className: "space-y-1", children: [
1932
- /* @__PURE__ */ jsx12("p", { className: "text-xs font-medium uppercase tracking-[0.18em] text-muted-foreground", children: props.label }),
1933
- /* @__PURE__ */ jsxs7(Select, { value: props.value, onValueChange: props.onValueChange, children: [
1934
- /* @__PURE__ */ jsx12(SelectTrigger, { className: "h-9 w-full min-w-[140px]", children: /* @__PURE__ */ jsx12(SelectValue, {}) }),
1935
- /* @__PURE__ */ jsx12(SelectContent, { children: props.options.map(([value, label]) => /* @__PURE__ */ jsx12(SelectItem, { value, children: label }, value)) })
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__ */ jsxs7("div", { className: "space-y-1", children: [
1941
- /* @__PURE__ */ jsx12("p", { className: "text-xs font-medium uppercase tracking-[0.18em] text-muted-foreground", children: props.label }),
1942
- /* @__PURE__ */ jsx12(
1943
- Input,
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-8 w-full max-w-44",
2100
- onChange: (event) => props.setSearchValue(event.target.value),
2101
- placeholder: props.searchPlaceholder,
2102
- value: props.searchValue
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 ThreadsTable({
2110
- rows,
2111
- labels,
2112
- onThreadClick
2352
+ function EmptyDashboard({
2353
+ description,
2354
+ title
2113
2355
  }) {
2114
- return /* @__PURE__ */ jsx12("div", { className: "space-y-3", children: rows.map((thread) => /* @__PURE__ */ jsxs7(
2115
- "div",
2116
- {
2117
- className: cn(
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 emptyToUndefined(value) {
2296
- const trimmed = value.trim();
2297
- return trimmed.length > 0 ? trimmed : void 0;
2298
- }
2299
- function getUsageRange(period, customFrom, customTo) {
2300
- if (period === "custom") {
2301
- return {
2302
- from: customFrom ? new Date(customFrom).toISOString() : void 0,
2303
- to: customTo ? new Date(customTo).toISOString() : void 0
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
- const to = /* @__PURE__ */ new Date();
2307
- const from = new Date(to);
2308
- if (period === "24h") {
2309
- from.setHours(from.getHours() - 24);
2310
- } else if (period === "30d") {
2311
- from.setDate(from.getDate() - 30);
2312
- } else {
2313
- from.setDate(from.getDate() - 7);
2314
- }
2315
- return { from: from.toISOString(), to: to.toISOString() };
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((a, b) => new Date(a.bucket).getTime() - new Date(b.bucket).getTime());
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 += getUsagePointValue(point, metricKind, dimension);
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 getOverviewUsageValue(overview, metricKind, dimension) {
2361
- const llmTotals = overview.llmTotals;
2362
- if (metricKind === "calls") return llmTotals.totalCalls;
2363
- if (metricKind === "cost") {
2364
- switch (dimension) {
2365
- case "input":
2366
- return llmTotals.inputCostUsd;
2367
- case "output":
2368
- return llmTotals.outputCostUsd;
2369
- case "reasoning":
2370
- return llmTotals.reasoningCostUsd;
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 llmTotals.totalTokens;
2539
+ return "Participant";
2394
2540
  }
2395
2541
  }
2396
- function getAgentUsageValue(agent, metricKind, dimension) {
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 agent.inputCostUsd;
2547
+ return totals.inputCostUsd;
2401
2548
  case "output":
2402
- return agent.outputCostUsd;
2549
+ return totals.outputCostUsd;
2403
2550
  case "reasoning":
2404
- return agent.reasoningCostUsd;
2551
+ return totals.reasoningCostUsd;
2405
2552
  case "cacheRead":
2406
- return agent.cacheReadInputCostUsd;
2553
+ return totals.cacheReadInputCostUsd;
2407
2554
  case "cacheWrite":
2408
- return agent.cacheCreationInputCostUsd;
2555
+ return totals.cacheCreationInputCostUsd;
2409
2556
  case "total":
2410
2557
  default:
2411
- return agent.totalCostUsd;
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 agent.inputTokens;
2563
+ return totals.inputTokens;
2418
2564
  case "output":
2419
- return agent.outputTokens;
2565
+ return totals.outputTokens;
2420
2566
  case "reasoning":
2421
- return agent.reasoningTokens;
2567
+ return totals.reasoningTokens;
2422
2568
  case "cacheRead":
2423
- return agent.cacheReadInputTokens;
2569
+ return totals.cacheReadInputTokens;
2424
2570
  case "cacheWrite":
2425
- return agent.cacheCreationInputTokens;
2571
+ return totals.cacheCreationInputTokens;
2426
2572
  case "total":
2427
2573
  default:
2428
- return agent.totalTokens;
2574
+ return totals.totalTokens;
2429
2575
  }
2430
2576
  }
2431
- function getActivityUsageValue(point, metricKind, dimension) {
2432
- if (metricKind === "cost") {
2433
- switch (dimension) {
2434
- case "input":
2435
- return point.inputCostUsd;
2436
- case "output":
2437
- return point.outputCostUsd;
2438
- case "reasoning":
2439
- return point.reasoningCostUsd;
2440
- case "cacheRead":
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 (metricKind === "calls") return point.llmCallCount;
2450
- switch (dimension) {
2451
- case "input":
2452
- return point.inputTokens;
2453
- case "output":
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 getUsagePointValue(point, metricKind, dimension) {
2467
- if (metricKind === "cost") {
2468
- switch (dimension) {
2469
- case "input":
2470
- return point.inputCostUsd;
2471
- case "output":
2472
- return point.outputCostUsd;
2473
- case "reasoning":
2474
- return point.reasoningCostUsd;
2475
- case "cacheRead":
2476
- return point.cacheReadInputCostUsd;
2477
- case "cacheWrite":
2478
- return point.cacheCreationInputCostUsd;
2479
- case "total":
2480
- default:
2481
- return point.totalCostUsd;
2482
- }
2483
- }
2484
- if (metricKind === "calls") return point.totalCalls;
2485
- switch (dimension) {
2486
- case "input":
2487
- return point.inputTokens;
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 jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
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__ */ jsxs8("div", { className: "space-y-4", children: [
2526
- /* @__PURE__ */ jsxs8("div", { className: "relative max-w-sm", children: [
2527
- /* @__PURE__ */ jsx13(Search, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
2528
- /* @__PURE__ */ jsx13(
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__ */ jsxs8("div", { className: "rounded-xl border border-dashed p-10 text-center", children: [
2539
- /* @__PURE__ */ jsx13(MessageSquare2, { className: "mx-auto h-8 w-8 text-muted-foreground/50" }),
2540
- /* @__PURE__ */ jsx13("p", { className: "mt-3 text-sm text-muted-foreground", children: searchValue ? config.labels.noResults : config.labels.emptyDescription })
2541
- ] }) : /* @__PURE__ */ jsx13("div", { className: "space-y-2", children: threads.map((thread) => /* @__PURE__ */ jsxs8(
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__ */ jsxs8("div", { className: "flex-1 min-w-0", children: [
2548
- /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2", children: [
2549
- /* @__PURE__ */ jsx13("p", { className: "font-medium truncate", children: thread.name }),
2550
- /* @__PURE__ */ jsx13(
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__ */ jsx13("p", { className: "mt-1 text-sm text-muted-foreground truncate", children: thread.summary ?? thread.lastMessagePreview ?? "No summary yet" })
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__ */ jsxs8("div", { className: "text-right text-xs text-muted-foreground shrink-0 space-y-1", children: [
2562
- /* @__PURE__ */ jsxs8("p", { children: [
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__ */ jsxs8("p", { children: [
2703
+ /* @__PURE__ */ jsxs9("p", { children: [
2567
2704
  thread.participantIds.length,
2568
2705
  " participants"
2569
2706
  ] }),
2570
- /* @__PURE__ */ jsx13("p", { children: formatDate2(thread.lastActivityAt) })
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 formatDate2(value) {
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 jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
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__ */ jsx14("div", { className: "flex items-center justify-center py-20", children: /* @__PURE__ */ jsx14(Loader2, { className: "h-6 w-6 animate-spin text-muted-foreground" }) });
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__ */ jsxs9("div", { className: "space-y-4 py-10 text-center", children: [
2666
- /* @__PURE__ */ jsx14("p", { className: "text-destructive font-medium", children: error.message }),
2667
- /* @__PURE__ */ jsxs9("div", { className: "flex justify-center gap-2", children: [
2668
- /* @__PURE__ */ jsxs9(Button, { variant: "outline", onClick: onBack, children: [
2669
- /* @__PURE__ */ jsx14(ArrowLeft, { className: "mr-2 h-4 w-4" }),
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__ */ jsx14(Button, { variant: "destructive", onClick: () => void loadInitial(), children: config.labels.retry })
2809
+ /* @__PURE__ */ jsx15(Button, { variant: "destructive", onClick: () => void loadInitial(), children: config.labels.retry })
2673
2810
  ] })
2674
2811
  ] });
2675
2812
  }
2676
- return /* @__PURE__ */ jsxs9("div", { className: "space-y-6", children: [
2677
- /* @__PURE__ */ jsxs9("div", { className: "flex items-start gap-4", children: [
2678
- /* @__PURE__ */ jsx14(
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__ */ jsx14(ArrowLeft, { className: "h-4 w-4" })
2822
+ children: /* @__PURE__ */ jsx15(ArrowLeft, { className: "h-4 w-4" })
2686
2823
  }
2687
2824
  ),
2688
- /* @__PURE__ */ jsxs9("div", { className: "flex-1 min-w-0", children: [
2689
- /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2", children: [
2690
- /* @__PURE__ */ jsx14("h2", { className: "text-xl font-semibold truncate", children: thread?.name ?? threadId }),
2691
- /* @__PURE__ */ jsx14(
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__ */ jsx14("p", { className: "mt-1 text-sm text-muted-foreground", children: thread.summary }),
2700
- /* @__PURE__ */ jsxs9("div", { className: "mt-2 flex flex-wrap gap-4 text-xs text-muted-foreground", children: [
2701
- thread?.createdAt && /* @__PURE__ */ jsxs9("span", { children: [
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
- formatDate3(thread.createdAt)
2840
+ formatDate2(thread.createdAt)
2704
2841
  ] }),
2705
- thread?.updatedAt && /* @__PURE__ */ jsxs9("span", { children: [
2842
+ thread?.updatedAt && /* @__PURE__ */ jsxs10("span", { children: [
2706
2843
  "Updated ",
2707
- formatDate3(thread.updatedAt)
2844
+ formatDate2(thread.updatedAt)
2708
2845
  ] }),
2709
- thread?.participants && /* @__PURE__ */ jsxs9("span", { children: [
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__ */ jsxs9("div", { className: "space-y-1", children: [
2717
- /* @__PURE__ */ jsx14("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ jsxs9("h3", { className: "text-sm font-medium text-muted-foreground", children: [
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__ */ jsx14("div", { className: "flex justify-center py-2", children: /* @__PURE__ */ jsxs9(
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__ */ jsx14(Loader2, { className: "mr-2 h-3 w-3 animate-spin" }) : /* @__PURE__ */ jsx14(ChevronUp2, { className: "mr-2 h-3 w-3" }),
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__ */ jsx14("div", { className: "rounded-lg border bg-card", children: messages.length === 0 ? /* @__PURE__ */ jsx14("p", { className: "p-6 text-center text-sm text-muted-foreground", children: "No messages in this thread yet." }) : /* @__PURE__ */ jsx14("div", { className: "divide-y", children: messages.map((message) => /* @__PURE__ */ jsx14(MessageRow, { message }, message.id)) }) })
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__ */ jsx14("div", { className: "px-4 py-3", children: /* @__PURE__ */ jsxs9("div", { className: "flex items-start gap-3", children: [
2745
- /* @__PURE__ */ jsx14(SenderIcon, { senderType: message.senderType }),
2746
- /* @__PURE__ */ jsxs9("div", { className: "flex-1 min-w-0", children: [
2747
- /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2 text-xs", children: [
2748
- /* @__PURE__ */ jsx14("span", { className: "font-medium", children: message.senderId ?? message.senderUserId ?? message.senderType }),
2749
- /* @__PURE__ */ jsx14(Badge, { variant: "outline", className: "text-[10px] px-1.5 py-0", children: message.senderType }),
2750
- message.createdAt && /* @__PURE__ */ jsx14("span", { className: "text-muted-foreground", children: formatTimestamp(message.createdAt) })
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__ */ jsx14("p", { className: "mt-1 text-sm whitespace-pre-wrap break-words", children: message.content }),
2753
- (hasToolCalls || hasReasoning) && /* @__PURE__ */ jsxs9("div", { className: "mt-2 space-y-2", children: [
2754
- hasToolCalls && /* @__PURE__ */ jsxs9(
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__ */ jsx14(Wrench, { className: "h-3 w-3" }),
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__ */ jsxs9(
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__ */ jsx14(Cpu, { className: "h-3 w-3" }),
2912
+ /* @__PURE__ */ jsx15(Cpu, { className: "h-3 w-3" }),
2776
2913
  "Reasoning"
2777
2914
  ]
2778
2915
  }
2779
2916
  ),
2780
- expanded && /* @__PURE__ */ jsx14("pre", { className: "mt-2 rounded-md bg-muted p-3 text-xs overflow-auto max-h-60", children: JSON.stringify(
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__ */ jsx14("div", { className: cn(base, "bg-primary/10 text-primary"), children: /* @__PURE__ */ jsx14(Bot2, { className: "h-3.5 w-3.5" }) });
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__ */ jsx14("div", { className: cn(base, "bg-secondary text-secondary-foreground"), children: /* @__PURE__ */ jsx14(User, { className: "h-3.5 w-3.5" }) });
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__ */ jsx14("div", { className: cn(base, "bg-muted text-muted-foreground"), children: /* @__PURE__ */ jsx14(Wrench, { className: "h-3.5 w-3.5" }) });
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__ */ jsx14("div", { className: cn(base, "bg-muted text-muted-foreground"), children: /* @__PURE__ */ jsx14(Cpu, { className: "h-3.5 w-3.5" }) });
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 formatDate3(value) {
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 Search2, Users as Users2 } from "lucide-react";
2828
- import { jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
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__ */ jsxs10("div", { className: "space-y-4", children: [
2837
- /* @__PURE__ */ jsxs10("div", { className: "relative max-w-sm", children: [
2838
- /* @__PURE__ */ jsx15(Search2, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
2839
- /* @__PURE__ */ jsx15(
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__ */ jsxs10("div", { className: "rounded-xl border border-dashed p-10 text-center", children: [
2850
- /* @__PURE__ */ jsx15(Users2, { className: "mx-auto h-8 w-8 text-muted-foreground/50" }),
2851
- /* @__PURE__ */ jsx15("p", { className: "mt-3 text-sm text-muted-foreground", children: searchValue ? config.labels.noResults : config.labels.emptyDescription })
2852
- ] }) : /* @__PURE__ */ jsx15("div", { className: "space-y-2", children: participants.map((p) => /* @__PURE__ */ jsxs10(
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__ */ jsxs10("div", { className: "flex-1 min-w-0", children: [
2859
- /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-2", children: [
2860
- /* @__PURE__ */ jsx15("p", { className: "font-medium truncate", children: p.displayName }),
2861
- /* @__PURE__ */ jsx15(Badge, { variant: "outline", className: "shrink-0 text-xs", children: p.participantType }),
2862
- /* @__PURE__ */ jsx15(Badge, { variant: p.isGlobal ? "default" : "secondary", className: "shrink-0 text-xs", children: p.isGlobal ? config.labels.scopeGlobal : config.labels.scopeScoped })
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__ */ jsx15("p", { className: "mt-1 text-xs text-muted-foreground", children: p.externalId })
3001
+ /* @__PURE__ */ jsx16("p", { className: "mt-1 text-xs text-muted-foreground", children: p.externalId })
2865
3002
  ] }),
2866
- /* @__PURE__ */ jsxs10("div", { className: "text-right text-xs text-muted-foreground shrink-0 space-y-1", children: [
2867
- /* @__PURE__ */ jsxs10("p", { children: [
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__ */ jsxs10("p", { children: [
3008
+ /* @__PURE__ */ jsxs11("p", { children: [
2872
3009
  formatNumber3(p.threadCount),
2873
3010
  " threads"
2874
3011
  ] }),
2875
- /* @__PURE__ */ jsx15("p", { children: formatDate4(p.lastActivityAt) })
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 formatDate4(value) {
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 jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
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__ */ jsx16("div", { className: "flex items-center justify-center py-20", children: /* @__PURE__ */ jsx16(Loader22, { className: "h-6 w-6 animate-spin text-muted-foreground" }) });
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__ */ jsxs11("div", { className: "space-y-6", children: [
2949
- /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-4", children: [
2950
- /* @__PURE__ */ jsx16(Button, { variant: "ghost", size: "icon", onClick: onBack, children: /* @__PURE__ */ jsx16(ArrowLeft2, { className: "h-4 w-4" }) }),
2951
- /* @__PURE__ */ jsxs11("div", { className: "flex-1 min-w-0", children: [
2952
- /* @__PURE__ */ jsx16("h2", { className: "text-xl font-semibold truncate", children: participantId }),
2953
- /* @__PURE__ */ jsx16("p", { className: "text-sm text-muted-foreground", children: "Participant Detail" })
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__ */ jsxs11("div", { className: "flex items-center gap-2", children: [
2956
- saveMessage && /* @__PURE__ */ jsx16("span", { className: "text-xs text-emerald-600", children: saveMessage }),
2957
- /* @__PURE__ */ jsxs11(Button, { size: "sm", onClick: () => void handleSave(), disabled: isSaving, children: [
2958
- isSaving ? /* @__PURE__ */ jsx16(Loader22, { className: "mr-2 h-3 w-3 animate-spin" }) : /* @__PURE__ */ jsx16(Save, { className: "mr-2 h-3 w-3" }),
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__ */ jsx16("div", { className: "rounded-lg border border-destructive/50 bg-destructive/10 p-3 text-sm text-destructive", children: error }),
2964
- /* @__PURE__ */ jsx16("div", { className: "rounded-lg border bg-card", children: /* @__PURE__ */ jsx16(
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 Search3, Bot as Bot3 } from "lucide-react";
2978
- import { jsx as jsx17, jsxs as jsxs12 } from "react/jsx-runtime";
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__ */ jsxs12("div", { className: "space-y-4", children: [
2987
- /* @__PURE__ */ jsxs12("div", { className: "relative max-w-sm", children: [
2988
- /* @__PURE__ */ jsx17(Search3, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
2989
- /* @__PURE__ */ jsx17(
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__ */ jsxs12("div", { className: "rounded-xl border border-dashed p-10 text-center", children: [
3000
- /* @__PURE__ */ jsx17(Bot3, { className: "mx-auto h-8 w-8 text-muted-foreground/50" }),
3001
- /* @__PURE__ */ jsx17("p", { className: "mt-3 text-sm text-muted-foreground", children: searchValue ? config.labels.noResults : config.labels.emptyDescription })
3002
- ] }) : /* @__PURE__ */ jsx17("div", { className: "grid gap-4 md:grid-cols-2 lg:grid-cols-3", children: agents.map((agent) => /* @__PURE__ */ jsxs12(
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__ */ jsxs12("div", { className: "flex items-start justify-between gap-3", children: [
3009
- /* @__PURE__ */ jsxs12("div", { className: "min-w-0", children: [
3010
- /* @__PURE__ */ jsx17("p", { className: "font-medium truncate", children: agent.displayName }),
3011
- /* @__PURE__ */ jsx17("p", { className: "mt-1 truncate text-xs text-muted-foreground", children: agent.description ?? agent.agentId })
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__ */ jsx17(Badge, { variant: "outline", className: "shrink-0", children: agent.isConfigured ? config.labels.configured : config.labels.unconfigured })
3150
+ /* @__PURE__ */ jsx18(Badge, { variant: "outline", className: "shrink-0", children: agent.isConfigured ? config.labels.configured : config.labels.unconfigured })
3014
3151
  ] }),
3015
- /* @__PURE__ */ jsxs12("div", { className: "mt-4 grid grid-cols-2 gap-2 text-xs text-muted-foreground", children: [
3016
- /* @__PURE__ */ jsxs12("span", { children: [
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__ */ jsxs12("span", { children: [
3157
+ /* @__PURE__ */ jsxs13("span", { children: [
3021
3158
  formatNumber4(agent.llmCallCount),
3022
3159
  " LLM calls"
3023
3160
  ] }),
3024
- /* @__PURE__ */ jsxs12("span", { children: [
3161
+ /* @__PURE__ */ jsxs13("span", { children: [
3025
3162
  formatNumber4(agent.toolCallMessageCount),
3026
3163
  " tool calls"
3027
3164
  ] }),
3028
- /* @__PURE__ */ jsxs12("span", { children: [
3165
+ /* @__PURE__ */ jsxs13("span", { children: [
3029
3166
  formatNumber4(agent.totalTokens),
3030
3167
  " tokens"
3031
3168
  ] })
3032
3169
  ] }),
3033
- /* @__PURE__ */ jsx17("p", { className: "mt-3 text-xs text-muted-foreground", children: formatDate5(agent.lastActivityAt) })
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 formatDate5(value) {
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 jsx18, jsxs as jsxs13 } from "react/jsx-runtime";
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__ */ jsxs13("div", { className: "space-y-4 py-10 text-center", children: [
3062
- /* @__PURE__ */ jsxs13("p", { className: "text-muted-foreground", children: [
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__ */ jsxs13(Button, { variant: "outline", onClick: onBack, children: [
3067
- /* @__PURE__ */ jsx18(ArrowLeft3, { className: "mr-2 h-4 w-4" }),
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__ */ jsxs13("div", { className: "space-y-6", children: [
3084
- /* @__PURE__ */ jsxs13("div", { className: "flex items-start gap-4", children: [
3085
- /* @__PURE__ */ jsx18(Button, { variant: "ghost", size: "icon", className: "mt-1 shrink-0", onClick: onBack, children: /* @__PURE__ */ jsx18(ArrowLeft3, { className: "h-4 w-4" }) }),
3086
- /* @__PURE__ */ jsxs13("div", { className: "flex-1 min-w-0", children: [
3087
- /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-3", children: [
3088
- /* @__PURE__ */ jsx18("div", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary", children: /* @__PURE__ */ jsx18(Bot4, { className: "h-5 w-5" }) }),
3089
- /* @__PURE__ */ jsxs13("div", { children: [
3090
- /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2", children: [
3091
- /* @__PURE__ */ jsx18("h2", { className: "text-xl font-semibold", children: agent.displayName }),
3092
- /* @__PURE__ */ jsx18(Badge, { variant: "outline", children: agent.isConfigured ? config.labels.configured : config.labels.unconfigured })
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__ */ jsx18("p", { className: "text-sm text-muted-foreground", children: agent.description })
3231
+ agent.description && /* @__PURE__ */ jsx19("p", { className: "text-sm text-muted-foreground", children: agent.description })
3095
3232
  ] })
3096
3233
  ] }),
3097
- /* @__PURE__ */ jsxs13("div", { className: "mt-2 flex flex-wrap gap-4 text-xs text-muted-foreground", children: [
3098
- /* @__PURE__ */ jsxs13("span", { children: [
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__ */ jsxs13("span", { children: [
3239
+ /* @__PURE__ */ jsxs14("span", { children: [
3103
3240
  "Namespace: ",
3104
3241
  agent.namespace
3105
3242
  ] }),
3106
- agent.lastActivityAt && /* @__PURE__ */ jsxs13("span", { children: [
3243
+ agent.lastActivityAt && /* @__PURE__ */ jsxs14("span", { children: [
3107
3244
  "Last active: ",
3108
- formatDate6(agent.lastActivityAt)
3245
+ formatDate5(agent.lastActivityAt)
3109
3246
  ] })
3110
3247
  ] })
3111
3248
  ] })
3112
3249
  ] }),
3113
- /* @__PURE__ */ jsx18("div", { className: "grid gap-4 sm:grid-cols-3 lg:grid-cols-3", children: stats.map((stat) => /* @__PURE__ */ jsxs13("div", { className: "rounded-xl border bg-card p-5 shadow-sm", children: [
3114
- /* @__PURE__ */ jsx18("p", { className: "text-sm font-medium text-muted-foreground", children: stat.label }),
3115
- /* @__PURE__ */ jsx18("p", { className: "mt-2 text-2xl font-semibold tracking-tight", children: new Intl.NumberFormat().format(stat.value) })
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 formatDate6(value) {
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 Search4, Database as Database2 } from "lucide-react";
3128
- import { jsx as jsx19, jsxs as jsxs14 } from "react/jsx-runtime";
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__ */ jsxs14("div", { className: "space-y-4", children: [
3175
- /* @__PURE__ */ jsxs14("div", { className: "flex items-center justify-between gap-4", children: [
3176
- /* @__PURE__ */ jsx19("h2", { className: "text-lg font-semibold capitalize", children: collection }),
3177
- onCreateNew && /* @__PURE__ */ jsxs14(Button, { size: "sm", onClick: onCreateNew, children: [
3178
- /* @__PURE__ */ jsx19(Plus, { className: "mr-2 h-3 w-3" }),
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__ */ jsxs14("div", { className: "relative max-w-sm", children: [
3183
- /* @__PURE__ */ jsx19(Search4, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
3184
- /* @__PURE__ */ jsx19(
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__ */ jsx19("div", { className: "rounded-lg border border-destructive/50 bg-destructive/10 p-3 text-sm text-destructive", children: error }),
3195
- isLoading ? /* @__PURE__ */ jsx19("div", { className: "flex items-center justify-center py-20", children: /* @__PURE__ */ jsx19(Loader23, { className: "h-6 w-6 animate-spin text-muted-foreground" }) }) : items.length === 0 ? /* @__PURE__ */ jsxs14("div", { className: "rounded-xl border border-dashed p-10 text-center", children: [
3196
- /* @__PURE__ */ jsx19(Database2, { className: "mx-auto h-8 w-8 text-muted-foreground/50" }),
3197
- /* @__PURE__ */ jsx19("p", { className: "mt-3 text-sm text-muted-foreground", children: search ? config.labels.noResults : `No items in ${collection}` })
3198
- ] }) : /* @__PURE__ */ jsx19("div", { className: "space-y-2", children: items.map((item, idx) => {
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__ */ jsx19(
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__ */ jsxs14("div", { className: "flex-1 min-w-0", children: [
3206
- /* @__PURE__ */ jsx19("p", { className: "font-medium font-mono text-sm truncate", children: itemId }),
3207
- /* @__PURE__ */ jsx19("p", { className: "mt-1 text-xs text-muted-foreground truncate", children: getItemPreview(item) })
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 jsx20, jsxs as jsxs15 } from "react/jsx-runtime";
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__ */ jsx20("div", { className: "flex items-center justify-center py-20", children: /* @__PURE__ */ jsx20(Loader24, { className: "h-6 w-6 animate-spin text-muted-foreground" }) });
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__ */ jsxs15("div", { className: "space-y-6", children: [
3296
- /* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-4", children: [
3297
- /* @__PURE__ */ jsx20(Button, { variant: "ghost", size: "icon", onClick: onBack, children: /* @__PURE__ */ jsx20(ArrowLeft5, { className: "h-4 w-4" }) }),
3298
- /* @__PURE__ */ jsx20("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsx20("h2", { className: "text-xl font-semibold truncate capitalize", children: isNew ? `New ${collection} item` : `${collection} / ${itemId}` }) }),
3299
- /* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-2", children: [
3300
- saveMessage && /* @__PURE__ */ jsx20("span", { className: "text-xs text-emerald-600", children: saveMessage }),
3301
- !isNew && /* @__PURE__ */ jsxs15(
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__ */ jsx20(Loader24, { className: "mr-2 h-3 w-3 animate-spin" }) : /* @__PURE__ */ jsx20(Trash2, { className: "mr-2 h-3 w-3" }),
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__ */ jsxs15(Button, { size: "sm", onClick: () => void handleSave(), disabled: isSaving, children: [
3315
- isSaving ? /* @__PURE__ */ jsx20(Loader24, { className: "mr-2 h-3 w-3 animate-spin" }) : /* @__PURE__ */ jsx20(Save2, { className: "mr-2 h-3 w-3" }),
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__ */ jsx20("div", { className: "rounded-lg border border-destructive/50 bg-destructive/10 p-3 text-sm text-destructive", children: error }),
3321
- /* @__PURE__ */ jsx20("div", { className: "rounded-lg border bg-card", children: /* @__PURE__ */ jsx20(
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 Activity2, Loader2 as Loader25, Search as Search5 } from "lucide-react";
3336
- import { jsx as jsx21, jsxs as jsxs16 } from "react/jsx-runtime";
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__ */ jsxs16("div", { className: "space-y-6", children: [
3370
- /* @__PURE__ */ jsxs16("div", { className: "flex items-end gap-3 max-w-lg", children: [
3371
- /* @__PURE__ */ jsxs16("div", { className: "flex-1", children: [
3372
- /* @__PURE__ */ jsx21("label", { className: "text-sm font-medium mb-1 block", children: "Thread ID" }),
3373
- /* @__PURE__ */ jsxs16("div", { className: "relative", children: [
3374
- /* @__PURE__ */ jsx21(Search5, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
3375
- /* @__PURE__ */ jsx21(
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__ */ jsxs16(Button, { onClick: () => void handleSearch(), disabled: isLoading || !threadId.trim(), children: [
3388
- isLoading ? /* @__PURE__ */ jsx21(Loader25, { className: "mr-2 h-4 w-4 animate-spin" }) : null,
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__ */ jsx21("div", { className: "rounded-lg border border-destructive/50 bg-destructive/10 p-3 text-sm text-destructive", children: error }),
3393
- !hasSearched ? /* @__PURE__ */ jsxs16("div", { className: "rounded-xl border border-dashed p-10 text-center", children: [
3394
- /* @__PURE__ */ jsx21(Activity2, { className: "mx-auto h-8 w-8 text-muted-foreground/50" }),
3395
- /* @__PURE__ */ jsx21("p", { className: "mt-3 text-sm text-muted-foreground", children: "Enter a thread ID to inspect its next pending queue event." })
3396
- ] }) : isLoading ? /* @__PURE__ */ jsx21("div", { className: "flex items-center justify-center py-20", children: /* @__PURE__ */ jsx21(Loader25, { className: "h-6 w-6 animate-spin text-muted-foreground" }) }) : !event ? /* @__PURE__ */ jsxs16("div", { className: "rounded-xl border border-dashed p-10 text-center", children: [
3397
- /* @__PURE__ */ jsx21(Activity2, { className: "mx-auto h-8 w-8 text-muted-foreground/50" }),
3398
- /* @__PURE__ */ jsx21("p", { className: "mt-3 text-sm text-muted-foreground", children: "No pending events found for this thread." })
3399
- ] }) : /* @__PURE__ */ jsxs16("div", { className: "rounded-lg border bg-card p-5 space-y-4", children: [
3400
- /* @__PURE__ */ jsxs16("div", { className: "flex items-start justify-between gap-3", children: [
3401
- /* @__PURE__ */ jsxs16("div", { children: [
3402
- /* @__PURE__ */ jsx21("p", { className: "font-medium", children: event.eventType }),
3403
- /* @__PURE__ */ jsx21("p", { className: "text-xs text-muted-foreground font-mono mt-1", children: event.id })
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__ */ jsx21(Badge, { variant: STATUS_VARIANTS[event.status] ?? "outline", children: event.status })
3542
+ /* @__PURE__ */ jsx22(Badge, { variant: STATUS_VARIANTS[event.status] ?? "outline", children: event.status })
3406
3543
  ] }),
3407
- /* @__PURE__ */ jsxs16("div", { className: "grid gap-3 sm:grid-cols-2 text-sm", children: [
3408
- event.traceId && /* @__PURE__ */ jsxs16("div", { children: [
3409
- /* @__PURE__ */ jsx21("span", { className: "text-muted-foreground", children: "Trace:" }),
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__ */ jsx21("span", { className: "font-mono text-xs", children: event.traceId })
3548
+ /* @__PURE__ */ jsx22("span", { className: "font-mono text-xs", children: event.traceId })
3412
3549
  ] }),
3413
- event.parentEventId && /* @__PURE__ */ jsxs16("div", { children: [
3414
- /* @__PURE__ */ jsx21("span", { className: "text-muted-foreground", children: "Parent:" }),
3550
+ event.parentEventId && /* @__PURE__ */ jsxs17("div", { children: [
3551
+ /* @__PURE__ */ jsx22("span", { className: "text-muted-foreground", children: "Parent:" }),
3415
3552
  " ",
3416
- /* @__PURE__ */ jsx21("span", { className: "font-mono text-xs", children: event.parentEventId })
3553
+ /* @__PURE__ */ jsx22("span", { className: "font-mono text-xs", children: event.parentEventId })
3417
3554
  ] }),
3418
- event.priority != null && /* @__PURE__ */ jsxs16("div", { children: [
3419
- /* @__PURE__ */ jsx21("span", { className: "text-muted-foreground", children: "Priority:" }),
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__ */ jsxs16("div", { children: [
3424
- /* @__PURE__ */ jsx21("span", { className: "text-muted-foreground", children: "Created:" }),
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__ */ jsxs16("div", { children: [
3430
- /* @__PURE__ */ jsx21("p", { className: "text-xs font-medium text-muted-foreground mb-1", children: "Payload" }),
3431
- /* @__PURE__ */ jsx21("pre", { className: "rounded-md bg-muted p-3 text-xs overflow-auto max-h-60", children: JSON.stringify(event.payload, null, 2) })
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__ */ jsxs16("div", { children: [
3434
- /* @__PURE__ */ jsx21("p", { className: "text-xs font-medium text-muted-foreground mb-1", children: "Metadata" }),
3435
- /* @__PURE__ */ jsx21("pre", { className: "rounded-md bg-muted p-3 text-xs overflow-auto max-h-40", children: JSON.stringify(event.metadata, null, 2) })
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 jsx22, jsxs as jsxs17 } from "react/jsx-runtime";
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__ */ jsx22(Card, { className: cn("border-border", className), children: /* @__PURE__ */ jsx22(CardContent, { className: "text-muted-foreground flex items-center justify-center min-h-[200px]", children: config.labels.loading }) });
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__ */ jsx22(Card, { className: cn("border-destructive/50 bg-destructive/10", className), children: /* @__PURE__ */ jsxs17(CardContent, { className: "space-y-4", children: [
3549
- /* @__PURE__ */ jsx22("p", { className: "text-base font-semibold text-destructive", children: admin.error.message }),
3550
- /* @__PURE__ */ jsx22(Button, { variant: "destructive", onClick: () => void admin.refresh(), children: config.labels.retry })
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__ */ jsx22(
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__ */ jsx22(
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__ */ jsx22(ThreadDetailView, { threadId: route.resourceId, config, onBack: handleBackToThreads }) : null;
3725
+ return route.resourceId ? /* @__PURE__ */ jsx23(ThreadDetailView, { threadId: route.resourceId, config, onBack: handleBackToThreads }) : null;
3589
3726
  case "participants":
3590
- return /* @__PURE__ */ jsx22(
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__ */ jsx22(ParticipantDetailView, { participantId: route.resourceId, config, onBack: handleBackToParticipants }) : null;
3738
+ return route.resourceId ? /* @__PURE__ */ jsx23(ParticipantDetailView, { participantId: route.resourceId, config, onBack: handleBackToParticipants }) : null;
3602
3739
  case "agents":
3603
- return /* @__PURE__ */ jsx22(
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__ */ jsx22(AgentDetailView, { agentId: route.resourceId, config, agents: admin.agents, onBack: handleBackToAgents }) : null;
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__ */ jsx22(
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__ */ jsx22(
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__ */ jsx22(EventsView, { config });
3775
+ return /* @__PURE__ */ jsx23(EventsView, { config });
3639
3776
  default:
3640
3777
  return null;
3641
3778
  }
3642
3779
  };
3643
- return /* @__PURE__ */ jsx22(TooltipProvider, { children: /* @__PURE__ */ jsx22(SidebarProvider, { defaultOpen: config.sidebar.defaultOpen, children: /* @__PURE__ */ jsxs17(
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__ */ jsx22(
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__ */ jsx22(SidebarInset, { children: /* @__PURE__ */ jsxs17("div", { className: "flex flex-col h-full min-h-0", children: [
3665
- /* @__PURE__ */ jsx22(
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__ */ jsx22("div", { className: "flex-1 overflow-auto p-6", children: renderCurrentView() })
3815
+ /* @__PURE__ */ jsx23("div", { className: "flex-1 overflow-auto p-6", children: renderCurrentView() })
3679
3816
  ] }) })
3680
3817
  ]
3681
3818
  }