@copilotz/admin 0.9.36 → 0.9.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +472 -112
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +25 -4
- package/dist/index.d.ts +25 -4
- package/dist/index.js +480 -113
- package/dist/index.js.map +1 -1
- package/dist/styles.css +3 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -81,6 +81,21 @@ function normalizeMessagePage(payload) {
|
|
|
81
81
|
const pageInfo = isRecord(candidate) ? normalizeMessagePageInfo(candidate.pageInfo, data) : normalizeMessagePageInfo(void 0, data);
|
|
82
82
|
return { data, pageInfo };
|
|
83
83
|
}
|
|
84
|
+
function isQueueEvent(value) {
|
|
85
|
+
return isRecord(value) && typeof value.id === "string" && typeof value.threadId === "string" && typeof value.eventType === "string";
|
|
86
|
+
}
|
|
87
|
+
function normalizeQueueEvent(value) {
|
|
88
|
+
if (isQueueEvent(value)) return value;
|
|
89
|
+
if (isRecord(value) && isQueueEvent(value.data)) return value.data;
|
|
90
|
+
return void 0;
|
|
91
|
+
}
|
|
92
|
+
function normalizeQueueEvents(value) {
|
|
93
|
+
if (Array.isArray(value)) return value.filter(isQueueEvent);
|
|
94
|
+
if (isRecord(value) && Array.isArray(value.data)) {
|
|
95
|
+
return value.data.filter(isQueueEvent);
|
|
96
|
+
}
|
|
97
|
+
return [];
|
|
98
|
+
}
|
|
84
99
|
function createAdminClient(options = {}) {
|
|
85
100
|
const baseUrl = resolveBaseUrl(options.baseUrl);
|
|
86
101
|
const paths = { ...DEFAULT_PATHS, ...options.paths };
|
|
@@ -140,12 +155,16 @@ function createAdminClient(options = {}) {
|
|
|
140
155
|
metric: filters.metric,
|
|
141
156
|
groupBy: filters.groupBy,
|
|
142
157
|
attribution: filters.attribution,
|
|
158
|
+
kind: filters.kind,
|
|
143
159
|
threadId: filters.threadId,
|
|
144
160
|
participantId: filters.participantId,
|
|
145
161
|
participantType: filters.participantType,
|
|
146
162
|
namespace: filters.namespace,
|
|
147
163
|
provider: filters.provider,
|
|
148
|
-
model: filters.model
|
|
164
|
+
model: filters.model,
|
|
165
|
+
resource: filters.resource,
|
|
166
|
+
operation: filters.operation,
|
|
167
|
+
status: filters.status
|
|
149
168
|
}),
|
|
150
169
|
listThreads: async (listOptions = {}) => await requestJson(`${paths.adminBase}/threads`, {
|
|
151
170
|
search: listOptions.search,
|
|
@@ -183,9 +202,25 @@ function createAdminClient(options = {}) {
|
|
|
183
202
|
);
|
|
184
203
|
return normalizeMessagePage(payload);
|
|
185
204
|
},
|
|
186
|
-
|
|
187
|
-
`${paths.
|
|
188
|
-
|
|
205
|
+
listEvents: async (eventOptions = {}) => {
|
|
206
|
+
const payload = await requestJson(`${paths.adminBase}/events`, {
|
|
207
|
+
namespace: eventOptions.namespace,
|
|
208
|
+
threadId: eventOptions.threadId,
|
|
209
|
+
status: eventOptions.status,
|
|
210
|
+
eventType: eventOptions.eventType,
|
|
211
|
+
traceId: eventOptions.traceId,
|
|
212
|
+
search: eventOptions.search,
|
|
213
|
+
limit: String(eventOptions.limit ?? 50),
|
|
214
|
+
offset: eventOptions.offset ? String(eventOptions.offset) : void 0
|
|
215
|
+
});
|
|
216
|
+
return normalizeQueueEvents(payload);
|
|
217
|
+
},
|
|
218
|
+
getThreadEvent: async (threadId) => {
|
|
219
|
+
const payload = await requestJson(
|
|
220
|
+
`${paths.threadsBase}/${encodeURIComponent(threadId)}/events`
|
|
221
|
+
);
|
|
222
|
+
return normalizeQueueEvent(payload);
|
|
223
|
+
},
|
|
189
224
|
listCollections: async () => await requestJson(paths.collectionsBase),
|
|
190
225
|
listCollectionItems: async (collection, listOptions = {}) => await requestJson(
|
|
191
226
|
`${paths.collectionsBase}/${encodeURIComponent(collection)}`,
|
|
@@ -1398,7 +1433,11 @@ var EMPTY_USAGE_TOTALS = {
|
|
|
1398
1433
|
reasoningTokens: 0,
|
|
1399
1434
|
totalCalls: 0,
|
|
1400
1435
|
totalCostUsd: 0,
|
|
1401
|
-
|
|
1436
|
+
failedCalls: 0,
|
|
1437
|
+
totalCredits: 0,
|
|
1438
|
+
totalDurationMs: 0,
|
|
1439
|
+
totalTokens: 0,
|
|
1440
|
+
unpricedCalls: 0
|
|
1402
1441
|
};
|
|
1403
1442
|
var USAGE_CHART_COLORS = [
|
|
1404
1443
|
"hsl(var(--primary))",
|
|
@@ -1409,53 +1448,66 @@ var USAGE_CHART_COLORS = [
|
|
|
1409
1448
|
"hsl(var(--muted-foreground))"
|
|
1410
1449
|
];
|
|
1411
1450
|
function addUsageTotals(target, source) {
|
|
1412
|
-
target.cacheCreationInputCostUsd += source.cacheCreationInputCostUsd;
|
|
1413
|
-
target.cacheCreationInputTokens += source.cacheCreationInputTokens;
|
|
1414
|
-
target.cacheReadInputCostUsd += source.cacheReadInputCostUsd;
|
|
1415
|
-
target.cacheReadInputTokens += source.cacheReadInputTokens;
|
|
1416
|
-
target.inputCostUsd += source.inputCostUsd;
|
|
1417
|
-
target.inputTokens += source.inputTokens;
|
|
1418
|
-
target.outputCostUsd += source.outputCostUsd;
|
|
1419
|
-
target.outputTokens += source.outputTokens;
|
|
1420
|
-
target.reasoningCostUsd += source.reasoningCostUsd;
|
|
1421
|
-
target.reasoningTokens += source.reasoningTokens;
|
|
1422
|
-
target.totalCalls += source.totalCalls;
|
|
1423
|
-
target.totalCostUsd += source.totalCostUsd;
|
|
1424
|
-
target.
|
|
1451
|
+
target.cacheCreationInputCostUsd += safeUsageNumber(source.cacheCreationInputCostUsd);
|
|
1452
|
+
target.cacheCreationInputTokens += safeUsageNumber(source.cacheCreationInputTokens);
|
|
1453
|
+
target.cacheReadInputCostUsd += safeUsageNumber(source.cacheReadInputCostUsd);
|
|
1454
|
+
target.cacheReadInputTokens += safeUsageNumber(source.cacheReadInputTokens);
|
|
1455
|
+
target.inputCostUsd += safeUsageNumber(source.inputCostUsd);
|
|
1456
|
+
target.inputTokens += safeUsageNumber(source.inputTokens);
|
|
1457
|
+
target.outputCostUsd += safeUsageNumber(source.outputCostUsd);
|
|
1458
|
+
target.outputTokens += safeUsageNumber(source.outputTokens);
|
|
1459
|
+
target.reasoningCostUsd += safeUsageNumber(source.reasoningCostUsd);
|
|
1460
|
+
target.reasoningTokens += safeUsageNumber(source.reasoningTokens);
|
|
1461
|
+
target.totalCalls += safeUsageNumber(source.totalCalls);
|
|
1462
|
+
target.totalCostUsd += safeUsageNumber(source.totalCostUsd);
|
|
1463
|
+
target.failedCalls += safeUsageNumber(source.failedCalls);
|
|
1464
|
+
target.totalCredits += safeUsageNumber(source.totalCredits);
|
|
1465
|
+
target.totalDurationMs += safeUsageNumber(source.totalDurationMs);
|
|
1466
|
+
target.totalTokens += safeUsageNumber(source.totalTokens);
|
|
1467
|
+
target.unpricedCalls += safeUsageNumber(source.unpricedCalls);
|
|
1468
|
+
}
|
|
1469
|
+
function safeUsageNumber(value) {
|
|
1470
|
+
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
1425
1471
|
}
|
|
1426
1472
|
function getUsageTotalValue(totals, metricKind, dimension) {
|
|
1427
|
-
if (metricKind === "calls") return totals.totalCalls;
|
|
1473
|
+
if (metricKind === "calls") return safeUsageNumber(totals.totalCalls);
|
|
1474
|
+
if (metricKind === "duration") {
|
|
1475
|
+
return safeUsageNumber(totals.totalDurationMs);
|
|
1476
|
+
}
|
|
1477
|
+
if (metricKind === "credits") return safeUsageNumber(totals.totalCredits);
|
|
1478
|
+
if (metricKind === "failures") return safeUsageNumber(totals.failedCalls);
|
|
1479
|
+
if (metricKind === "unpriced") return safeUsageNumber(totals.unpricedCalls);
|
|
1428
1480
|
if (metricKind === "cost") {
|
|
1429
1481
|
switch (dimension) {
|
|
1430
1482
|
case "input":
|
|
1431
|
-
return totals.inputCostUsd;
|
|
1483
|
+
return safeUsageNumber(totals.inputCostUsd);
|
|
1432
1484
|
case "output":
|
|
1433
|
-
return totals.outputCostUsd;
|
|
1485
|
+
return safeUsageNumber(totals.outputCostUsd);
|
|
1434
1486
|
case "reasoning":
|
|
1435
|
-
return totals.reasoningCostUsd;
|
|
1487
|
+
return safeUsageNumber(totals.reasoningCostUsd);
|
|
1436
1488
|
case "cacheRead":
|
|
1437
|
-
return totals.cacheReadInputCostUsd;
|
|
1489
|
+
return safeUsageNumber(totals.cacheReadInputCostUsd);
|
|
1438
1490
|
case "cacheWrite":
|
|
1439
|
-
return totals.cacheCreationInputCostUsd;
|
|
1491
|
+
return safeUsageNumber(totals.cacheCreationInputCostUsd);
|
|
1440
1492
|
case "total":
|
|
1441
1493
|
default:
|
|
1442
|
-
return totals.totalCostUsd;
|
|
1494
|
+
return safeUsageNumber(totals.totalCostUsd);
|
|
1443
1495
|
}
|
|
1444
1496
|
}
|
|
1445
1497
|
switch (dimension) {
|
|
1446
1498
|
case "input":
|
|
1447
|
-
return totals.inputTokens;
|
|
1499
|
+
return safeUsageNumber(totals.inputTokens);
|
|
1448
1500
|
case "output":
|
|
1449
|
-
return totals.outputTokens;
|
|
1501
|
+
return safeUsageNumber(totals.outputTokens);
|
|
1450
1502
|
case "reasoning":
|
|
1451
|
-
return totals.reasoningTokens;
|
|
1503
|
+
return safeUsageNumber(totals.reasoningTokens);
|
|
1452
1504
|
case "cacheRead":
|
|
1453
|
-
return totals.cacheReadInputTokens;
|
|
1505
|
+
return safeUsageNumber(totals.cacheReadInputTokens);
|
|
1454
1506
|
case "cacheWrite":
|
|
1455
|
-
return totals.cacheCreationInputTokens;
|
|
1507
|
+
return safeUsageNumber(totals.cacheCreationInputTokens);
|
|
1456
1508
|
case "total":
|
|
1457
1509
|
default:
|
|
1458
|
-
return totals.totalTokens;
|
|
1510
|
+
return safeUsageNumber(totals.totalTokens);
|
|
1459
1511
|
}
|
|
1460
1512
|
}
|
|
1461
1513
|
function aggregateUsageRows(points, metricKind, dimension) {
|
|
@@ -1567,6 +1619,14 @@ function getUsageDimensionLabel(dimension) {
|
|
|
1567
1619
|
}
|
|
1568
1620
|
function getUsageGroupLabel(groupBy) {
|
|
1569
1621
|
switch (groupBy) {
|
|
1622
|
+
case "kind":
|
|
1623
|
+
return "Kind";
|
|
1624
|
+
case "resource":
|
|
1625
|
+
return "Resource";
|
|
1626
|
+
case "operation":
|
|
1627
|
+
return "Operation";
|
|
1628
|
+
case "status":
|
|
1629
|
+
return "Status";
|
|
1570
1630
|
case "thread":
|
|
1571
1631
|
return "Thread";
|
|
1572
1632
|
case "namespace":
|
|
@@ -1580,6 +1640,25 @@ function getUsageGroupLabel(groupBy) {
|
|
|
1580
1640
|
return "Participant";
|
|
1581
1641
|
}
|
|
1582
1642
|
}
|
|
1643
|
+
function getUsageMetricLabel(metricKind) {
|
|
1644
|
+
switch (metricKind) {
|
|
1645
|
+
case "cost":
|
|
1646
|
+
return "Spend";
|
|
1647
|
+
case "tokens":
|
|
1648
|
+
return "Tokens";
|
|
1649
|
+
case "duration":
|
|
1650
|
+
return "Duration";
|
|
1651
|
+
case "credits":
|
|
1652
|
+
return "Credits";
|
|
1653
|
+
case "failures":
|
|
1654
|
+
return "Failures";
|
|
1655
|
+
case "unpriced":
|
|
1656
|
+
return "Unpriced";
|
|
1657
|
+
case "calls":
|
|
1658
|
+
default:
|
|
1659
|
+
return "Calls";
|
|
1660
|
+
}
|
|
1661
|
+
}
|
|
1583
1662
|
function formatUsageBucket(bucket, interval) {
|
|
1584
1663
|
const date = new Date(bucket);
|
|
1585
1664
|
if (Number.isNaN(date.getTime())) return bucket;
|
|
@@ -1622,6 +1701,9 @@ function formatMetricValue(value, metricKind) {
|
|
|
1622
1701
|
style: "currency"
|
|
1623
1702
|
}).format(value);
|
|
1624
1703
|
}
|
|
1704
|
+
if (metricKind === "duration") {
|
|
1705
|
+
return formatDuration(value);
|
|
1706
|
+
}
|
|
1625
1707
|
return formatNumber(value);
|
|
1626
1708
|
}
|
|
1627
1709
|
function formatCompactMetric(value, metricKind) {
|
|
@@ -1634,12 +1716,30 @@ function formatCompactMetric(value, metricKind) {
|
|
|
1634
1716
|
style: "currency"
|
|
1635
1717
|
}).format(value);
|
|
1636
1718
|
}
|
|
1719
|
+
if (metricKind === "duration") {
|
|
1720
|
+
if (value >= 36e5) return `${(value / 36e5).toFixed(1)}h`;
|
|
1721
|
+
if (value >= 6e4) return `${(value / 6e4).toFixed(1)}m`;
|
|
1722
|
+
if (value >= 1e3) return `${(value / 1e3).toFixed(1)}s`;
|
|
1723
|
+
return `${Math.round(value)}ms`;
|
|
1724
|
+
}
|
|
1637
1725
|
return new Intl.NumberFormat(void 0, {
|
|
1638
1726
|
compactDisplay: "short",
|
|
1639
1727
|
maximumFractionDigits: 1,
|
|
1640
1728
|
notation: "compact"
|
|
1641
1729
|
}).format(value);
|
|
1642
1730
|
}
|
|
1731
|
+
function formatDuration(value) {
|
|
1732
|
+
if (value >= 36e5) {
|
|
1733
|
+
return `${new Intl.NumberFormat(void 0, { maximumFractionDigits: 1 }).format(value / 36e5)} h`;
|
|
1734
|
+
}
|
|
1735
|
+
if (value >= 6e4) {
|
|
1736
|
+
return `${new Intl.NumberFormat(void 0, { maximumFractionDigits: 1 }).format(value / 6e4)} min`;
|
|
1737
|
+
}
|
|
1738
|
+
if (value >= 1e3) {
|
|
1739
|
+
return `${new Intl.NumberFormat(void 0, { maximumFractionDigits: 1 }).format(value / 1e3)} sec`;
|
|
1740
|
+
}
|
|
1741
|
+
return `${formatNumber(Math.round(value))} ms`;
|
|
1742
|
+
}
|
|
1643
1743
|
|
|
1644
1744
|
// src/modules/agents/index.tsx
|
|
1645
1745
|
import { jsx as jsx20, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
@@ -2117,33 +2217,61 @@ function eventsModule() {
|
|
|
2117
2217
|
}]
|
|
2118
2218
|
};
|
|
2119
2219
|
}
|
|
2220
|
+
var EVENT_STATUSES = [
|
|
2221
|
+
"all",
|
|
2222
|
+
"pending",
|
|
2223
|
+
"processing",
|
|
2224
|
+
"completed",
|
|
2225
|
+
"failed",
|
|
2226
|
+
"expired",
|
|
2227
|
+
"overwritten"
|
|
2228
|
+
];
|
|
2120
2229
|
function EventsPage({ context }) {
|
|
2121
2230
|
const [threadId, setThreadId] = React8.useState("");
|
|
2122
|
-
const [status, setStatus] = React8.useState(
|
|
2123
|
-
|
|
2231
|
+
const [status, setStatus] = React8.useState(
|
|
2232
|
+
"all"
|
|
2233
|
+
);
|
|
2234
|
+
const [eventType, setEventType] = React8.useState("");
|
|
2124
2235
|
const [traceId, setTraceId] = React8.useState("");
|
|
2125
|
-
const [
|
|
2236
|
+
const [events, setEvents] = React8.useState([]);
|
|
2237
|
+
const [selectedEvent, setSelectedEvent] = React8.useState(null);
|
|
2126
2238
|
const [error, setError] = React8.useState(null);
|
|
2127
|
-
const [
|
|
2239
|
+
const [loading, setLoading] = React8.useState(false);
|
|
2240
|
+
const [hasLoaded, setHasLoaded] = React8.useState(false);
|
|
2128
2241
|
const inspect = async () => {
|
|
2129
|
-
|
|
2130
|
-
|
|
2242
|
+
setHasLoaded(true);
|
|
2243
|
+
setLoading(true);
|
|
2131
2244
|
setError(null);
|
|
2132
2245
|
try {
|
|
2133
|
-
const next = await context.client.
|
|
2134
|
-
|
|
2246
|
+
const next = await context.client.listEvents({
|
|
2247
|
+
namespace: context.scope.namespace || void 0,
|
|
2248
|
+
threadId: threadId.trim() || void 0,
|
|
2249
|
+
status: status === "all" ? void 0 : status,
|
|
2250
|
+
eventType: eventType.trim() || void 0,
|
|
2251
|
+
traceId: traceId.trim() || void 0,
|
|
2252
|
+
limit: 50
|
|
2253
|
+
});
|
|
2254
|
+
setEvents(next);
|
|
2255
|
+
setSelectedEvent(
|
|
2256
|
+
(current) => current && next.some((event) => event.id === current.id) ? current : next[0] ?? null
|
|
2257
|
+
);
|
|
2135
2258
|
} catch (cause) {
|
|
2136
2259
|
setError(cause instanceof Error ? cause.message : "Failed to load event");
|
|
2137
|
-
|
|
2260
|
+
setEvents([]);
|
|
2261
|
+
setSelectedEvent(null);
|
|
2262
|
+
} finally {
|
|
2263
|
+
setLoading(false);
|
|
2138
2264
|
}
|
|
2139
2265
|
};
|
|
2140
|
-
|
|
2266
|
+
React8.useEffect(() => {
|
|
2267
|
+
void inspect();
|
|
2268
|
+
}, [context.client, context.refreshKey, context.scope.namespace]);
|
|
2141
2269
|
return /* @__PURE__ */ jsxs14("div", { className: "space-y-4", children: [
|
|
2142
2270
|
/* @__PURE__ */ jsx22(
|
|
2143
2271
|
PageHeader,
|
|
2144
2272
|
{
|
|
2145
2273
|
title: "Events",
|
|
2146
|
-
description: "Queue and event inspection
|
|
2274
|
+
description: "Queue and event inspection across the active namespace."
|
|
2147
2275
|
}
|
|
2148
2276
|
),
|
|
2149
2277
|
/* @__PURE__ */ jsxs14(
|
|
@@ -2152,13 +2280,13 @@ function EventsPage({ context }) {
|
|
|
2152
2280
|
actions: /* @__PURE__ */ jsxs14(
|
|
2153
2281
|
Button,
|
|
2154
2282
|
{
|
|
2155
|
-
disabled:
|
|
2283
|
+
disabled: loading,
|
|
2156
2284
|
onClick: () => void inspect(),
|
|
2157
2285
|
size: "sm",
|
|
2158
2286
|
type: "button",
|
|
2159
2287
|
children: [
|
|
2160
2288
|
/* @__PURE__ */ jsx22(Search2, { className: "size-3" }),
|
|
2161
|
-
"Inspect"
|
|
2289
|
+
loading ? "Loading" : "Inspect"
|
|
2162
2290
|
]
|
|
2163
2291
|
}
|
|
2164
2292
|
),
|
|
@@ -2167,37 +2295,45 @@ function EventsPage({ context }) {
|
|
|
2167
2295
|
Input,
|
|
2168
2296
|
{
|
|
2169
2297
|
className: "h-8 w-[220px]",
|
|
2170
|
-
onChange: (
|
|
2171
|
-
onKeyDown: (
|
|
2172
|
-
if (
|
|
2298
|
+
onChange: (event) => setThreadId(event.target.value),
|
|
2299
|
+
onKeyDown: (event) => {
|
|
2300
|
+
if (event.key === "Enter") void inspect();
|
|
2173
2301
|
},
|
|
2174
2302
|
placeholder: "Thread ID",
|
|
2175
2303
|
value: threadId
|
|
2176
2304
|
}
|
|
2177
2305
|
),
|
|
2178
|
-
/* @__PURE__ */
|
|
2179
|
-
|
|
2306
|
+
/* @__PURE__ */ jsxs14(
|
|
2307
|
+
Select,
|
|
2180
2308
|
{
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2309
|
+
value: status,
|
|
2310
|
+
onValueChange: (value) => setStatus(value),
|
|
2311
|
+
children: [
|
|
2312
|
+
/* @__PURE__ */ jsx22(SelectTrigger, { className: "h-8 w-[150px] text-xs", "aria-label": "Status", children: /* @__PURE__ */ jsx22(SelectValue, {}) }),
|
|
2313
|
+
/* @__PURE__ */ jsx22(SelectContent, { children: EVENT_STATUSES.map((option) => /* @__PURE__ */ jsx22(SelectItem, { value: option, children: option === "all" ? "All statuses" : option }, option)) })
|
|
2314
|
+
]
|
|
2185
2315
|
}
|
|
2186
2316
|
),
|
|
2187
2317
|
/* @__PURE__ */ jsx22(
|
|
2188
2318
|
Input,
|
|
2189
2319
|
{
|
|
2190
2320
|
className: "h-8 w-[180px]",
|
|
2191
|
-
onChange: (
|
|
2321
|
+
onChange: (event) => setEventType(event.target.value),
|
|
2322
|
+
onKeyDown: (event) => {
|
|
2323
|
+
if (event.key === "Enter") void inspect();
|
|
2324
|
+
},
|
|
2192
2325
|
placeholder: "Event type",
|
|
2193
|
-
value:
|
|
2326
|
+
value: eventType
|
|
2194
2327
|
}
|
|
2195
2328
|
),
|
|
2196
2329
|
/* @__PURE__ */ jsx22(
|
|
2197
2330
|
Input,
|
|
2198
2331
|
{
|
|
2199
2332
|
className: "h-8 w-[180px]",
|
|
2200
|
-
onChange: (
|
|
2333
|
+
onChange: (event) => setTraceId(event.target.value),
|
|
2334
|
+
onKeyDown: (event) => {
|
|
2335
|
+
if (event.key === "Enter") void inspect();
|
|
2336
|
+
},
|
|
2201
2337
|
placeholder: "Trace ID",
|
|
2202
2338
|
value: traceId
|
|
2203
2339
|
}
|
|
@@ -2205,27 +2341,34 @@ function EventsPage({ context }) {
|
|
|
2205
2341
|
]
|
|
2206
2342
|
}
|
|
2207
2343
|
),
|
|
2208
|
-
error ? /* @__PURE__ */ jsx22(EmptyState, { title: "Unable to inspect event", description: error }) : !
|
|
2344
|
+
error ? /* @__PURE__ */ jsx22(EmptyState, { title: "Unable to inspect event", description: error }) : !hasLoaded && loading ? /* @__PURE__ */ jsx22(
|
|
2209
2345
|
EmptyState,
|
|
2210
2346
|
{
|
|
2211
2347
|
icon: Activity,
|
|
2212
|
-
title: "
|
|
2213
|
-
description: "
|
|
2348
|
+
title: "Loading events",
|
|
2349
|
+
description: "Fetching recent queue events for the active namespace."
|
|
2214
2350
|
}
|
|
2215
2351
|
) : /* @__PURE__ */ jsxs14("div", { className: "grid gap-4 xl:grid-cols-[1fr_420px]", children: [
|
|
2216
2352
|
/* @__PURE__ */ jsx22(
|
|
2217
2353
|
ResourceTable,
|
|
2218
2354
|
{
|
|
2219
|
-
rows,
|
|
2355
|
+
rows: events,
|
|
2220
2356
|
getRowKey: (row) => row.id,
|
|
2357
|
+
onRowClick: setSelectedEvent,
|
|
2221
2358
|
empty: /* @__PURE__ */ jsx22(
|
|
2222
2359
|
EmptyState,
|
|
2223
2360
|
{
|
|
2224
|
-
title: "No matching
|
|
2225
|
-
description: "No
|
|
2361
|
+
title: "No matching events",
|
|
2362
|
+
description: "No event rows matched the current filters."
|
|
2226
2363
|
}
|
|
2227
2364
|
),
|
|
2228
2365
|
columns: [
|
|
2366
|
+
{
|
|
2367
|
+
id: "thread",
|
|
2368
|
+
header: "Thread",
|
|
2369
|
+
className: "max-w-[180px] truncate font-mono text-xs",
|
|
2370
|
+
render: (row) => row.threadId
|
|
2371
|
+
},
|
|
2229
2372
|
{
|
|
2230
2373
|
id: "type",
|
|
2231
2374
|
header: "Type",
|
|
@@ -2249,7 +2392,20 @@ function EventsPage({ context }) {
|
|
|
2249
2392
|
]
|
|
2250
2393
|
}
|
|
2251
2394
|
),
|
|
2252
|
-
/* @__PURE__ */ jsx22(
|
|
2395
|
+
selectedEvent ? /* @__PURE__ */ jsx22(
|
|
2396
|
+
JsonPanel,
|
|
2397
|
+
{
|
|
2398
|
+
title: "Event JSON",
|
|
2399
|
+
value: selectedEvent,
|
|
2400
|
+
minHeight: 420
|
|
2401
|
+
}
|
|
2402
|
+
) : /* @__PURE__ */ jsx22(
|
|
2403
|
+
EmptyState,
|
|
2404
|
+
{
|
|
2405
|
+
title: "No event selected",
|
|
2406
|
+
description: "Select an event row to inspect its payload."
|
|
2407
|
+
}
|
|
2408
|
+
)
|
|
2253
2409
|
] })
|
|
2254
2410
|
] });
|
|
2255
2411
|
}
|
|
@@ -2963,7 +3119,15 @@ import {
|
|
|
2963
3119
|
XAxis,
|
|
2964
3120
|
YAxis
|
|
2965
3121
|
} from "recharts";
|
|
2966
|
-
import {
|
|
3122
|
+
import {
|
|
3123
|
+
Activity as Activity3,
|
|
3124
|
+
AlertTriangle as AlertTriangle2,
|
|
3125
|
+
BarChart3,
|
|
3126
|
+
Clock,
|
|
3127
|
+
Coins,
|
|
3128
|
+
DollarSign,
|
|
3129
|
+
Sparkles as Sparkles2
|
|
3130
|
+
} from "lucide-react";
|
|
2967
3131
|
|
|
2968
3132
|
// src/components/ui/chart.tsx
|
|
2969
3133
|
import * as React12 from "react";
|
|
@@ -3091,6 +3255,22 @@ var USAGE_DIMENSIONS = [
|
|
|
3091
3255
|
"cacheRead",
|
|
3092
3256
|
"cacheWrite"
|
|
3093
3257
|
];
|
|
3258
|
+
var USAGE_WORKLOADS = [
|
|
3259
|
+
"all",
|
|
3260
|
+
"llm",
|
|
3261
|
+
"tool",
|
|
3262
|
+
"asset",
|
|
3263
|
+
"rag",
|
|
3264
|
+
"embedding"
|
|
3265
|
+
];
|
|
3266
|
+
var STATUS_OPTIONS = [
|
|
3267
|
+
"all",
|
|
3268
|
+
"completed",
|
|
3269
|
+
"failed",
|
|
3270
|
+
"cancelled",
|
|
3271
|
+
"aborted",
|
|
3272
|
+
"error"
|
|
3273
|
+
];
|
|
3094
3274
|
function usageModule() {
|
|
3095
3275
|
return {
|
|
3096
3276
|
group: "operate",
|
|
@@ -3117,11 +3297,12 @@ function UsagePage({ context }) {
|
|
|
3117
3297
|
"7d"
|
|
3118
3298
|
);
|
|
3119
3299
|
const [interval, setInterval] = React13.useState("day");
|
|
3300
|
+
const [workload, setWorkload] = React13.useState("all");
|
|
3120
3301
|
const [metricKind, setMetricKind] = React13.useState(
|
|
3121
|
-
"
|
|
3302
|
+
"calls"
|
|
3122
3303
|
);
|
|
3123
3304
|
const [dimension, setDimension] = React13.useState("total");
|
|
3124
|
-
const [groupBy, setGroupBy] = React13.useState("
|
|
3305
|
+
const [groupBy, setGroupBy] = React13.useState("kind");
|
|
3125
3306
|
const [attribution, setAttribution] = React13.useState(
|
|
3126
3307
|
"initiatedBy"
|
|
3127
3308
|
);
|
|
@@ -3130,6 +3311,11 @@ function UsagePage({ context }) {
|
|
|
3130
3311
|
const [participantId, setParticipantId] = React13.useState("");
|
|
3131
3312
|
const [provider, setProvider] = React13.useState("");
|
|
3132
3313
|
const [model, setModel] = React13.useState("");
|
|
3314
|
+
const [resource, setResource] = React13.useState("");
|
|
3315
|
+
const [operation, setOperation] = React13.useState("");
|
|
3316
|
+
const [status, setStatus] = React13.useState(
|
|
3317
|
+
"all"
|
|
3318
|
+
);
|
|
3133
3319
|
const [customFrom, setCustomFrom] = React13.useState("");
|
|
3134
3320
|
const [customTo, setCustomTo] = React13.useState("");
|
|
3135
3321
|
const [usage, setUsage] = React13.useState(null);
|
|
@@ -3139,6 +3325,32 @@ function UsagePage({ context }) {
|
|
|
3139
3325
|
() => getUsageRange(period, customFrom, customTo),
|
|
3140
3326
|
[customFrom, customTo, period]
|
|
3141
3327
|
);
|
|
3328
|
+
const metricOptions = React13.useMemo(
|
|
3329
|
+
() => getUsageMetricOptions(workload),
|
|
3330
|
+
[workload]
|
|
3331
|
+
);
|
|
3332
|
+
const groupOptions = React13.useMemo(
|
|
3333
|
+
() => getUsageGroupOptions(workload),
|
|
3334
|
+
[workload]
|
|
3335
|
+
);
|
|
3336
|
+
const showLlmFields = workload === "llm";
|
|
3337
|
+
const showResourceFields = workload !== "llm";
|
|
3338
|
+
const showDimension = metricKind === "tokens" || metricKind === "cost" && workload === "llm";
|
|
3339
|
+
React13.useEffect(() => {
|
|
3340
|
+
if (!metricOptions.includes(metricKind)) {
|
|
3341
|
+
setMetricKind(metricOptions[0]);
|
|
3342
|
+
}
|
|
3343
|
+
}, [metricKind, metricOptions]);
|
|
3344
|
+
React13.useEffect(() => {
|
|
3345
|
+
if (!groupOptions.includes(groupBy)) {
|
|
3346
|
+
setGroupBy(groupOptions[0]);
|
|
3347
|
+
}
|
|
3348
|
+
}, [groupBy, groupOptions]);
|
|
3349
|
+
React13.useEffect(() => {
|
|
3350
|
+
if (!showDimension && dimension !== "total") {
|
|
3351
|
+
setDimension("total");
|
|
3352
|
+
}
|
|
3353
|
+
}, [dimension, showDimension]);
|
|
3142
3354
|
React13.useEffect(() => {
|
|
3143
3355
|
let active = true;
|
|
3144
3356
|
setIsLoading(true);
|
|
@@ -3147,13 +3359,17 @@ function UsagePage({ context }) {
|
|
|
3147
3359
|
attribution,
|
|
3148
3360
|
from: range.from,
|
|
3149
3361
|
groupBy,
|
|
3362
|
+
kind: workload,
|
|
3150
3363
|
interval,
|
|
3151
3364
|
metric: metricKind,
|
|
3152
|
-
model: emptyToUndefined(model),
|
|
3365
|
+
model: showLlmFields ? emptyToUndefined(model) : void 0,
|
|
3153
3366
|
namespace: context.scope.namespace || void 0,
|
|
3367
|
+
operation: showResourceFields ? emptyToUndefined(operation) : void 0,
|
|
3154
3368
|
participantId: emptyToUndefined(participantId),
|
|
3155
3369
|
participantType,
|
|
3156
|
-
provider: emptyToUndefined(provider),
|
|
3370
|
+
provider: showLlmFields ? emptyToUndefined(provider) : void 0,
|
|
3371
|
+
resource: showResourceFields ? emptyToUndefined(resource) : void 0,
|
|
3372
|
+
status: status === "all" ? void 0 : status,
|
|
3157
3373
|
threadId: emptyToUndefined(threadId),
|
|
3158
3374
|
to: range.to
|
|
3159
3375
|
}).then((next) => {
|
|
@@ -3178,12 +3394,18 @@ function UsagePage({ context }) {
|
|
|
3178
3394
|
interval,
|
|
3179
3395
|
metricKind,
|
|
3180
3396
|
model,
|
|
3397
|
+
operation,
|
|
3181
3398
|
participantId,
|
|
3182
3399
|
participantType,
|
|
3183
3400
|
provider,
|
|
3184
3401
|
range.from,
|
|
3185
3402
|
range.to,
|
|
3186
|
-
|
|
3403
|
+
resource,
|
|
3404
|
+
showLlmFields,
|
|
3405
|
+
showResourceFields,
|
|
3406
|
+
status,
|
|
3407
|
+
threadId,
|
|
3408
|
+
workload
|
|
3187
3409
|
]);
|
|
3188
3410
|
const points = usage?.points ?? [];
|
|
3189
3411
|
const totals = usage?.totals ?? EMPTY_USAGE_TOTALS;
|
|
@@ -3200,9 +3422,10 @@ function UsagePage({ context }) {
|
|
|
3200
3422
|
PageHeader,
|
|
3201
3423
|
{
|
|
3202
3424
|
title: "Usage",
|
|
3203
|
-
description: "Inspect
|
|
3425
|
+
description: "Inspect metered LLM, tool, and resource activity by workload, actor, status, cost, duration, tokens, and credits.",
|
|
3204
3426
|
badges: [
|
|
3205
|
-
{ label:
|
|
3427
|
+
{ label: workload },
|
|
3428
|
+
{ label: getUsageMetricLabel(metricKind), variant: "secondary" },
|
|
3206
3429
|
{ label: getUsageGroupLabel(groupBy), variant: "secondary" },
|
|
3207
3430
|
...isLoading ? [{ label: "Loading" }] : []
|
|
3208
3431
|
]
|
|
@@ -3230,10 +3453,21 @@ function UsagePage({ context }) {
|
|
|
3230
3453
|
/* @__PURE__ */ jsx27(
|
|
3231
3454
|
UsageSelect,
|
|
3232
3455
|
{
|
|
3233
|
-
label: "
|
|
3456
|
+
label: "Workload",
|
|
3457
|
+
onValueChange: (value) => setWorkload(value),
|
|
3458
|
+
options: USAGE_WORKLOADS,
|
|
3459
|
+
value: workload,
|
|
3460
|
+
formatOption: getUsageKindLabel
|
|
3461
|
+
}
|
|
3462
|
+
),
|
|
3463
|
+
/* @__PURE__ */ jsx27(
|
|
3464
|
+
UsageSelect,
|
|
3465
|
+
{
|
|
3466
|
+
label: "Measure",
|
|
3234
3467
|
onValueChange: (value) => setMetricKind(value),
|
|
3235
|
-
options:
|
|
3236
|
-
value: metricKind
|
|
3468
|
+
options: metricOptions,
|
|
3469
|
+
value: metricKind,
|
|
3470
|
+
formatOption: getUsageMetricLabel
|
|
3237
3471
|
}
|
|
3238
3472
|
),
|
|
3239
3473
|
/* @__PURE__ */ jsx27(
|
|
@@ -3241,20 +3475,22 @@ function UsagePage({ context }) {
|
|
|
3241
3475
|
{
|
|
3242
3476
|
label: "Group",
|
|
3243
3477
|
onValueChange: (value) => setGroupBy(value),
|
|
3244
|
-
options:
|
|
3245
|
-
value: groupBy
|
|
3478
|
+
options: groupOptions,
|
|
3479
|
+
value: groupBy,
|
|
3480
|
+
formatOption: getUsageGroupLabel
|
|
3246
3481
|
}
|
|
3247
3482
|
),
|
|
3248
3483
|
/* @__PURE__ */ jsx27(
|
|
3249
3484
|
UsageSelect,
|
|
3250
3485
|
{
|
|
3251
|
-
label: "
|
|
3486
|
+
label: "Actor",
|
|
3252
3487
|
onValueChange: (value) => setAttribution(value),
|
|
3253
3488
|
options: ["initiatedBy", "generatedBy"],
|
|
3254
|
-
value: attribution
|
|
3489
|
+
value: attribution,
|
|
3490
|
+
formatOption: getUsageAttributionLabel
|
|
3255
3491
|
}
|
|
3256
3492
|
),
|
|
3257
|
-
/* @__PURE__ */ jsx27(
|
|
3493
|
+
showDimension && /* @__PURE__ */ jsx27(
|
|
3258
3494
|
UsageSelect,
|
|
3259
3495
|
{
|
|
3260
3496
|
label: "Dimension",
|
|
@@ -3289,12 +3525,21 @@ function UsagePage({ context }) {
|
|
|
3289
3525
|
/* @__PURE__ */ jsx27(
|
|
3290
3526
|
UsageSelect,
|
|
3291
3527
|
{
|
|
3292
|
-
label: "
|
|
3528
|
+
label: "Actor type",
|
|
3293
3529
|
onValueChange: (value) => setParticipantType(value),
|
|
3294
3530
|
options: ["all", "human", "agent", "job"],
|
|
3295
3531
|
value: participantType
|
|
3296
3532
|
}
|
|
3297
3533
|
),
|
|
3534
|
+
/* @__PURE__ */ jsx27(
|
|
3535
|
+
UsageSelect,
|
|
3536
|
+
{
|
|
3537
|
+
label: "Status",
|
|
3538
|
+
onValueChange: (value) => setStatus(value),
|
|
3539
|
+
options: STATUS_OPTIONS,
|
|
3540
|
+
value: status
|
|
3541
|
+
}
|
|
3542
|
+
),
|
|
3298
3543
|
/* @__PURE__ */ jsx27(
|
|
3299
3544
|
Input,
|
|
3300
3545
|
{
|
|
@@ -3313,46 +3558,86 @@ function UsagePage({ context }) {
|
|
|
3313
3558
|
value: participantId
|
|
3314
3559
|
}
|
|
3315
3560
|
),
|
|
3316
|
-
/* @__PURE__ */
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
|
|
3323
|
-
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
|
|
3561
|
+
showResourceFields && /* @__PURE__ */ jsxs19(Fragment2, { children: [
|
|
3562
|
+
/* @__PURE__ */ jsx27(
|
|
3563
|
+
Input,
|
|
3564
|
+
{
|
|
3565
|
+
className: "h-8 w-[170px]",
|
|
3566
|
+
onChange: (event) => setResource(event.target.value),
|
|
3567
|
+
placeholder: "Resource / tool",
|
|
3568
|
+
value: resource
|
|
3569
|
+
}
|
|
3570
|
+
),
|
|
3571
|
+
/* @__PURE__ */ jsx27(
|
|
3572
|
+
Input,
|
|
3573
|
+
{
|
|
3574
|
+
className: "h-8 w-[150px]",
|
|
3575
|
+
onChange: (event) => setOperation(event.target.value),
|
|
3576
|
+
placeholder: "Operation",
|
|
3577
|
+
value: operation
|
|
3578
|
+
}
|
|
3579
|
+
)
|
|
3580
|
+
] }),
|
|
3581
|
+
showLlmFields && /* @__PURE__ */ jsxs19(Fragment2, { children: [
|
|
3582
|
+
/* @__PURE__ */ jsx27(
|
|
3583
|
+
Input,
|
|
3584
|
+
{
|
|
3585
|
+
className: "h-8 w-[140px]",
|
|
3586
|
+
onChange: (event) => setProvider(event.target.value),
|
|
3587
|
+
placeholder: "Provider",
|
|
3588
|
+
value: provider
|
|
3589
|
+
}
|
|
3590
|
+
),
|
|
3591
|
+
/* @__PURE__ */ jsx27(
|
|
3592
|
+
Input,
|
|
3593
|
+
{
|
|
3594
|
+
className: "h-8 w-[140px]",
|
|
3595
|
+
onChange: (event) => setModel(event.target.value),
|
|
3596
|
+
placeholder: "Model",
|
|
3597
|
+
value: model
|
|
3598
|
+
}
|
|
3599
|
+
)
|
|
3600
|
+
] })
|
|
3334
3601
|
] }),
|
|
3335
3602
|
/* @__PURE__ */ jsx27(
|
|
3336
3603
|
MetricStrip,
|
|
3337
3604
|
{
|
|
3338
3605
|
items: [
|
|
3339
3606
|
{
|
|
3340
|
-
detail: `${totals.
|
|
3607
|
+
detail: `${formatMetricValue(totals.unpricedCalls, "unpriced")} unpriced`,
|
|
3341
3608
|
icon: DollarSign,
|
|
3342
|
-
label: "
|
|
3609
|
+
label: "Spend",
|
|
3343
3610
|
value: formatMetricValue(totals.totalCostUsd, "cost")
|
|
3344
3611
|
},
|
|
3345
3612
|
{
|
|
3346
|
-
detail: `${formatMetricValue(totals.
|
|
3613
|
+
detail: `${formatMetricValue(totals.failedCalls, "failures")} failed`,
|
|
3347
3614
|
icon: Activity3,
|
|
3615
|
+
label: "Calls",
|
|
3616
|
+
value: formatMetricValue(totals.totalCalls, "calls")
|
|
3617
|
+
},
|
|
3618
|
+
{
|
|
3619
|
+
detail: "Tool and resource runtime",
|
|
3620
|
+
icon: Clock,
|
|
3621
|
+
label: "Duration",
|
|
3622
|
+
value: formatMetricValue(totals.totalDurationMs, "duration")
|
|
3623
|
+
},
|
|
3624
|
+
{
|
|
3625
|
+
detail: `${formatMetricValue(totals.inputTokens, "tokens")} input`,
|
|
3626
|
+
icon: Sparkles2,
|
|
3348
3627
|
label: "Tokens",
|
|
3349
3628
|
value: formatMetricValue(totals.totalTokens, "tokens")
|
|
3350
3629
|
},
|
|
3351
3630
|
{
|
|
3352
|
-
detail:
|
|
3353
|
-
icon:
|
|
3354
|
-
label: "
|
|
3355
|
-
value: formatMetricValue(totals.
|
|
3631
|
+
detail: "Custom metering",
|
|
3632
|
+
icon: Coins,
|
|
3633
|
+
label: "Credits",
|
|
3634
|
+
value: formatMetricValue(totals.totalCredits, "credits")
|
|
3635
|
+
},
|
|
3636
|
+
{
|
|
3637
|
+
detail: "Failed or aborted work",
|
|
3638
|
+
icon: AlertTriangle2,
|
|
3639
|
+
label: "Failures",
|
|
3640
|
+
value: formatMetricValue(totals.failedCalls, "failures")
|
|
3356
3641
|
}
|
|
3357
3642
|
]
|
|
3358
3643
|
}
|
|
@@ -3361,7 +3646,7 @@ function UsagePage({ context }) {
|
|
|
3361
3646
|
EmptyState,
|
|
3362
3647
|
{
|
|
3363
3648
|
title: "No usage",
|
|
3364
|
-
description: "
|
|
3649
|
+
description: "Metered LLM, tool, and resource records will appear here after work is captured in the usage ledger."
|
|
3365
3650
|
}
|
|
3366
3651
|
) : /* @__PURE__ */ jsxs19(Fragment2, { children: [
|
|
3367
3652
|
/* @__PURE__ */ jsx27(Card, { className: "h-[320px] py-3", children: /* @__PURE__ */ jsx27(CardContent, { className: "h-full px-3", children: /* @__PURE__ */ jsx27(UsageChart, { chartState, metricKind }) }) }),
|
|
@@ -3440,6 +3725,7 @@ function UsageRowsTable({
|
|
|
3440
3725
|
totals
|
|
3441
3726
|
}) {
|
|
3442
3727
|
const totalValue = getUsageTotalValue(totals, metricKind, dimension);
|
|
3728
|
+
const valueHeader = (metricKind === "tokens" || metricKind === "cost") && dimension !== "total" ? `${getUsageDimensionLabel(dimension)} ${getUsageMetricLabel(metricKind)}` : getUsageMetricLabel(metricKind);
|
|
3443
3729
|
return /* @__PURE__ */ jsx27(
|
|
3444
3730
|
ResourceTable,
|
|
3445
3731
|
{
|
|
@@ -3457,7 +3743,7 @@ function UsageRowsTable({
|
|
|
3457
3743
|
{
|
|
3458
3744
|
align: "right",
|
|
3459
3745
|
id: "value",
|
|
3460
|
-
header:
|
|
3746
|
+
header: valueHeader,
|
|
3461
3747
|
render: (row) => formatMetricValue(row.value, metricKind)
|
|
3462
3748
|
},
|
|
3463
3749
|
{
|
|
@@ -3474,20 +3760,100 @@ function UsageRowsTable({
|
|
|
3474
3760
|
},
|
|
3475
3761
|
{
|
|
3476
3762
|
align: "right",
|
|
3477
|
-
id: "
|
|
3478
|
-
header: "
|
|
3479
|
-
render: (row) => formatMetricValue(
|
|
3763
|
+
id: "spend",
|
|
3764
|
+
header: "Spend",
|
|
3765
|
+
render: (row) => formatMetricValue(row.totalCostUsd, "cost")
|
|
3766
|
+
},
|
|
3767
|
+
{
|
|
3768
|
+
align: "right",
|
|
3769
|
+
id: "duration",
|
|
3770
|
+
header: "Duration",
|
|
3771
|
+
render: (row) => formatMetricValue(row.totalDurationMs, "duration")
|
|
3772
|
+
},
|
|
3773
|
+
{
|
|
3774
|
+
align: "right",
|
|
3775
|
+
id: "tokens",
|
|
3776
|
+
header: "Tokens",
|
|
3777
|
+
render: (row) => formatMetricValue(row.totalTokens, "tokens")
|
|
3778
|
+
},
|
|
3779
|
+
{
|
|
3780
|
+
align: "right",
|
|
3781
|
+
id: "failures",
|
|
3782
|
+
header: "Failures",
|
|
3783
|
+
render: (row) => formatMetricValue(row.failedCalls, "failures")
|
|
3480
3784
|
},
|
|
3481
3785
|
{
|
|
3482
3786
|
align: "right",
|
|
3483
|
-
id: "
|
|
3484
|
-
header: "
|
|
3485
|
-
render: (row) => formatMetricValue(
|
|
3787
|
+
id: "unpriced",
|
|
3788
|
+
header: "Unpriced",
|
|
3789
|
+
render: (row) => formatMetricValue(row.unpricedCalls, "unpriced")
|
|
3486
3790
|
}
|
|
3487
3791
|
]
|
|
3488
3792
|
}
|
|
3489
3793
|
);
|
|
3490
3794
|
}
|
|
3795
|
+
function getUsageMetricOptions(workload) {
|
|
3796
|
+
if (workload === "llm") {
|
|
3797
|
+
return ["cost", "tokens", "calls", "failures", "unpriced"];
|
|
3798
|
+
}
|
|
3799
|
+
if (workload === "tool") {
|
|
3800
|
+
return ["calls", "duration", "cost", "credits", "failures", "unpriced"];
|
|
3801
|
+
}
|
|
3802
|
+
return [
|
|
3803
|
+
"calls",
|
|
3804
|
+
"cost",
|
|
3805
|
+
"duration",
|
|
3806
|
+
"tokens",
|
|
3807
|
+
"credits",
|
|
3808
|
+
"failures",
|
|
3809
|
+
"unpriced"
|
|
3810
|
+
];
|
|
3811
|
+
}
|
|
3812
|
+
function getUsageGroupOptions(workload) {
|
|
3813
|
+
if (workload === "llm") {
|
|
3814
|
+
return ["participant", "model", "provider", "thread", "namespace", "status"];
|
|
3815
|
+
}
|
|
3816
|
+
if (workload === "tool") {
|
|
3817
|
+
return [
|
|
3818
|
+
"resource",
|
|
3819
|
+
"operation",
|
|
3820
|
+
"status",
|
|
3821
|
+
"participant",
|
|
3822
|
+
"thread",
|
|
3823
|
+
"namespace"
|
|
3824
|
+
];
|
|
3825
|
+
}
|
|
3826
|
+
return [
|
|
3827
|
+
"kind",
|
|
3828
|
+
"resource",
|
|
3829
|
+
"operation",
|
|
3830
|
+
"status",
|
|
3831
|
+
"participant",
|
|
3832
|
+
"thread",
|
|
3833
|
+
"namespace"
|
|
3834
|
+
];
|
|
3835
|
+
}
|
|
3836
|
+
function getUsageKindLabel(kind) {
|
|
3837
|
+
switch (kind) {
|
|
3838
|
+
case "all":
|
|
3839
|
+
return "All";
|
|
3840
|
+
case "llm":
|
|
3841
|
+
return "LLM";
|
|
3842
|
+
case "tool":
|
|
3843
|
+
return "Tools";
|
|
3844
|
+
case "asset":
|
|
3845
|
+
return "Assets";
|
|
3846
|
+
case "rag":
|
|
3847
|
+
return "RAG";
|
|
3848
|
+
case "embedding":
|
|
3849
|
+
return "Embeddings";
|
|
3850
|
+
default:
|
|
3851
|
+
return kind;
|
|
3852
|
+
}
|
|
3853
|
+
}
|
|
3854
|
+
function getUsageAttributionLabel(attribution) {
|
|
3855
|
+
return attribution === "initiatedBy" ? "Initiator" : "Performer";
|
|
3856
|
+
}
|
|
3491
3857
|
function emptyToUndefined(value) {
|
|
3492
3858
|
const trimmed = value.trim();
|
|
3493
3859
|
return trimmed.length > 0 ? trimmed : void 0;
|
|
@@ -3975,6 +4341,7 @@ export {
|
|
|
3975
4341
|
formatUsageBucket,
|
|
3976
4342
|
getUsageDimensionLabel,
|
|
3977
4343
|
getUsageGroupLabel,
|
|
4344
|
+
getUsageMetricLabel,
|
|
3978
4345
|
getUsageRange,
|
|
3979
4346
|
getUsageTotalValue,
|
|
3980
4347
|
mergeAdminConfig,
|