@ipv9/tokentracker-cli 0.39.50 → 0.39.52
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/README.md +7 -14
- package/dashboard/dist/assets/{Card-G3yjiaQ3.js → Card-CEz9362Q.js} +1 -1
- package/dashboard/dist/assets/DashboardPage-BEzDx9x_.js +60 -0
- package/dashboard/dist/assets/{IpCheckPage-DsTJ2UMw.js → IpCheckPage-COYl0L0c.js} +1 -1
- package/dashboard/dist/assets/LimitsPage-CxKP9yCf.js +2 -0
- package/dashboard/dist/assets/LocalOnlyNotice-mkvVeaxU.js +1 -0
- package/dashboard/dist/assets/PopoverPopup-CcXnjekJ.js +1 -0
- package/dashboard/dist/assets/Select-DfLcXuzD.js +1 -0
- package/dashboard/dist/assets/SettingsPage-BKATdxHm.js +1 -0
- package/dashboard/dist/assets/SkillsPage-BCS1cw7N.js +1 -0
- package/dashboard/dist/assets/{WrappedPage-D1BDK0Ph.js → WrappedPage-BZMXgdYx.js} +1 -1
- package/dashboard/dist/assets/{format-C3ekCmoV.js → format-DXnZAXRS.js} +1 -1
- package/dashboard/dist/assets/limitDisplay-Dkfaklpc.js +1 -0
- package/dashboard/dist/assets/main-C7rJ1TVR.css +1 -0
- package/dashboard/dist/assets/main-Dft1sGV7.js +610 -0
- package/dashboard/dist/assets/{mock-data-C1NPjE59.js → mock-data-u9UDfqcX.js} +1 -1
- package/dashboard/dist/assets/use-limits-display-prefs-Nj1Nil2m.js +1 -0
- package/dashboard/dist/assets/useCurrency-BxAIQJRl.js +12 -0
- package/dashboard/dist/index.html +2 -18
- package/package.json +4 -6
- package/src/cli.js +1 -1
- package/src/commands/sync.js +4 -0
- package/src/lib/local-api.js +35 -10
- package/src/lib/pricing/seed-snapshot.json +1 -1
- package/src/lib/rollout.js +429 -27
- package/dashboard/dist/assets/DashboardPage-p9US1mNh.js +0 -60
- package/dashboard/dist/assets/FadeIn-Bcqp5CE1.js +0 -1
- package/dashboard/dist/assets/LimitsPage-Dh7MA0MN.js +0 -2
- package/dashboard/dist/assets/LocalOnlyNotice-TF43yZEk.js +0 -1
- package/dashboard/dist/assets/PopoverPopup-BTJTO2ZT.js +0 -1
- package/dashboard/dist/assets/Select-_DHMSUO0.js +0 -1
- package/dashboard/dist/assets/SelectItemText-CFGxP_cw.js +0 -12
- package/dashboard/dist/assets/SettingsPage-CbHgbVTV.js +0 -1
- package/dashboard/dist/assets/SkillsPage-Pbf_dSEd.js +0 -1
- package/dashboard/dist/assets/WidgetsPage-DdncxT2a.js +0 -1
- package/dashboard/dist/assets/arrow-up-right-BAE7-yZI.js +0 -1
- package/dashboard/dist/assets/download-CwfCmvh_.js +0 -1
- package/dashboard/dist/assets/limitDisplay-DhC8fM_W.js +0 -1
- package/dashboard/dist/assets/main-rZD26_5f.js +0 -700
- package/dashboard/dist/assets/main-t7dbBL4x.css +0 -1
- package/dashboard/dist/assets/use-limits-display-prefs-vLrVb6Bn.js +0 -1
- package/dashboard/dist/assets/use-native-settings-B8qCQ9aO.js +0 -1
- package/dashboard/dist/assets/useCurrency-MOYNpGd7.js +0 -1
package/src/lib/local-api.js
CHANGED
|
@@ -201,6 +201,20 @@ function normalizeQueueRow(row) {
|
|
|
201
201
|
return normalized;
|
|
202
202
|
}
|
|
203
203
|
|
|
204
|
+
function hasHermesAuthoritativeCost(row) {
|
|
205
|
+
const cost = Number(row?.actual_cost_usd);
|
|
206
|
+
return (
|
|
207
|
+
String(row?.source || "").toLowerCase() === "hermes" &&
|
|
208
|
+
row?.cost_provenance === "hermes-actual" &&
|
|
209
|
+
Number.isFinite(cost) &&
|
|
210
|
+
cost >= 0
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function resolveQueueRowCost(row) {
|
|
215
|
+
return hasHermesAuthoritativeCost(row) ? Number(row.actual_cost_usd) : computeRowCost(row);
|
|
216
|
+
}
|
|
217
|
+
|
|
204
218
|
function readQueueData(queuePath) {
|
|
205
219
|
let raw;
|
|
206
220
|
try {
|
|
@@ -278,7 +292,7 @@ function aggregateByDay(rows, timeZoneContext = null) {
|
|
|
278
292
|
const a = byDay.get(day);
|
|
279
293
|
a.total_tokens += row.total_tokens || 0;
|
|
280
294
|
a.billable_total_tokens += row.billable_total_tokens ?? row.total_tokens ?? 0;
|
|
281
|
-
a.total_cost_usd +=
|
|
295
|
+
a.total_cost_usd += resolveQueueRowCost(row);
|
|
282
296
|
a.input_tokens += row.input_tokens || 0;
|
|
283
297
|
a.output_tokens += row.output_tokens || 0;
|
|
284
298
|
a.cached_input_tokens += row.cached_input_tokens || 0;
|
|
@@ -502,7 +516,7 @@ function aggregateHourlyByDay(rows, dayKey, timeZoneContext) {
|
|
|
502
516
|
const bucket = byHour.get(hourKey);
|
|
503
517
|
bucket.total_tokens += row.total_tokens || 0;
|
|
504
518
|
bucket.billable_total_tokens += row.total_tokens || 0;
|
|
505
|
-
bucket.total_cost_usd +=
|
|
519
|
+
bucket.total_cost_usd += resolveQueueRowCost(row);
|
|
506
520
|
bucket.input_tokens += row.input_tokens || 0;
|
|
507
521
|
bucket.output_tokens += row.output_tokens || 0;
|
|
508
522
|
bucket.cached_input_tokens += row.cached_input_tokens || 0;
|
|
@@ -1418,8 +1432,10 @@ function createLocalApiHandler({ queuePath }) {
|
|
|
1418
1432
|
for (const row of rows) {
|
|
1419
1433
|
const src = row.source || "unknown";
|
|
1420
1434
|
const mdl = row.model || "unknown";
|
|
1435
|
+
const rowCost = resolveQueueRowCost(row);
|
|
1436
|
+
const rowUsesAuthoritativeCost = hasHermesAuthoritativeCost(row);
|
|
1421
1437
|
if (!bySource.has(src))
|
|
1422
|
-
bySource.set(src, { source: src, source_scope: getSourceScope(src), totals: { total_tokens: 0, billable_total_tokens: 0, input_tokens: 0, output_tokens: 0, cached_input_tokens: 0, cache_creation_input_tokens: 0, reasoning_output_tokens: 0, total_cost_usd:
|
|
1438
|
+
bySource.set(src, { source: src, source_scope: getSourceScope(src), totals: { total_tokens: 0, billable_total_tokens: 0, input_tokens: 0, output_tokens: 0, cached_input_tokens: 0, cache_creation_input_tokens: 0, reasoning_output_tokens: 0, total_cost_usd: 0 }, models: new Map() });
|
|
1423
1439
|
const sa = bySource.get(src);
|
|
1424
1440
|
sa.totals.total_tokens += row.total_tokens || 0;
|
|
1425
1441
|
sa.totals.billable_total_tokens += row.billable_total_tokens ?? row.total_tokens ?? 0;
|
|
@@ -1428,8 +1444,9 @@ function createLocalApiHandler({ queuePath }) {
|
|
|
1428
1444
|
sa.totals.cached_input_tokens += row.cached_input_tokens || 0;
|
|
1429
1445
|
sa.totals.cache_creation_input_tokens += row.cache_creation_input_tokens || 0;
|
|
1430
1446
|
sa.totals.reasoning_output_tokens += row.reasoning_output_tokens || 0;
|
|
1447
|
+
sa.totals.total_cost_usd += rowCost;
|
|
1431
1448
|
if (!sa.models.has(mdl))
|
|
1432
|
-
sa.models.set(mdl, { model: mdl, model_id: mdl, totals: { total_tokens: 0, billable_total_tokens: 0, input_tokens: 0, output_tokens: 0, cached_input_tokens: 0, cache_creation_input_tokens: 0, reasoning_output_tokens: 0, total_cost_usd:
|
|
1449
|
+
sa.models.set(mdl, { model: mdl, model_id: mdl, authoritative_cost_rows: 0, estimated_cost_rows: 0, totals: { total_tokens: 0, billable_total_tokens: 0, input_tokens: 0, output_tokens: 0, cached_input_tokens: 0, cache_creation_input_tokens: 0, reasoning_output_tokens: 0, total_cost_usd: 0 } });
|
|
1433
1450
|
const ma = sa.models.get(mdl);
|
|
1434
1451
|
ma.totals.total_tokens += row.total_tokens || 0;
|
|
1435
1452
|
ma.totals.billable_total_tokens += row.billable_total_tokens ?? row.total_tokens ?? 0;
|
|
@@ -1438,22 +1455,30 @@ function createLocalApiHandler({ queuePath }) {
|
|
|
1438
1455
|
ma.totals.cached_input_tokens += row.cached_input_tokens || 0;
|
|
1439
1456
|
ma.totals.cache_creation_input_tokens += row.cache_creation_input_tokens || 0;
|
|
1440
1457
|
ma.totals.reasoning_output_tokens += row.reasoning_output_tokens || 0;
|
|
1458
|
+
ma.totals.total_cost_usd += rowCost;
|
|
1459
|
+
if (rowUsesAuthoritativeCost) ma.authoritative_cost_rows += 1;
|
|
1460
|
+
else ma.estimated_cost_rows += 1;
|
|
1441
1461
|
}
|
|
1442
1462
|
|
|
1443
1463
|
const sources = Array.from(bySource.values()).map((s) => {
|
|
1444
1464
|
s.models = Array.from(s.models.values())
|
|
1445
1465
|
.map((m) => {
|
|
1446
|
-
const cost =
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1466
|
+
const cost = Number(m.totals.total_cost_usd || 0);
|
|
1467
|
+
const costProvenance =
|
|
1468
|
+
m.authoritative_cost_rows > 0 && m.estimated_cost_rows === 0
|
|
1469
|
+
? "hermes-actual"
|
|
1470
|
+
: m.authoritative_cost_rows > 0
|
|
1471
|
+
? "mixed"
|
|
1472
|
+
: "estimated";
|
|
1451
1473
|
// How the price was resolved, so the dashboard can say "unpriced"
|
|
1452
1474
|
// or "matched by substring" instead of inferring it from a $0 cost
|
|
1453
1475
|
// — a genuinely free model and an unknown one both cost $0.
|
|
1454
|
-
const
|
|
1476
|
+
const tier = costProvenance === "hermes-actual"
|
|
1477
|
+
? "hermes:actual"
|
|
1478
|
+
: getModelPricingMeta(m.model, { source: s.source }).tier;
|
|
1455
1479
|
return {
|
|
1456
1480
|
...m,
|
|
1481
|
+
cost_provenance: costProvenance,
|
|
1457
1482
|
pricing_tier: tier,
|
|
1458
1483
|
totals: { ...m.totals, total_cost_usd: cost.toFixed(6) },
|
|
1459
1484
|
};
|