@copilotz/admin 0.9.36 → 0.9.37

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
@@ -140,12 +140,16 @@ function createAdminClient(options = {}) {
140
140
  metric: filters.metric,
141
141
  groupBy: filters.groupBy,
142
142
  attribution: filters.attribution,
143
+ kind: filters.kind,
143
144
  threadId: filters.threadId,
144
145
  participantId: filters.participantId,
145
146
  participantType: filters.participantType,
146
147
  namespace: filters.namespace,
147
148
  provider: filters.provider,
148
- model: filters.model
149
+ model: filters.model,
150
+ resource: filters.resource,
151
+ operation: filters.operation,
152
+ status: filters.status
149
153
  }),
150
154
  listThreads: async (listOptions = {}) => await requestJson(`${paths.adminBase}/threads`, {
151
155
  search: listOptions.search,
@@ -1398,7 +1402,11 @@ var EMPTY_USAGE_TOTALS = {
1398
1402
  reasoningTokens: 0,
1399
1403
  totalCalls: 0,
1400
1404
  totalCostUsd: 0,
1401
- totalTokens: 0
1405
+ failedCalls: 0,
1406
+ totalCredits: 0,
1407
+ totalDurationMs: 0,
1408
+ totalTokens: 0,
1409
+ unpricedCalls: 0
1402
1410
  };
1403
1411
  var USAGE_CHART_COLORS = [
1404
1412
  "hsl(var(--primary))",
@@ -1409,53 +1417,66 @@ var USAGE_CHART_COLORS = [
1409
1417
  "hsl(var(--muted-foreground))"
1410
1418
  ];
1411
1419
  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.totalTokens += source.totalTokens;
1420
+ target.cacheCreationInputCostUsd += safeUsageNumber(source.cacheCreationInputCostUsd);
1421
+ target.cacheCreationInputTokens += safeUsageNumber(source.cacheCreationInputTokens);
1422
+ target.cacheReadInputCostUsd += safeUsageNumber(source.cacheReadInputCostUsd);
1423
+ target.cacheReadInputTokens += safeUsageNumber(source.cacheReadInputTokens);
1424
+ target.inputCostUsd += safeUsageNumber(source.inputCostUsd);
1425
+ target.inputTokens += safeUsageNumber(source.inputTokens);
1426
+ target.outputCostUsd += safeUsageNumber(source.outputCostUsd);
1427
+ target.outputTokens += safeUsageNumber(source.outputTokens);
1428
+ target.reasoningCostUsd += safeUsageNumber(source.reasoningCostUsd);
1429
+ target.reasoningTokens += safeUsageNumber(source.reasoningTokens);
1430
+ target.totalCalls += safeUsageNumber(source.totalCalls);
1431
+ target.totalCostUsd += safeUsageNumber(source.totalCostUsd);
1432
+ target.failedCalls += safeUsageNumber(source.failedCalls);
1433
+ target.totalCredits += safeUsageNumber(source.totalCredits);
1434
+ target.totalDurationMs += safeUsageNumber(source.totalDurationMs);
1435
+ target.totalTokens += safeUsageNumber(source.totalTokens);
1436
+ target.unpricedCalls += safeUsageNumber(source.unpricedCalls);
1437
+ }
1438
+ function safeUsageNumber(value) {
1439
+ return typeof value === "number" && Number.isFinite(value) ? value : 0;
1425
1440
  }
1426
1441
  function getUsageTotalValue(totals, metricKind, dimension) {
1427
- if (metricKind === "calls") return totals.totalCalls;
1442
+ if (metricKind === "calls") return safeUsageNumber(totals.totalCalls);
1443
+ if (metricKind === "duration") {
1444
+ return safeUsageNumber(totals.totalDurationMs);
1445
+ }
1446
+ if (metricKind === "credits") return safeUsageNumber(totals.totalCredits);
1447
+ if (metricKind === "failures") return safeUsageNumber(totals.failedCalls);
1448
+ if (metricKind === "unpriced") return safeUsageNumber(totals.unpricedCalls);
1428
1449
  if (metricKind === "cost") {
1429
1450
  switch (dimension) {
1430
1451
  case "input":
1431
- return totals.inputCostUsd;
1452
+ return safeUsageNumber(totals.inputCostUsd);
1432
1453
  case "output":
1433
- return totals.outputCostUsd;
1454
+ return safeUsageNumber(totals.outputCostUsd);
1434
1455
  case "reasoning":
1435
- return totals.reasoningCostUsd;
1456
+ return safeUsageNumber(totals.reasoningCostUsd);
1436
1457
  case "cacheRead":
1437
- return totals.cacheReadInputCostUsd;
1458
+ return safeUsageNumber(totals.cacheReadInputCostUsd);
1438
1459
  case "cacheWrite":
1439
- return totals.cacheCreationInputCostUsd;
1460
+ return safeUsageNumber(totals.cacheCreationInputCostUsd);
1440
1461
  case "total":
1441
1462
  default:
1442
- return totals.totalCostUsd;
1463
+ return safeUsageNumber(totals.totalCostUsd);
1443
1464
  }
1444
1465
  }
1445
1466
  switch (dimension) {
1446
1467
  case "input":
1447
- return totals.inputTokens;
1468
+ return safeUsageNumber(totals.inputTokens);
1448
1469
  case "output":
1449
- return totals.outputTokens;
1470
+ return safeUsageNumber(totals.outputTokens);
1450
1471
  case "reasoning":
1451
- return totals.reasoningTokens;
1472
+ return safeUsageNumber(totals.reasoningTokens);
1452
1473
  case "cacheRead":
1453
- return totals.cacheReadInputTokens;
1474
+ return safeUsageNumber(totals.cacheReadInputTokens);
1454
1475
  case "cacheWrite":
1455
- return totals.cacheCreationInputTokens;
1476
+ return safeUsageNumber(totals.cacheCreationInputTokens);
1456
1477
  case "total":
1457
1478
  default:
1458
- return totals.totalTokens;
1479
+ return safeUsageNumber(totals.totalTokens);
1459
1480
  }
1460
1481
  }
1461
1482
  function aggregateUsageRows(points, metricKind, dimension) {
@@ -1567,6 +1588,14 @@ function getUsageDimensionLabel(dimension) {
1567
1588
  }
1568
1589
  function getUsageGroupLabel(groupBy) {
1569
1590
  switch (groupBy) {
1591
+ case "kind":
1592
+ return "Kind";
1593
+ case "resource":
1594
+ return "Resource";
1595
+ case "operation":
1596
+ return "Operation";
1597
+ case "status":
1598
+ return "Status";
1570
1599
  case "thread":
1571
1600
  return "Thread";
1572
1601
  case "namespace":
@@ -1580,6 +1609,25 @@ function getUsageGroupLabel(groupBy) {
1580
1609
  return "Participant";
1581
1610
  }
1582
1611
  }
1612
+ function getUsageMetricLabel(metricKind) {
1613
+ switch (metricKind) {
1614
+ case "cost":
1615
+ return "Spend";
1616
+ case "tokens":
1617
+ return "Tokens";
1618
+ case "duration":
1619
+ return "Duration";
1620
+ case "credits":
1621
+ return "Credits";
1622
+ case "failures":
1623
+ return "Failures";
1624
+ case "unpriced":
1625
+ return "Unpriced";
1626
+ case "calls":
1627
+ default:
1628
+ return "Calls";
1629
+ }
1630
+ }
1583
1631
  function formatUsageBucket(bucket, interval) {
1584
1632
  const date = new Date(bucket);
1585
1633
  if (Number.isNaN(date.getTime())) return bucket;
@@ -1622,6 +1670,9 @@ function formatMetricValue(value, metricKind) {
1622
1670
  style: "currency"
1623
1671
  }).format(value);
1624
1672
  }
1673
+ if (metricKind === "duration") {
1674
+ return formatDuration(value);
1675
+ }
1625
1676
  return formatNumber(value);
1626
1677
  }
1627
1678
  function formatCompactMetric(value, metricKind) {
@@ -1634,12 +1685,30 @@ function formatCompactMetric(value, metricKind) {
1634
1685
  style: "currency"
1635
1686
  }).format(value);
1636
1687
  }
1688
+ if (metricKind === "duration") {
1689
+ if (value >= 36e5) return `${(value / 36e5).toFixed(1)}h`;
1690
+ if (value >= 6e4) return `${(value / 6e4).toFixed(1)}m`;
1691
+ if (value >= 1e3) return `${(value / 1e3).toFixed(1)}s`;
1692
+ return `${Math.round(value)}ms`;
1693
+ }
1637
1694
  return new Intl.NumberFormat(void 0, {
1638
1695
  compactDisplay: "short",
1639
1696
  maximumFractionDigits: 1,
1640
1697
  notation: "compact"
1641
1698
  }).format(value);
1642
1699
  }
1700
+ function formatDuration(value) {
1701
+ if (value >= 36e5) {
1702
+ return `${new Intl.NumberFormat(void 0, { maximumFractionDigits: 1 }).format(value / 36e5)} h`;
1703
+ }
1704
+ if (value >= 6e4) {
1705
+ return `${new Intl.NumberFormat(void 0, { maximumFractionDigits: 1 }).format(value / 6e4)} min`;
1706
+ }
1707
+ if (value >= 1e3) {
1708
+ return `${new Intl.NumberFormat(void 0, { maximumFractionDigits: 1 }).format(value / 1e3)} sec`;
1709
+ }
1710
+ return `${formatNumber(Math.round(value))} ms`;
1711
+ }
1643
1712
 
1644
1713
  // src/modules/agents/index.tsx
1645
1714
  import { jsx as jsx20, jsxs as jsxs12 } from "react/jsx-runtime";
@@ -2963,7 +3032,15 @@ import {
2963
3032
  XAxis,
2964
3033
  YAxis
2965
3034
  } from "recharts";
2966
- import { Activity as Activity3, BarChart3, DollarSign, Sparkles as Sparkles2 } from "lucide-react";
3035
+ import {
3036
+ Activity as Activity3,
3037
+ AlertTriangle as AlertTriangle2,
3038
+ BarChart3,
3039
+ Clock,
3040
+ Coins,
3041
+ DollarSign,
3042
+ Sparkles as Sparkles2
3043
+ } from "lucide-react";
2967
3044
 
2968
3045
  // src/components/ui/chart.tsx
2969
3046
  import * as React12 from "react";
@@ -3091,6 +3168,22 @@ var USAGE_DIMENSIONS = [
3091
3168
  "cacheRead",
3092
3169
  "cacheWrite"
3093
3170
  ];
3171
+ var USAGE_WORKLOADS = [
3172
+ "all",
3173
+ "llm",
3174
+ "tool",
3175
+ "asset",
3176
+ "rag",
3177
+ "embedding"
3178
+ ];
3179
+ var STATUS_OPTIONS = [
3180
+ "all",
3181
+ "completed",
3182
+ "failed",
3183
+ "cancelled",
3184
+ "aborted",
3185
+ "error"
3186
+ ];
3094
3187
  function usageModule() {
3095
3188
  return {
3096
3189
  group: "operate",
@@ -3117,11 +3210,12 @@ function UsagePage({ context }) {
3117
3210
  "7d"
3118
3211
  );
3119
3212
  const [interval, setInterval] = React13.useState("day");
3213
+ const [workload, setWorkload] = React13.useState("all");
3120
3214
  const [metricKind, setMetricKind] = React13.useState(
3121
- "cost"
3215
+ "calls"
3122
3216
  );
3123
3217
  const [dimension, setDimension] = React13.useState("total");
3124
- const [groupBy, setGroupBy] = React13.useState("participant");
3218
+ const [groupBy, setGroupBy] = React13.useState("kind");
3125
3219
  const [attribution, setAttribution] = React13.useState(
3126
3220
  "initiatedBy"
3127
3221
  );
@@ -3130,6 +3224,11 @@ function UsagePage({ context }) {
3130
3224
  const [participantId, setParticipantId] = React13.useState("");
3131
3225
  const [provider, setProvider] = React13.useState("");
3132
3226
  const [model, setModel] = React13.useState("");
3227
+ const [resource, setResource] = React13.useState("");
3228
+ const [operation, setOperation] = React13.useState("");
3229
+ const [status, setStatus] = React13.useState(
3230
+ "all"
3231
+ );
3133
3232
  const [customFrom, setCustomFrom] = React13.useState("");
3134
3233
  const [customTo, setCustomTo] = React13.useState("");
3135
3234
  const [usage, setUsage] = React13.useState(null);
@@ -3139,6 +3238,32 @@ function UsagePage({ context }) {
3139
3238
  () => getUsageRange(period, customFrom, customTo),
3140
3239
  [customFrom, customTo, period]
3141
3240
  );
3241
+ const metricOptions = React13.useMemo(
3242
+ () => getUsageMetricOptions(workload),
3243
+ [workload]
3244
+ );
3245
+ const groupOptions = React13.useMemo(
3246
+ () => getUsageGroupOptions(workload),
3247
+ [workload]
3248
+ );
3249
+ const showLlmFields = workload === "llm";
3250
+ const showResourceFields = workload !== "llm";
3251
+ const showDimension = metricKind === "tokens" || metricKind === "cost" && workload === "llm";
3252
+ React13.useEffect(() => {
3253
+ if (!metricOptions.includes(metricKind)) {
3254
+ setMetricKind(metricOptions[0]);
3255
+ }
3256
+ }, [metricKind, metricOptions]);
3257
+ React13.useEffect(() => {
3258
+ if (!groupOptions.includes(groupBy)) {
3259
+ setGroupBy(groupOptions[0]);
3260
+ }
3261
+ }, [groupBy, groupOptions]);
3262
+ React13.useEffect(() => {
3263
+ if (!showDimension && dimension !== "total") {
3264
+ setDimension("total");
3265
+ }
3266
+ }, [dimension, showDimension]);
3142
3267
  React13.useEffect(() => {
3143
3268
  let active = true;
3144
3269
  setIsLoading(true);
@@ -3147,13 +3272,17 @@ function UsagePage({ context }) {
3147
3272
  attribution,
3148
3273
  from: range.from,
3149
3274
  groupBy,
3275
+ kind: workload,
3150
3276
  interval,
3151
3277
  metric: metricKind,
3152
- model: emptyToUndefined(model),
3278
+ model: showLlmFields ? emptyToUndefined(model) : void 0,
3153
3279
  namespace: context.scope.namespace || void 0,
3280
+ operation: showResourceFields ? emptyToUndefined(operation) : void 0,
3154
3281
  participantId: emptyToUndefined(participantId),
3155
3282
  participantType,
3156
- provider: emptyToUndefined(provider),
3283
+ provider: showLlmFields ? emptyToUndefined(provider) : void 0,
3284
+ resource: showResourceFields ? emptyToUndefined(resource) : void 0,
3285
+ status: status === "all" ? void 0 : status,
3157
3286
  threadId: emptyToUndefined(threadId),
3158
3287
  to: range.to
3159
3288
  }).then((next) => {
@@ -3178,12 +3307,18 @@ function UsagePage({ context }) {
3178
3307
  interval,
3179
3308
  metricKind,
3180
3309
  model,
3310
+ operation,
3181
3311
  participantId,
3182
3312
  participantType,
3183
3313
  provider,
3184
3314
  range.from,
3185
3315
  range.to,
3186
- threadId
3316
+ resource,
3317
+ showLlmFields,
3318
+ showResourceFields,
3319
+ status,
3320
+ threadId,
3321
+ workload
3187
3322
  ]);
3188
3323
  const points = usage?.points ?? [];
3189
3324
  const totals = usage?.totals ?? EMPTY_USAGE_TOTALS;
@@ -3200,9 +3335,10 @@ function UsagePage({ context }) {
3200
3335
  PageHeader,
3201
3336
  {
3202
3337
  title: "Usage",
3203
- description: "Inspect cost, token, and call attribution across namespaces, models, participants, threads, and providers.",
3338
+ description: "Inspect metered LLM, tool, and resource activity by workload, actor, status, cost, duration, tokens, and credits.",
3204
3339
  badges: [
3205
- { label: period },
3340
+ { label: workload },
3341
+ { label: getUsageMetricLabel(metricKind), variant: "secondary" },
3206
3342
  { label: getUsageGroupLabel(groupBy), variant: "secondary" },
3207
3343
  ...isLoading ? [{ label: "Loading" }] : []
3208
3344
  ]
@@ -3230,10 +3366,21 @@ function UsagePage({ context }) {
3230
3366
  /* @__PURE__ */ jsx27(
3231
3367
  UsageSelect,
3232
3368
  {
3233
- label: "Metric",
3369
+ label: "Workload",
3370
+ onValueChange: (value) => setWorkload(value),
3371
+ options: USAGE_WORKLOADS,
3372
+ value: workload,
3373
+ formatOption: getUsageKindLabel
3374
+ }
3375
+ ),
3376
+ /* @__PURE__ */ jsx27(
3377
+ UsageSelect,
3378
+ {
3379
+ label: "Measure",
3234
3380
  onValueChange: (value) => setMetricKind(value),
3235
- options: ["cost", "tokens", "calls"],
3236
- value: metricKind
3381
+ options: metricOptions,
3382
+ value: metricKind,
3383
+ formatOption: getUsageMetricLabel
3237
3384
  }
3238
3385
  ),
3239
3386
  /* @__PURE__ */ jsx27(
@@ -3241,20 +3388,22 @@ function UsagePage({ context }) {
3241
3388
  {
3242
3389
  label: "Group",
3243
3390
  onValueChange: (value) => setGroupBy(value),
3244
- options: ["participant", "thread", "namespace", "provider", "model"],
3245
- value: groupBy
3391
+ options: groupOptions,
3392
+ value: groupBy,
3393
+ formatOption: getUsageGroupLabel
3246
3394
  }
3247
3395
  ),
3248
3396
  /* @__PURE__ */ jsx27(
3249
3397
  UsageSelect,
3250
3398
  {
3251
- label: "Attribution",
3399
+ label: "Actor",
3252
3400
  onValueChange: (value) => setAttribution(value),
3253
3401
  options: ["initiatedBy", "generatedBy"],
3254
- value: attribution
3402
+ value: attribution,
3403
+ formatOption: getUsageAttributionLabel
3255
3404
  }
3256
3405
  ),
3257
- /* @__PURE__ */ jsx27(
3406
+ showDimension && /* @__PURE__ */ jsx27(
3258
3407
  UsageSelect,
3259
3408
  {
3260
3409
  label: "Dimension",
@@ -3289,12 +3438,21 @@ function UsagePage({ context }) {
3289
3438
  /* @__PURE__ */ jsx27(
3290
3439
  UsageSelect,
3291
3440
  {
3292
- label: "Type",
3441
+ label: "Actor type",
3293
3442
  onValueChange: (value) => setParticipantType(value),
3294
3443
  options: ["all", "human", "agent", "job"],
3295
3444
  value: participantType
3296
3445
  }
3297
3446
  ),
3447
+ /* @__PURE__ */ jsx27(
3448
+ UsageSelect,
3449
+ {
3450
+ label: "Status",
3451
+ onValueChange: (value) => setStatus(value),
3452
+ options: STATUS_OPTIONS,
3453
+ value: status
3454
+ }
3455
+ ),
3298
3456
  /* @__PURE__ */ jsx27(
3299
3457
  Input,
3300
3458
  {
@@ -3313,46 +3471,86 @@ function UsagePage({ context }) {
3313
3471
  value: participantId
3314
3472
  }
3315
3473
  ),
3316
- /* @__PURE__ */ jsx27(
3317
- Input,
3318
- {
3319
- className: "h-8 w-[140px]",
3320
- onChange: (event) => setProvider(event.target.value),
3321
- placeholder: "Provider",
3322
- value: provider
3323
- }
3324
- ),
3325
- /* @__PURE__ */ jsx27(
3326
- Input,
3327
- {
3328
- className: "h-8 w-[140px]",
3329
- onChange: (event) => setModel(event.target.value),
3330
- placeholder: "Model",
3331
- value: model
3332
- }
3333
- )
3474
+ showResourceFields && /* @__PURE__ */ jsxs19(Fragment2, { children: [
3475
+ /* @__PURE__ */ jsx27(
3476
+ Input,
3477
+ {
3478
+ className: "h-8 w-[170px]",
3479
+ onChange: (event) => setResource(event.target.value),
3480
+ placeholder: "Resource / tool",
3481
+ value: resource
3482
+ }
3483
+ ),
3484
+ /* @__PURE__ */ jsx27(
3485
+ Input,
3486
+ {
3487
+ className: "h-8 w-[150px]",
3488
+ onChange: (event) => setOperation(event.target.value),
3489
+ placeholder: "Operation",
3490
+ value: operation
3491
+ }
3492
+ )
3493
+ ] }),
3494
+ showLlmFields && /* @__PURE__ */ jsxs19(Fragment2, { children: [
3495
+ /* @__PURE__ */ jsx27(
3496
+ Input,
3497
+ {
3498
+ className: "h-8 w-[140px]",
3499
+ onChange: (event) => setProvider(event.target.value),
3500
+ placeholder: "Provider",
3501
+ value: provider
3502
+ }
3503
+ ),
3504
+ /* @__PURE__ */ jsx27(
3505
+ Input,
3506
+ {
3507
+ className: "h-8 w-[140px]",
3508
+ onChange: (event) => setModel(event.target.value),
3509
+ placeholder: "Model",
3510
+ value: model
3511
+ }
3512
+ )
3513
+ ] })
3334
3514
  ] }),
3335
3515
  /* @__PURE__ */ jsx27(
3336
3516
  MetricStrip,
3337
3517
  {
3338
3518
  items: [
3339
3519
  {
3340
- detail: `${totals.totalCalls} calls`,
3520
+ detail: `${formatMetricValue(totals.unpricedCalls, "unpriced")} unpriced`,
3341
3521
  icon: DollarSign,
3342
- label: "Cost",
3522
+ label: "Spend",
3343
3523
  value: formatMetricValue(totals.totalCostUsd, "cost")
3344
3524
  },
3345
3525
  {
3346
- detail: `${formatMetricValue(totals.inputTokens, "tokens")} input`,
3526
+ detail: `${formatMetricValue(totals.failedCalls, "failures")} failed`,
3347
3527
  icon: Activity3,
3528
+ label: "Calls",
3529
+ value: formatMetricValue(totals.totalCalls, "calls")
3530
+ },
3531
+ {
3532
+ detail: "Tool and resource runtime",
3533
+ icon: Clock,
3534
+ label: "Duration",
3535
+ value: formatMetricValue(totals.totalDurationMs, "duration")
3536
+ },
3537
+ {
3538
+ detail: `${formatMetricValue(totals.inputTokens, "tokens")} input`,
3539
+ icon: Sparkles2,
3348
3540
  label: "Tokens",
3349
3541
  value: formatMetricValue(totals.totalTokens, "tokens")
3350
3542
  },
3351
3543
  {
3352
- detail: `${formatMetricValue(totals.reasoningTokens, "tokens")} reasoning`,
3353
- icon: Sparkles2,
3354
- label: "Calls",
3355
- value: formatMetricValue(totals.totalCalls, "calls")
3544
+ detail: "Custom metering",
3545
+ icon: Coins,
3546
+ label: "Credits",
3547
+ value: formatMetricValue(totals.totalCredits, "credits")
3548
+ },
3549
+ {
3550
+ detail: "Failed or aborted work",
3551
+ icon: AlertTriangle2,
3552
+ label: "Failures",
3553
+ value: formatMetricValue(totals.failedCalls, "failures")
3356
3554
  }
3357
3555
  ]
3358
3556
  }
@@ -3361,7 +3559,7 @@ function UsagePage({ context }) {
3361
3559
  EmptyState,
3362
3560
  {
3363
3561
  title: "No usage",
3364
- description: "Usage records will appear here when provider-native usage is captured."
3562
+ description: "Metered LLM, tool, and resource records will appear here after work is captured in the usage ledger."
3365
3563
  }
3366
3564
  ) : /* @__PURE__ */ jsxs19(Fragment2, { children: [
3367
3565
  /* @__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 +3638,7 @@ function UsageRowsTable({
3440
3638
  totals
3441
3639
  }) {
3442
3640
  const totalValue = getUsageTotalValue(totals, metricKind, dimension);
3641
+ const valueHeader = (metricKind === "tokens" || metricKind === "cost") && dimension !== "total" ? `${getUsageDimensionLabel(dimension)} ${getUsageMetricLabel(metricKind)}` : getUsageMetricLabel(metricKind);
3443
3642
  return /* @__PURE__ */ jsx27(
3444
3643
  ResourceTable,
3445
3644
  {
@@ -3457,7 +3656,7 @@ function UsageRowsTable({
3457
3656
  {
3458
3657
  align: "right",
3459
3658
  id: "value",
3460
- header: `${getUsageDimensionLabel(dimension)} ${metricKind}`,
3659
+ header: valueHeader,
3461
3660
  render: (row) => formatMetricValue(row.value, metricKind)
3462
3661
  },
3463
3662
  {
@@ -3474,20 +3673,100 @@ function UsageRowsTable({
3474
3673
  },
3475
3674
  {
3476
3675
  align: "right",
3477
- id: "input",
3478
- header: "Input",
3479
- render: (row) => formatMetricValue(getUsageTotalValue(row, metricKind, "input"), metricKind)
3676
+ id: "spend",
3677
+ header: "Spend",
3678
+ render: (row) => formatMetricValue(row.totalCostUsd, "cost")
3480
3679
  },
3481
3680
  {
3482
3681
  align: "right",
3483
- id: "output",
3484
- header: "Output",
3485
- render: (row) => formatMetricValue(getUsageTotalValue(row, metricKind, "output"), metricKind)
3682
+ id: "duration",
3683
+ header: "Duration",
3684
+ render: (row) => formatMetricValue(row.totalDurationMs, "duration")
3685
+ },
3686
+ {
3687
+ align: "right",
3688
+ id: "tokens",
3689
+ header: "Tokens",
3690
+ render: (row) => formatMetricValue(row.totalTokens, "tokens")
3691
+ },
3692
+ {
3693
+ align: "right",
3694
+ id: "failures",
3695
+ header: "Failures",
3696
+ render: (row) => formatMetricValue(row.failedCalls, "failures")
3697
+ },
3698
+ {
3699
+ align: "right",
3700
+ id: "unpriced",
3701
+ header: "Unpriced",
3702
+ render: (row) => formatMetricValue(row.unpricedCalls, "unpriced")
3486
3703
  }
3487
3704
  ]
3488
3705
  }
3489
3706
  );
3490
3707
  }
3708
+ function getUsageMetricOptions(workload) {
3709
+ if (workload === "llm") {
3710
+ return ["cost", "tokens", "calls", "failures", "unpriced"];
3711
+ }
3712
+ if (workload === "tool") {
3713
+ return ["calls", "duration", "cost", "credits", "failures", "unpriced"];
3714
+ }
3715
+ return [
3716
+ "calls",
3717
+ "cost",
3718
+ "duration",
3719
+ "tokens",
3720
+ "credits",
3721
+ "failures",
3722
+ "unpriced"
3723
+ ];
3724
+ }
3725
+ function getUsageGroupOptions(workload) {
3726
+ if (workload === "llm") {
3727
+ return ["participant", "model", "provider", "thread", "namespace", "status"];
3728
+ }
3729
+ if (workload === "tool") {
3730
+ return [
3731
+ "resource",
3732
+ "operation",
3733
+ "status",
3734
+ "participant",
3735
+ "thread",
3736
+ "namespace"
3737
+ ];
3738
+ }
3739
+ return [
3740
+ "kind",
3741
+ "resource",
3742
+ "operation",
3743
+ "status",
3744
+ "participant",
3745
+ "thread",
3746
+ "namespace"
3747
+ ];
3748
+ }
3749
+ function getUsageKindLabel(kind) {
3750
+ switch (kind) {
3751
+ case "all":
3752
+ return "All";
3753
+ case "llm":
3754
+ return "LLM";
3755
+ case "tool":
3756
+ return "Tools";
3757
+ case "asset":
3758
+ return "Assets";
3759
+ case "rag":
3760
+ return "RAG";
3761
+ case "embedding":
3762
+ return "Embeddings";
3763
+ default:
3764
+ return kind;
3765
+ }
3766
+ }
3767
+ function getUsageAttributionLabel(attribution) {
3768
+ return attribution === "initiatedBy" ? "Initiator" : "Performer";
3769
+ }
3491
3770
  function emptyToUndefined(value) {
3492
3771
  const trimmed = value.trim();
3493
3772
  return trimmed.length > 0 ? trimmed : void 0;
@@ -3975,6 +4254,7 @@ export {
3975
4254
  formatUsageBucket,
3976
4255
  getUsageDimensionLabel,
3977
4256
  getUsageGroupLabel,
4257
+ getUsageMetricLabel,
3978
4258
  getUsageRange,
3979
4259
  getUsageTotalValue,
3980
4260
  mergeAdminConfig,