@copilotz/admin 0.3.8 → 0.6.0

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",
@@ -251,16 +265,17 @@ async function fetchThreadMessages(threadId, messageOptions, options) {
251
265
  }
252
266
  async function fetchParticipantDetail(participantId, options) {
253
267
  return await fetchAdminJson(
254
- `/v1/participants/${encodeURIComponent(participantId)}`,
255
- {},
268
+ `/v1/collections/participant/${encodeURIComponent(participantId)}`,
269
+ { namespace: "global" },
256
270
  options
257
271
  );
258
272
  }
259
273
  async function updateParticipant(participantId, data, options) {
260
274
  const url = new URL(
261
- `${resolveBaseUrl(options?.baseUrl)}/v1/participants/${encodeURIComponent(participantId)}`,
275
+ `${resolveBaseUrl(options?.baseUrl)}/v1/collections/participant/${encodeURIComponent(participantId)}`,
262
276
  window.location.origin
263
277
  );
278
+ url.searchParams.set("namespace", "global");
264
279
  const response = await fetch(url.toString(), {
265
280
  method: "PUT",
266
281
  headers: await withAuthHeaders(
@@ -1495,6 +1510,9 @@ var AdminHeader = ({
1495
1510
  ] }) }) });
1496
1511
  };
1497
1512
 
1513
+ // src/components/views/DashboardView.tsx
1514
+ import React5 from "react";
1515
+
1498
1516
  // src/components/ui/badge.tsx
1499
1517
  import { Slot as Slot3 } from "@radix-ui/react-slot";
1500
1518
  import { cva as cva3 } from "class-variance-authority";
@@ -1550,6 +1568,23 @@ var DashboardView = ({
1550
1568
  onAgentSearchChange,
1551
1569
  onThreadClick
1552
1570
  }) => {
1571
+ const [usageMetricKind, setUsageMetricKind] = React5.useState(
1572
+ "tokens"
1573
+ );
1574
+ const [usageDimension, setUsageDimension] = React5.useState(
1575
+ "total"
1576
+ );
1577
+ const llmSummaryValue = overview ? getOverviewUsageValue(overview, usageMetricKind, usageDimension) : 0;
1578
+ const llmSummaryLabel = getUsageSummaryLabel(
1579
+ config.labels,
1580
+ usageMetricKind,
1581
+ usageDimension
1582
+ );
1583
+ const usageBreakdownCards = USAGE_DIMENSIONS.map((dimension) => ({
1584
+ dimension,
1585
+ label: getUsageDimensionLabel(config.labels, dimension),
1586
+ value: overview ? getOverviewUsageValue(overview, usageMetricKind, dimension) : 0
1587
+ }));
1553
1588
  const cards = [
1554
1589
  {
1555
1590
  label: config.labels.messagesCard,
@@ -1567,9 +1602,10 @@ var DashboardView = ({
1567
1602
  detail: `${overview?.participantTotals.agents ?? 0} agents`
1568
1603
  },
1569
1604
  {
1570
- label: config.labels.tokensCard,
1571
- value: overview?.llmTotals.totalTokens ?? 0,
1572
- detail: `${overview?.llmTotals.totalCalls ?? 0} calls`
1605
+ label: llmSummaryLabel,
1606
+ value: llmSummaryValue,
1607
+ detail: `${overview?.llmTotals.totalCalls ?? 0} ${config.labels.usageCallsDetail}`,
1608
+ metricKind: usageMetricKind
1573
1609
  },
1574
1610
  {
1575
1611
  label: config.labels.queueCard,
@@ -1591,13 +1627,81 @@ var DashboardView = ({
1591
1627
  className: "rounded-xl border bg-card p-5 shadow-sm",
1592
1628
  children: [
1593
1629
  /* @__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) }),
1630
+ /* @__PURE__ */ jsx12("p", { className: "mt-3 text-3xl font-semibold tracking-tight", children: formatMetricValue(
1631
+ card.value,
1632
+ card.metricKind ?? "tokens"
1633
+ ) }),
1595
1634
  /* @__PURE__ */ jsx12("p", { className: "mt-2 text-xs text-muted-foreground", children: card.detail })
1596
1635
  ]
1597
1636
  },
1598
1637
  card.label
1599
1638
  )) })
1600
1639
  ] }),
1640
+ config.features.showOverview && /* @__PURE__ */ jsxs7("section", { className: "space-y-4", children: [
1641
+ /* @__PURE__ */ jsxs7("div", { className: "flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between", children: [
1642
+ /* @__PURE__ */ jsx12(SectionHeading, { title: config.labels.llmUsageTitle }),
1643
+ /* @__PURE__ */ jsxs7("div", { className: "grid gap-3 sm:grid-cols-2", children: [
1644
+ /* @__PURE__ */ jsxs7("div", { className: "space-y-1", children: [
1645
+ /* @__PURE__ */ jsx12("p", { className: "text-xs font-medium uppercase tracking-[0.18em] text-muted-foreground", children: config.labels.usageMetricLabel }),
1646
+ /* @__PURE__ */ jsxs7(
1647
+ Select,
1648
+ {
1649
+ value: usageMetricKind,
1650
+ onValueChange: (value) => setUsageMetricKind(value),
1651
+ children: [
1652
+ /* @__PURE__ */ jsx12(SelectTrigger, { className: "h-9 w-full min-w-[160px]", children: /* @__PURE__ */ jsx12(SelectValue, {}) }),
1653
+ /* @__PURE__ */ jsxs7(SelectContent, { children: [
1654
+ /* @__PURE__ */ jsx12(SelectItem, { value: "tokens", children: config.labels.usageMetricTokens }),
1655
+ /* @__PURE__ */ jsx12(SelectItem, { value: "cost", children: config.labels.usageMetricCost })
1656
+ ] })
1657
+ ]
1658
+ }
1659
+ )
1660
+ ] }),
1661
+ /* @__PURE__ */ jsxs7("div", { className: "space-y-1", children: [
1662
+ /* @__PURE__ */ jsx12("p", { className: "text-xs font-medium uppercase tracking-[0.18em] text-muted-foreground", children: config.labels.usageDimensionLabel }),
1663
+ /* @__PURE__ */ jsxs7(
1664
+ Select,
1665
+ {
1666
+ value: usageDimension,
1667
+ onValueChange: (value) => setUsageDimension(value),
1668
+ children: [
1669
+ /* @__PURE__ */ jsx12(SelectTrigger, { className: "h-9 w-full min-w-[160px]", children: /* @__PURE__ */ jsx12(SelectValue, {}) }),
1670
+ /* @__PURE__ */ jsx12(SelectContent, { children: USAGE_DIMENSIONS.map((dimension) => /* @__PURE__ */ jsx12(SelectItem, { value: dimension, children: getUsageDimensionLabel(config.labels, dimension) }, dimension)) })
1671
+ ]
1672
+ }
1673
+ )
1674
+ ] })
1675
+ ] })
1676
+ ] }),
1677
+ /* @__PURE__ */ jsx12("div", { className: "grid gap-4 sm:grid-cols-2 xl:grid-cols-3", children: usageBreakdownCards.map((card) => {
1678
+ const isSelected = card.dimension === usageDimension;
1679
+ return /* @__PURE__ */ jsxs7(
1680
+ "div",
1681
+ {
1682
+ className: cn(
1683
+ "rounded-xl border bg-card p-5 shadow-sm transition-colors",
1684
+ isSelected && "border-primary/60 ring-1 ring-primary/15"
1685
+ ),
1686
+ children: [
1687
+ /* @__PURE__ */ jsxs7("div", { className: "flex items-start justify-between gap-3", children: [
1688
+ /* @__PURE__ */ jsxs7("div", { children: [
1689
+ /* @__PURE__ */ jsx12("p", { className: "text-sm font-medium text-muted-foreground", children: card.label }),
1690
+ /* @__PURE__ */ jsx12("p", { className: "mt-3 text-2xl font-semibold tracking-tight", children: formatMetricValue(card.value, usageMetricKind) })
1691
+ ] }),
1692
+ isSelected && /* @__PURE__ */ jsx12(Badge, { variant: "outline", children: config.labels.usageDimensionLabel })
1693
+ ] }),
1694
+ /* @__PURE__ */ jsxs7("p", { className: "mt-2 text-xs text-muted-foreground", children: [
1695
+ overview?.llmTotals.totalCalls ?? 0,
1696
+ " ",
1697
+ config.labels.usageCallsDetail
1698
+ ] })
1699
+ ]
1700
+ },
1701
+ card.dimension
1702
+ );
1703
+ }) })
1704
+ ] }),
1601
1705
  config.features.showActivity && /* @__PURE__ */ jsxs7("section", { className: "space-y-4", children: [
1602
1706
  /* @__PURE__ */ jsx12(SectionHeading, { title: config.labels.activityTitle }),
1603
1707
  /* @__PURE__ */ jsx12(
@@ -1606,7 +1710,9 @@ var DashboardView = ({
1606
1710
  interval,
1607
1711
  labels: config.labels,
1608
1712
  maxBars: config.ui.maxActivityBars,
1609
- points: activity
1713
+ points: activity,
1714
+ usageDimension,
1715
+ usageMetricKind
1610
1716
  }
1611
1717
  )
1612
1718
  ] }),
@@ -1648,7 +1754,15 @@ var DashboardView = ({
1648
1754
  searchValue: agentSearch,
1649
1755
  setSearchValue: onAgentSearchChange,
1650
1756
  title: config.labels.agentsTitle,
1651
- children: /* @__PURE__ */ jsx12(AgentsTable, { rows: agents, labels: config.labels })
1757
+ children: /* @__PURE__ */ jsx12(
1758
+ AgentsTable,
1759
+ {
1760
+ rows: agents,
1761
+ labels: config.labels,
1762
+ usageMetricKind,
1763
+ usageDimension
1764
+ }
1765
+ )
1652
1766
  }
1653
1767
  )
1654
1768
  ] })
@@ -1659,35 +1773,50 @@ function SectionHeading({ title }) {
1659
1773
  }
1660
1774
  function ActivityChart(props) {
1661
1775
  const trimmedPoints = props.points.slice(-props.maxBars);
1662
- const maxMessages = Math.max(
1663
- ...trimmedPoints.map((point) => point.messageCount),
1776
+ const maxUsageValue = Math.max(
1777
+ ...trimmedPoints.map(
1778
+ (point) => getActivityUsageValue(
1779
+ point,
1780
+ props.usageMetricKind,
1781
+ props.usageDimension
1782
+ )
1783
+ ),
1664
1784
  1
1665
1785
  );
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)}%`
1786
+ 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) => {
1787
+ const usageValue = getActivityUsageValue(
1788
+ point,
1789
+ props.usageMetricKind,
1790
+ props.usageDimension
1791
+ );
1792
+ return /* @__PURE__ */ jsxs7(
1793
+ "div",
1794
+ {
1795
+ className: "flex min-w-0 flex-1 flex-col items-center gap-2",
1796
+ children: [
1797
+ /* @__PURE__ */ jsx12("div", { className: "flex h-36 w-full items-end rounded-lg bg-muted px-1 pb-1", children: /* @__PURE__ */ jsx12(
1798
+ "div",
1799
+ {
1800
+ className: "w-full rounded-md bg-primary transition-all",
1801
+ style: {
1802
+ height: `${Math.max(usageValue / maxUsageValue * 100, 8)}%`
1803
+ }
1677
1804
  }
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"
1805
+ ) }),
1806
+ /* @__PURE__ */ jsxs7("div", { className: "text-center", children: [
1807
+ /* @__PURE__ */ jsx12("p", { className: "text-xs font-medium", children: formatBucket(point.bucket, props.interval) }),
1808
+ /* @__PURE__ */ jsx12("p", { className: "text-[11px] text-muted-foreground", children: formatMetricValue(usageValue, props.usageMetricKind) }),
1809
+ /* @__PURE__ */ jsxs7("p", { className: "text-[11px] text-muted-foreground", children: [
1810
+ formatNumber(point.totalCalls),
1811
+ " ",
1812
+ props.labels.usageCallsDetail
1813
+ ] })
1685
1814
  ] })
1686
- ] })
1687
- ]
1688
- },
1689
- point.bucket
1690
- )) }) });
1815
+ ]
1816
+ },
1817
+ point.bucket
1818
+ );
1819
+ }) }) });
1691
1820
  }
1692
1821
  function DataTable(props) {
1693
1822
  return /* @__PURE__ */ jsxs7("div", { className: "rounded-xl border bg-card p-5 shadow-sm", children: [
@@ -1783,7 +1912,9 @@ function ParticipantsTable({
1783
1912
  }
1784
1913
  function AgentsTable({
1785
1914
  rows,
1786
- labels
1915
+ labels,
1916
+ usageMetricKind,
1917
+ usageDimension
1787
1918
  }) {
1788
1919
  return /* @__PURE__ */ jsx12("div", { className: "space-y-3", children: rows.map((agent) => /* @__PURE__ */ jsxs7(
1789
1920
  "div",
@@ -1797,24 +1928,30 @@ function AgentsTable({
1797
1928
  ] }),
1798
1929
  /* @__PURE__ */ jsx12(Badge, { variant: "outline", children: agent.isConfigured ? labels.configured : labels.unconfigured })
1799
1930
  ] }),
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
- ] })
1931
+ /* @__PURE__ */ jsx12("div", { className: "mt-3 grid grid-cols-2 gap-2 text-xs", children: [
1932
+ {
1933
+ label: "Messages",
1934
+ value: formatNumber(agent.messageCount)
1935
+ },
1936
+ {
1937
+ label: "LLM calls",
1938
+ value: formatNumber(agent.llmCallCount)
1939
+ },
1940
+ {
1941
+ label: "Tool calls",
1942
+ value: formatNumber(agent.toolCallMessageCount)
1943
+ },
1944
+ {
1945
+ label: getUsageSummaryLabel(labels, usageMetricKind, usageDimension),
1946
+ value: formatMetricValue(
1947
+ getAgentUsageValue(agent, usageMetricKind, usageDimension),
1948
+ usageMetricKind
1949
+ )
1950
+ }
1951
+ ].map((item) => /* @__PURE__ */ jsxs7("div", { children: [
1952
+ /* @__PURE__ */ jsx12("p", { className: "font-medium text-foreground", children: item.value }),
1953
+ /* @__PURE__ */ jsx12("p", { className: "text-muted-foreground", children: item.label })
1954
+ ] }, item.label)) })
1818
1955
  ]
1819
1956
  },
1820
1957
  `${agent.namespace}:${agent.agentId}`
@@ -1846,6 +1983,151 @@ function formatDate(value) {
1846
1983
  function formatNumber(value) {
1847
1984
  return new Intl.NumberFormat().format(value);
1848
1985
  }
1986
+ var USAGE_DIMENSIONS = [
1987
+ "total",
1988
+ "input",
1989
+ "output",
1990
+ "reasoning",
1991
+ "cacheRead",
1992
+ "cacheWrite"
1993
+ ];
1994
+ function getUsageDimensionLabel(labels, dimension) {
1995
+ switch (dimension) {
1996
+ case "input":
1997
+ return labels.usageInput;
1998
+ case "output":
1999
+ return labels.usageOutput;
2000
+ case "reasoning":
2001
+ return labels.usageReasoning;
2002
+ case "cacheRead":
2003
+ return labels.usageCacheRead;
2004
+ case "cacheWrite":
2005
+ return labels.usageCacheWrite;
2006
+ case "total":
2007
+ default:
2008
+ return labels.usageTotal;
2009
+ }
2010
+ }
2011
+ function getUsageSummaryLabel(labels, metricKind, dimension) {
2012
+ const metricLabel = metricKind === "cost" ? labels.usageMetricCost : labels.usageMetricTokens;
2013
+ return `${getUsageDimensionLabel(labels, dimension)} ${metricLabel}`;
2014
+ }
2015
+ function getOverviewUsageValue(overview, metricKind, dimension) {
2016
+ const llmTotals = overview.llmTotals;
2017
+ if (metricKind === "cost") {
2018
+ switch (dimension) {
2019
+ case "input":
2020
+ return llmTotals.inputCostUsd;
2021
+ case "output":
2022
+ return llmTotals.outputCostUsd;
2023
+ case "reasoning":
2024
+ return llmTotals.reasoningCostUsd;
2025
+ case "cacheRead":
2026
+ return llmTotals.cacheReadInputCostUsd;
2027
+ case "cacheWrite":
2028
+ return llmTotals.cacheCreationInputCostUsd;
2029
+ case "total":
2030
+ default:
2031
+ return llmTotals.totalCostUsd;
2032
+ }
2033
+ }
2034
+ switch (dimension) {
2035
+ case "input":
2036
+ return llmTotals.inputTokens;
2037
+ case "output":
2038
+ return llmTotals.outputTokens;
2039
+ case "reasoning":
2040
+ return llmTotals.reasoningTokens;
2041
+ case "cacheRead":
2042
+ return llmTotals.cacheReadInputTokens;
2043
+ case "cacheWrite":
2044
+ return llmTotals.cacheCreationInputTokens;
2045
+ case "total":
2046
+ default:
2047
+ return llmTotals.totalTokens;
2048
+ }
2049
+ }
2050
+ function getAgentUsageValue(agent, metricKind, dimension) {
2051
+ if (metricKind === "cost") {
2052
+ switch (dimension) {
2053
+ case "input":
2054
+ return agent.inputCostUsd;
2055
+ case "output":
2056
+ return agent.outputCostUsd;
2057
+ case "reasoning":
2058
+ return agent.reasoningCostUsd;
2059
+ case "cacheRead":
2060
+ return agent.cacheReadInputCostUsd;
2061
+ case "cacheWrite":
2062
+ return agent.cacheCreationInputCostUsd;
2063
+ case "total":
2064
+ default:
2065
+ return agent.totalCostUsd;
2066
+ }
2067
+ }
2068
+ switch (dimension) {
2069
+ case "input":
2070
+ return agent.inputTokens;
2071
+ case "output":
2072
+ return agent.outputTokens;
2073
+ case "reasoning":
2074
+ return agent.reasoningTokens;
2075
+ case "cacheRead":
2076
+ return agent.cacheReadInputTokens;
2077
+ case "cacheWrite":
2078
+ return agent.cacheCreationInputTokens;
2079
+ case "total":
2080
+ default:
2081
+ return agent.totalTokens;
2082
+ }
2083
+ }
2084
+ function getActivityUsageValue(point, metricKind, dimension) {
2085
+ if (metricKind === "cost") {
2086
+ switch (dimension) {
2087
+ case "input":
2088
+ return point.inputCostUsd;
2089
+ case "output":
2090
+ return point.outputCostUsd;
2091
+ case "reasoning":
2092
+ return point.reasoningCostUsd;
2093
+ case "cacheRead":
2094
+ return point.cacheReadInputCostUsd;
2095
+ case "cacheWrite":
2096
+ return point.cacheCreationInputCostUsd;
2097
+ case "total":
2098
+ default:
2099
+ return point.totalCostUsd;
2100
+ }
2101
+ }
2102
+ switch (dimension) {
2103
+ case "input":
2104
+ return point.inputTokens;
2105
+ case "output":
2106
+ return point.outputTokens;
2107
+ case "reasoning":
2108
+ return point.reasoningTokens;
2109
+ case "cacheRead":
2110
+ return point.cacheReadInputTokens;
2111
+ case "cacheWrite":
2112
+ return point.cacheCreationInputTokens;
2113
+ case "total":
2114
+ default:
2115
+ return point.totalTokens;
2116
+ }
2117
+ }
2118
+ function formatMetricValue(value, metricKind) {
2119
+ if (metricKind === "cost") {
2120
+ const absoluteValue = Math.abs(value);
2121
+ const maximumFractionDigits = absoluteValue >= 1 ? 2 : absoluteValue >= 0.01 ? 4 : 6;
2122
+ return new Intl.NumberFormat(void 0, {
2123
+ style: "currency",
2124
+ currency: "USD",
2125
+ minimumFractionDigits: 2,
2126
+ maximumFractionDigits
2127
+ }).format(value);
2128
+ }
2129
+ return formatNumber(value);
2130
+ }
1849
2131
 
1850
2132
  // src/components/views/ThreadsView.tsx
1851
2133
  import { Search, MessageSquare as MessageSquare2 } from "lucide-react";