@copilotz/admin 0.3.8 → 0.3.9

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.d.cts CHANGED
@@ -9,6 +9,23 @@ interface AdminRoute {
9
9
  resourceId?: string;
10
10
  collection?: string;
11
11
  }
12
+ interface AdminUsageBreakdown {
13
+ inputTokens: number;
14
+ outputTokens: number;
15
+ reasoningTokens: number;
16
+ cacheReadInputTokens: number;
17
+ cacheCreationInputTokens: number;
18
+ totalTokens: number;
19
+ inputCostUsd: number;
20
+ outputCostUsd: number;
21
+ reasoningCostUsd: number;
22
+ cacheReadInputCostUsd: number;
23
+ cacheCreationInputCostUsd: number;
24
+ totalCostUsd: number;
25
+ }
26
+ interface AdminUsageTotals extends AdminUsageBreakdown {
27
+ totalCalls: number;
28
+ }
12
29
  interface AdminOverview {
13
30
  threadTotals: {
14
31
  total: number;
@@ -33,22 +50,13 @@ interface AdminOverview {
33
50
  humans: number;
34
51
  agents: number;
35
52
  };
36
- llmTotals: {
37
- totalCalls: number;
38
- inputTokens: number;
39
- outputTokens: number;
40
- reasoningTokens: number;
41
- cacheReadInputTokens: number;
42
- cacheCreationInputTokens: number;
43
- totalTokens: number;
44
- };
53
+ llmTotals: AdminUsageTotals;
45
54
  }
46
- interface AdminActivityPoint {
55
+ interface AdminActivityPoint extends AdminUsageTotals {
47
56
  bucket: string;
48
57
  messageCount: number;
49
- llmCallCount: number;
50
58
  toolCallMessageCount: number;
51
- totalTokens: number;
59
+ llmCallCount: number;
52
60
  }
53
61
  interface AdminThreadSummary {
54
62
  threadId: string;
@@ -82,12 +90,18 @@ interface AdminAgentSummary {
82
90
  messageCount: number;
83
91
  llmCallCount: number;
84
92
  toolCallMessageCount: number;
85
- inputTokens: number;
86
- outputTokens: number;
87
- reasoningTokens: number;
88
- cacheReadInputTokens: number;
89
- cacheCreationInputTokens: number;
90
- totalTokens: number;
93
+ inputTokens: AdminUsageBreakdown["inputTokens"];
94
+ outputTokens: AdminUsageBreakdown["outputTokens"];
95
+ reasoningTokens: AdminUsageBreakdown["reasoningTokens"];
96
+ cacheReadInputTokens: AdminUsageBreakdown["cacheReadInputTokens"];
97
+ cacheCreationInputTokens: AdminUsageBreakdown["cacheCreationInputTokens"];
98
+ totalTokens: AdminUsageBreakdown["totalTokens"];
99
+ inputCostUsd: AdminUsageBreakdown["inputCostUsd"];
100
+ outputCostUsd: AdminUsageBreakdown["outputCostUsd"];
101
+ reasoningCostUsd: AdminUsageBreakdown["reasoningCostUsd"];
102
+ cacheReadInputCostUsd: AdminUsageBreakdown["cacheReadInputCostUsd"];
103
+ cacheCreationInputCostUsd: AdminUsageBreakdown["cacheCreationInputCostUsd"];
104
+ totalCostUsd: AdminUsageBreakdown["totalCostUsd"];
91
105
  lastActivityAt: string | null;
92
106
  }
93
107
  interface AdminThreadDetail {
@@ -183,7 +197,21 @@ interface AdminConfig {
183
197
  activeThreadsCard?: string;
184
198
  participantsCard?: string;
185
199
  tokensCard?: string;
200
+ costCard?: string;
186
201
  queueCard?: string;
202
+ llmUsageTitle?: string;
203
+ usageMetricLabel?: string;
204
+ usageDimensionLabel?: string;
205
+ usageMetricTokens?: string;
206
+ usageMetricCost?: string;
207
+ usageTotal?: string;
208
+ usageInput?: string;
209
+ usageOutput?: string;
210
+ usageReasoning?: string;
211
+ usageCacheRead?: string;
212
+ usageCacheWrite?: string;
213
+ usageCallsDetail?: string;
214
+ usageUnavailableDetail?: string;
187
215
  statusActive?: string;
188
216
  statusArchived?: string;
189
217
  scopeGlobal?: string;
package/dist/index.d.ts CHANGED
@@ -9,6 +9,23 @@ interface AdminRoute {
9
9
  resourceId?: string;
10
10
  collection?: string;
11
11
  }
12
+ interface AdminUsageBreakdown {
13
+ inputTokens: number;
14
+ outputTokens: number;
15
+ reasoningTokens: number;
16
+ cacheReadInputTokens: number;
17
+ cacheCreationInputTokens: number;
18
+ totalTokens: number;
19
+ inputCostUsd: number;
20
+ outputCostUsd: number;
21
+ reasoningCostUsd: number;
22
+ cacheReadInputCostUsd: number;
23
+ cacheCreationInputCostUsd: number;
24
+ totalCostUsd: number;
25
+ }
26
+ interface AdminUsageTotals extends AdminUsageBreakdown {
27
+ totalCalls: number;
28
+ }
12
29
  interface AdminOverview {
13
30
  threadTotals: {
14
31
  total: number;
@@ -33,22 +50,13 @@ interface AdminOverview {
33
50
  humans: number;
34
51
  agents: number;
35
52
  };
36
- llmTotals: {
37
- totalCalls: number;
38
- inputTokens: number;
39
- outputTokens: number;
40
- reasoningTokens: number;
41
- cacheReadInputTokens: number;
42
- cacheCreationInputTokens: number;
43
- totalTokens: number;
44
- };
53
+ llmTotals: AdminUsageTotals;
45
54
  }
46
- interface AdminActivityPoint {
55
+ interface AdminActivityPoint extends AdminUsageTotals {
47
56
  bucket: string;
48
57
  messageCount: number;
49
- llmCallCount: number;
50
58
  toolCallMessageCount: number;
51
- totalTokens: number;
59
+ llmCallCount: number;
52
60
  }
53
61
  interface AdminThreadSummary {
54
62
  threadId: string;
@@ -82,12 +90,18 @@ interface AdminAgentSummary {
82
90
  messageCount: number;
83
91
  llmCallCount: number;
84
92
  toolCallMessageCount: number;
85
- inputTokens: number;
86
- outputTokens: number;
87
- reasoningTokens: number;
88
- cacheReadInputTokens: number;
89
- cacheCreationInputTokens: number;
90
- totalTokens: number;
93
+ inputTokens: AdminUsageBreakdown["inputTokens"];
94
+ outputTokens: AdminUsageBreakdown["outputTokens"];
95
+ reasoningTokens: AdminUsageBreakdown["reasoningTokens"];
96
+ cacheReadInputTokens: AdminUsageBreakdown["cacheReadInputTokens"];
97
+ cacheCreationInputTokens: AdminUsageBreakdown["cacheCreationInputTokens"];
98
+ totalTokens: AdminUsageBreakdown["totalTokens"];
99
+ inputCostUsd: AdminUsageBreakdown["inputCostUsd"];
100
+ outputCostUsd: AdminUsageBreakdown["outputCostUsd"];
101
+ reasoningCostUsd: AdminUsageBreakdown["reasoningCostUsd"];
102
+ cacheReadInputCostUsd: AdminUsageBreakdown["cacheReadInputCostUsd"];
103
+ cacheCreationInputCostUsd: AdminUsageBreakdown["cacheCreationInputCostUsd"];
104
+ totalCostUsd: AdminUsageBreakdown["totalCostUsd"];
91
105
  lastActivityAt: string | null;
92
106
  }
93
107
  interface AdminThreadDetail {
@@ -183,7 +197,21 @@ interface AdminConfig {
183
197
  activeThreadsCard?: string;
184
198
  participantsCard?: string;
185
199
  tokensCard?: string;
200
+ costCard?: string;
186
201
  queueCard?: string;
202
+ llmUsageTitle?: string;
203
+ usageMetricLabel?: string;
204
+ usageDimensionLabel?: string;
205
+ usageMetricTokens?: string;
206
+ usageMetricCost?: string;
207
+ usageTotal?: string;
208
+ usageInput?: string;
209
+ usageOutput?: string;
210
+ usageReasoning?: string;
211
+ usageCacheRead?: string;
212
+ usageCacheWrite?: string;
213
+ usageCallsDetail?: string;
214
+ usageUnavailableDetail?: string;
187
215
  statusActive?: string;
188
216
  statusArchived?: string;
189
217
  scopeGlobal?: string;
package/dist/index.js CHANGED
@@ -38,7 +38,21 @@ var defaultAdminConfig = {
38
38
  activeThreadsCard: "Active threads",
39
39
  participantsCard: "Participants",
40
40
  tokensCard: "LLM tokens",
41
+ costCard: "LLM cost",
41
42
  queueCard: "Queued events",
43
+ llmUsageTitle: "LLM Usage",
44
+ usageMetricLabel: "Metric",
45
+ usageDimensionLabel: "Usage type",
46
+ usageMetricTokens: "Tokens",
47
+ usageMetricCost: "Cost",
48
+ usageTotal: "Total",
49
+ usageInput: "Input",
50
+ usageOutput: "Output",
51
+ usageReasoning: "Reasoning",
52
+ usageCacheRead: "Cache read",
53
+ usageCacheWrite: "Cache write",
54
+ usageCallsDetail: "LLM calls",
55
+ usageUnavailableDetail: "Available when provider-native usage exists",
42
56
  statusActive: "Active",
43
57
  statusArchived: "Archived",
44
58
  scopeGlobal: "Global",
@@ -1495,6 +1509,9 @@ var AdminHeader = ({
1495
1509
  ] }) }) });
1496
1510
  };
1497
1511
 
1512
+ // src/components/views/DashboardView.tsx
1513
+ import React5 from "react";
1514
+
1498
1515
  // src/components/ui/badge.tsx
1499
1516
  import { Slot as Slot3 } from "@radix-ui/react-slot";
1500
1517
  import { cva as cva3 } from "class-variance-authority";
@@ -1550,6 +1567,23 @@ var DashboardView = ({
1550
1567
  onAgentSearchChange,
1551
1568
  onThreadClick
1552
1569
  }) => {
1570
+ const [usageMetricKind, setUsageMetricKind] = React5.useState(
1571
+ "tokens"
1572
+ );
1573
+ const [usageDimension, setUsageDimension] = React5.useState(
1574
+ "total"
1575
+ );
1576
+ const llmSummaryValue = overview ? getOverviewUsageValue(overview, usageMetricKind, usageDimension) : 0;
1577
+ const llmSummaryLabel = getUsageSummaryLabel(
1578
+ config.labels,
1579
+ usageMetricKind,
1580
+ usageDimension
1581
+ );
1582
+ const usageBreakdownCards = USAGE_DIMENSIONS.map((dimension) => ({
1583
+ dimension,
1584
+ label: getUsageDimensionLabel(config.labels, dimension),
1585
+ value: overview ? getOverviewUsageValue(overview, usageMetricKind, dimension) : 0
1586
+ }));
1553
1587
  const cards = [
1554
1588
  {
1555
1589
  label: config.labels.messagesCard,
@@ -1567,9 +1601,10 @@ var DashboardView = ({
1567
1601
  detail: `${overview?.participantTotals.agents ?? 0} agents`
1568
1602
  },
1569
1603
  {
1570
- label: config.labels.tokensCard,
1571
- value: overview?.llmTotals.totalTokens ?? 0,
1572
- detail: `${overview?.llmTotals.totalCalls ?? 0} calls`
1604
+ label: llmSummaryLabel,
1605
+ value: llmSummaryValue,
1606
+ detail: `${overview?.llmTotals.totalCalls ?? 0} ${config.labels.usageCallsDetail}`,
1607
+ metricKind: usageMetricKind
1573
1608
  },
1574
1609
  {
1575
1610
  label: config.labels.queueCard,
@@ -1591,13 +1626,81 @@ var DashboardView = ({
1591
1626
  className: "rounded-xl border bg-card p-5 shadow-sm",
1592
1627
  children: [
1593
1628
  /* @__PURE__ */ jsx12("p", { className: "text-sm font-medium text-muted-foreground", children: card.label }),
1594
- /* @__PURE__ */ jsx12("p", { className: "mt-3 text-3xl font-semibold tracking-tight", children: formatNumber(card.value) }),
1629
+ /* @__PURE__ */ jsx12("p", { className: "mt-3 text-3xl font-semibold tracking-tight", children: formatMetricValue(
1630
+ card.value,
1631
+ card.metricKind ?? "tokens"
1632
+ ) }),
1595
1633
  /* @__PURE__ */ jsx12("p", { className: "mt-2 text-xs text-muted-foreground", children: card.detail })
1596
1634
  ]
1597
1635
  },
1598
1636
  card.label
1599
1637
  )) })
1600
1638
  ] }),
1639
+ config.features.showOverview && /* @__PURE__ */ jsxs7("section", { className: "space-y-4", children: [
1640
+ /* @__PURE__ */ jsxs7("div", { className: "flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between", children: [
1641
+ /* @__PURE__ */ jsx12(SectionHeading, { title: config.labels.llmUsageTitle }),
1642
+ /* @__PURE__ */ jsxs7("div", { className: "grid gap-3 sm:grid-cols-2", children: [
1643
+ /* @__PURE__ */ jsxs7("div", { className: "space-y-1", children: [
1644
+ /* @__PURE__ */ jsx12("p", { className: "text-xs font-medium uppercase tracking-[0.18em] text-muted-foreground", children: config.labels.usageMetricLabel }),
1645
+ /* @__PURE__ */ jsxs7(
1646
+ Select,
1647
+ {
1648
+ value: usageMetricKind,
1649
+ onValueChange: (value) => setUsageMetricKind(value),
1650
+ children: [
1651
+ /* @__PURE__ */ jsx12(SelectTrigger, { className: "h-9 w-full min-w-[160px]", children: /* @__PURE__ */ jsx12(SelectValue, {}) }),
1652
+ /* @__PURE__ */ jsxs7(SelectContent, { children: [
1653
+ /* @__PURE__ */ jsx12(SelectItem, { value: "tokens", children: config.labels.usageMetricTokens }),
1654
+ /* @__PURE__ */ jsx12(SelectItem, { value: "cost", children: config.labels.usageMetricCost })
1655
+ ] })
1656
+ ]
1657
+ }
1658
+ )
1659
+ ] }),
1660
+ /* @__PURE__ */ jsxs7("div", { className: "space-y-1", children: [
1661
+ /* @__PURE__ */ jsx12("p", { className: "text-xs font-medium uppercase tracking-[0.18em] text-muted-foreground", children: config.labels.usageDimensionLabel }),
1662
+ /* @__PURE__ */ jsxs7(
1663
+ Select,
1664
+ {
1665
+ value: usageDimension,
1666
+ onValueChange: (value) => setUsageDimension(value),
1667
+ children: [
1668
+ /* @__PURE__ */ jsx12(SelectTrigger, { className: "h-9 w-full min-w-[160px]", children: /* @__PURE__ */ jsx12(SelectValue, {}) }),
1669
+ /* @__PURE__ */ jsx12(SelectContent, { children: USAGE_DIMENSIONS.map((dimension) => /* @__PURE__ */ jsx12(SelectItem, { value: dimension, children: getUsageDimensionLabel(config.labels, dimension) }, dimension)) })
1670
+ ]
1671
+ }
1672
+ )
1673
+ ] })
1674
+ ] })
1675
+ ] }),
1676
+ /* @__PURE__ */ jsx12("div", { className: "grid gap-4 sm:grid-cols-2 xl:grid-cols-3", children: usageBreakdownCards.map((card) => {
1677
+ const isSelected = card.dimension === usageDimension;
1678
+ return /* @__PURE__ */ jsxs7(
1679
+ "div",
1680
+ {
1681
+ className: cn(
1682
+ "rounded-xl border bg-card p-5 shadow-sm transition-colors",
1683
+ isSelected && "border-primary/60 ring-1 ring-primary/15"
1684
+ ),
1685
+ children: [
1686
+ /* @__PURE__ */ jsxs7("div", { className: "flex items-start justify-between gap-3", children: [
1687
+ /* @__PURE__ */ jsxs7("div", { children: [
1688
+ /* @__PURE__ */ jsx12("p", { className: "text-sm font-medium text-muted-foreground", children: card.label }),
1689
+ /* @__PURE__ */ jsx12("p", { className: "mt-3 text-2xl font-semibold tracking-tight", children: formatMetricValue(card.value, usageMetricKind) })
1690
+ ] }),
1691
+ isSelected && /* @__PURE__ */ jsx12(Badge, { variant: "outline", children: config.labels.usageDimensionLabel })
1692
+ ] }),
1693
+ /* @__PURE__ */ jsxs7("p", { className: "mt-2 text-xs text-muted-foreground", children: [
1694
+ overview?.llmTotals.totalCalls ?? 0,
1695
+ " ",
1696
+ config.labels.usageCallsDetail
1697
+ ] })
1698
+ ]
1699
+ },
1700
+ card.dimension
1701
+ );
1702
+ }) })
1703
+ ] }),
1601
1704
  config.features.showActivity && /* @__PURE__ */ jsxs7("section", { className: "space-y-4", children: [
1602
1705
  /* @__PURE__ */ jsx12(SectionHeading, { title: config.labels.activityTitle }),
1603
1706
  /* @__PURE__ */ jsx12(
@@ -1606,7 +1709,9 @@ var DashboardView = ({
1606
1709
  interval,
1607
1710
  labels: config.labels,
1608
1711
  maxBars: config.ui.maxActivityBars,
1609
- points: activity
1712
+ points: activity,
1713
+ usageDimension,
1714
+ usageMetricKind
1610
1715
  }
1611
1716
  )
1612
1717
  ] }),
@@ -1648,7 +1753,15 @@ var DashboardView = ({
1648
1753
  searchValue: agentSearch,
1649
1754
  setSearchValue: onAgentSearchChange,
1650
1755
  title: config.labels.agentsTitle,
1651
- children: /* @__PURE__ */ jsx12(AgentsTable, { rows: agents, labels: config.labels })
1756
+ children: /* @__PURE__ */ jsx12(
1757
+ AgentsTable,
1758
+ {
1759
+ rows: agents,
1760
+ labels: config.labels,
1761
+ usageMetricKind,
1762
+ usageDimension
1763
+ }
1764
+ )
1652
1765
  }
1653
1766
  )
1654
1767
  ] })
@@ -1659,35 +1772,50 @@ function SectionHeading({ title }) {
1659
1772
  }
1660
1773
  function ActivityChart(props) {
1661
1774
  const trimmedPoints = props.points.slice(-props.maxBars);
1662
- const maxMessages = Math.max(
1663
- ...trimmedPoints.map((point) => point.messageCount),
1775
+ const maxUsageValue = Math.max(
1776
+ ...trimmedPoints.map(
1777
+ (point) => getActivityUsageValue(
1778
+ point,
1779
+ props.usageMetricKind,
1780
+ props.usageDimension
1781
+ )
1782
+ ),
1664
1783
  1
1665
1784
  );
1666
- 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) => /* @__PURE__ */ jsxs7(
1667
- "div",
1668
- {
1669
- className: "flex min-w-0 flex-1 flex-col items-center gap-2",
1670
- children: [
1671
- /* @__PURE__ */ jsx12("div", { className: "flex h-36 w-full items-end rounded-lg bg-muted px-1 pb-1", children: /* @__PURE__ */ jsx12(
1672
- "div",
1673
- {
1674
- className: "w-full rounded-md bg-primary transition-all",
1675
- style: {
1676
- height: `${Math.max(point.messageCount / maxMessages * 100, 8)}%`
1785
+ 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) => {
1786
+ const usageValue = getActivityUsageValue(
1787
+ point,
1788
+ props.usageMetricKind,
1789
+ props.usageDimension
1790
+ );
1791
+ return /* @__PURE__ */ jsxs7(
1792
+ "div",
1793
+ {
1794
+ className: "flex min-w-0 flex-1 flex-col items-center gap-2",
1795
+ children: [
1796
+ /* @__PURE__ */ jsx12("div", { className: "flex h-36 w-full items-end rounded-lg bg-muted px-1 pb-1", children: /* @__PURE__ */ jsx12(
1797
+ "div",
1798
+ {
1799
+ className: "w-full rounded-md bg-primary transition-all",
1800
+ style: {
1801
+ height: `${Math.max(usageValue / maxUsageValue * 100, 8)}%`
1802
+ }
1677
1803
  }
1678
- }
1679
- ) }),
1680
- /* @__PURE__ */ jsxs7("div", { className: "text-center", children: [
1681
- /* @__PURE__ */ jsx12("p", { className: "text-xs font-medium", children: formatBucket(point.bucket, props.interval) }),
1682
- /* @__PURE__ */ jsxs7("p", { className: "text-[11px] text-muted-foreground", children: [
1683
- formatNumber(point.messageCount),
1684
- " msg"
1804
+ ) }),
1805
+ /* @__PURE__ */ jsxs7("div", { className: "text-center", children: [
1806
+ /* @__PURE__ */ jsx12("p", { className: "text-xs font-medium", children: formatBucket(point.bucket, props.interval) }),
1807
+ /* @__PURE__ */ jsx12("p", { className: "text-[11px] text-muted-foreground", children: formatMetricValue(usageValue, props.usageMetricKind) }),
1808
+ /* @__PURE__ */ jsxs7("p", { className: "text-[11px] text-muted-foreground", children: [
1809
+ formatNumber(point.totalCalls),
1810
+ " ",
1811
+ props.labels.usageCallsDetail
1812
+ ] })
1685
1813
  ] })
1686
- ] })
1687
- ]
1688
- },
1689
- point.bucket
1690
- )) }) });
1814
+ ]
1815
+ },
1816
+ point.bucket
1817
+ );
1818
+ }) }) });
1691
1819
  }
1692
1820
  function DataTable(props) {
1693
1821
  return /* @__PURE__ */ jsxs7("div", { className: "rounded-xl border bg-card p-5 shadow-sm", children: [
@@ -1783,7 +1911,9 @@ function ParticipantsTable({
1783
1911
  }
1784
1912
  function AgentsTable({
1785
1913
  rows,
1786
- labels
1914
+ labels,
1915
+ usageMetricKind,
1916
+ usageDimension
1787
1917
  }) {
1788
1918
  return /* @__PURE__ */ jsx12("div", { className: "space-y-3", children: rows.map((agent) => /* @__PURE__ */ jsxs7(
1789
1919
  "div",
@@ -1797,24 +1927,30 @@ function AgentsTable({
1797
1927
  ] }),
1798
1928
  /* @__PURE__ */ jsx12(Badge, { variant: "outline", children: agent.isConfigured ? labels.configured : labels.unconfigured })
1799
1929
  ] }),
1800
- /* @__PURE__ */ jsxs7("div", { className: "mt-3 grid grid-cols-2 gap-2 text-xs text-muted-foreground", children: [
1801
- /* @__PURE__ */ jsxs7("span", { children: [
1802
- formatNumber(agent.messageCount),
1803
- " messages"
1804
- ] }),
1805
- /* @__PURE__ */ jsxs7("span", { children: [
1806
- formatNumber(agent.llmCallCount),
1807
- " LLM calls"
1808
- ] }),
1809
- /* @__PURE__ */ jsxs7("span", { children: [
1810
- formatNumber(agent.toolCallMessageCount),
1811
- " tool calls"
1812
- ] }),
1813
- /* @__PURE__ */ jsxs7("span", { children: [
1814
- formatNumber(agent.totalTokens),
1815
- " tokens"
1816
- ] })
1817
- ] })
1930
+ /* @__PURE__ */ jsx12("div", { className: "mt-3 grid grid-cols-2 gap-2 text-xs", children: [
1931
+ {
1932
+ label: "Messages",
1933
+ value: formatNumber(agent.messageCount)
1934
+ },
1935
+ {
1936
+ label: "LLM calls",
1937
+ value: formatNumber(agent.llmCallCount)
1938
+ },
1939
+ {
1940
+ label: "Tool calls",
1941
+ value: formatNumber(agent.toolCallMessageCount)
1942
+ },
1943
+ {
1944
+ label: getUsageSummaryLabel(labels, usageMetricKind, usageDimension),
1945
+ value: formatMetricValue(
1946
+ getAgentUsageValue(agent, usageMetricKind, usageDimension),
1947
+ usageMetricKind
1948
+ )
1949
+ }
1950
+ ].map((item) => /* @__PURE__ */ jsxs7("div", { children: [
1951
+ /* @__PURE__ */ jsx12("p", { className: "font-medium text-foreground", children: item.value }),
1952
+ /* @__PURE__ */ jsx12("p", { className: "text-muted-foreground", children: item.label })
1953
+ ] }, item.label)) })
1818
1954
  ]
1819
1955
  },
1820
1956
  `${agent.namespace}:${agent.agentId}`
@@ -1846,6 +1982,151 @@ function formatDate(value) {
1846
1982
  function formatNumber(value) {
1847
1983
  return new Intl.NumberFormat().format(value);
1848
1984
  }
1985
+ var USAGE_DIMENSIONS = [
1986
+ "total",
1987
+ "input",
1988
+ "output",
1989
+ "reasoning",
1990
+ "cacheRead",
1991
+ "cacheWrite"
1992
+ ];
1993
+ function getUsageDimensionLabel(labels, dimension) {
1994
+ switch (dimension) {
1995
+ case "input":
1996
+ return labels.usageInput;
1997
+ case "output":
1998
+ return labels.usageOutput;
1999
+ case "reasoning":
2000
+ return labels.usageReasoning;
2001
+ case "cacheRead":
2002
+ return labels.usageCacheRead;
2003
+ case "cacheWrite":
2004
+ return labels.usageCacheWrite;
2005
+ case "total":
2006
+ default:
2007
+ return labels.usageTotal;
2008
+ }
2009
+ }
2010
+ function getUsageSummaryLabel(labels, metricKind, dimension) {
2011
+ const metricLabel = metricKind === "cost" ? labels.usageMetricCost : labels.usageMetricTokens;
2012
+ return `${getUsageDimensionLabel(labels, dimension)} ${metricLabel}`;
2013
+ }
2014
+ function getOverviewUsageValue(overview, metricKind, dimension) {
2015
+ const llmTotals = overview.llmTotals;
2016
+ if (metricKind === "cost") {
2017
+ switch (dimension) {
2018
+ case "input":
2019
+ return llmTotals.inputCostUsd;
2020
+ case "output":
2021
+ return llmTotals.outputCostUsd;
2022
+ case "reasoning":
2023
+ return llmTotals.reasoningCostUsd;
2024
+ case "cacheRead":
2025
+ return llmTotals.cacheReadInputCostUsd;
2026
+ case "cacheWrite":
2027
+ return llmTotals.cacheCreationInputCostUsd;
2028
+ case "total":
2029
+ default:
2030
+ return llmTotals.totalCostUsd;
2031
+ }
2032
+ }
2033
+ switch (dimension) {
2034
+ case "input":
2035
+ return llmTotals.inputTokens;
2036
+ case "output":
2037
+ return llmTotals.outputTokens;
2038
+ case "reasoning":
2039
+ return llmTotals.reasoningTokens;
2040
+ case "cacheRead":
2041
+ return llmTotals.cacheReadInputTokens;
2042
+ case "cacheWrite":
2043
+ return llmTotals.cacheCreationInputTokens;
2044
+ case "total":
2045
+ default:
2046
+ return llmTotals.totalTokens;
2047
+ }
2048
+ }
2049
+ function getAgentUsageValue(agent, metricKind, dimension) {
2050
+ if (metricKind === "cost") {
2051
+ switch (dimension) {
2052
+ case "input":
2053
+ return agent.inputCostUsd;
2054
+ case "output":
2055
+ return agent.outputCostUsd;
2056
+ case "reasoning":
2057
+ return agent.reasoningCostUsd;
2058
+ case "cacheRead":
2059
+ return agent.cacheReadInputCostUsd;
2060
+ case "cacheWrite":
2061
+ return agent.cacheCreationInputCostUsd;
2062
+ case "total":
2063
+ default:
2064
+ return agent.totalCostUsd;
2065
+ }
2066
+ }
2067
+ switch (dimension) {
2068
+ case "input":
2069
+ return agent.inputTokens;
2070
+ case "output":
2071
+ return agent.outputTokens;
2072
+ case "reasoning":
2073
+ return agent.reasoningTokens;
2074
+ case "cacheRead":
2075
+ return agent.cacheReadInputTokens;
2076
+ case "cacheWrite":
2077
+ return agent.cacheCreationInputTokens;
2078
+ case "total":
2079
+ default:
2080
+ return agent.totalTokens;
2081
+ }
2082
+ }
2083
+ function getActivityUsageValue(point, metricKind, dimension) {
2084
+ if (metricKind === "cost") {
2085
+ switch (dimension) {
2086
+ case "input":
2087
+ return point.inputCostUsd;
2088
+ case "output":
2089
+ return point.outputCostUsd;
2090
+ case "reasoning":
2091
+ return point.reasoningCostUsd;
2092
+ case "cacheRead":
2093
+ return point.cacheReadInputCostUsd;
2094
+ case "cacheWrite":
2095
+ return point.cacheCreationInputCostUsd;
2096
+ case "total":
2097
+ default:
2098
+ return point.totalCostUsd;
2099
+ }
2100
+ }
2101
+ switch (dimension) {
2102
+ case "input":
2103
+ return point.inputTokens;
2104
+ case "output":
2105
+ return point.outputTokens;
2106
+ case "reasoning":
2107
+ return point.reasoningTokens;
2108
+ case "cacheRead":
2109
+ return point.cacheReadInputTokens;
2110
+ case "cacheWrite":
2111
+ return point.cacheCreationInputTokens;
2112
+ case "total":
2113
+ default:
2114
+ return point.totalTokens;
2115
+ }
2116
+ }
2117
+ function formatMetricValue(value, metricKind) {
2118
+ if (metricKind === "cost") {
2119
+ const absoluteValue = Math.abs(value);
2120
+ const maximumFractionDigits = absoluteValue >= 1 ? 2 : absoluteValue >= 0.01 ? 4 : 6;
2121
+ return new Intl.NumberFormat(void 0, {
2122
+ style: "currency",
2123
+ currency: "USD",
2124
+ minimumFractionDigits: 2,
2125
+ maximumFractionDigits
2126
+ }).format(value);
2127
+ }
2128
+ return formatNumber(value);
2129
+ }
1849
2130
 
1850
2131
  // src/components/views/ThreadsView.tsx
1851
2132
  import { Search, MessageSquare as MessageSquare2 } from "lucide-react";