usage-board 3.2.0 → 4.0.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.mjs +1 -1
- package/dist/public/_nuxt/37OOe3RF.js +1 -0
- package/dist/public/_nuxt/65Ayv2XK.js +146 -0
- package/dist/public/_nuxt/BOWwkrCY.js +25 -0
- package/dist/public/_nuxt/C0GhHHgI.js +3 -0
- package/dist/public/_nuxt/{uHQwCIHg.js → D7qEPtpx.js} +1 -1
- package/dist/public/_nuxt/D9-Yw1TR.js +1 -0
- package/dist/public/_nuxt/DF2WsXH3.js +1 -0
- package/dist/public/_nuxt/DKaPq50Z.js +6 -0
- package/dist/public/_nuxt/{COIbUy5w.js → DXWxIyGU.js} +1 -1
- package/dist/public/_nuxt/De8DvPWL.js +1 -0
- package/dist/public/_nuxt/DgMMKsPE.js +258 -0
- package/dist/public/_nuxt/DxvuOJRP.js +1 -0
- package/dist/public/_nuxt/Jp5cgQZi.js +4 -0
- package/dist/public/_nuxt/builds/latest.json +1 -1
- package/dist/public/_nuxt/builds/meta/7ce9c611-6071-4cbd-8926-1e53d9ef21bd.json +1 -0
- package/dist/public/_nuxt/entry.DnkKc-6G.css +1 -0
- package/dist/public/_nuxt/qXgLTL_3.js +21 -0
- package/dist/public/_nuxt/y6mAKUDU.js +1 -0
- package/dist/server/chunks/build/client.precomputed.mjs +1 -1
- package/dist/server/chunks/nitro/nitro.mjs +2119 -1107
- package/dist/server/chunks/routes/api/analysis/agent/session.json.mjs +1 -1
- package/dist/server/chunks/routes/api/analysis/agent/token.json.mjs +1 -1
- package/dist/server/chunks/routes/api/analysis/cache.json.mjs +1 -1
- package/dist/server/chunks/routes/api/analysis/hot-project.json.mjs +1 -1
- package/dist/server/chunks/routes/api/analysis/model.json.mjs +1 -1
- package/dist/server/chunks/routes/api/analysis/overview-cards.json.mjs +4 -4
- package/dist/server/chunks/routes/api/analysis/session.json.mjs +1 -1
- package/dist/server/chunks/routes/api/analysis/token/daily.json.mjs +1 -1
- package/dist/server/chunks/routes/api/analysis/token/today-hourly.json.mjs +21 -0
- package/dist/server/chunks/routes/api/analysis/token.json.mjs +1 -1
- package/dist/server/chunks/routes/api/payload.json.mjs +2 -2
- package/dist/server/chunks/routes/api/projects/_project/modules.get.mjs +2 -2
- package/dist/server/chunks/routes/api/projects/catalog.get.mjs +2 -2
- package/dist/server/chunks/routes/renderer.mjs +2 -2
- package/dist/server/chunks/routes/ws.mjs +2 -2
- package/dist/server/index.mjs +2 -2
- package/dist/server/package.json +1 -1
- package/package.json +2 -2
- package/dist/public/_nuxt/B6C9KBQ4.js +0 -105
- package/dist/public/_nuxt/Bv6agYS5.js +0 -119
- package/dist/public/_nuxt/BvRyOET7.js +0 -1
- package/dist/public/_nuxt/CMWftE4h.js +0 -1
- package/dist/public/_nuxt/CXLmM1yO.js +0 -25
- package/dist/public/_nuxt/DFqWEFN4.js +0 -1
- package/dist/public/_nuxt/DUoLvn3A.js +0 -6
- package/dist/public/_nuxt/D_W11Quh.js +0 -21
- package/dist/public/_nuxt/DgKrPjze.js +0 -4
- package/dist/public/_nuxt/DkxY2YMp.js +0 -1
- package/dist/public/_nuxt/DtbPvE6R.js +0 -260
- package/dist/public/_nuxt/HiqUua3-.js +0 -1
- package/dist/public/_nuxt/builds/meta/ae3c6372-8821-43fb-aa55-bb47729a5660.json +0 -1
- package/dist/public/_nuxt/entry.vHfFzkyD.css +0 -1
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import process from 'node:process';globalThis._importMeta_=globalThis._importMeta_||{url:"file:///_entry.js",env:process.env};import
|
|
2
|
-
import http from 'node:http';
|
|
1
|
+
import process from 'node:process';globalThis._importMeta_=globalThis._importMeta_||{url:"file:///_entry.js",env:process.env};import http from 'node:http';
|
|
3
2
|
import https from 'node:https';
|
|
4
3
|
import { EventEmitter } from 'node:events';
|
|
5
4
|
import { Buffer as Buffer$1 } from 'node:buffer';
|
|
6
|
-
import { promises, existsSync, mkdirSync, readFileSync, statSync, accessSync, constants } from 'node:fs';
|
|
5
|
+
import { promises, existsSync, mkdirSync, readFileSync, statSync, readdirSync, accessSync, constants } from 'node:fs';
|
|
7
6
|
import { resolve as resolve$1, dirname as dirname$1, join, sep, basename as basename$1 } from 'node:path';
|
|
8
7
|
import { createHash } from 'node:crypto';
|
|
9
8
|
import { DatabaseSync } from 'node:sqlite';
|
|
9
|
+
import { formatNumber } from '@lonewolfyx/utils';
|
|
10
10
|
import { glob } from 'glob';
|
|
11
11
|
import chokidar from 'chokidar';
|
|
12
12
|
import { homedir } from 'node:os';
|
|
@@ -4163,9 +4163,13 @@ const inlineAppConfig = {
|
|
|
4163
4163
|
"wi",
|
|
4164
4164
|
"wpf",
|
|
4165
4165
|
"zmdi",
|
|
4166
|
-
"zondicons"
|
|
4166
|
+
"zondicons",
|
|
4167
|
+
"ai"
|
|
4167
4168
|
],
|
|
4168
|
-
"fetchTimeout": 1500
|
|
4169
|
+
"fetchTimeout": 1500,
|
|
4170
|
+
"customCollections": [
|
|
4171
|
+
"ai"
|
|
4172
|
+
]
|
|
4169
4173
|
}
|
|
4170
4174
|
};
|
|
4171
4175
|
|
|
@@ -4267,7 +4271,7 @@ function _expandFromEnv(value) {
|
|
|
4267
4271
|
const _inlineRuntimeConfig = {
|
|
4268
4272
|
"app": {
|
|
4269
4273
|
"baseURL": "/",
|
|
4270
|
-
"buildId": "
|
|
4274
|
+
"buildId": "7ce9c611-6071-4cbd-8926-1e53d9ef21bd",
|
|
4271
4275
|
"buildAssetsDir": "/_nuxt/",
|
|
4272
4276
|
"cdnURL": ""
|
|
4273
4277
|
},
|
|
@@ -4295,7 +4299,7 @@ const _inlineRuntimeConfig = {
|
|
|
4295
4299
|
}
|
|
4296
4300
|
},
|
|
4297
4301
|
"public": {
|
|
4298
|
-
"appVersion": "
|
|
4302
|
+
"appVersion": "4.0.0",
|
|
4299
4303
|
"home": "/Users/tangchenghui"
|
|
4300
4304
|
},
|
|
4301
4305
|
"icon": {
|
|
@@ -4710,7 +4714,17 @@ function defineNitroPlugin(def) {
|
|
|
4710
4714
|
}
|
|
4711
4715
|
|
|
4712
4716
|
function openSqliteDatabase(location, options) {
|
|
4713
|
-
|
|
4717
|
+
const database = new DatabaseSync(location, options != null ? options : {});
|
|
4718
|
+
try {
|
|
4719
|
+
database.exec("PRAGMA journal_mode = WAL");
|
|
4720
|
+
database.exec("PRAGMA synchronous = NORMAL");
|
|
4721
|
+
} catch {
|
|
4722
|
+
}
|
|
4723
|
+
try {
|
|
4724
|
+
database.exec("PRAGMA busy_timeout = 15000");
|
|
4725
|
+
} catch {
|
|
4726
|
+
}
|
|
4727
|
+
return database;
|
|
4714
4728
|
}
|
|
4715
4729
|
|
|
4716
4730
|
const PROJECT_USAGE_PLATFORMS = [
|
|
@@ -4780,10 +4794,296 @@ function normalizeProjectUsageDetail(detail) {
|
|
|
4780
4794
|
};
|
|
4781
4795
|
}
|
|
4782
4796
|
|
|
4797
|
+
const compactNumberFormatter = new Intl.NumberFormat("en-US", {
|
|
4798
|
+
notation: "compact",
|
|
4799
|
+
maximumFractionDigits: 1
|
|
4800
|
+
});
|
|
4801
|
+
const currencyFormatter = new Intl.NumberFormat("en-US", {
|
|
4802
|
+
style: "currency",
|
|
4803
|
+
currency: "USD",
|
|
4804
|
+
minimumFractionDigits: 2,
|
|
4805
|
+
maximumFractionDigits: 2
|
|
4806
|
+
});
|
|
4807
|
+
const percentFormatter = new Intl.NumberFormat("en-US", {
|
|
4808
|
+
style: "percent",
|
|
4809
|
+
minimumFractionDigits: 1,
|
|
4810
|
+
maximumFractionDigits: 1
|
|
4811
|
+
});
|
|
4812
|
+
const dateKeyFormatter = new Intl.DateTimeFormat("en-CA", {
|
|
4813
|
+
day: "2-digit",
|
|
4814
|
+
month: "2-digit",
|
|
4815
|
+
year: "numeric"
|
|
4816
|
+
});
|
|
4817
|
+
const dateLabelFormatter = new Intl.DateTimeFormat("en-US", {
|
|
4818
|
+
day: "2-digit",
|
|
4819
|
+
month: "short",
|
|
4820
|
+
timeZone: "UTC",
|
|
4821
|
+
year: "numeric"
|
|
4822
|
+
});
|
|
4823
|
+
function normalizeNumber(value) {
|
|
4824
|
+
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
4825
|
+
}
|
|
4826
|
+
function roundCurrency(value) {
|
|
4827
|
+
return Math.round(value * 1e6) / 1e6;
|
|
4828
|
+
}
|
|
4829
|
+
function uniqueItems(items) {
|
|
4830
|
+
return Array.from(new Set(items));
|
|
4831
|
+
}
|
|
4832
|
+
function formatCompactNumber(value) {
|
|
4833
|
+
return compactNumberFormatter.format(normalizeNumber(value));
|
|
4834
|
+
}
|
|
4835
|
+
function formatCurrency(value) {
|
|
4836
|
+
return currencyFormatter.format(normalizeNumber(value));
|
|
4837
|
+
}
|
|
4838
|
+
function formatPercent(value) {
|
|
4839
|
+
return percentFormatter.format(normalizeNumber(value));
|
|
4840
|
+
}
|
|
4841
|
+
function buildPercentTrend(currentValue, previousValue) {
|
|
4842
|
+
const current = normalizeNumber(currentValue);
|
|
4843
|
+
const previous = normalizeNumber(previousValue);
|
|
4844
|
+
if (previous === 0) {
|
|
4845
|
+
return {
|
|
4846
|
+
label: current > 0 ? "+100%" : "0%",
|
|
4847
|
+
tone: current > 0 ? "up" : "neutral"
|
|
4848
|
+
};
|
|
4849
|
+
}
|
|
4850
|
+
const ratio = (current - previous) / previous;
|
|
4851
|
+
return {
|
|
4852
|
+
label: formatSignedPercent(ratio),
|
|
4853
|
+
tone: getTrendTone(ratio)
|
|
4854
|
+
};
|
|
4855
|
+
}
|
|
4856
|
+
function buildGrowthTrend(currentValue, previousValue, formatValue) {
|
|
4857
|
+
const current = Math.max(normalizeNumber(currentValue), 0);
|
|
4858
|
+
const previous = Math.max(normalizeNumber(previousValue), 0);
|
|
4859
|
+
if (previous === 0) {
|
|
4860
|
+
if (current === 0) {
|
|
4861
|
+
return {
|
|
4862
|
+
trend: "0.0%",
|
|
4863
|
+
trendTone: "neutral"
|
|
4864
|
+
};
|
|
4865
|
+
}
|
|
4866
|
+
return {
|
|
4867
|
+
trend: `+${formatValue(current)}`,
|
|
4868
|
+
trendTone: "up"
|
|
4869
|
+
};
|
|
4870
|
+
}
|
|
4871
|
+
const ratio = (current - previous) / previous;
|
|
4872
|
+
return {
|
|
4873
|
+
trend: formatSignedPercent(ratio),
|
|
4874
|
+
trendTone: getTrendTone(ratio)
|
|
4875
|
+
};
|
|
4876
|
+
}
|
|
4877
|
+
function buildInputOutputTokenSubvalue(usage) {
|
|
4878
|
+
var _a, _b;
|
|
4879
|
+
return {
|
|
4880
|
+
items: [
|
|
4881
|
+
{
|
|
4882
|
+
label: "In",
|
|
4883
|
+
value: formatCompactNumber((_a = usage == null ? void 0 : usage.inputTokens) != null ? _a : 0)
|
|
4884
|
+
},
|
|
4885
|
+
{
|
|
4886
|
+
label: "Out",
|
|
4887
|
+
value: formatCompactNumber((_b = usage == null ? void 0 : usage.outputTokens) != null ? _b : 0)
|
|
4888
|
+
}
|
|
4889
|
+
]
|
|
4890
|
+
};
|
|
4891
|
+
}
|
|
4892
|
+
function buildOverviewCardsWithTodayTokenBreakdown(overviewCards, dailyTokenUsage) {
|
|
4893
|
+
const todayDateKey = getDateKey(/* @__PURE__ */ new Date());
|
|
4894
|
+
return overviewCards.map((card) => card.name === "Today Tokens" ? {
|
|
4895
|
+
...card,
|
|
4896
|
+
subvalue: buildInputOutputTokenSubvalue(
|
|
4897
|
+
dailyTokenUsage.find((item) => getDateKeyFromLabel(item.date) === todayDateKey)
|
|
4898
|
+
)
|
|
4899
|
+
} : card);
|
|
4900
|
+
}
|
|
4901
|
+
function getDateKey(date) {
|
|
4902
|
+
var _a, _b, _c, _d, _e, _f;
|
|
4903
|
+
const parts = dateKeyFormatter.formatToParts(date);
|
|
4904
|
+
const year = (_b = (_a = parts.find((part) => part.type === "year")) == null ? void 0 : _a.value) != null ? _b : "0000";
|
|
4905
|
+
const month = (_d = (_c = parts.find((part) => part.type === "month")) == null ? void 0 : _c.value) != null ? _d : "01";
|
|
4906
|
+
const day = (_f = (_e = parts.find((part) => part.type === "day")) == null ? void 0 : _e.value) != null ? _f : "01";
|
|
4907
|
+
return `${year}-${month}-${day}`;
|
|
4908
|
+
}
|
|
4909
|
+
function getDateKeyFromLabel(label) {
|
|
4910
|
+
const date = new Date(label);
|
|
4911
|
+
if (Number.isNaN(date.getTime())) {
|
|
4912
|
+
return label;
|
|
4913
|
+
}
|
|
4914
|
+
return getDateKey(date);
|
|
4915
|
+
}
|
|
4916
|
+
function getPreviousDateKey(dateKey) {
|
|
4917
|
+
const [year, month, day] = dateKey.split("-").map((value) => Number.parseInt(value, 10));
|
|
4918
|
+
const date = new Date(year || 0, (month || 1) - 1, day || 1);
|
|
4919
|
+
date.setDate(date.getDate() - 1);
|
|
4920
|
+
return getDateKey(date);
|
|
4921
|
+
}
|
|
4922
|
+
function formatDateLabelFromDateKey(dateKey, fallback = dateKey) {
|
|
4923
|
+
const [year, month, day] = dateKey.split("-").map((value) => Number.parseInt(value, 10));
|
|
4924
|
+
if (!year || !month || !day) {
|
|
4925
|
+
return fallback;
|
|
4926
|
+
}
|
|
4927
|
+
return dateLabelFormatter.format(new Date(Date.UTC(year, month - 1, day)));
|
|
4928
|
+
}
|
|
4929
|
+
function buildProjectUsage(sessionUsage) {
|
|
4930
|
+
var _a;
|
|
4931
|
+
const projects = /* @__PURE__ */ new Map();
|
|
4932
|
+
for (const session of sessionUsage) {
|
|
4933
|
+
const project = (_a = projects.get(session.project)) != null ? _a : {
|
|
4934
|
+
costUSD: 0,
|
|
4935
|
+
repository: session.repository,
|
|
4936
|
+
sessions: 0,
|
|
4937
|
+
tokenTotal: 0
|
|
4938
|
+
};
|
|
4939
|
+
project.costUSD += session.costUSD;
|
|
4940
|
+
project.sessions += 1;
|
|
4941
|
+
project.tokenTotal += session.tokenTotal;
|
|
4942
|
+
projects.set(session.project, project);
|
|
4943
|
+
}
|
|
4944
|
+
const maxCost = Math.max(...Array.from(projects.values()).map((project) => project.costUSD), 0);
|
|
4945
|
+
return Array.from(projects.entries()).map(([label, project]) => ({
|
|
4946
|
+
costUSD: project.costUSD,
|
|
4947
|
+
detail: `${project.sessions} sessions / ${formatCompactNumber(project.tokenTotal)} tokens`,
|
|
4948
|
+
label,
|
|
4949
|
+
percent: maxCost > 0 ? project.costUSD / maxCost * 100 : 0,
|
|
4950
|
+
repository: project.repository,
|
|
4951
|
+
sessions: project.sessions,
|
|
4952
|
+
tokenTotal: project.tokenTotal,
|
|
4953
|
+
tone: "amber",
|
|
4954
|
+
value: formatCurrency(project.costUSD)
|
|
4955
|
+
})).sort((a, b) => b.costUSD - a.costUSD);
|
|
4956
|
+
}
|
|
4957
|
+
function mergeDailyTokenUsage(items) {
|
|
4958
|
+
var _a, _b, _c, _d, _e;
|
|
4959
|
+
const groups = /* @__PURE__ */ new Map();
|
|
4960
|
+
for (const item of items) {
|
|
4961
|
+
const dateKey = getDateKeyFromLabel(item.date);
|
|
4962
|
+
const group = (_a = groups.get(dateKey)) != null ? _a : {
|
|
4963
|
+
cachedInputTokens: 0,
|
|
4964
|
+
costUSD: 0,
|
|
4965
|
+
date: formatDateLabelFromDateKey(dateKey, item.date),
|
|
4966
|
+
inputTokens: 0,
|
|
4967
|
+
models: /* @__PURE__ */ new Map(),
|
|
4968
|
+
outputTokens: 0,
|
|
4969
|
+
platforms: /* @__PURE__ */ new Map(),
|
|
4970
|
+
reasoningOutputTokens: 0,
|
|
4971
|
+
totalTokens: 0
|
|
4972
|
+
};
|
|
4973
|
+
group.cachedInputTokens += item.cachedInputTokens;
|
|
4974
|
+
group.costUSD += item.costUSD;
|
|
4975
|
+
group.inputTokens += item.inputTokens;
|
|
4976
|
+
group.outputTokens += item.outputTokens;
|
|
4977
|
+
group.reasoningOutputTokens += item.reasoningOutputTokens;
|
|
4978
|
+
group.totalTokens += item.totalTokens;
|
|
4979
|
+
for (const [modelName, usage] of Object.entries(item.models)) {
|
|
4980
|
+
const model = (_b = group.models.get(modelName)) != null ? _b : createEmptyModelUsage();
|
|
4981
|
+
model.cachedInputTokens += usage.cachedInputTokens;
|
|
4982
|
+
model.costUSD += usage.costUSD;
|
|
4983
|
+
model.inputTokens += usage.inputTokens;
|
|
4984
|
+
model.isFallback = model.isFallback || usage.isFallback;
|
|
4985
|
+
model.outputTokens += usage.outputTokens;
|
|
4986
|
+
model.reasoningOutputTokens += usage.reasoningOutputTokens;
|
|
4987
|
+
model.totalTokens += usage.totalTokens;
|
|
4988
|
+
group.models.set(modelName, model);
|
|
4989
|
+
}
|
|
4990
|
+
for (const [platform, platformUsage] of Object.entries((_c = item.platforms) != null ? _c : {})) {
|
|
4991
|
+
const currentPlatformUsage = (_d = group.platforms.get(platform)) != null ? _d : createEmptyDailyPlatformTokenUsage();
|
|
4992
|
+
currentPlatformUsage.cachedInputTokens += platformUsage.cachedInputTokens;
|
|
4993
|
+
currentPlatformUsage.costUSD += platformUsage.costUSD;
|
|
4994
|
+
currentPlatformUsage.inputTokens += platformUsage.inputTokens;
|
|
4995
|
+
currentPlatformUsage.outputTokens += platformUsage.outputTokens;
|
|
4996
|
+
currentPlatformUsage.reasoningOutputTokens += platformUsage.reasoningOutputTokens;
|
|
4997
|
+
currentPlatformUsage.totalTokens += platformUsage.totalTokens;
|
|
4998
|
+
for (const [modelName, usage] of Object.entries(platformUsage.models)) {
|
|
4999
|
+
const model = (_e = currentPlatformUsage.models[modelName]) != null ? _e : createEmptyModelUsage();
|
|
5000
|
+
model.cachedInputTokens += usage.cachedInputTokens;
|
|
5001
|
+
model.costUSD += usage.costUSD;
|
|
5002
|
+
model.inputTokens += usage.inputTokens;
|
|
5003
|
+
model.isFallback = model.isFallback || usage.isFallback;
|
|
5004
|
+
model.outputTokens += usage.outputTokens;
|
|
5005
|
+
model.reasoningOutputTokens += usage.reasoningOutputTokens;
|
|
5006
|
+
model.totalTokens += usage.totalTokens;
|
|
5007
|
+
currentPlatformUsage.models[modelName] = model;
|
|
5008
|
+
}
|
|
5009
|
+
group.platforms.set(platform, currentPlatformUsage);
|
|
5010
|
+
}
|
|
5011
|
+
groups.set(dateKey, group);
|
|
5012
|
+
}
|
|
5013
|
+
return Array.from(groups.entries()).sort((a, b) => b[0].localeCompare(a[0])).map(([, group]) => ({
|
|
5014
|
+
cachedInputTokens: group.cachedInputTokens,
|
|
5015
|
+
costUSD: roundCurrency(group.costUSD),
|
|
5016
|
+
date: group.date,
|
|
5017
|
+
inputTokens: group.inputTokens,
|
|
5018
|
+
models: Object.fromEntries(group.models.entries()),
|
|
5019
|
+
outputTokens: group.outputTokens,
|
|
5020
|
+
platforms: group.platforms.size > 0 ? Object.fromEntries(Array.from(group.platforms.entries()).map(([platform, usage]) => [platform, {
|
|
5021
|
+
...usage,
|
|
5022
|
+
costUSD: roundCurrency(usage.costUSD),
|
|
5023
|
+
models: Object.fromEntries(Object.entries(usage.models).map(([modelName, modelUsage]) => [modelName, {
|
|
5024
|
+
...modelUsage,
|
|
5025
|
+
costUSD: roundCurrency(modelUsage.costUSD)
|
|
5026
|
+
}]))
|
|
5027
|
+
}])) : void 0,
|
|
5028
|
+
reasoningOutputTokens: group.reasoningOutputTokens,
|
|
5029
|
+
totalTokens: group.totalTokens
|
|
5030
|
+
}));
|
|
5031
|
+
}
|
|
5032
|
+
function mergeMonthlyModelUsage(items) {
|
|
5033
|
+
var _a;
|
|
5034
|
+
const groups = /* @__PURE__ */ new Map();
|
|
5035
|
+
for (const item of items) {
|
|
5036
|
+
const key = `${item.month}__${item.model}`;
|
|
5037
|
+
const group = (_a = groups.get(key)) != null ? _a : {
|
|
5038
|
+
model: item.model,
|
|
5039
|
+
month: item.month,
|
|
5040
|
+
tokenTotal: 0
|
|
5041
|
+
};
|
|
5042
|
+
group.tokenTotal += item.tokenTotal;
|
|
5043
|
+
groups.set(key, group);
|
|
5044
|
+
}
|
|
5045
|
+
return Array.from(groups.values()).sort((a, b) => a.month.localeCompare(b.month) || a.model.localeCompare(b.model));
|
|
5046
|
+
}
|
|
5047
|
+
function formatSignedPercent(value) {
|
|
5048
|
+
const prefix = value > 0 ? "+" : "";
|
|
5049
|
+
return `${prefix}${formatPercent(value)}`;
|
|
5050
|
+
}
|
|
5051
|
+
function getTrendTone(value) {
|
|
5052
|
+
if (value > 0) {
|
|
5053
|
+
return "up";
|
|
5054
|
+
}
|
|
5055
|
+
if (value < 0) {
|
|
5056
|
+
return "down";
|
|
5057
|
+
}
|
|
5058
|
+
return "neutral";
|
|
5059
|
+
}
|
|
5060
|
+
function createEmptyModelUsage() {
|
|
5061
|
+
return {
|
|
5062
|
+
cachedInputTokens: 0,
|
|
5063
|
+
costUSD: 0,
|
|
5064
|
+
inputTokens: 0,
|
|
5065
|
+
isFallback: false,
|
|
5066
|
+
outputTokens: 0,
|
|
5067
|
+
reasoningOutputTokens: 0,
|
|
5068
|
+
totalTokens: 0
|
|
5069
|
+
};
|
|
5070
|
+
}
|
|
5071
|
+
function createEmptyDailyPlatformTokenUsage() {
|
|
5072
|
+
return {
|
|
5073
|
+
cachedInputTokens: 0,
|
|
5074
|
+
costUSD: 0,
|
|
5075
|
+
inputTokens: 0,
|
|
5076
|
+
models: {},
|
|
5077
|
+
outputTokens: 0,
|
|
5078
|
+
reasoningOutputTokens: 0,
|
|
5079
|
+
totalTokens: 0
|
|
5080
|
+
};
|
|
5081
|
+
}
|
|
5082
|
+
|
|
4783
5083
|
var __defProp$1 = Object.defineProperty;
|
|
4784
5084
|
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
4785
5085
|
var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, key + "" , value);
|
|
4786
|
-
const CACHE_SCHEMA_VERSION =
|
|
5086
|
+
const CACHE_SCHEMA_VERSION = 9;
|
|
4787
5087
|
const ROW_KEY_SEPARATOR = "";
|
|
4788
5088
|
const CACHE_SCHEMA_SQL = `
|
|
4789
5089
|
CREATE TABLE IF NOT EXISTS cache_schema_meta (
|
|
@@ -4800,7 +5100,8 @@ const CACHE_SCHEMA_SQL = `
|
|
|
4800
5100
|
|
|
4801
5101
|
CREATE TABLE IF NOT EXISTS project_catalog_entries (
|
|
4802
5102
|
label TEXT PRIMARY KEY,
|
|
4803
|
-
|
|
5103
|
+
platforms_json TEXT NOT NULL,
|
|
5104
|
+
total_tokens INTEGER NOT NULL,
|
|
4804
5105
|
updated_at TEXT NOT NULL
|
|
4805
5106
|
);
|
|
4806
5107
|
|
|
@@ -4845,6 +5146,7 @@ const CACHE_SCHEMA_SQL = `
|
|
|
4845
5146
|
name TEXT NOT NULL,
|
|
4846
5147
|
value TEXT NOT NULL,
|
|
4847
5148
|
detail TEXT,
|
|
5149
|
+
subvalue_json TEXT,
|
|
4848
5150
|
trend TEXT NOT NULL,
|
|
4849
5151
|
trend_tone TEXT NOT NULL,
|
|
4850
5152
|
PRIMARY KEY (scope_key, position),
|
|
@@ -4923,6 +5225,7 @@ const CACHE_SCHEMA_SQL = `
|
|
|
4923
5225
|
output_tokens INTEGER NOT NULL,
|
|
4924
5226
|
reasoning_output_tokens INTEGER NOT NULL,
|
|
4925
5227
|
total_tokens INTEGER NOT NULL,
|
|
5228
|
+
cost_usd REAL NOT NULL,
|
|
4926
5229
|
is_fallback INTEGER NOT NULL,
|
|
4927
5230
|
PRIMARY KEY (scope_key, date, model),
|
|
4928
5231
|
FOREIGN KEY (scope_key, date)
|
|
@@ -4991,6 +5294,8 @@ const CACHE_SCHEMA_SQL = `
|
|
|
4991
5294
|
|
|
4992
5295
|
CREATE INDEX IF NOT EXISTS idx_usage_scope_sessions_order
|
|
4993
5296
|
ON usage_scope_sessions(scope_key, session_order);
|
|
5297
|
+
CREATE INDEX IF NOT EXISTS idx_usage_scope_sessions_started_at
|
|
5298
|
+
ON usage_scope_sessions(scope_key, started_at);
|
|
4994
5299
|
|
|
4995
5300
|
CREATE TABLE IF NOT EXISTS usage_scope_session_models (
|
|
4996
5301
|
scope_key TEXT NOT NULL,
|
|
@@ -5018,6 +5323,7 @@ const CACHE_SCHEMA_SQL = `
|
|
|
5018
5323
|
cached_input_tokens INTEGER,
|
|
5019
5324
|
output_tokens INTEGER,
|
|
5020
5325
|
reasoning_output_tokens INTEGER,
|
|
5326
|
+
extra_total_tokens INTEGER,
|
|
5021
5327
|
total_tokens INTEGER,
|
|
5022
5328
|
usage_cost_usd REAL,
|
|
5023
5329
|
cache_creation_tokens INTEGER,
|
|
@@ -5029,10 +5335,15 @@ const CACHE_SCHEMA_SQL = `
|
|
|
5029
5335
|
REFERENCES usage_scope_sessions(scope_key, session_key)
|
|
5030
5336
|
ON DELETE CASCADE
|
|
5031
5337
|
);
|
|
5338
|
+
CREATE INDEX IF NOT EXISTS idx_usage_scope_interactions_role_timestamp
|
|
5339
|
+
ON usage_scope_interactions(scope_key, role, timestamp);
|
|
5340
|
+
CREATE INDEX IF NOT EXISTS idx_usage_scope_interactions_timestamp
|
|
5341
|
+
ON usage_scope_interactions(scope_key, timestamp);
|
|
5032
5342
|
|
|
5033
5343
|
CREATE TABLE IF NOT EXISTS indexed_files (
|
|
5034
5344
|
path TEXT PRIMARY KEY,
|
|
5035
5345
|
platform TEXT NOT NULL,
|
|
5346
|
+
cache_signature TEXT NOT NULL DEFAULT '',
|
|
5036
5347
|
size INTEGER NOT NULL,
|
|
5037
5348
|
mtime_ms INTEGER NOT NULL,
|
|
5038
5349
|
updated_at TEXT NOT NULL
|
|
@@ -5079,6 +5390,7 @@ const CACHE_SCHEMA_SQL = `
|
|
|
5079
5390
|
cached_input_tokens INTEGER,
|
|
5080
5391
|
output_tokens INTEGER,
|
|
5081
5392
|
reasoning_output_tokens INTEGER,
|
|
5393
|
+
extra_total_tokens INTEGER,
|
|
5082
5394
|
total_tokens INTEGER,
|
|
5083
5395
|
usage_cost_usd REAL,
|
|
5084
5396
|
cache_creation_tokens INTEGER,
|
|
@@ -5103,7 +5415,7 @@ class UsageCacheRepository {
|
|
|
5103
5415
|
if (!meta) {
|
|
5104
5416
|
return null;
|
|
5105
5417
|
}
|
|
5106
|
-
const scopes = this.loadHydratedUsageScopes("bootstrap");
|
|
5418
|
+
const scopes = this.loadHydratedUsageScopes("bootstrap", false);
|
|
5107
5419
|
const payload = Object.fromEntries(
|
|
5108
5420
|
PROJECT_USAGE_PLATFORMS.map((platform) => {
|
|
5109
5421
|
var _a2;
|
|
@@ -5125,20 +5437,76 @@ class UsageCacheRepository {
|
|
|
5125
5437
|
saveBootstrap(payload) {
|
|
5126
5438
|
this.persistBootstrap(payload);
|
|
5127
5439
|
}
|
|
5440
|
+
loadHomeDashboardTodayInsights() {
|
|
5441
|
+
const { previousDayStartAt, todayStartAt, tomorrowStartAt } = getHomeInsightRange();
|
|
5442
|
+
const promptCount = groupTodayInsightCounts(this.database.prepare(`
|
|
5443
|
+
SELECT
|
|
5444
|
+
CASE
|
|
5445
|
+
WHEN interaction.timestamp >= ? AND interaction.timestamp < ? THEN 'today'
|
|
5446
|
+
ELSE 'previous'
|
|
5447
|
+
END AS period,
|
|
5448
|
+
COUNT(*) AS total
|
|
5449
|
+
FROM usage_scope_interactions AS interaction
|
|
5450
|
+
JOIN usage_scopes AS scope ON scope.scope_key = interaction.scope_key
|
|
5451
|
+
WHERE scope.scope_kind = 'bootstrap'
|
|
5452
|
+
AND interaction.role = 'user'
|
|
5453
|
+
AND interaction.timestamp IS NOT NULL
|
|
5454
|
+
AND interaction.timestamp >= ?
|
|
5455
|
+
AND interaction.timestamp < ?
|
|
5456
|
+
GROUP BY period
|
|
5457
|
+
`).all(todayStartAt, tomorrowStartAt, previousDayStartAt, tomorrowStartAt));
|
|
5458
|
+
const sessionCount = groupTodayInsightCounts(this.database.prepare(`
|
|
5459
|
+
SELECT
|
|
5460
|
+
CASE
|
|
5461
|
+
WHEN session.started_at >= ? AND session.started_at < ? THEN 'today'
|
|
5462
|
+
ELSE 'previous'
|
|
5463
|
+
END AS period,
|
|
5464
|
+
COUNT(*) AS total
|
|
5465
|
+
FROM usage_scope_sessions AS session
|
|
5466
|
+
JOIN usage_scopes AS scope ON scope.scope_key = session.scope_key
|
|
5467
|
+
WHERE scope.scope_kind = 'bootstrap'
|
|
5468
|
+
AND session.started_at >= ?
|
|
5469
|
+
AND session.started_at < ?
|
|
5470
|
+
GROUP BY period
|
|
5471
|
+
`).all(todayStartAt, tomorrowStartAt, previousDayStartAt, tomorrowStartAt));
|
|
5472
|
+
return {
|
|
5473
|
+
previousPromptCount: promptCount.previous,
|
|
5474
|
+
previousSessionCount: sessionCount.previous,
|
|
5475
|
+
promptCount: promptCount.today,
|
|
5476
|
+
sessionCount: sessionCount.today,
|
|
5477
|
+
todayHourlyUsage: buildTodayHourlyUsage(this.database.prepare(`
|
|
5478
|
+
SELECT
|
|
5479
|
+
scope.platform AS platform,
|
|
5480
|
+
CAST(strftime('%H', interaction.timestamp, 'localtime') AS INTEGER) AS hour,
|
|
5481
|
+
ROUND(SUM(COALESCE(interaction.usage_cost_usd, 0)), 6) AS cost_usd,
|
|
5482
|
+
SUM(COALESCE(interaction.total_tokens, 0)) AS total_tokens
|
|
5483
|
+
FROM usage_scope_interactions AS interaction
|
|
5484
|
+
JOIN usage_scopes AS scope ON scope.scope_key = interaction.scope_key
|
|
5485
|
+
WHERE scope.scope_kind = 'bootstrap'
|
|
5486
|
+
AND interaction.timestamp IS NOT NULL
|
|
5487
|
+
AND interaction.total_tokens IS NOT NULL
|
|
5488
|
+
AND interaction.timestamp >= ?
|
|
5489
|
+
AND interaction.timestamp < ?
|
|
5490
|
+
GROUP BY scope.platform, hour
|
|
5491
|
+
ORDER BY hour ASC, scope.platform ASC
|
|
5492
|
+
`).all(todayStartAt, tomorrowStartAt))
|
|
5493
|
+
};
|
|
5494
|
+
}
|
|
5128
5495
|
loadProjectCatalog() {
|
|
5129
5496
|
const meta = this.getCacheState("project_catalog");
|
|
5130
5497
|
if (!meta) {
|
|
5131
5498
|
return null;
|
|
5132
5499
|
}
|
|
5133
5500
|
const rows = this.database.prepare(`
|
|
5134
|
-
SELECT label,
|
|
5501
|
+
SELECT label, platforms_json, total_tokens
|
|
5135
5502
|
FROM project_catalog_entries
|
|
5136
5503
|
ORDER BY label ASC
|
|
5137
5504
|
`).all();
|
|
5138
5505
|
return {
|
|
5139
5506
|
payload: rows.map((row) => ({
|
|
5140
5507
|
label: row.label,
|
|
5141
|
-
|
|
5508
|
+
platforms: parseProjectCatalogPlatforms(row.platforms_json),
|
|
5509
|
+
totalTokens: row.total_tokens
|
|
5142
5510
|
})),
|
|
5143
5511
|
payloadHash: meta.payload_hash,
|
|
5144
5512
|
updatedAt: meta.updated_at
|
|
@@ -5191,7 +5559,7 @@ class UsageCacheRepository {
|
|
|
5191
5559
|
loadIndexedSourceFiles() {
|
|
5192
5560
|
var _a, _b, _c;
|
|
5193
5561
|
const files = this.database.prepare(`
|
|
5194
|
-
SELECT path, platform, size, mtime_ms, updated_at
|
|
5562
|
+
SELECT path, platform, cache_signature, size, mtime_ms, updated_at
|
|
5195
5563
|
FROM indexed_files
|
|
5196
5564
|
ORDER BY path ASC
|
|
5197
5565
|
`).all();
|
|
@@ -5234,6 +5602,7 @@ class UsageCacheRepository {
|
|
|
5234
5602
|
cached_input_tokens,
|
|
5235
5603
|
output_tokens,
|
|
5236
5604
|
reasoning_output_tokens,
|
|
5605
|
+
extra_total_tokens,
|
|
5237
5606
|
total_tokens,
|
|
5238
5607
|
usage_cost_usd,
|
|
5239
5608
|
cache_creation_tokens,
|
|
@@ -5262,6 +5631,7 @@ class UsageCacheRepository {
|
|
|
5262
5631
|
return files.map((file) => {
|
|
5263
5632
|
var _a2, _b2;
|
|
5264
5633
|
return {
|
|
5634
|
+
cacheSignature: file.cache_signature,
|
|
5265
5635
|
mtimeMs: file.mtime_ms,
|
|
5266
5636
|
path: file.path,
|
|
5267
5637
|
payload: (_a2 = fragmentsByPath.get(file.path)) != null ? _a2 : [],
|
|
@@ -5273,14 +5643,14 @@ class UsageCacheRepository {
|
|
|
5273
5643
|
});
|
|
5274
5644
|
}
|
|
5275
5645
|
upsertIndexedSourceFiles(files) {
|
|
5276
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t;
|
|
5646
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v;
|
|
5277
5647
|
if (files.length === 0) {
|
|
5278
5648
|
return;
|
|
5279
5649
|
}
|
|
5280
5650
|
const deleteFileStatement = this.database.prepare("DELETE FROM indexed_files WHERE path = ?");
|
|
5281
5651
|
const insertFileStatement = this.database.prepare(`
|
|
5282
|
-
INSERT INTO indexed_files (path, platform, size, mtime_ms, updated_at)
|
|
5283
|
-
VALUES (?, ?, ?, ?, ?)
|
|
5652
|
+
INSERT INTO indexed_files (path, platform, cache_signature, size, mtime_ms, updated_at)
|
|
5653
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
5284
5654
|
`);
|
|
5285
5655
|
const insertProjectStatement = this.database.prepare(`
|
|
5286
5656
|
INSERT INTO indexed_file_projects (path, project_name, project_order)
|
|
@@ -5316,6 +5686,7 @@ class UsageCacheRepository {
|
|
|
5316
5686
|
cached_input_tokens,
|
|
5317
5687
|
output_tokens,
|
|
5318
5688
|
reasoning_output_tokens,
|
|
5689
|
+
extra_total_tokens,
|
|
5319
5690
|
total_tokens,
|
|
5320
5691
|
usage_cost_usd,
|
|
5321
5692
|
cache_creation_tokens,
|
|
@@ -5323,13 +5694,13 @@ class UsageCacheRepository {
|
|
|
5323
5694
|
tool_tokens,
|
|
5324
5695
|
is_fallback_model
|
|
5325
5696
|
)
|
|
5326
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
5697
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
5327
5698
|
`);
|
|
5328
5699
|
this.database.exec("BEGIN");
|
|
5329
5700
|
try {
|
|
5330
5701
|
for (const file of files) {
|
|
5331
5702
|
deleteFileStatement.run(file.path);
|
|
5332
|
-
insertFileStatement.run(file.path, file.platform, file.size, file.mtimeMs, file.updatedAt);
|
|
5703
|
+
insertFileStatement.run(file.path, file.platform, file.cacheSignature, file.size, file.mtimeMs, file.updatedAt);
|
|
5333
5704
|
for (const [projectOrder, projectName] of file.projectNames.entries()) {
|
|
5334
5705
|
insertProjectStatement.run(file.path, projectName, projectOrder);
|
|
5335
5706
|
}
|
|
@@ -5362,12 +5733,13 @@ class UsageCacheRepository {
|
|
|
5362
5733
|
(_e = (_d = interaction.usage) == null ? void 0 : _d.cachedInputTokens) != null ? _e : null,
|
|
5363
5734
|
(_g = (_f = interaction.usage) == null ? void 0 : _f.outputTokens) != null ? _g : null,
|
|
5364
5735
|
(_i = (_h = interaction.usage) == null ? void 0 : _h.reasoningOutputTokens) != null ? _i : null,
|
|
5365
|
-
(_k = (_j = interaction.usage) == null ? void 0 : _j.
|
|
5366
|
-
(_m = (_l = interaction.usage) == null ? void 0 : _l.
|
|
5367
|
-
(_o = (_n = interaction.usage) == null ? void 0 : _n.
|
|
5368
|
-
(_q = (_p = interaction.usage) == null ? void 0 : _p.
|
|
5369
|
-
(_s = (_r = interaction.usage) == null ? void 0 : _r.
|
|
5370
|
-
((_t = interaction.usage) == null ? void 0 : _t.
|
|
5736
|
+
(_k = (_j = interaction.usage) == null ? void 0 : _j.extraTotalTokens) != null ? _k : null,
|
|
5737
|
+
(_m = (_l = interaction.usage) == null ? void 0 : _l.totalTokens) != null ? _m : null,
|
|
5738
|
+
(_o = (_n = interaction.usage) == null ? void 0 : _n.costUSD) != null ? _o : null,
|
|
5739
|
+
(_q = (_p = interaction.usage) == null ? void 0 : _p.cacheCreationTokens) != null ? _q : null,
|
|
5740
|
+
(_s = (_r = interaction.usage) == null ? void 0 : _r.cacheReadTokens) != null ? _s : null,
|
|
5741
|
+
(_u = (_t = interaction.usage) == null ? void 0 : _t.toolTokens) != null ? _u : null,
|
|
5742
|
+
((_v = interaction.usage) == null ? void 0 : _v.isFallbackModel) ? 1 : 0
|
|
5371
5743
|
);
|
|
5372
5744
|
}
|
|
5373
5745
|
}
|
|
@@ -5439,7 +5811,13 @@ class UsageCacheRepository {
|
|
|
5439
5811
|
}
|
|
5440
5812
|
initializeSchema() {
|
|
5441
5813
|
this.database.exec(CACHE_SCHEMA_SQL);
|
|
5442
|
-
|
|
5814
|
+
this.ensureIndexedFilesCacheSignatureColumn();
|
|
5815
|
+
this.ensureDailyUsageModelCostColumn();
|
|
5816
|
+
this.ensureOverviewCardSubvalueColumn();
|
|
5817
|
+
this.ensureProjectCatalogColumns();
|
|
5818
|
+
this.ensureInteractionExtraTotalTokenColumns();
|
|
5819
|
+
const currentSchemaVersion = this.getCurrentSchemaVersion();
|
|
5820
|
+
if (currentSchemaVersion >= CACHE_SCHEMA_VERSION) {
|
|
5443
5821
|
return;
|
|
5444
5822
|
}
|
|
5445
5823
|
this.migrateLegacyDataIfNeeded();
|
|
@@ -5462,13 +5840,13 @@ class UsageCacheRepository {
|
|
|
5462
5840
|
`).run(version);
|
|
5463
5841
|
}
|
|
5464
5842
|
migrateLegacyDataIfNeeded() {
|
|
5465
|
-
|
|
5466
|
-
const hasLegacyProjectSnapshots = this.hasTable("project_snapshots");
|
|
5467
|
-
const hasLegacyIndexedFiles = this.hasTable("indexed_source_files");
|
|
5468
|
-
if (!hasLegacySnapshots && !hasLegacyProjectSnapshots && !hasLegacyIndexedFiles) {
|
|
5843
|
+
if (!this.hasLegacyData()) {
|
|
5469
5844
|
return;
|
|
5470
5845
|
}
|
|
5471
5846
|
this.clearNormalizedTables();
|
|
5847
|
+
const hasLegacySnapshots = this.hasTable("cache_snapshots");
|
|
5848
|
+
const hasLegacyProjectSnapshots = this.hasTable("project_snapshots");
|
|
5849
|
+
const hasLegacyIndexedFiles = this.hasTable("indexed_source_files");
|
|
5472
5850
|
if (hasLegacySnapshots) {
|
|
5473
5851
|
const bootstrap = this.loadLegacyBootstrap();
|
|
5474
5852
|
const projectCatalog = this.loadLegacyProjectCatalog();
|
|
@@ -5494,6 +5872,81 @@ class UsageCacheRepository {
|
|
|
5494
5872
|
}
|
|
5495
5873
|
this.dropLegacyTables();
|
|
5496
5874
|
}
|
|
5875
|
+
hasLegacyData() {
|
|
5876
|
+
return this.hasTable("cache_snapshots") || this.hasTable("project_snapshots") || this.hasTable("indexed_source_files");
|
|
5877
|
+
}
|
|
5878
|
+
ensureIndexedFilesCacheSignatureColumn() {
|
|
5879
|
+
if (!this.hasTable("indexed_files")) {
|
|
5880
|
+
return;
|
|
5881
|
+
}
|
|
5882
|
+
const columns = this.database.prepare("PRAGMA table_info(indexed_files)").all();
|
|
5883
|
+
if (columns.some((column) => column.name === "cache_signature")) {
|
|
5884
|
+
return;
|
|
5885
|
+
}
|
|
5886
|
+
this.database.exec("ALTER TABLE indexed_files ADD COLUMN cache_signature TEXT NOT NULL DEFAULT ''");
|
|
5887
|
+
}
|
|
5888
|
+
ensureProjectCatalogColumns() {
|
|
5889
|
+
if (!this.hasTable("project_catalog_entries")) {
|
|
5890
|
+
return;
|
|
5891
|
+
}
|
|
5892
|
+
const columns = this.database.prepare("PRAGMA table_info(project_catalog_entries)").all();
|
|
5893
|
+
if (!columns.some((column) => column.name === "platforms_json")) {
|
|
5894
|
+
this.database.exec("ALTER TABLE project_catalog_entries ADD COLUMN platforms_json TEXT NOT NULL DEFAULT '[]'");
|
|
5895
|
+
}
|
|
5896
|
+
if (!columns.some((column) => column.name === "total_tokens")) {
|
|
5897
|
+
this.database.exec("ALTER TABLE project_catalog_entries ADD COLUMN total_tokens INTEGER NOT NULL DEFAULT 0");
|
|
5898
|
+
}
|
|
5899
|
+
if (!columns.some((column) => column.name === "type")) {
|
|
5900
|
+
return;
|
|
5901
|
+
}
|
|
5902
|
+
const legacyRows = this.database.prepare(`
|
|
5903
|
+
SELECT label, type
|
|
5904
|
+
FROM project_catalog_entries
|
|
5905
|
+
`).all();
|
|
5906
|
+
const updateStatement = this.database.prepare(`
|
|
5907
|
+
UPDATE project_catalog_entries
|
|
5908
|
+
SET platforms_json = ?, total_tokens = 0
|
|
5909
|
+
WHERE label = ?
|
|
5910
|
+
`);
|
|
5911
|
+
for (const row of legacyRows) {
|
|
5912
|
+
const platforms = row.type === "mixed" ? [] : [row.type];
|
|
5913
|
+
updateStatement.run(JSON.stringify(platforms), row.label);
|
|
5914
|
+
}
|
|
5915
|
+
}
|
|
5916
|
+
ensureDailyUsageModelCostColumn() {
|
|
5917
|
+
if (!this.hasTable("usage_scope_daily_usage_models")) {
|
|
5918
|
+
return;
|
|
5919
|
+
}
|
|
5920
|
+
const columns = this.database.prepare("PRAGMA table_info(usage_scope_daily_usage_models)").all();
|
|
5921
|
+
if (columns.some((column) => column.name === "cost_usd")) {
|
|
5922
|
+
return;
|
|
5923
|
+
}
|
|
5924
|
+
this.database.exec("ALTER TABLE usage_scope_daily_usage_models ADD COLUMN cost_usd REAL NOT NULL DEFAULT 0");
|
|
5925
|
+
}
|
|
5926
|
+
ensureOverviewCardSubvalueColumn() {
|
|
5927
|
+
if (!this.hasTable("usage_scope_overview_cards")) {
|
|
5928
|
+
return;
|
|
5929
|
+
}
|
|
5930
|
+
const columns = this.database.prepare("PRAGMA table_info(usage_scope_overview_cards)").all();
|
|
5931
|
+
if (columns.some((column) => column.name === "subvalue_json")) {
|
|
5932
|
+
return;
|
|
5933
|
+
}
|
|
5934
|
+
this.database.exec("ALTER TABLE usage_scope_overview_cards ADD COLUMN subvalue_json TEXT");
|
|
5935
|
+
}
|
|
5936
|
+
ensureInteractionExtraTotalTokenColumns() {
|
|
5937
|
+
if (this.hasTable("usage_scope_interactions")) {
|
|
5938
|
+
const usageScopeInteractionColumns = this.database.prepare("PRAGMA table_info(usage_scope_interactions)").all();
|
|
5939
|
+
if (!usageScopeInteractionColumns.some((column) => column.name === "extra_total_tokens")) {
|
|
5940
|
+
this.database.exec("ALTER TABLE usage_scope_interactions ADD COLUMN extra_total_tokens INTEGER");
|
|
5941
|
+
}
|
|
5942
|
+
}
|
|
5943
|
+
if (this.hasTable("indexed_fragment_interactions")) {
|
|
5944
|
+
const indexedInteractionColumns = this.database.prepare("PRAGMA table_info(indexed_fragment_interactions)").all();
|
|
5945
|
+
if (!indexedInteractionColumns.some((column) => column.name === "extra_total_tokens")) {
|
|
5946
|
+
this.database.exec("ALTER TABLE indexed_fragment_interactions ADD COLUMN extra_total_tokens INTEGER");
|
|
5947
|
+
}
|
|
5948
|
+
}
|
|
5949
|
+
}
|
|
5497
5950
|
clearNormalizedTables() {
|
|
5498
5951
|
this.database.exec("BEGIN");
|
|
5499
5952
|
try {
|
|
@@ -5559,14 +6012,14 @@ class UsageCacheRepository {
|
|
|
5559
6012
|
const payloadHash = (_b = options.payloadHash) != null ? _b : createPayloadHash(JSON.stringify(payload));
|
|
5560
6013
|
const deleteStatement = this.database.prepare("DELETE FROM project_catalog_entries");
|
|
5561
6014
|
const insertStatement = this.database.prepare(`
|
|
5562
|
-
INSERT INTO project_catalog_entries (label,
|
|
5563
|
-
VALUES (?, ?, ?)
|
|
6015
|
+
INSERT INTO project_catalog_entries (label, platforms_json, total_tokens, updated_at)
|
|
6016
|
+
VALUES (?, ?, ?, ?)
|
|
5564
6017
|
`);
|
|
5565
6018
|
this.database.exec("BEGIN");
|
|
5566
6019
|
try {
|
|
5567
6020
|
deleteStatement.run();
|
|
5568
6021
|
for (const item of payload) {
|
|
5569
|
-
insertStatement.run(item.label, item.
|
|
6022
|
+
insertStatement.run(item.label, JSON.stringify(item.platforms), item.totalTokens, updatedAt);
|
|
5570
6023
|
}
|
|
5571
6024
|
this.upsertCacheState("project_catalog", payloadHash, updatedAt);
|
|
5572
6025
|
this.database.exec("COMMIT");
|
|
@@ -5586,7 +6039,7 @@ class UsageCacheRepository {
|
|
|
5586
6039
|
`).run(key, payloadHash, updatedAt, version != null ? version : null);
|
|
5587
6040
|
}
|
|
5588
6041
|
insertUsageScope(options) {
|
|
5589
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D;
|
|
6042
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F;
|
|
5590
6043
|
const scopeKey = createUsageScopeKey(options.kind, options.platform, options.projectLabel);
|
|
5591
6044
|
const payloadHash = createPayloadHash(JSON.stringify(options.usage));
|
|
5592
6045
|
const insertScopeStatement = this.database.prepare(`
|
|
@@ -5614,10 +6067,11 @@ class UsageCacheRepository {
|
|
|
5614
6067
|
name,
|
|
5615
6068
|
value,
|
|
5616
6069
|
detail,
|
|
6070
|
+
subvalue_json,
|
|
5617
6071
|
trend,
|
|
5618
6072
|
trend_tone
|
|
5619
6073
|
)
|
|
5620
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
6074
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
5621
6075
|
`);
|
|
5622
6076
|
const insertTokenRowStatement = this.database.prepare(`
|
|
5623
6077
|
INSERT INTO usage_scope_token_rows (
|
|
@@ -5682,9 +6136,10 @@ class UsageCacheRepository {
|
|
|
5682
6136
|
output_tokens,
|
|
5683
6137
|
reasoning_output_tokens,
|
|
5684
6138
|
total_tokens,
|
|
6139
|
+
cost_usd,
|
|
5685
6140
|
is_fallback
|
|
5686
6141
|
)
|
|
5687
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
6142
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
5688
6143
|
`);
|
|
5689
6144
|
const insertMonthlyModelStatement = this.database.prepare(`
|
|
5690
6145
|
INSERT INTO usage_scope_monthly_model_usage (
|
|
@@ -5764,6 +6219,7 @@ class UsageCacheRepository {
|
|
|
5764
6219
|
cached_input_tokens,
|
|
5765
6220
|
output_tokens,
|
|
5766
6221
|
reasoning_output_tokens,
|
|
6222
|
+
extra_total_tokens,
|
|
5767
6223
|
total_tokens,
|
|
5768
6224
|
usage_cost_usd,
|
|
5769
6225
|
cache_creation_tokens,
|
|
@@ -5771,7 +6227,7 @@ class UsageCacheRepository {
|
|
|
5771
6227
|
tool_tokens,
|
|
5772
6228
|
is_fallback_model
|
|
5773
6229
|
)
|
|
5774
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
6230
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
5775
6231
|
`);
|
|
5776
6232
|
insertScopeStatement.run(
|
|
5777
6233
|
scopeKey,
|
|
@@ -5795,6 +6251,7 @@ class UsageCacheRepository {
|
|
|
5795
6251
|
card.name,
|
|
5796
6252
|
card.value,
|
|
5797
6253
|
(_j = card.detail) != null ? _j : null,
|
|
6254
|
+
card.subvalue ? JSON.stringify(card.subvalue) : null,
|
|
5798
6255
|
card.trend,
|
|
5799
6256
|
card.trendTone
|
|
5800
6257
|
);
|
|
@@ -5848,6 +6305,7 @@ class UsageCacheRepository {
|
|
|
5848
6305
|
usage.outputTokens,
|
|
5849
6306
|
usage.reasoningOutputTokens,
|
|
5850
6307
|
usage.totalTokens,
|
|
6308
|
+
usage.costUSD,
|
|
5851
6309
|
usage.isFallback ? 1 : 0
|
|
5852
6310
|
);
|
|
5853
6311
|
}
|
|
@@ -5920,17 +6378,18 @@ class UsageCacheRepository {
|
|
|
5920
6378
|
(_o = (_n = interaction.usage) == null ? void 0 : _n.cachedInputTokens) != null ? _o : null,
|
|
5921
6379
|
(_q = (_p = interaction.usage) == null ? void 0 : _p.outputTokens) != null ? _q : null,
|
|
5922
6380
|
(_s = (_r = interaction.usage) == null ? void 0 : _r.reasoningOutputTokens) != null ? _s : null,
|
|
5923
|
-
(_u = (_t = interaction.usage) == null ? void 0 : _t.
|
|
5924
|
-
(_w = (_v = interaction.usage) == null ? void 0 : _v.
|
|
5925
|
-
(_y = (_x = interaction.usage) == null ? void 0 : _x.
|
|
5926
|
-
(_A = (_z = interaction.usage) == null ? void 0 : _z.
|
|
5927
|
-
(_C = (_B = interaction.usage) == null ? void 0 : _B.
|
|
5928
|
-
((_D = interaction.usage) == null ? void 0 : _D.
|
|
6381
|
+
(_u = (_t = interaction.usage) == null ? void 0 : _t.extraTotalTokens) != null ? _u : null,
|
|
6382
|
+
(_w = (_v = interaction.usage) == null ? void 0 : _v.totalTokens) != null ? _w : null,
|
|
6383
|
+
(_y = (_x = interaction.usage) == null ? void 0 : _x.costUSD) != null ? _y : null,
|
|
6384
|
+
(_A = (_z = interaction.usage) == null ? void 0 : _z.cacheCreationTokens) != null ? _A : null,
|
|
6385
|
+
(_C = (_B = interaction.usage) == null ? void 0 : _B.cacheReadTokens) != null ? _C : null,
|
|
6386
|
+
(_E = (_D = interaction.usage) == null ? void 0 : _D.toolTokens) != null ? _E : null,
|
|
6387
|
+
((_F = interaction.usage) == null ? void 0 : _F.isFallbackModel) ? 1 : 0
|
|
5929
6388
|
);
|
|
5930
6389
|
}
|
|
5931
6390
|
}
|
|
5932
6391
|
}
|
|
5933
|
-
loadHydratedUsageScopes(kind) {
|
|
6392
|
+
loadHydratedUsageScopes(kind, includeInteractions = true) {
|
|
5934
6393
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
5935
6394
|
const scopes = this.database.prepare(`
|
|
5936
6395
|
SELECT
|
|
@@ -5955,7 +6414,7 @@ class UsageCacheRepository {
|
|
|
5955
6414
|
}
|
|
5956
6415
|
const scopeSet = new Set(scopes.map((scope) => scope.scope_key));
|
|
5957
6416
|
const overviewCards = groupOverviewCards(this.database.prepare(`
|
|
5958
|
-
SELECT card.scope_key, card.position, card.icon, card.name, card.value, card.detail, card.trend, card.trend_tone
|
|
6417
|
+
SELECT card.scope_key, card.position, card.icon, card.name, card.value, card.detail, card.subvalue_json, card.trend, card.trend_tone
|
|
5959
6418
|
FROM usage_scope_overview_cards AS card
|
|
5960
6419
|
JOIN usage_scopes AS scope ON scope.scope_key = card.scope_key
|
|
5961
6420
|
WHERE scope.scope_kind = ?
|
|
@@ -6025,6 +6484,7 @@ class UsageCacheRepository {
|
|
|
6025
6484
|
model.output_tokens,
|
|
6026
6485
|
model.reasoning_output_tokens,
|
|
6027
6486
|
model.total_tokens,
|
|
6487
|
+
model.cost_usd,
|
|
6028
6488
|
model.is_fallback
|
|
6029
6489
|
FROM usage_scope_daily_usage_models AS model
|
|
6030
6490
|
JOIN usage_scopes AS scope ON scope.scope_key = model.scope_key
|
|
@@ -6094,33 +6554,34 @@ class UsageCacheRepository {
|
|
|
6094
6554
|
WHERE scope.scope_kind = ?
|
|
6095
6555
|
ORDER BY model.scope_key ASC, model.session_key ASC, model.model_order ASC
|
|
6096
6556
|
`).all(kind),
|
|
6097
|
-
this.database.prepare(`
|
|
6098
|
-
|
|
6099
|
-
|
|
6100
|
-
|
|
6101
|
-
|
|
6102
|
-
|
|
6103
|
-
|
|
6104
|
-
|
|
6105
|
-
|
|
6106
|
-
|
|
6107
|
-
|
|
6108
|
-
|
|
6109
|
-
|
|
6110
|
-
|
|
6111
|
-
|
|
6112
|
-
|
|
6113
|
-
|
|
6114
|
-
|
|
6115
|
-
|
|
6116
|
-
|
|
6117
|
-
|
|
6118
|
-
|
|
6119
|
-
|
|
6120
|
-
|
|
6121
|
-
|
|
6122
|
-
|
|
6123
|
-
|
|
6557
|
+
includeInteractions ? this.database.prepare(`
|
|
6558
|
+
SELECT
|
|
6559
|
+
interaction.scope_key,
|
|
6560
|
+
interaction.session_key,
|
|
6561
|
+
interaction.interaction_order,
|
|
6562
|
+
interaction.interaction_index,
|
|
6563
|
+
interaction.content,
|
|
6564
|
+
interaction.cost_usd,
|
|
6565
|
+
interaction.model,
|
|
6566
|
+
interaction.role,
|
|
6567
|
+
interaction.timestamp,
|
|
6568
|
+
interaction.type,
|
|
6569
|
+
interaction.input_tokens,
|
|
6570
|
+
interaction.cached_input_tokens,
|
|
6571
|
+
interaction.output_tokens,
|
|
6572
|
+
interaction.reasoning_output_tokens,
|
|
6573
|
+
interaction.extra_total_tokens,
|
|
6574
|
+
interaction.total_tokens,
|
|
6575
|
+
interaction.usage_cost_usd,
|
|
6576
|
+
interaction.cache_creation_tokens,
|
|
6577
|
+
interaction.cache_read_tokens,
|
|
6578
|
+
interaction.tool_tokens,
|
|
6579
|
+
interaction.is_fallback_model
|
|
6580
|
+
FROM usage_scope_interactions AS interaction
|
|
6581
|
+
JOIN usage_scopes AS scope ON scope.scope_key = interaction.scope_key
|
|
6582
|
+
WHERE scope.scope_kind = ?
|
|
6583
|
+
ORDER BY interaction.scope_key ASC, interaction.session_key ASC, interaction.interaction_order ASC
|
|
6584
|
+
`).all(kind) : []
|
|
6124
6585
|
);
|
|
6125
6586
|
const hydrated = /* @__PURE__ */ new Map();
|
|
6126
6587
|
for (const scope of scopes) {
|
|
@@ -6178,7 +6639,7 @@ class UsageCacheRepository {
|
|
|
6178
6639
|
return null;
|
|
6179
6640
|
}
|
|
6180
6641
|
return {
|
|
6181
|
-
payload: JSON.parse(row.payload),
|
|
6642
|
+
payload: normalizeProjectCatalogItems(JSON.parse(row.payload)),
|
|
6182
6643
|
payloadHash: row.payload_hash,
|
|
6183
6644
|
updatedAt: row.updated_at
|
|
6184
6645
|
};
|
|
@@ -6202,6 +6663,7 @@ class UsageCacheRepository {
|
|
|
6202
6663
|
ORDER BY path ASC
|
|
6203
6664
|
`).all();
|
|
6204
6665
|
return rows.map((row) => ({
|
|
6666
|
+
cacheSignature: "",
|
|
6205
6667
|
mtimeMs: row.mtime_ms,
|
|
6206
6668
|
path: row.path,
|
|
6207
6669
|
payload: JSON.parse(row.payload),
|
|
@@ -6224,6 +6686,54 @@ function getTokenRowsByBucket(usage, bucket) {
|
|
|
6224
6686
|
return usage.weeklyRows;
|
|
6225
6687
|
}
|
|
6226
6688
|
}
|
|
6689
|
+
function buildTodayHourlyUsage(rows) {
|
|
6690
|
+
var _a;
|
|
6691
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
6692
|
+
for (const row of rows) {
|
|
6693
|
+
const item = (_a = grouped.get(row.hour)) != null ? _a : {
|
|
6694
|
+
agents: {},
|
|
6695
|
+
costUSD: 0,
|
|
6696
|
+
hour: row.hour,
|
|
6697
|
+
label: `${String(row.hour).padStart(2, "0")}:00`,
|
|
6698
|
+
totalTokens: 0
|
|
6699
|
+
};
|
|
6700
|
+
item.agents[row.platform] = {
|
|
6701
|
+
costUSD: row.cost_usd,
|
|
6702
|
+
totalTokens: row.total_tokens
|
|
6703
|
+
};
|
|
6704
|
+
item.costUSD = roundCurrency(item.costUSD + row.cost_usd);
|
|
6705
|
+
item.totalTokens += row.total_tokens;
|
|
6706
|
+
grouped.set(row.hour, item);
|
|
6707
|
+
}
|
|
6708
|
+
return Array.from({ length: 24 }, (_, hour) => {
|
|
6709
|
+
var _a2;
|
|
6710
|
+
return (_a2 = grouped.get(hour)) != null ? _a2 : {
|
|
6711
|
+
agents: {},
|
|
6712
|
+
costUSD: 0,
|
|
6713
|
+
hour,
|
|
6714
|
+
label: `${String(hour).padStart(2, "0")}:00`,
|
|
6715
|
+
totalTokens: 0
|
|
6716
|
+
};
|
|
6717
|
+
});
|
|
6718
|
+
}
|
|
6719
|
+
function groupTodayInsightCounts(rows) {
|
|
6720
|
+
return rows.reduce((result, row) => {
|
|
6721
|
+
result[row.period] = row.total;
|
|
6722
|
+
return result;
|
|
6723
|
+
}, {
|
|
6724
|
+
previous: 0,
|
|
6725
|
+
today: 0
|
|
6726
|
+
});
|
|
6727
|
+
}
|
|
6728
|
+
function getHomeInsightRange() {
|
|
6729
|
+
const today = /* @__PURE__ */ new Date();
|
|
6730
|
+
today.setHours(0, 0, 0, 0);
|
|
6731
|
+
return {
|
|
6732
|
+
previousDayStartAt: new Date(today.getTime() - 24 * 60 * 60 * 1e3).toISOString(),
|
|
6733
|
+
todayStartAt: today.toISOString(),
|
|
6734
|
+
tomorrowStartAt: new Date(today.getTime() + 24 * 60 * 60 * 1e3).toISOString()
|
|
6735
|
+
};
|
|
6736
|
+
}
|
|
6227
6737
|
function groupProjectModels(rows) {
|
|
6228
6738
|
var _a;
|
|
6229
6739
|
const grouped = /* @__PURE__ */ new Map();
|
|
@@ -6273,6 +6783,7 @@ function groupOverviewCards(rows) {
|
|
|
6273
6783
|
detail: (_b = row.detail) != null ? _b : void 0,
|
|
6274
6784
|
icon: row.icon,
|
|
6275
6785
|
name: row.name,
|
|
6786
|
+
subvalue: parseOverviewCardSubvalue(row.subvalue_json),
|
|
6276
6787
|
trend: row.trend,
|
|
6277
6788
|
trendTone: row.trend_tone,
|
|
6278
6789
|
value: row.value
|
|
@@ -6281,6 +6792,17 @@ function groupOverviewCards(rows) {
|
|
|
6281
6792
|
}
|
|
6282
6793
|
return grouped;
|
|
6283
6794
|
}
|
|
6795
|
+
function parseOverviewCardSubvalue(value) {
|
|
6796
|
+
if (!value) {
|
|
6797
|
+
return void 0;
|
|
6798
|
+
}
|
|
6799
|
+
try {
|
|
6800
|
+
const subvalue = JSON.parse(value);
|
|
6801
|
+
return Array.isArray(subvalue == null ? void 0 : subvalue.items) ? subvalue : void 0;
|
|
6802
|
+
} catch {
|
|
6803
|
+
return void 0;
|
|
6804
|
+
}
|
|
6805
|
+
}
|
|
6284
6806
|
function groupTokenRows(rows, modelRows, projectRows) {
|
|
6285
6807
|
var _a, _b, _c, _d, _e;
|
|
6286
6808
|
const modelsByRow = /* @__PURE__ */ new Map();
|
|
@@ -6332,6 +6854,7 @@ function groupDailyUsage(rows, modelRows) {
|
|
|
6332
6854
|
const models = (_a = modelsByRow.get(key)) != null ? _a : {};
|
|
6333
6855
|
models[row.model] = {
|
|
6334
6856
|
cachedInputTokens: row.cached_input_tokens,
|
|
6857
|
+
costUSD: row.cost_usd,
|
|
6335
6858
|
inputTokens: row.input_tokens,
|
|
6336
6859
|
isFallback: Boolean(row.is_fallback),
|
|
6337
6860
|
outputTokens: row.output_tokens,
|
|
@@ -6461,6 +6984,9 @@ function buildInteractionUsage(row) {
|
|
|
6461
6984
|
reasoningOutputTokens: row.reasoning_output_tokens,
|
|
6462
6985
|
totalTokens: row.total_tokens
|
|
6463
6986
|
};
|
|
6987
|
+
if (row.extra_total_tokens !== null) {
|
|
6988
|
+
usage.extraTotalTokens = row.extra_total_tokens;
|
|
6989
|
+
}
|
|
6464
6990
|
if (row.cache_creation_tokens !== null) {
|
|
6465
6991
|
usage.cacheCreationTokens = row.cache_creation_tokens;
|
|
6466
6992
|
}
|
|
@@ -6514,6 +7040,53 @@ function createCompositeKey(...parts) {
|
|
|
6514
7040
|
function createPayloadHash(value) {
|
|
6515
7041
|
return createHash("sha1").update(value).digest("hex");
|
|
6516
7042
|
}
|
|
7043
|
+
function normalizeProjectCatalogItems(value) {
|
|
7044
|
+
if (!Array.isArray(value)) {
|
|
7045
|
+
return [];
|
|
7046
|
+
}
|
|
7047
|
+
return value.flatMap((item) => {
|
|
7048
|
+
if (!item || typeof item !== "object") {
|
|
7049
|
+
return [];
|
|
7050
|
+
}
|
|
7051
|
+
const record = item;
|
|
7052
|
+
if (typeof record.label !== "string") {
|
|
7053
|
+
return [];
|
|
7054
|
+
}
|
|
7055
|
+
if (Array.isArray(record.platforms)) {
|
|
7056
|
+
return [{
|
|
7057
|
+
label: record.label,
|
|
7058
|
+
platforms: normalizeProjectCatalogPlatforms(record.platforms),
|
|
7059
|
+
totalTokens: normalizeProjectCatalogTotalTokens(record.totalTokens)
|
|
7060
|
+
}];
|
|
7061
|
+
}
|
|
7062
|
+
if (typeof record.type === "string") {
|
|
7063
|
+
return [{
|
|
7064
|
+
label: record.label,
|
|
7065
|
+
platforms: normalizeProjectCatalogPlatforms(record.type === "mixed" ? [] : [record.type]),
|
|
7066
|
+
totalTokens: normalizeProjectCatalogTotalTokens(record.totalTokens)
|
|
7067
|
+
}];
|
|
7068
|
+
}
|
|
7069
|
+
return [];
|
|
7070
|
+
});
|
|
7071
|
+
}
|
|
7072
|
+
function parseProjectCatalogPlatforms(value) {
|
|
7073
|
+
try {
|
|
7074
|
+
return normalizeProjectCatalogPlatforms(JSON.parse(value));
|
|
7075
|
+
} catch {
|
|
7076
|
+
return [];
|
|
7077
|
+
}
|
|
7078
|
+
}
|
|
7079
|
+
function normalizeProjectCatalogPlatforms(value) {
|
|
7080
|
+
if (!Array.isArray(value)) {
|
|
7081
|
+
return [];
|
|
7082
|
+
}
|
|
7083
|
+
return value.filter(
|
|
7084
|
+
(platform) => typeof platform === "string" && PROJECT_USAGE_PLATFORMS.includes(platform)
|
|
7085
|
+
);
|
|
7086
|
+
}
|
|
7087
|
+
function normalizeProjectCatalogTotalTokens(value) {
|
|
7088
|
+
return typeof value === "number" && Number.isFinite(value) ? Math.max(0, value) : 0;
|
|
7089
|
+
}
|
|
6517
7090
|
function mkdirParentDirectory(filePath) {
|
|
6518
7091
|
const directory = dirname$1(filePath);
|
|
6519
7092
|
if (!existsSync(directory)) {
|
|
@@ -6521,234 +7094,389 @@ function mkdirParentDirectory(filePath) {
|
|
|
6521
7094
|
}
|
|
6522
7095
|
}
|
|
6523
7096
|
|
|
6524
|
-
|
|
6525
|
-
|
|
6526
|
-
|
|
6527
|
-
|
|
6528
|
-
|
|
6529
|
-
|
|
7097
|
+
const MILLION = 1e6;
|
|
7098
|
+
const DEFAULT_PRICING_CACHE_TTL_MS = 1e3 * 60 * 5;
|
|
7099
|
+
const DEFAULT_LITELLM_PRICING_URL = "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json";
|
|
7100
|
+
const FAST_MULTIPLIER_EXACT_OVERRIDES = {
|
|
7101
|
+
"gpt-5.3-codex": 2,
|
|
7102
|
+
"gpt-5.4": 2,
|
|
7103
|
+
"gpt-5.5": 2.5
|
|
7104
|
+
};
|
|
7105
|
+
const FAST_MULTIPLIER_PREFIX_OVERRIDES = {
|
|
7106
|
+
"claude-opus-4-6": 6,
|
|
7107
|
+
"claude-opus-4-7": 6
|
|
7108
|
+
};
|
|
7109
|
+
const DEFAULT_FALLBACK_PRICING_TABLE = {
|
|
7110
|
+
"gpt-5": {
|
|
7111
|
+
cachedInputCostPerMTokens: 0.125,
|
|
7112
|
+
cacheCreationInputCostPerMTokens: 1.25,
|
|
7113
|
+
inputCostPerMTokens: 1.25,
|
|
7114
|
+
outputCostPerMTokens: 10
|
|
7115
|
+
},
|
|
7116
|
+
"gpt-5.2-codex": {
|
|
7117
|
+
cachedInputCostPerMTokens: 0.175,
|
|
7118
|
+
cacheCreationInputCostPerMTokens: 1.75,
|
|
7119
|
+
inputCostPerMTokens: 1.75,
|
|
7120
|
+
outputCostPerMTokens: 14
|
|
7121
|
+
},
|
|
7122
|
+
"gpt-5.4": {
|
|
7123
|
+
cachedInputCostPerMTokens: 0.25,
|
|
7124
|
+
cacheCreationInputCostPerMTokens: 2.5,
|
|
7125
|
+
inputCostPerMTokens: 2.5,
|
|
7126
|
+
outputCostPerMTokens: 15
|
|
7127
|
+
},
|
|
7128
|
+
"gpt-5.5": {
|
|
7129
|
+
cachedInputCostPerMTokens: 0.5,
|
|
7130
|
+
cacheCreationInputCostPerMTokens: 5,
|
|
7131
|
+
fastMultiplier: FAST_MULTIPLIER_EXACT_OVERRIDES["gpt-5.5"],
|
|
7132
|
+
inputCostPerMTokens: 5,
|
|
7133
|
+
outputCostPerMTokens: 30
|
|
7134
|
+
},
|
|
7135
|
+
"claude-haiku-4-5": {
|
|
7136
|
+
cachedInputCostPerMTokens: 0.1,
|
|
7137
|
+
cacheCreationInputCostPerMTokens: 1.25,
|
|
7138
|
+
inputCostPerMTokens: 1,
|
|
7139
|
+
outputCostPerMTokens: 5
|
|
7140
|
+
},
|
|
7141
|
+
"claude-opus-4-1": {
|
|
7142
|
+
cachedInputCostPerMTokens: 1.5,
|
|
7143
|
+
cachedInputCostPerMTokensAbove200K: 3,
|
|
7144
|
+
cacheCreationInputCostPerMTokens: 18.75,
|
|
7145
|
+
cacheCreationInputCostPerMTokensAbove200K: 37.5,
|
|
7146
|
+
inputCostPerMTokens: 15,
|
|
7147
|
+
inputCostPerMTokensAbove200K: 30,
|
|
7148
|
+
outputCostPerMTokens: 75,
|
|
7149
|
+
outputCostPerMTokensAbove200K: 112.5
|
|
7150
|
+
},
|
|
7151
|
+
"claude-opus-4-6": {
|
|
7152
|
+
cachedInputCostPerMTokens: 0.5,
|
|
7153
|
+
cacheCreationInputCostPerMTokens: 6.25,
|
|
7154
|
+
fastMultiplier: FAST_MULTIPLIER_PREFIX_OVERRIDES["claude-opus-4-6"],
|
|
7155
|
+
inputCostPerMTokens: 5,
|
|
7156
|
+
outputCostPerMTokens: 25
|
|
7157
|
+
},
|
|
7158
|
+
"claude-opus-4-7": {
|
|
7159
|
+
cachedInputCostPerMTokens: 0.5,
|
|
7160
|
+
cacheCreationInputCostPerMTokens: 6.25,
|
|
7161
|
+
fastMultiplier: FAST_MULTIPLIER_PREFIX_OVERRIDES["claude-opus-4-7"],
|
|
7162
|
+
inputCostPerMTokens: 5,
|
|
7163
|
+
outputCostPerMTokens: 25
|
|
7164
|
+
},
|
|
7165
|
+
"claude-sonnet-4-5": {
|
|
7166
|
+
cachedInputCostPerMTokens: 0.3,
|
|
7167
|
+
cachedInputCostPerMTokensAbove200K: 0.6,
|
|
7168
|
+
cacheCreationInputCostPerMTokens: 3.75,
|
|
7169
|
+
cacheCreationInputCostPerMTokensAbove200K: 7.5,
|
|
7170
|
+
inputCostPerMTokens: 3,
|
|
7171
|
+
inputCostPerMTokensAbove200K: 6,
|
|
7172
|
+
outputCostPerMTokens: 15,
|
|
7173
|
+
outputCostPerMTokensAbove200K: 22.5
|
|
6530
7174
|
}
|
|
6531
|
-
|
|
6532
|
-
|
|
7175
|
+
};
|
|
7176
|
+
const pricingCache = /* @__PURE__ */ new Map();
|
|
7177
|
+
async function fetchLiteLLMPricingDataset(options = {}) {
|
|
7178
|
+
var _a, _b, _c, _d;
|
|
7179
|
+
const url = (_a = options.url) != null ? _a : DEFAULT_LITELLM_PRICING_URL;
|
|
7180
|
+
const cacheTtlMs = (_b = options.cacheTtlMs) != null ? _b : DEFAULT_PRICING_CACHE_TTL_MS;
|
|
7181
|
+
const now = Date.now();
|
|
7182
|
+
const cacheEntry = pricingCache.get(url);
|
|
7183
|
+
if (!options.forceRefresh && (cacheEntry == null ? void 0 : cacheEntry.value) && now - cacheEntry.fetchedAt < cacheTtlMs) {
|
|
7184
|
+
return cacheEntry.value;
|
|
6533
7185
|
}
|
|
6534
|
-
|
|
6535
|
-
|
|
6536
|
-
|
|
6537
|
-
|
|
7186
|
+
if (!options.forceRefresh && (cacheEntry == null ? void 0 : cacheEntry.promise)) {
|
|
7187
|
+
return cacheEntry.promise;
|
|
7188
|
+
}
|
|
7189
|
+
const fetcher = (_c = options.fetcher) != null ? _c : globalThis.fetch;
|
|
7190
|
+
if (typeof fetcher !== "function") {
|
|
7191
|
+
return createFallbackLiteLLMPricingDataset();
|
|
7192
|
+
}
|
|
7193
|
+
const promise = fetcher(url).then(async (response) => {
|
|
7194
|
+
if (!response.ok) {
|
|
7195
|
+
throw new Error(`Failed to fetch LiteLLM pricing dataset: ${response.status} ${response.statusText}`);
|
|
7196
|
+
}
|
|
7197
|
+
const data = await response.json();
|
|
7198
|
+
if (!isLiteLLMPricingDataset(data)) {
|
|
7199
|
+
throw new Error("Invalid LiteLLM pricing dataset payload.");
|
|
7200
|
+
}
|
|
7201
|
+
const dataset = {
|
|
7202
|
+
...createFallbackLiteLLMPricingDataset(),
|
|
7203
|
+
...data
|
|
7204
|
+
};
|
|
7205
|
+
pricingCache.set(url, {
|
|
7206
|
+
fetchedAt: Date.now(),
|
|
7207
|
+
value: dataset
|
|
7208
|
+
});
|
|
7209
|
+
return dataset;
|
|
7210
|
+
}).catch(() => {
|
|
7211
|
+
const fallback = createFallbackLiteLLMPricingDataset();
|
|
7212
|
+
pricingCache.set(url, {
|
|
7213
|
+
fetchedAt: Date.now(),
|
|
7214
|
+
value: fallback
|
|
7215
|
+
});
|
|
7216
|
+
return fallback;
|
|
7217
|
+
});
|
|
7218
|
+
pricingCache.set(url, {
|
|
7219
|
+
fetchedAt: (_d = cacheEntry == null ? void 0 : cacheEntry.fetchedAt) != null ? _d : 0,
|
|
7220
|
+
promise,
|
|
7221
|
+
value: cacheEntry == null ? void 0 : cacheEntry.value
|
|
7222
|
+
});
|
|
7223
|
+
return promise;
|
|
6538
7224
|
}
|
|
6539
|
-
function
|
|
6540
|
-
|
|
7225
|
+
async function createLiteLLMPricingResolver(options = {}) {
|
|
7226
|
+
var _a, _b, _c, _d;
|
|
7227
|
+
const dataset = await fetchLiteLLMPricingDataset(options);
|
|
7228
|
+
const aliases = (_a = options.aliases) != null ? _a : {};
|
|
7229
|
+
const fallbackPricingTable = {
|
|
7230
|
+
...DEFAULT_FALLBACK_PRICING_TABLE,
|
|
7231
|
+
...(_b = options.fallbackPricingTable) != null ? _b : {}
|
|
7232
|
+
};
|
|
7233
|
+
const getLookupCandidates = (_c = options.getLookupCandidates) != null ? _c : defaultLookupCandidates;
|
|
7234
|
+
const fallbackModel = options.fallbackModel;
|
|
7235
|
+
const isZeroCostModel = (_d = options.isZeroCostModel) != null ? _d : (() => false);
|
|
7236
|
+
return (model) => {
|
|
7237
|
+
var _a2, _b2;
|
|
7238
|
+
if (isZeroCostModel(model)) {
|
|
7239
|
+
return createZeroPricing();
|
|
7240
|
+
}
|
|
7241
|
+
const lookupCandidates = uniqueItems(expandLookupCandidates(model, aliases, getLookupCandidates).filter(Boolean));
|
|
7242
|
+
const datasetPricing = resolveDatasetPricing(dataset, lookupCandidates);
|
|
7243
|
+
if (datasetPricing) {
|
|
7244
|
+
return datasetPricing;
|
|
7245
|
+
}
|
|
7246
|
+
const fallbackPricing = resolveFallbackPricing(fallbackPricingTable, lookupCandidates);
|
|
7247
|
+
if (fallbackPricing) {
|
|
7248
|
+
return fallbackPricing;
|
|
7249
|
+
}
|
|
7250
|
+
if (fallbackModel) {
|
|
7251
|
+
const fallbackCandidates = uniqueItems(expandLookupCandidates(fallbackModel, aliases, getLookupCandidates).filter(Boolean));
|
|
7252
|
+
return (_b2 = (_a2 = resolveDatasetPricing(dataset, fallbackCandidates)) != null ? _a2 : resolveFallbackPricing(fallbackPricingTable, fallbackCandidates)) != null ? _b2 : createZeroPricing();
|
|
7253
|
+
}
|
|
7254
|
+
return createZeroPricing();
|
|
7255
|
+
};
|
|
6541
7256
|
}
|
|
6542
|
-
function
|
|
6543
|
-
|
|
6544
|
-
|
|
7257
|
+
function calculateUsageCostUSD(usage, pricing, options = {}) {
|
|
7258
|
+
var _a, _b, _c;
|
|
7259
|
+
const multiplier = options.speed === "fast" ? (_b = (_a = pricing.fastMultiplier) != null ? _a : options.defaultFastMultiplier) != null ? _b : 1 : 1;
|
|
7260
|
+
const inputCost = calculateTieredCost(usage.inputTokens, pricing.inputCostPerMTokens, pricing.inputCostPerMTokensAbove200K);
|
|
7261
|
+
const cachedCost = calculateTieredCost(usage.cachedInputTokens, pricing.cachedInputCostPerMTokens, pricing.cachedInputCostPerMTokensAbove200K);
|
|
7262
|
+
const cacheCreationCost = calculateTieredCost((_c = usage.cacheCreationTokens) != null ? _c : 0, pricing.cacheCreationInputCostPerMTokens, pricing.cacheCreationInputCostPerMTokensAbove200K);
|
|
7263
|
+
const outputCost = calculateTieredCost(usage.outputTokens, pricing.outputCostPerMTokens, pricing.outputCostPerMTokensAbove200K);
|
|
7264
|
+
return (inputCost + cachedCost + cacheCreationCost + outputCost) * multiplier;
|
|
6545
7265
|
}
|
|
6546
|
-
function
|
|
6547
|
-
return
|
|
6548
|
-
|
|
6549
|
-
|
|
6550
|
-
|
|
6551
|
-
|
|
6552
|
-
|
|
6553
|
-
}
|
|
6554
|
-
|
|
6555
|
-
|
|
6556
|
-
|
|
6557
|
-
|
|
6558
|
-
|
|
6559
|
-
}
|
|
6560
|
-
|
|
6561
|
-
|
|
6562
|
-
|
|
6563
|
-
|
|
6564
|
-
|
|
6565
|
-
|
|
6566
|
-
|
|
6567
|
-
|
|
6568
|
-
|
|
6569
|
-
|
|
6570
|
-
|
|
6571
|
-
|
|
6572
|
-
|
|
6573
|
-
|
|
6574
|
-
|
|
6575
|
-
|
|
6576
|
-
|
|
6577
|
-
|
|
6578
|
-
|
|
6579
|
-
|
|
6580
|
-
|
|
7266
|
+
function createFallbackLiteLLMPricingDataset() {
|
|
7267
|
+
return {
|
|
7268
|
+
"gpt-5": {
|
|
7269
|
+
input_cost_per_token: 125e-8,
|
|
7270
|
+
output_cost_per_token: 1e-5,
|
|
7271
|
+
cache_creation_input_token_cost: 125e-8,
|
|
7272
|
+
cache_read_input_token_cost: 125e-9
|
|
7273
|
+
},
|
|
7274
|
+
"gpt-5.2-codex": {
|
|
7275
|
+
input_cost_per_token: 175e-8,
|
|
7276
|
+
output_cost_per_token: 14e-6,
|
|
7277
|
+
cache_creation_input_token_cost: 175e-8,
|
|
7278
|
+
cache_read_input_token_cost: 175e-9
|
|
7279
|
+
},
|
|
7280
|
+
"gpt-5.4": {
|
|
7281
|
+
input_cost_per_token: 25e-7,
|
|
7282
|
+
output_cost_per_token: 15e-6,
|
|
7283
|
+
cache_creation_input_token_cost: 25e-7,
|
|
7284
|
+
cache_read_input_token_cost: 25e-8
|
|
7285
|
+
},
|
|
7286
|
+
"gpt-5.5": {
|
|
7287
|
+
input_cost_per_token: 5e-6,
|
|
7288
|
+
output_cost_per_token: 3e-5,
|
|
7289
|
+
cache_creation_input_token_cost: 5e-6,
|
|
7290
|
+
cache_read_input_token_cost: 5e-7,
|
|
7291
|
+
provider_specific_entry: {
|
|
7292
|
+
fast: 2.5
|
|
7293
|
+
}
|
|
7294
|
+
},
|
|
7295
|
+
"claude-haiku-4-5": {
|
|
7296
|
+
input_cost_per_token: 1e-6,
|
|
7297
|
+
output_cost_per_token: 5e-6,
|
|
7298
|
+
cache_creation_input_token_cost: 125e-8,
|
|
7299
|
+
cache_read_input_token_cost: 1e-7
|
|
7300
|
+
},
|
|
7301
|
+
"claude-opus-4-1": {
|
|
7302
|
+
input_cost_per_token: 15e-6,
|
|
7303
|
+
output_cost_per_token: 75e-6,
|
|
7304
|
+
cache_creation_input_token_cost: 1875e-8,
|
|
7305
|
+
cache_read_input_token_cost: 15e-7,
|
|
7306
|
+
input_cost_per_token_above_200k_tokens: 3e-5,
|
|
7307
|
+
output_cost_per_token_above_200k_tokens: 1125e-7,
|
|
7308
|
+
cache_creation_input_token_cost_above_200k_tokens: 375e-7,
|
|
7309
|
+
cache_read_input_token_cost_above_200k_tokens: 3e-6
|
|
7310
|
+
},
|
|
7311
|
+
"claude-opus-4-6": {
|
|
7312
|
+
input_cost_per_token: 5e-6,
|
|
7313
|
+
output_cost_per_token: 25e-6,
|
|
7314
|
+
cache_creation_input_token_cost: 625e-8,
|
|
7315
|
+
cache_read_input_token_cost: 5e-7,
|
|
7316
|
+
provider_specific_entry: {
|
|
7317
|
+
fast: 6
|
|
7318
|
+
}
|
|
7319
|
+
},
|
|
7320
|
+
"claude-opus-4-7": {
|
|
7321
|
+
input_cost_per_token: 5e-6,
|
|
7322
|
+
output_cost_per_token: 25e-6,
|
|
7323
|
+
cache_creation_input_token_cost: 625e-8,
|
|
7324
|
+
cache_read_input_token_cost: 5e-7,
|
|
7325
|
+
provider_specific_entry: {
|
|
7326
|
+
fast: 6
|
|
7327
|
+
}
|
|
7328
|
+
},
|
|
7329
|
+
"claude-sonnet-4-5": {
|
|
7330
|
+
input_cost_per_token: 3e-6,
|
|
7331
|
+
output_cost_per_token: 15e-6,
|
|
7332
|
+
cache_creation_input_token_cost: 375e-8,
|
|
7333
|
+
cache_read_input_token_cost: 3e-7,
|
|
7334
|
+
input_cost_per_token_above_200k_tokens: 6e-6,
|
|
7335
|
+
output_cost_per_token_above_200k_tokens: 225e-7,
|
|
7336
|
+
cache_creation_input_token_cost_above_200k_tokens: 75e-7,
|
|
7337
|
+
cache_read_input_token_cost_above_200k_tokens: 6e-7
|
|
7338
|
+
}
|
|
7339
|
+
};
|
|
6581
7340
|
}
|
|
6582
|
-
function
|
|
6583
|
-
|
|
7341
|
+
function isLiteLLMPricingDataset(value) {
|
|
7342
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
7343
|
+
return false;
|
|
7344
|
+
}
|
|
7345
|
+
return true;
|
|
6584
7346
|
}
|
|
6585
|
-
function
|
|
6586
|
-
|
|
7347
|
+
function defaultLookupCandidates(model) {
|
|
7348
|
+
const normalizedModel = model.trim();
|
|
7349
|
+
return [
|
|
7350
|
+
normalizedModel,
|
|
7351
|
+
normalizedModel.replace(/^openai\//u, ""),
|
|
7352
|
+
normalizedModel.replace(/^azure\//u, ""),
|
|
7353
|
+
normalizedModel.replace(/^openrouter\/openai\//u, "")
|
|
7354
|
+
];
|
|
6587
7355
|
}
|
|
6588
|
-
function
|
|
6589
|
-
|
|
7356
|
+
function expandLookupCandidates(model, aliases, getLookupCandidates) {
|
|
7357
|
+
const candidates = getLookupCandidates(model);
|
|
7358
|
+
const expanded = [...candidates];
|
|
7359
|
+
for (const candidate of candidates) {
|
|
7360
|
+
const alias = aliases[candidate];
|
|
7361
|
+
if (alias) {
|
|
7362
|
+
expanded.push(...getLookupCandidates(alias));
|
|
7363
|
+
}
|
|
7364
|
+
}
|
|
7365
|
+
return expanded;
|
|
6590
7366
|
}
|
|
6591
|
-
function
|
|
6592
|
-
|
|
7367
|
+
function resolveDatasetPricing(dataset, candidates) {
|
|
7368
|
+
for (const candidate of candidates) {
|
|
7369
|
+
const pricing = dataset[candidate];
|
|
7370
|
+
if (!pricing || !hasNonZeroTokenPricing(pricing)) {
|
|
7371
|
+
continue;
|
|
7372
|
+
}
|
|
7373
|
+
return toModelPricing(pricing, candidates);
|
|
7374
|
+
}
|
|
7375
|
+
return null;
|
|
6593
7376
|
}
|
|
6594
|
-
function
|
|
6595
|
-
|
|
6596
|
-
const
|
|
6597
|
-
|
|
6598
|
-
if (
|
|
6599
|
-
|
|
6600
|
-
|
|
6601
|
-
trendTone: "neutral"
|
|
6602
|
-
};
|
|
7377
|
+
function resolveFallbackPricing(fallbackPricingTable, candidates) {
|
|
7378
|
+
var _a;
|
|
7379
|
+
for (const candidate of candidates) {
|
|
7380
|
+
const pricing = fallbackPricingTable[candidate];
|
|
7381
|
+
if (pricing) {
|
|
7382
|
+
const fastMultiplier = (_a = pricing.fastMultiplier) != null ? _a : resolveFastMultiplierOverride(candidates);
|
|
7383
|
+
return fastMultiplier == null ? pricing : { ...pricing, fastMultiplier };
|
|
6603
7384
|
}
|
|
6604
|
-
return {
|
|
6605
|
-
trend: `+${formatValue(current)}`,
|
|
6606
|
-
trendTone: "up"
|
|
6607
|
-
};
|
|
6608
7385
|
}
|
|
6609
|
-
|
|
7386
|
+
return null;
|
|
7387
|
+
}
|
|
7388
|
+
function hasNonZeroTokenPricing(pricing) {
|
|
7389
|
+
var _a, _b, _c, _d;
|
|
7390
|
+
return ((_a = pricing.input_cost_per_token) != null ? _a : 0) > 0 || ((_b = pricing.output_cost_per_token) != null ? _b : 0) > 0 || ((_c = pricing.cache_creation_input_token_cost) != null ? _c : 0) > 0 || ((_d = pricing.cache_read_input_token_cost) != null ? _d : 0) > 0;
|
|
7391
|
+
}
|
|
7392
|
+
function toModelPricing(pricing, candidates) {
|
|
7393
|
+
var _a, _b, _c, _d, _e, _f;
|
|
7394
|
+
const inputCostPerToken = (_a = pricing.input_cost_per_token) != null ? _a : 0;
|
|
7395
|
+
const cachedInputCostPerToken = (_b = pricing.cache_read_input_token_cost) != null ? _b : inputCostPerToken;
|
|
7396
|
+
const cacheCreationInputCostPerToken = (_c = pricing.cache_creation_input_token_cost) != null ? _c : inputCostPerToken;
|
|
7397
|
+
const outputCostPerToken = (_d = pricing.output_cost_per_token) != null ? _d : 0;
|
|
6610
7398
|
return {
|
|
6611
|
-
|
|
6612
|
-
|
|
7399
|
+
cachedInputCostPerMTokens: cachedInputCostPerToken * MILLION,
|
|
7400
|
+
cachedInputCostPerMTokensAbove200K: pricing.cache_read_input_token_cost_above_200k_tokens != null ? pricing.cache_read_input_token_cost_above_200k_tokens * MILLION : void 0,
|
|
7401
|
+
cacheCreationInputCostPerMTokens: cacheCreationInputCostPerToken * MILLION,
|
|
7402
|
+
cacheCreationInputCostPerMTokensAbove200K: pricing.cache_creation_input_token_cost_above_200k_tokens != null ? pricing.cache_creation_input_token_cost_above_200k_tokens * MILLION : void 0,
|
|
7403
|
+
fastMultiplier: (_f = (_e = pricing.provider_specific_entry) == null ? void 0 : _e.fast) != null ? _f : resolveFastMultiplierOverride(candidates),
|
|
7404
|
+
inputCostPerMTokens: inputCostPerToken * MILLION,
|
|
7405
|
+
inputCostPerMTokensAbove200K: pricing.input_cost_per_token_above_200k_tokens != null ? pricing.input_cost_per_token_above_200k_tokens * MILLION : void 0,
|
|
7406
|
+
outputCostPerMTokens: outputCostPerToken * MILLION,
|
|
7407
|
+
outputCostPerMTokensAbove200K: pricing.output_cost_per_token_above_200k_tokens != null ? pricing.output_cost_per_token_above_200k_tokens * MILLION : void 0
|
|
6613
7408
|
};
|
|
6614
7409
|
}
|
|
6615
|
-
function
|
|
6616
|
-
|
|
6617
|
-
|
|
6618
|
-
|
|
6619
|
-
|
|
6620
|
-
|
|
6621
|
-
|
|
7410
|
+
function resolveFastMultiplierOverride(candidates) {
|
|
7411
|
+
for (const candidate of candidates) {
|
|
7412
|
+
const multiplier = FAST_MULTIPLIER_EXACT_OVERRIDES[candidate];
|
|
7413
|
+
if (multiplier != null) {
|
|
7414
|
+
return multiplier;
|
|
7415
|
+
}
|
|
7416
|
+
}
|
|
7417
|
+
for (const candidate of candidates) {
|
|
7418
|
+
const normalized = candidate.replace(/[.@]/gu, "-");
|
|
7419
|
+
for (const part of normalized.split(/[/:]/u)) {
|
|
7420
|
+
for (const [base, multiplier] of Object.entries(FAST_MULTIPLIER_PREFIX_OVERRIDES)) {
|
|
7421
|
+
if (matchesModelSuffix(part, base)) {
|
|
7422
|
+
return multiplier;
|
|
7423
|
+
}
|
|
7424
|
+
}
|
|
7425
|
+
}
|
|
7426
|
+
}
|
|
7427
|
+
return void 0;
|
|
6622
7428
|
}
|
|
6623
|
-
function
|
|
6624
|
-
const
|
|
6625
|
-
if (
|
|
6626
|
-
return
|
|
7429
|
+
function matchesModelSuffix(part, base) {
|
|
7430
|
+
const index = part.lastIndexOf(base);
|
|
7431
|
+
if (index < 0) {
|
|
7432
|
+
return false;
|
|
6627
7433
|
}
|
|
6628
|
-
|
|
7434
|
+
const suffix = part.slice(index);
|
|
7435
|
+
return suffix === base || suffix[base.length] === "-";
|
|
6629
7436
|
}
|
|
6630
|
-
function
|
|
6631
|
-
|
|
6632
|
-
|
|
6633
|
-
|
|
6634
|
-
|
|
7437
|
+
function createZeroPricing() {
|
|
7438
|
+
return {
|
|
7439
|
+
cachedInputCostPerMTokens: 0,
|
|
7440
|
+
cacheCreationInputCostPerMTokens: 0,
|
|
7441
|
+
inputCostPerMTokens: 0,
|
|
7442
|
+
outputCostPerMTokens: 0
|
|
7443
|
+
};
|
|
6635
7444
|
}
|
|
6636
|
-
function
|
|
6637
|
-
const
|
|
6638
|
-
if (
|
|
6639
|
-
return
|
|
7445
|
+
function calculateTieredCost(tokens, baseCostPerMTokens, above200KCostPerMTokens) {
|
|
7446
|
+
const safeTokens = Math.max(tokens != null ? tokens : 0, 0);
|
|
7447
|
+
if (safeTokens === 0) {
|
|
7448
|
+
return 0;
|
|
6640
7449
|
}
|
|
6641
|
-
|
|
7450
|
+
if (safeTokens > 2e5 && above200KCostPerMTokens != null) {
|
|
7451
|
+
return 2e5 / MILLION * baseCostPerMTokens + (safeTokens - 2e5) / MILLION * above200KCostPerMTokens;
|
|
7452
|
+
}
|
|
7453
|
+
return safeTokens / MILLION * baseCostPerMTokens;
|
|
6642
7454
|
}
|
|
6643
|
-
|
|
6644
|
-
|
|
6645
|
-
|
|
6646
|
-
|
|
6647
|
-
|
|
6648
|
-
|
|
6649
|
-
|
|
6650
|
-
sessions: 0,
|
|
6651
|
-
tokenTotal: 0
|
|
6652
|
-
};
|
|
6653
|
-
project.costUSD += session.costUSD;
|
|
6654
|
-
project.sessions += 1;
|
|
6655
|
-
project.tokenTotal += session.tokenTotal;
|
|
6656
|
-
projects.set(session.project, project);
|
|
7455
|
+
|
|
7456
|
+
function normalizeStringValue(value) {
|
|
7457
|
+
return typeof value === "string" ? value.trim() : void 0;
|
|
7458
|
+
}
|
|
7459
|
+
function normalizeStringList(value) {
|
|
7460
|
+
if (Array.isArray(value)) {
|
|
7461
|
+
return value.flatMap((item) => typeof item === "string" ? splitCommaValues(item) : []);
|
|
6657
7462
|
}
|
|
6658
|
-
|
|
6659
|
-
|
|
6660
|
-
|
|
6661
|
-
|
|
6662
|
-
label,
|
|
6663
|
-
percent: maxCost > 0 ? project.costUSD / maxCost * 100 : 0,
|
|
6664
|
-
repository: project.repository,
|
|
6665
|
-
sessions: project.sessions,
|
|
6666
|
-
tokenTotal: project.tokenTotal,
|
|
6667
|
-
tone: "amber",
|
|
6668
|
-
value: formatCurrency(project.costUSD)
|
|
6669
|
-
})).sort((a, b) => b.costUSD - a.costUSD);
|
|
7463
|
+
if (typeof value === "string") {
|
|
7464
|
+
return splitCommaValues(value);
|
|
7465
|
+
}
|
|
7466
|
+
return void 0;
|
|
6670
7467
|
}
|
|
6671
|
-
function
|
|
6672
|
-
|
|
6673
|
-
const groups = /* @__PURE__ */ new Map();
|
|
6674
|
-
for (const item of items) {
|
|
6675
|
-
const dateKey = getDateKeyFromLabel(item.date);
|
|
6676
|
-
const group = (_a = groups.get(dateKey)) != null ? _a : {
|
|
6677
|
-
cachedInputTokens: 0,
|
|
6678
|
-
costUSD: 0,
|
|
6679
|
-
date: formatDateLabelFromDateKey(dateKey, item.date),
|
|
6680
|
-
inputTokens: 0,
|
|
6681
|
-
models: /* @__PURE__ */ new Map(),
|
|
6682
|
-
outputTokens: 0,
|
|
6683
|
-
reasoningOutputTokens: 0,
|
|
6684
|
-
totalTokens: 0
|
|
6685
|
-
};
|
|
6686
|
-
group.cachedInputTokens += item.cachedInputTokens;
|
|
6687
|
-
group.costUSD += item.costUSD;
|
|
6688
|
-
group.inputTokens += item.inputTokens;
|
|
6689
|
-
group.outputTokens += item.outputTokens;
|
|
6690
|
-
group.reasoningOutputTokens += item.reasoningOutputTokens;
|
|
6691
|
-
group.totalTokens += item.totalTokens;
|
|
6692
|
-
for (const [modelName, usage] of Object.entries(item.models)) {
|
|
6693
|
-
const model = (_b = group.models.get(modelName)) != null ? _b : createEmptyModelUsage();
|
|
6694
|
-
model.cachedInputTokens += usage.cachedInputTokens;
|
|
6695
|
-
model.inputTokens += usage.inputTokens;
|
|
6696
|
-
model.isFallback = model.isFallback || usage.isFallback;
|
|
6697
|
-
model.outputTokens += usage.outputTokens;
|
|
6698
|
-
model.reasoningOutputTokens += usage.reasoningOutputTokens;
|
|
6699
|
-
model.totalTokens += usage.totalTokens;
|
|
6700
|
-
group.models.set(modelName, model);
|
|
6701
|
-
}
|
|
6702
|
-
groups.set(dateKey, group);
|
|
6703
|
-
}
|
|
6704
|
-
return Array.from(groups.entries()).sort((a, b) => b[0].localeCompare(a[0])).map(([, group]) => ({
|
|
6705
|
-
cachedInputTokens: group.cachedInputTokens,
|
|
6706
|
-
costUSD: roundCurrency(group.costUSD),
|
|
6707
|
-
date: group.date,
|
|
6708
|
-
inputTokens: group.inputTokens,
|
|
6709
|
-
models: Object.fromEntries(group.models.entries()),
|
|
6710
|
-
outputTokens: group.outputTokens,
|
|
6711
|
-
reasoningOutputTokens: group.reasoningOutputTokens,
|
|
6712
|
-
totalTokens: group.totalTokens
|
|
6713
|
-
}));
|
|
6714
|
-
}
|
|
6715
|
-
function mergeMonthlyModelUsage(items) {
|
|
6716
|
-
var _a;
|
|
6717
|
-
const groups = /* @__PURE__ */ new Map();
|
|
6718
|
-
for (const item of items) {
|
|
6719
|
-
const key = `${item.month}__${item.model}`;
|
|
6720
|
-
const group = (_a = groups.get(key)) != null ? _a : {
|
|
6721
|
-
model: item.model,
|
|
6722
|
-
month: item.month,
|
|
6723
|
-
tokenTotal: 0
|
|
6724
|
-
};
|
|
6725
|
-
group.tokenTotal += item.tokenTotal;
|
|
6726
|
-
groups.set(key, group);
|
|
6727
|
-
}
|
|
6728
|
-
return Array.from(groups.values()).sort((a, b) => a.month.localeCompare(b.month) || a.model.localeCompare(b.model));
|
|
7468
|
+
function normalizeUnknownRecord(value) {
|
|
7469
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
6729
7470
|
}
|
|
6730
|
-
function
|
|
6731
|
-
|
|
6732
|
-
return `${prefix}${formatPercent(value)}`;
|
|
7471
|
+
function normalizeFiniteNumberOrNull(value) {
|
|
7472
|
+
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
6733
7473
|
}
|
|
6734
|
-
function
|
|
6735
|
-
|
|
6736
|
-
|
|
6737
|
-
}
|
|
6738
|
-
if (value < 0) {
|
|
6739
|
-
return "down";
|
|
6740
|
-
}
|
|
6741
|
-
return "neutral";
|
|
7474
|
+
function normalizeTimestampValue(value) {
|
|
7475
|
+
const normalizedValue = normalizeStringValue(value);
|
|
7476
|
+
return normalizedValue && Number.isFinite(Date.parse(normalizedValue)) ? normalizedValue : null;
|
|
6742
7477
|
}
|
|
6743
|
-
function
|
|
6744
|
-
return
|
|
6745
|
-
cachedInputTokens: 0,
|
|
6746
|
-
inputTokens: 0,
|
|
6747
|
-
isFallback: false,
|
|
6748
|
-
outputTokens: 0,
|
|
6749
|
-
reasoningOutputTokens: 0,
|
|
6750
|
-
totalTokens: 0
|
|
6751
|
-
};
|
|
7478
|
+
function splitCommaValues(value) {
|
|
7479
|
+
return value.split(",").map((item) => item.trim()).filter(Boolean);
|
|
6752
7480
|
}
|
|
6753
7481
|
|
|
6754
7482
|
function parseJsonlFile(filePath) {
|
|
@@ -6795,9 +7523,11 @@ function buildDailyUsageGroups(events, options = {}) {
|
|
|
6795
7523
|
if (shouldIncludeModel(event, options)) {
|
|
6796
7524
|
const modelUsage = (_b = group.modelUsage.get(event.model)) != null ? _b : {
|
|
6797
7525
|
...createEmptyUsage(),
|
|
7526
|
+
costUSD: 0,
|
|
6798
7527
|
isFallback: false
|
|
6799
7528
|
};
|
|
6800
7529
|
addUsage(modelUsage, event);
|
|
7530
|
+
modelUsage.costUSD += getEventCostUSD(event, options);
|
|
6801
7531
|
if (event.isFallbackModel) {
|
|
6802
7532
|
modelUsage.isFallback = true;
|
|
6803
7533
|
}
|
|
@@ -6815,6 +7545,7 @@ function buildDailyTokenUsage(dailyGroups) {
|
|
|
6815
7545
|
inputTokens: group.inputTokens,
|
|
6816
7546
|
models: Object.fromEntries(Array.from(group.modelUsage.entries()).map(([model, usage]) => [model, {
|
|
6817
7547
|
cachedInputTokens: usage.cachedInputTokens,
|
|
7548
|
+
costUSD: roundCurrency(usage.costUSD),
|
|
6818
7549
|
inputTokens: usage.inputTokens,
|
|
6819
7550
|
isFallback: usage.isFallback,
|
|
6820
7551
|
outputTokens: usage.outputTokens,
|
|
@@ -6896,22 +7627,26 @@ function buildMonthlyModelUsage(events, options = {}) {
|
|
|
6896
7627
|
})).sort((a, b) => a.month.localeCompare(b.month) || a.model.localeCompare(b.model));
|
|
6897
7628
|
}
|
|
6898
7629
|
function buildSessionRows(sessions, options = {}) {
|
|
6899
|
-
return [...sessions].sort((a, b) => getSessionSortTimestamp(b) - getSessionSortTimestamp(a)).map((session) =>
|
|
6900
|
-
|
|
6901
|
-
|
|
6902
|
-
|
|
6903
|
-
|
|
6904
|
-
|
|
6905
|
-
|
|
6906
|
-
|
|
6907
|
-
|
|
6908
|
-
|
|
6909
|
-
|
|
6910
|
-
|
|
6911
|
-
|
|
6912
|
-
|
|
7630
|
+
return [...sessions].sort((a, b) => getSessionSortTimestamp(b) - getSessionSortTimestamp(a)).map((session) => {
|
|
7631
|
+
var _a;
|
|
7632
|
+
return {
|
|
7633
|
+
cachedInputTokens: getCachedInputTokens(session, options),
|
|
7634
|
+
costUSD: session.costUSD,
|
|
7635
|
+
id: (_a = session.id) != null ? _a : session.sessionId,
|
|
7636
|
+
inputTokens: session.inputTokens,
|
|
7637
|
+
label: session.sessionId,
|
|
7638
|
+
models: session.models,
|
|
7639
|
+
outputTokens: session.outputTokens,
|
|
7640
|
+
period: formatDateLabelFromDateKey(getDateKey(new Date(session.lastActivity))),
|
|
7641
|
+
projects: [session.project],
|
|
7642
|
+
reasoningOutputTokens: getReasoningOutputTokens(session, options),
|
|
7643
|
+
sessionCount: 1,
|
|
7644
|
+
totalTokens: session.tokenTotal
|
|
7645
|
+
};
|
|
7646
|
+
});
|
|
6913
7647
|
}
|
|
6914
7648
|
function toUsageSessionUsageItem(session, options = {}) {
|
|
7649
|
+
var _a;
|
|
6915
7650
|
const startedAtDate = new Date(session.startedAt);
|
|
6916
7651
|
return {
|
|
6917
7652
|
cachedInputTokens: getCachedInputTokens(session, options),
|
|
@@ -6919,7 +7654,7 @@ function toUsageSessionUsageItem(session, options = {}) {
|
|
|
6919
7654
|
date: formatDateLabelFromDateKey(getDateKey(startedAtDate)),
|
|
6920
7655
|
duration: formatDuration(session.durationMinutes),
|
|
6921
7656
|
durationMinutes: session.durationMinutes,
|
|
6922
|
-
id: session.sessionId,
|
|
7657
|
+
id: (_a = session.id) != null ? _a : session.sessionId,
|
|
6923
7658
|
inputTokens: session.inputTokens,
|
|
6924
7659
|
model: session.topModel,
|
|
6925
7660
|
month: getMonthKey(startedAtDate),
|
|
@@ -6951,6 +7686,10 @@ function buildOverviewCards(options) {
|
|
|
6951
7686
|
detail: `${formatNumber(options.todayTotalTokens)} tokens used today`,
|
|
6952
7687
|
icon: "solar:cpu-line-duotone",
|
|
6953
7688
|
name: "Today Tokens",
|
|
7689
|
+
subvalue: buildInputOutputTokenSubvalue({
|
|
7690
|
+
inputTokens: options.todayInputTokens,
|
|
7691
|
+
outputTokens: options.todayOutputTokens
|
|
7692
|
+
}),
|
|
6954
7693
|
trend: tokenTrend.trend,
|
|
6955
7694
|
trendTone: tokenTrend.trendTone,
|
|
6956
7695
|
value: formatCompactNumber(options.todayTotalTokens)
|
|
@@ -6982,7 +7721,7 @@ function buildOverviewCards(options) {
|
|
|
6982
7721
|
];
|
|
6983
7722
|
}
|
|
6984
7723
|
function buildLoadUsageResult(events, sessions, options = {}) {
|
|
6985
|
-
var _a, _b, _c, _d, _e, _f;
|
|
7724
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
6986
7725
|
const aggregateOptions = (_a = options.aggregateOptions) != null ? _a : {};
|
|
6987
7726
|
const sessionOptions = (_b = options.sessionOptions) != null ? _b : {};
|
|
6988
7727
|
const sortedSessions = [...sessions].sort((a, b) => getSessionSortTimestamp(b) - getSessionSortTimestamp(a));
|
|
@@ -7005,6 +7744,8 @@ function buildLoadUsageResult(events, sessions, options = {}) {
|
|
|
7005
7744
|
overviewCards: buildOverviewCards({
|
|
7006
7745
|
previousDayCost: roundCurrency((_e = previousDayDailyGroup == null ? void 0 : previousDayDailyGroup.costUSD) != null ? _e : 0),
|
|
7007
7746
|
previousDayTokens: (_f = previousDayDailyGroup == null ? void 0 : previousDayDailyGroup.totalTokens) != null ? _f : 0,
|
|
7747
|
+
todayInputTokens: (_g = todayDailyGroup == null ? void 0 : todayDailyGroup.inputTokens) != null ? _g : 0,
|
|
7748
|
+
todayOutputTokens: (_h = todayDailyGroup == null ? void 0 : todayDailyGroup.outputTokens) != null ? _h : 0,
|
|
7008
7749
|
todayTopModel,
|
|
7009
7750
|
todayTopProject,
|
|
7010
7751
|
todayTotalCost,
|
|
@@ -7104,10 +7845,21 @@ function getDurationMinutes(startedAt, endedAt) {
|
|
|
7104
7845
|
return Math.round(durationMs / 6e4);
|
|
7105
7846
|
}
|
|
7106
7847
|
function toIsoString(value) {
|
|
7848
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
7849
|
+
const timestamp2 = value > 1e10 ? value : value * 1e3;
|
|
7850
|
+
return new Date(timestamp2).toISOString();
|
|
7851
|
+
}
|
|
7852
|
+
if (value instanceof Date) {
|
|
7853
|
+
return Number.isFinite(value.getTime()) ? value.toISOString() : null;
|
|
7854
|
+
}
|
|
7107
7855
|
if (typeof value !== "string") {
|
|
7108
7856
|
return null;
|
|
7109
7857
|
}
|
|
7110
|
-
const
|
|
7858
|
+
const normalizedValue = value.trim();
|
|
7859
|
+
if (!normalizedValue) {
|
|
7860
|
+
return null;
|
|
7861
|
+
}
|
|
7862
|
+
const timestamp = Date.parse(normalizedValue);
|
|
7111
7863
|
return Number.isFinite(timestamp) ? new Date(timestamp).toISOString() : null;
|
|
7112
7864
|
}
|
|
7113
7865
|
function getMonthKey(date) {
|
|
@@ -7157,7 +7909,7 @@ function normalizeRawUsage(usage) {
|
|
|
7157
7909
|
input_tokens: input,
|
|
7158
7910
|
output_tokens: output,
|
|
7159
7911
|
reasoning_output_tokens: reasoning,
|
|
7160
|
-
total_tokens: total > 0 ? total : input + output
|
|
7912
|
+
total_tokens: total > 0 ? total : input + output + reasoning
|
|
7161
7913
|
};
|
|
7162
7914
|
}
|
|
7163
7915
|
function subtractRawUsage(current, previous) {
|
|
@@ -7237,14 +7989,23 @@ function decodeClaudeProjectPath(projectPath) {
|
|
|
7237
7989
|
return (_a = parts.at(-1)) != null ? _a : projectPath;
|
|
7238
7990
|
}
|
|
7239
7991
|
function getClaudeLookupCandidates(model) {
|
|
7992
|
+
var _a;
|
|
7240
7993
|
const normalizedModel = model.trim();
|
|
7994
|
+
const withoutFastSuffix = normalizedModel.replace(/-fast$/u, "");
|
|
7995
|
+
const baseModel = (_a = withoutFastSuffix.split("/").at(-1)) != null ? _a : withoutFastSuffix;
|
|
7996
|
+
const normalizedBaseModel = baseModel.replace(/[.@]/gu, "-");
|
|
7997
|
+
const baseModelWithoutDate = normalizedBaseModel.replace(/-\d{8}$/u, "");
|
|
7241
7998
|
return [
|
|
7242
7999
|
normalizedModel,
|
|
7243
|
-
|
|
7244
|
-
|
|
8000
|
+
withoutFastSuffix,
|
|
8001
|
+
withoutFastSuffix.replace(/^anthropic\//u, ""),
|
|
7245
8002
|
`anthropic/${normalizedModel}`,
|
|
7246
|
-
|
|
7247
|
-
|
|
8003
|
+
baseModel,
|
|
8004
|
+
normalizedBaseModel,
|
|
8005
|
+
baseModelWithoutDate,
|
|
8006
|
+
`anthropic/${baseModelWithoutDate}`,
|
|
8007
|
+
baseModelWithoutDate.replace(/^claude-3-5-/u, "claude-"),
|
|
8008
|
+
baseModelWithoutDate.replace(/^claude-3-7-/u, "claude-")
|
|
7248
8009
|
];
|
|
7249
8010
|
}
|
|
7250
8011
|
function getGeminiLookupCandidates(model) {
|
|
@@ -7347,349 +8108,77 @@ function getCachedInputTokens(session, options) {
|
|
|
7347
8108
|
return (_b = (_a = options.getCachedInputTokens) == null ? void 0 : _a.call(options, session)) != null ? _b : getNumericProperty(session, "cachedInputTokens");
|
|
7348
8109
|
}
|
|
7349
8110
|
function getReasoningOutputTokens(session, options) {
|
|
7350
|
-
var _a, _b;
|
|
7351
|
-
return (_b = (_a = options.getReasoningOutputTokens) == null ? void 0 : _a.call(options, session)) != null ? _b : getNumericProperty(session, "reasoningOutputTokens");
|
|
7352
|
-
}
|
|
7353
|
-
function getNumericProperty(value, key) {
|
|
7354
|
-
const record = value;
|
|
7355
|
-
const property = record[key];
|
|
7356
|
-
return typeof property === "number" && Number.isFinite(property) ? property : 0;
|
|
7357
|
-
}
|
|
7358
|
-
function cloneDate(date) {
|
|
7359
|
-
return new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
|
7360
|
-
}
|
|
7361
|
-
|
|
7362
|
-
function toDiscoveredUsageFile(filePath, platform) {
|
|
7363
|
-
try {
|
|
7364
|
-
const stats = statSync(filePath);
|
|
7365
|
-
return [{
|
|
7366
|
-
mtimeMs: stats.mtimeMs,
|
|
7367
|
-
path: filePath,
|
|
7368
|
-
platform,
|
|
7369
|
-
size: stats.size
|
|
7370
|
-
}];
|
|
7371
|
-
} catch {
|
|
7372
|
-
return [];
|
|
7373
|
-
}
|
|
7374
|
-
}
|
|
7375
|
-
function createSessionFragment(options) {
|
|
7376
|
-
return {
|
|
7377
|
-
durationEndAt: "",
|
|
7378
|
-
interactions: [],
|
|
7379
|
-
key: getSessionLookupKey(options.project, options.sessionId),
|
|
7380
|
-
project: options.project,
|
|
7381
|
-
repository: options.repository,
|
|
7382
|
-
sessionId: options.sessionId,
|
|
7383
|
-
startedAt: options.startedAt,
|
|
7384
|
-
threadName: options.threadName
|
|
7385
|
-
};
|
|
7386
|
-
}
|
|
7387
|
-
function addFragmentInteraction(fragment, interaction) {
|
|
7388
|
-
fragment.interactions.push(interaction);
|
|
7389
|
-
if (!interaction.timestamp) {
|
|
7390
|
-
return;
|
|
7391
|
-
}
|
|
7392
|
-
if (!fragment.startedAt || Date.parse(interaction.timestamp) < Date.parse(fragment.startedAt)) {
|
|
7393
|
-
fragment.startedAt = interaction.timestamp;
|
|
7394
|
-
}
|
|
7395
|
-
if (!fragment.durationEndAt || Date.parse(interaction.timestamp) > Date.parse(fragment.durationEndAt)) {
|
|
7396
|
-
fragment.durationEndAt = interaction.timestamp;
|
|
7397
|
-
}
|
|
7398
|
-
}
|
|
7399
|
-
function getSessionLookupKey(project, sessionId) {
|
|
7400
|
-
return `${project}:${sessionId}`;
|
|
7401
|
-
}
|
|
7402
|
-
function normalizeRole(value) {
|
|
7403
|
-
const normalized = value.toLowerCase();
|
|
7404
|
-
if (normalized.includes("user")) {
|
|
7405
|
-
return "user";
|
|
7406
|
-
}
|
|
7407
|
-
if (normalized.includes("assistant") || normalized.includes("agent") || normalized.includes("gemini")) {
|
|
7408
|
-
return "assistant";
|
|
7409
|
-
}
|
|
7410
|
-
if (normalized.includes("system")) {
|
|
7411
|
-
return "system";
|
|
7412
|
-
}
|
|
7413
|
-
if (normalized.includes("tool")) {
|
|
7414
|
-
return "tool";
|
|
7415
|
-
}
|
|
7416
|
-
if (normalized.includes("token") || normalized.includes("usage")) {
|
|
7417
|
-
return "usage";
|
|
7418
|
-
}
|
|
7419
|
-
return "unknown";
|
|
7420
|
-
}
|
|
7421
|
-
|
|
7422
|
-
const MILLION = 1e6;
|
|
7423
|
-
const DEFAULT_PRICING_CACHE_TTL_MS = 1e3 * 60 * 5;
|
|
7424
|
-
const DEFAULT_LITELLM_PRICING_URL = "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json";
|
|
7425
|
-
const DEFAULT_FALLBACK_PRICING_TABLE = {
|
|
7426
|
-
"gpt-5": {
|
|
7427
|
-
cachedInputCostPerMTokens: 0.125,
|
|
7428
|
-
cacheCreationInputCostPerMTokens: 1.25,
|
|
7429
|
-
inputCostPerMTokens: 1.25,
|
|
7430
|
-
outputCostPerMTokens: 10
|
|
7431
|
-
},
|
|
7432
|
-
"gpt-5.2-codex": {
|
|
7433
|
-
cachedInputCostPerMTokens: 0.175,
|
|
7434
|
-
cacheCreationInputCostPerMTokens: 1.75,
|
|
7435
|
-
inputCostPerMTokens: 1.75,
|
|
7436
|
-
outputCostPerMTokens: 14
|
|
7437
|
-
},
|
|
7438
|
-
"gpt-5.4": {
|
|
7439
|
-
cachedInputCostPerMTokens: 0.25,
|
|
7440
|
-
cacheCreationInputCostPerMTokens: 2.5,
|
|
7441
|
-
inputCostPerMTokens: 2.5,
|
|
7442
|
-
outputCostPerMTokens: 15
|
|
7443
|
-
},
|
|
7444
|
-
"claude-haiku-4-5": {
|
|
7445
|
-
cachedInputCostPerMTokens: 0.1,
|
|
7446
|
-
cacheCreationInputCostPerMTokens: 1.25,
|
|
7447
|
-
inputCostPerMTokens: 1,
|
|
7448
|
-
outputCostPerMTokens: 5
|
|
7449
|
-
},
|
|
7450
|
-
"claude-opus-4-1": {
|
|
7451
|
-
cachedInputCostPerMTokens: 1.5,
|
|
7452
|
-
cachedInputCostPerMTokensAbove200K: 3,
|
|
7453
|
-
cacheCreationInputCostPerMTokens: 18.75,
|
|
7454
|
-
cacheCreationInputCostPerMTokensAbove200K: 37.5,
|
|
7455
|
-
inputCostPerMTokens: 15,
|
|
7456
|
-
inputCostPerMTokensAbove200K: 30,
|
|
7457
|
-
outputCostPerMTokens: 75,
|
|
7458
|
-
outputCostPerMTokensAbove200K: 112.5
|
|
7459
|
-
},
|
|
7460
|
-
"claude-sonnet-4-5": {
|
|
7461
|
-
cachedInputCostPerMTokens: 0.3,
|
|
7462
|
-
cachedInputCostPerMTokensAbove200K: 0.6,
|
|
7463
|
-
cacheCreationInputCostPerMTokens: 3.75,
|
|
7464
|
-
cacheCreationInputCostPerMTokensAbove200K: 7.5,
|
|
7465
|
-
inputCostPerMTokens: 3,
|
|
7466
|
-
inputCostPerMTokensAbove200K: 6,
|
|
7467
|
-
outputCostPerMTokens: 15,
|
|
7468
|
-
outputCostPerMTokensAbove200K: 22.5
|
|
7469
|
-
}
|
|
7470
|
-
};
|
|
7471
|
-
const pricingCache = /* @__PURE__ */ new Map();
|
|
7472
|
-
async function fetchLiteLLMPricingDataset(options = {}) {
|
|
7473
|
-
var _a, _b, _c, _d;
|
|
7474
|
-
const url = (_a = options.url) != null ? _a : DEFAULT_LITELLM_PRICING_URL;
|
|
7475
|
-
const cacheTtlMs = (_b = options.cacheTtlMs) != null ? _b : DEFAULT_PRICING_CACHE_TTL_MS;
|
|
7476
|
-
const now = Date.now();
|
|
7477
|
-
const cacheEntry = pricingCache.get(url);
|
|
7478
|
-
if (!options.forceRefresh && (cacheEntry == null ? void 0 : cacheEntry.value) && now - cacheEntry.fetchedAt < cacheTtlMs) {
|
|
7479
|
-
return cacheEntry.value;
|
|
7480
|
-
}
|
|
7481
|
-
if (!options.forceRefresh && (cacheEntry == null ? void 0 : cacheEntry.promise)) {
|
|
7482
|
-
return cacheEntry.promise;
|
|
7483
|
-
}
|
|
7484
|
-
const fetcher = (_c = options.fetcher) != null ? _c : globalThis.fetch;
|
|
7485
|
-
if (typeof fetcher !== "function") {
|
|
7486
|
-
return createFallbackLiteLLMPricingDataset();
|
|
7487
|
-
}
|
|
7488
|
-
const promise = fetcher(url).then(async (response) => {
|
|
7489
|
-
if (!response.ok) {
|
|
7490
|
-
throw new Error(`Failed to fetch LiteLLM pricing dataset: ${response.status} ${response.statusText}`);
|
|
7491
|
-
}
|
|
7492
|
-
const data = await response.json();
|
|
7493
|
-
if (!isLiteLLMPricingDataset(data)) {
|
|
7494
|
-
throw new Error("Invalid LiteLLM pricing dataset payload.");
|
|
7495
|
-
}
|
|
7496
|
-
const dataset = {
|
|
7497
|
-
...createFallbackLiteLLMPricingDataset(),
|
|
7498
|
-
...data
|
|
7499
|
-
};
|
|
7500
|
-
pricingCache.set(url, {
|
|
7501
|
-
fetchedAt: Date.now(),
|
|
7502
|
-
value: dataset
|
|
7503
|
-
});
|
|
7504
|
-
return dataset;
|
|
7505
|
-
}).catch(() => {
|
|
7506
|
-
const fallback = createFallbackLiteLLMPricingDataset();
|
|
7507
|
-
pricingCache.set(url, {
|
|
7508
|
-
fetchedAt: Date.now(),
|
|
7509
|
-
value: fallback
|
|
7510
|
-
});
|
|
7511
|
-
return fallback;
|
|
7512
|
-
});
|
|
7513
|
-
pricingCache.set(url, {
|
|
7514
|
-
fetchedAt: (_d = cacheEntry == null ? void 0 : cacheEntry.fetchedAt) != null ? _d : 0,
|
|
7515
|
-
promise,
|
|
7516
|
-
value: cacheEntry == null ? void 0 : cacheEntry.value
|
|
7517
|
-
});
|
|
7518
|
-
return promise;
|
|
7519
|
-
}
|
|
7520
|
-
async function createLiteLLMPricingResolver(options = {}) {
|
|
7521
|
-
var _a, _b, _c, _d;
|
|
7522
|
-
const dataset = await fetchLiteLLMPricingDataset(options);
|
|
7523
|
-
const aliases = (_a = options.aliases) != null ? _a : {};
|
|
7524
|
-
const fallbackPricingTable = {
|
|
7525
|
-
...DEFAULT_FALLBACK_PRICING_TABLE,
|
|
7526
|
-
...(_b = options.fallbackPricingTable) != null ? _b : {}
|
|
7527
|
-
};
|
|
7528
|
-
const getLookupCandidates = (_c = options.getLookupCandidates) != null ? _c : defaultLookupCandidates;
|
|
7529
|
-
const fallbackModel = options.fallbackModel;
|
|
7530
|
-
const isZeroCostModel = (_d = options.isZeroCostModel) != null ? _d : (() => false);
|
|
7531
|
-
return (model) => {
|
|
7532
|
-
var _a2, _b2;
|
|
7533
|
-
if (isZeroCostModel(model)) {
|
|
7534
|
-
return createZeroPricing();
|
|
7535
|
-
}
|
|
7536
|
-
const lookupCandidates = uniqueItems(expandLookupCandidates(model, aliases, getLookupCandidates).filter(Boolean));
|
|
7537
|
-
const datasetPricing = resolveDatasetPricing(dataset, lookupCandidates);
|
|
7538
|
-
if (datasetPricing) {
|
|
7539
|
-
return datasetPricing;
|
|
7540
|
-
}
|
|
7541
|
-
const fallbackPricing = resolveFallbackPricing(fallbackPricingTable, lookupCandidates);
|
|
7542
|
-
if (fallbackPricing) {
|
|
7543
|
-
return fallbackPricing;
|
|
7544
|
-
}
|
|
7545
|
-
if (fallbackModel) {
|
|
7546
|
-
const fallbackCandidates = uniqueItems(expandLookupCandidates(fallbackModel, aliases, getLookupCandidates).filter(Boolean));
|
|
7547
|
-
return (_b2 = (_a2 = resolveDatasetPricing(dataset, fallbackCandidates)) != null ? _a2 : resolveFallbackPricing(fallbackPricingTable, fallbackCandidates)) != null ? _b2 : createZeroPricing();
|
|
7548
|
-
}
|
|
7549
|
-
return createZeroPricing();
|
|
7550
|
-
};
|
|
7551
|
-
}
|
|
7552
|
-
function calculateUsageCostUSD(usage, pricing, options = {}) {
|
|
7553
|
-
var _a, _b;
|
|
7554
|
-
const multiplier = options.speed === "fast" ? (_a = pricing.fastMultiplier) != null ? _a : 1 : 1;
|
|
7555
|
-
const inputCost = calculateTieredCost(usage.inputTokens, pricing.inputCostPerMTokens, pricing.inputCostPerMTokensAbove200K);
|
|
7556
|
-
const cachedCost = calculateTieredCost(usage.cachedInputTokens, pricing.cachedInputCostPerMTokens, pricing.cachedInputCostPerMTokensAbove200K);
|
|
7557
|
-
const cacheCreationCost = calculateTieredCost((_b = usage.cacheCreationTokens) != null ? _b : 0, pricing.cacheCreationInputCostPerMTokens, pricing.cacheCreationInputCostPerMTokensAbove200K);
|
|
7558
|
-
const outputCost = calculateTieredCost(usage.outputTokens, pricing.outputCostPerMTokens, pricing.outputCostPerMTokensAbove200K);
|
|
7559
|
-
return (inputCost + cachedCost + cacheCreationCost + outputCost) * multiplier;
|
|
7560
|
-
}
|
|
7561
|
-
function createFallbackLiteLLMPricingDataset() {
|
|
7562
|
-
return {
|
|
7563
|
-
"gpt-5": {
|
|
7564
|
-
input_cost_per_token: 125e-8,
|
|
7565
|
-
output_cost_per_token: 1e-5,
|
|
7566
|
-
cache_creation_input_token_cost: 125e-8,
|
|
7567
|
-
cache_read_input_token_cost: 125e-9
|
|
7568
|
-
},
|
|
7569
|
-
"gpt-5.2-codex": {
|
|
7570
|
-
input_cost_per_token: 175e-8,
|
|
7571
|
-
output_cost_per_token: 14e-6,
|
|
7572
|
-
cache_creation_input_token_cost: 175e-8,
|
|
7573
|
-
cache_read_input_token_cost: 175e-9
|
|
7574
|
-
},
|
|
7575
|
-
"gpt-5.4": {
|
|
7576
|
-
input_cost_per_token: 25e-7,
|
|
7577
|
-
output_cost_per_token: 15e-6,
|
|
7578
|
-
cache_creation_input_token_cost: 25e-7,
|
|
7579
|
-
cache_read_input_token_cost: 25e-8
|
|
7580
|
-
},
|
|
7581
|
-
"claude-haiku-4-5": {
|
|
7582
|
-
input_cost_per_token: 1e-6,
|
|
7583
|
-
output_cost_per_token: 5e-6,
|
|
7584
|
-
cache_creation_input_token_cost: 125e-8,
|
|
7585
|
-
cache_read_input_token_cost: 1e-7
|
|
7586
|
-
},
|
|
7587
|
-
"claude-opus-4-1": {
|
|
7588
|
-
input_cost_per_token: 15e-6,
|
|
7589
|
-
output_cost_per_token: 75e-6,
|
|
7590
|
-
cache_creation_input_token_cost: 1875e-8,
|
|
7591
|
-
cache_read_input_token_cost: 15e-7,
|
|
7592
|
-
input_cost_per_token_above_200k_tokens: 3e-5,
|
|
7593
|
-
output_cost_per_token_above_200k_tokens: 1125e-7,
|
|
7594
|
-
cache_creation_input_token_cost_above_200k_tokens: 375e-7,
|
|
7595
|
-
cache_read_input_token_cost_above_200k_tokens: 3e-6
|
|
7596
|
-
},
|
|
7597
|
-
"claude-sonnet-4-5": {
|
|
7598
|
-
input_cost_per_token: 3e-6,
|
|
7599
|
-
output_cost_per_token: 15e-6,
|
|
7600
|
-
cache_creation_input_token_cost: 375e-8,
|
|
7601
|
-
cache_read_input_token_cost: 3e-7,
|
|
7602
|
-
input_cost_per_token_above_200k_tokens: 6e-6,
|
|
7603
|
-
output_cost_per_token_above_200k_tokens: 225e-7,
|
|
7604
|
-
cache_creation_input_token_cost_above_200k_tokens: 75e-7,
|
|
7605
|
-
cache_read_input_token_cost_above_200k_tokens: 6e-7
|
|
7606
|
-
}
|
|
7607
|
-
};
|
|
7608
|
-
}
|
|
7609
|
-
function isLiteLLMPricingDataset(value) {
|
|
7610
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
7611
|
-
return false;
|
|
7612
|
-
}
|
|
7613
|
-
return true;
|
|
7614
|
-
}
|
|
7615
|
-
function defaultLookupCandidates(model) {
|
|
7616
|
-
const normalizedModel = model.trim();
|
|
7617
|
-
return [
|
|
7618
|
-
normalizedModel,
|
|
7619
|
-
normalizedModel.replace(/^openai\//u, ""),
|
|
7620
|
-
normalizedModel.replace(/^azure\//u, ""),
|
|
7621
|
-
normalizedModel.replace(/^openrouter\/openai\//u, "")
|
|
7622
|
-
];
|
|
7623
|
-
}
|
|
7624
|
-
function expandLookupCandidates(model, aliases, getLookupCandidates) {
|
|
7625
|
-
const candidates = getLookupCandidates(model);
|
|
7626
|
-
const expanded = [...candidates];
|
|
7627
|
-
for (const candidate of candidates) {
|
|
7628
|
-
const alias = aliases[candidate];
|
|
7629
|
-
if (alias) {
|
|
7630
|
-
expanded.push(...getLookupCandidates(alias));
|
|
7631
|
-
}
|
|
7632
|
-
}
|
|
7633
|
-
return expanded;
|
|
8111
|
+
var _a, _b;
|
|
8112
|
+
return (_b = (_a = options.getReasoningOutputTokens) == null ? void 0 : _a.call(options, session)) != null ? _b : getNumericProperty(session, "reasoningOutputTokens");
|
|
7634
8113
|
}
|
|
7635
|
-
function
|
|
7636
|
-
|
|
7637
|
-
|
|
7638
|
-
|
|
7639
|
-
continue;
|
|
7640
|
-
}
|
|
7641
|
-
return toModelPricing(pricing);
|
|
7642
|
-
}
|
|
7643
|
-
return null;
|
|
8114
|
+
function getNumericProperty(value, key) {
|
|
8115
|
+
const record = value;
|
|
8116
|
+
const property = record[key];
|
|
8117
|
+
return typeof property === "number" && Number.isFinite(property) ? property : 0;
|
|
7644
8118
|
}
|
|
7645
|
-
function
|
|
7646
|
-
|
|
7647
|
-
const pricing = fallbackPricingTable[candidate];
|
|
7648
|
-
if (pricing) {
|
|
7649
|
-
return pricing;
|
|
7650
|
-
}
|
|
7651
|
-
}
|
|
7652
|
-
return null;
|
|
8119
|
+
function cloneDate(date) {
|
|
8120
|
+
return new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
|
7653
8121
|
}
|
|
7654
|
-
|
|
7655
|
-
|
|
7656
|
-
|
|
8122
|
+
|
|
8123
|
+
function toDiscoveredUsageFile(filePath, platform, cacheSignature = "") {
|
|
8124
|
+
try {
|
|
8125
|
+
const stats = statSync(filePath);
|
|
8126
|
+
return [{
|
|
8127
|
+
cacheSignature,
|
|
8128
|
+
mtimeMs: stats.mtimeMs,
|
|
8129
|
+
path: filePath,
|
|
8130
|
+
platform,
|
|
8131
|
+
size: stats.size
|
|
8132
|
+
}];
|
|
8133
|
+
} catch {
|
|
8134
|
+
return [];
|
|
8135
|
+
}
|
|
7657
8136
|
}
|
|
7658
|
-
function
|
|
7659
|
-
var _a, _b, _c, _d, _e;
|
|
7660
|
-
const inputCostPerToken = (_a = pricing.input_cost_per_token) != null ? _a : 0;
|
|
7661
|
-
const cachedInputCostPerToken = (_b = pricing.cache_read_input_token_cost) != null ? _b : inputCostPerToken;
|
|
7662
|
-
const cacheCreationInputCostPerToken = (_c = pricing.cache_creation_input_token_cost) != null ? _c : inputCostPerToken;
|
|
7663
|
-
const outputCostPerToken = (_d = pricing.output_cost_per_token) != null ? _d : 0;
|
|
8137
|
+
function createSessionFragment(options) {
|
|
7664
8138
|
return {
|
|
7665
|
-
|
|
7666
|
-
|
|
7667
|
-
|
|
7668
|
-
|
|
7669
|
-
|
|
7670
|
-
|
|
7671
|
-
|
|
7672
|
-
|
|
7673
|
-
outputCostPerMTokensAbove200K: pricing.output_cost_per_token_above_200k_tokens != null ? pricing.output_cost_per_token_above_200k_tokens * MILLION : void 0
|
|
8139
|
+
durationEndAt: "",
|
|
8140
|
+
interactions: [],
|
|
8141
|
+
key: getSessionLookupKey(options.repository, options.sessionId),
|
|
8142
|
+
project: options.project,
|
|
8143
|
+
repository: options.repository,
|
|
8144
|
+
sessionId: options.sessionId,
|
|
8145
|
+
startedAt: options.startedAt,
|
|
8146
|
+
threadName: options.threadName
|
|
7674
8147
|
};
|
|
7675
8148
|
}
|
|
7676
|
-
function
|
|
7677
|
-
|
|
7678
|
-
|
|
7679
|
-
|
|
7680
|
-
|
|
7681
|
-
|
|
7682
|
-
|
|
8149
|
+
function addFragmentInteraction(fragment, interaction) {
|
|
8150
|
+
fragment.interactions.push(interaction);
|
|
8151
|
+
if (!interaction.timestamp) {
|
|
8152
|
+
return;
|
|
8153
|
+
}
|
|
8154
|
+
if (!fragment.startedAt || Date.parse(interaction.timestamp) < Date.parse(fragment.startedAt)) {
|
|
8155
|
+
fragment.startedAt = interaction.timestamp;
|
|
8156
|
+
}
|
|
8157
|
+
if (!fragment.durationEndAt || Date.parse(interaction.timestamp) > Date.parse(fragment.durationEndAt)) {
|
|
8158
|
+
fragment.durationEndAt = interaction.timestamp;
|
|
8159
|
+
}
|
|
7683
8160
|
}
|
|
7684
|
-
function
|
|
7685
|
-
|
|
7686
|
-
|
|
7687
|
-
|
|
8161
|
+
function getSessionLookupKey(project, sessionId) {
|
|
8162
|
+
return `${project}:${sessionId}`;
|
|
8163
|
+
}
|
|
8164
|
+
function normalizeRole(value) {
|
|
8165
|
+
const normalized = value.toLowerCase();
|
|
8166
|
+
if (normalized.includes("user")) {
|
|
8167
|
+
return "user";
|
|
7688
8168
|
}
|
|
7689
|
-
if (
|
|
7690
|
-
return
|
|
8169
|
+
if (normalized.includes("assistant") || normalized.includes("agent") || normalized.includes("gemini")) {
|
|
8170
|
+
return "assistant";
|
|
7691
8171
|
}
|
|
7692
|
-
|
|
8172
|
+
if (normalized.includes("system")) {
|
|
8173
|
+
return "system";
|
|
8174
|
+
}
|
|
8175
|
+
if (normalized.includes("tool")) {
|
|
8176
|
+
return "tool";
|
|
8177
|
+
}
|
|
8178
|
+
if (normalized.includes("token") || normalized.includes("usage")) {
|
|
8179
|
+
return "usage";
|
|
8180
|
+
}
|
|
8181
|
+
return "unknown";
|
|
7693
8182
|
}
|
|
7694
8183
|
|
|
7695
8184
|
const ZERO_PRICING = {
|
|
@@ -7702,12 +8191,7 @@ async function createZeroPricingResolver() {
|
|
|
7702
8191
|
return () => ZERO_PRICING;
|
|
7703
8192
|
}
|
|
7704
8193
|
function applyTotalUsageFallback(usage) {
|
|
7705
|
-
const cacheCreationTokens =
|
|
7706
|
-
const cacheReadTokens = normalizeUsageNumber(usage.cacheReadTokens);
|
|
7707
|
-
const inputTokens = normalizeUsageNumber(usage.inputTokens);
|
|
7708
|
-
const outputTokens = normalizeUsageNumber(usage.outputTokens);
|
|
7709
|
-
const totalTokens = normalizeUsageNumber(usage.totalTokens);
|
|
7710
|
-
const baseTokens = inputTokens + outputTokens + cacheCreationTokens + cacheReadTokens;
|
|
8194
|
+
const { baseTokens, cacheCreationTokens, cacheReadTokens, inputTokens, outputTokens, totalTokens } = readUsageParts(usage);
|
|
7711
8195
|
if (baseTokens === 0 && totalTokens > 0) {
|
|
7712
8196
|
return {
|
|
7713
8197
|
cacheCreationTokens,
|
|
@@ -7729,6 +8213,29 @@ function applyTotalUsageFallback(usage) {
|
|
|
7729
8213
|
reasoningOutputTokens
|
|
7730
8214
|
};
|
|
7731
8215
|
}
|
|
8216
|
+
function applyTotalUsageAsExtra(usage) {
|
|
8217
|
+
const { baseTokens, cacheCreationTokens, cacheReadTokens, inputTokens, outputTokens, totalTokens } = readUsageParts(usage);
|
|
8218
|
+
if (baseTokens === 0 && totalTokens > 0) {
|
|
8219
|
+
return {
|
|
8220
|
+
cacheCreationTokens,
|
|
8221
|
+
cacheReadTokens,
|
|
8222
|
+
inputTokens,
|
|
8223
|
+
outputTokens: totalTokens,
|
|
8224
|
+
extraTotalTokens: 0
|
|
8225
|
+
};
|
|
8226
|
+
}
|
|
8227
|
+
const extraTotalTokens = Math.max(
|
|
8228
|
+
normalizeUsageNumber(usage.extraTotalTokens),
|
|
8229
|
+
totalTokens > baseTokens ? totalTokens - baseTokens : 0
|
|
8230
|
+
);
|
|
8231
|
+
return {
|
|
8232
|
+
cacheCreationTokens,
|
|
8233
|
+
cacheReadTokens,
|
|
8234
|
+
inputTokens,
|
|
8235
|
+
outputTokens,
|
|
8236
|
+
extraTotalTokens
|
|
8237
|
+
};
|
|
8238
|
+
}
|
|
7732
8239
|
function toInteractionUsage(usage) {
|
|
7733
8240
|
var _a;
|
|
7734
8241
|
const cacheCreationTokens = normalizeUsageNumber(usage.cacheCreationTokens);
|
|
@@ -7736,13 +8243,15 @@ function toInteractionUsage(usage) {
|
|
|
7736
8243
|
const inputTokens = normalizeUsageNumber(usage.inputTokens);
|
|
7737
8244
|
const outputTokens = normalizeUsageNumber(usage.outputTokens);
|
|
7738
8245
|
const reasoningOutputTokens = normalizeUsageNumber(usage.reasoningOutputTokens);
|
|
8246
|
+
const extraTotalTokens = normalizeUsageNumber(usage.extraTotalTokens);
|
|
7739
8247
|
const toolTokens = normalizeUsageNumber(usage.toolTokens);
|
|
7740
|
-
const totalTokens = inputTokens + outputTokens + cacheCreationTokens + cacheReadTokens + reasoningOutputTokens + toolTokens;
|
|
8248
|
+
const totalTokens = inputTokens + outputTokens + cacheCreationTokens + cacheReadTokens + reasoningOutputTokens + extraTotalTokens + toolTokens;
|
|
7741
8249
|
return {
|
|
7742
8250
|
cacheCreationTokens,
|
|
7743
8251
|
cacheReadTokens,
|
|
7744
8252
|
cachedInputTokens: cacheCreationTokens + cacheReadTokens,
|
|
7745
8253
|
costUSD: (_a = usage.costUSD) != null ? _a : 0,
|
|
8254
|
+
extraTotalTokens: extraTotalTokens > 0 ? extraTotalTokens : void 0,
|
|
7746
8255
|
inputTokens,
|
|
7747
8256
|
isFallbackModel: usage.isFallbackModel,
|
|
7748
8257
|
outputTokens,
|
|
@@ -7752,15 +8261,15 @@ function toInteractionUsage(usage) {
|
|
|
7752
8261
|
};
|
|
7753
8262
|
}
|
|
7754
8263
|
function isZeroInteractionUsage(usage) {
|
|
7755
|
-
var _a;
|
|
7756
|
-
return usage.totalTokens <= 0 && usage.inputTokens <= 0 && usage.cachedInputTokens <= 0 && usage.outputTokens <= 0 && usage.reasoningOutputTokens <= 0 && ((_a = usage.
|
|
8264
|
+
var _a, _b;
|
|
8265
|
+
return usage.totalTokens <= 0 && usage.inputTokens <= 0 && usage.cachedInputTokens <= 0 && usage.outputTokens <= 0 && usage.reasoningOutputTokens <= 0 && ((_a = usage.extraTotalTokens) != null ? _a : 0) <= 0 && ((_b = usage.toolTokens) != null ? _b : 0) <= 0;
|
|
7757
8266
|
}
|
|
7758
8267
|
function calculateUsageCostFromCandidates(usage, candidates, resolvePricing, options = {}) {
|
|
7759
|
-
var _a, _b;
|
|
7760
|
-
const outputTokens = usage.outputTokens + ((_a = usage.
|
|
8268
|
+
var _a, _b, _c;
|
|
8269
|
+
const outputTokens = usage.outputTokens + (options.includeExtraTotalAsOutput === false ? 0 : (_a = usage.extraTotalTokens) != null ? _a : 0) + ((_b = usage.toolTokens) != null ? _b : 0) + (options.includeReasoningAsOutput === false ? 0 : usage.reasoningOutputTokens);
|
|
7761
8270
|
for (const candidate of uniqueItems(candidates.map((candidate2) => candidate2.trim()).filter(Boolean))) {
|
|
7762
8271
|
const costUSD = calculateUsageCostUSD({
|
|
7763
|
-
cacheCreationTokens: (
|
|
8272
|
+
cacheCreationTokens: (_c = usage.cacheCreationTokens) != null ? _c : 0,
|
|
7764
8273
|
cachedInputTokens: usage.cachedInputTokens,
|
|
7765
8274
|
inputTokens: usage.inputTokens,
|
|
7766
8275
|
outputTokens
|
|
@@ -7781,17 +8290,34 @@ function getFileModifiedAtIso(filePath) {
|
|
|
7781
8290
|
function normalizeUsageNumber(value) {
|
|
7782
8291
|
return Number.isFinite(value) && value > 0 ? Math.trunc(value) : 0;
|
|
7783
8292
|
}
|
|
8293
|
+
function readUsageParts(usage) {
|
|
8294
|
+
const cacheCreationTokens = normalizeUsageNumber(usage.cacheCreationTokens);
|
|
8295
|
+
const cacheReadTokens = normalizeUsageNumber(usage.cacheReadTokens);
|
|
8296
|
+
const inputTokens = normalizeUsageNumber(usage.inputTokens);
|
|
8297
|
+
const outputTokens = normalizeUsageNumber(usage.outputTokens);
|
|
8298
|
+
const totalTokens = normalizeUsageNumber(usage.totalTokens);
|
|
8299
|
+
return {
|
|
8300
|
+
baseTokens: inputTokens + outputTokens + cacheCreationTokens + cacheReadTokens,
|
|
8301
|
+
cacheCreationTokens,
|
|
8302
|
+
cacheReadTokens,
|
|
8303
|
+
inputTokens,
|
|
8304
|
+
outputTokens,
|
|
8305
|
+
totalTokens
|
|
8306
|
+
};
|
|
8307
|
+
}
|
|
7784
8308
|
|
|
7785
8309
|
const ampUsageAdapter = {
|
|
7786
|
-
createPricingResolver
|
|
8310
|
+
async createPricingResolver() {
|
|
8311
|
+
return createLiteLLMPricingResolver();
|
|
8312
|
+
},
|
|
7787
8313
|
async discoverFiles(config) {
|
|
7788
8314
|
const groups = await Promise.all(config.ampPaths.map((path) => glob(join(path, "threads", "**", "*.json"), {
|
|
7789
8315
|
absolute: true
|
|
7790
8316
|
}).catch(() => [])));
|
|
7791
8317
|
return groups.flat().flatMap((filePath) => toDiscoveredUsageFile(filePath, "amp"));
|
|
7792
8318
|
},
|
|
7793
|
-
parseFile(filePath) {
|
|
7794
|
-
var _a, _b
|
|
8319
|
+
parseFile(filePath, resolvePricing) {
|
|
8320
|
+
var _a, _b;
|
|
7795
8321
|
const data = parseJsonFile(filePath);
|
|
7796
8322
|
const record = normalizeUnknownRecord(data);
|
|
7797
8323
|
const sessionId = normalizeStringValue(record == null ? void 0 : record.id) || basename$1(filePath, ".json");
|
|
@@ -7820,27 +8346,32 @@ const ampUsageAdapter = {
|
|
|
7820
8346
|
const messageId = Number.isFinite(event.toMessageId) ? Number(event.toMessageId) : null;
|
|
7821
8347
|
const [cacheCreationTokens = 0, cacheReadTokens = 0] = messageId != null ? (_b = cacheTokensByMessageId.get(messageId)) != null ? _b : [0, 0] : [0, 0];
|
|
7822
8348
|
const usage = toInteractionUsage({
|
|
7823
|
-
...
|
|
8349
|
+
...applyTotalUsageAsExtra({
|
|
7824
8350
|
cacheCreationTokens,
|
|
7825
8351
|
cacheReadTokens,
|
|
7826
8352
|
inputTokens: getNumber$8(tokens.input),
|
|
7827
8353
|
outputTokens: getNumber$8(tokens.output),
|
|
7828
8354
|
totalTokens: getNumber$8(tokens.total)
|
|
7829
|
-
})
|
|
7830
|
-
costUSD: (_c = normalizeFiniteNumberOrNull(event.credits)) != null ? _c : 0
|
|
8355
|
+
})
|
|
7831
8356
|
});
|
|
7832
8357
|
if (isZeroInteractionUsage(usage)) {
|
|
7833
8358
|
continue;
|
|
7834
8359
|
}
|
|
8360
|
+
const costUSD = calculateUsageCostFromCandidates(usage, [model], resolvePricing, {
|
|
8361
|
+
includeExtraTotalAsOutput: true
|
|
8362
|
+
});
|
|
7835
8363
|
addFragmentInteraction(fragment, {
|
|
7836
8364
|
content: "",
|
|
7837
|
-
costUSD
|
|
8365
|
+
costUSD,
|
|
7838
8366
|
index,
|
|
7839
8367
|
model,
|
|
7840
8368
|
role: "usage",
|
|
7841
8369
|
timestamp,
|
|
7842
8370
|
type: "usage_ledger",
|
|
7843
|
-
usage
|
|
8371
|
+
usage: toInteractionUsage({
|
|
8372
|
+
...usage,
|
|
8373
|
+
costUSD
|
|
8374
|
+
})
|
|
7844
8375
|
});
|
|
7845
8376
|
}
|
|
7846
8377
|
return fragment.interactions.length > 0 ? [fragment] : [];
|
|
@@ -7871,7 +8402,6 @@ function getNumber$8(value) {
|
|
|
7871
8402
|
return typeof value === "number" && Number.isFinite(value) ? Math.max(0, Math.trunc(value)) : 0;
|
|
7872
8403
|
}
|
|
7873
8404
|
|
|
7874
|
-
const CLAUDE_FALLBACK_MODEL = "claude-sonnet-4-5";
|
|
7875
8405
|
const CODEX_FALLBACK_MODEL = "gpt-5";
|
|
7876
8406
|
const GEMINI_FALLBACK_MODEL = "gemini-2.5-flash";
|
|
7877
8407
|
const CLAUDE_MODEL_ALIASES = {
|
|
@@ -7929,11 +8459,11 @@ const GEMINI_FALLBACK_PRICING_TABLE = {
|
|
|
7929
8459
|
}
|
|
7930
8460
|
};
|
|
7931
8461
|
|
|
8462
|
+
const CLAUDE_CODE_CACHE_SIGNATURE = "claude-code-dedupe:message-id-v1";
|
|
7932
8463
|
const claudeCodeUsageAdapter = {
|
|
7933
8464
|
async createPricingResolver() {
|
|
7934
8465
|
return createLiteLLMPricingResolver({
|
|
7935
8466
|
aliases: CLAUDE_MODEL_ALIASES,
|
|
7936
|
-
fallbackModel: CLAUDE_FALLBACK_MODEL,
|
|
7937
8467
|
getLookupCandidates: getClaudeLookupCandidates
|
|
7938
8468
|
});
|
|
7939
8469
|
},
|
|
@@ -7949,7 +8479,7 @@ const claudeCodeUsageAdapter = {
|
|
|
7949
8479
|
absolute: true
|
|
7950
8480
|
}).catch(() => []);
|
|
7951
8481
|
}));
|
|
7952
|
-
return fileGroups.flat().flatMap((filePath) => toDiscoveredUsageFile(filePath, "claudeCode"));
|
|
8482
|
+
return fileGroups.flat().flatMap((filePath) => toDiscoveredUsageFile(filePath, "claudeCode", CLAUDE_CODE_CACHE_SIGNATURE));
|
|
7953
8483
|
},
|
|
7954
8484
|
parseFile(filePath, resolvePricing) {
|
|
7955
8485
|
var _a, _b, _c, _d;
|
|
@@ -7959,6 +8489,9 @@ const claudeCodeUsageAdapter = {
|
|
|
7959
8489
|
const fragments = /* @__PURE__ */ new Map();
|
|
7960
8490
|
for (let index = 0; index < lines.length; index += 1) {
|
|
7961
8491
|
const line = lines[index];
|
|
8492
|
+
if (!isSupportedClaudeUsageLine(line)) {
|
|
8493
|
+
continue;
|
|
8494
|
+
}
|
|
7962
8495
|
const sessionId = normalizeStringValue(line.sessionId) || fallbackSessionId;
|
|
7963
8496
|
const cwd = (_a = normalizeStringValue(line.cwd)) != null ? _a : "";
|
|
7964
8497
|
const project = getProjectName(cwd, "") || decodeClaudeProjectPath(projectPath);
|
|
@@ -8032,7 +8565,7 @@ function getClaudeUniqueHash(line) {
|
|
|
8032
8565
|
const message = normalizeUnknownRecord(line.message);
|
|
8033
8566
|
const messageId = normalizeStringValue(message == null ? void 0 : message.id);
|
|
8034
8567
|
const requestId = normalizeStringValue(line.requestId);
|
|
8035
|
-
return messageId
|
|
8568
|
+
return messageId ? `${messageId}:${requestId != null ? requestId : ""}` : null;
|
|
8036
8569
|
}
|
|
8037
8570
|
function extractClaudeMessageText(content) {
|
|
8038
8571
|
if (typeof content === "string") {
|
|
@@ -8050,6 +8583,31 @@ function getInteractionRole(line, message) {
|
|
|
8050
8583
|
const role = normalizeStringValue(line.type) || normalizeStringValue(message == null ? void 0 : message.role) || normalizeStringValue(message == null ? void 0 : message.type) || "";
|
|
8051
8584
|
return normalizeRole(role);
|
|
8052
8585
|
}
|
|
8586
|
+
function isSupportedClaudeUsageLine(line) {
|
|
8587
|
+
const message = normalizeUnknownRecord(line.message);
|
|
8588
|
+
const usage = normalizeUnknownRecord(message == null ? void 0 : message.usage);
|
|
8589
|
+
if (hasUnsupportedClaudeNullField(line, message, usage)) {
|
|
8590
|
+
return false;
|
|
8591
|
+
}
|
|
8592
|
+
const version = normalizeStringValue(line.version);
|
|
8593
|
+
if (version && !/^\d+\.\d+\.\d+/u.test(version)) {
|
|
8594
|
+
return false;
|
|
8595
|
+
}
|
|
8596
|
+
return !hasEmptyClaudeField(line, message);
|
|
8597
|
+
}
|
|
8598
|
+
function hasUnsupportedClaudeNullField(line, message, usage) {
|
|
8599
|
+
return line.cwd === null || line.costUSD === null || line.version === null || line.sessionId === null || line.requestId === null || line.isApiErrorMessage === null || (message == null ? void 0 : message.id) === null || (message == null ? void 0 : message.model) === null || (usage == null ? void 0 : usage.speed) === null || (usage == null ? void 0 : usage.cache_read_input_tokens) === null || (usage == null ? void 0 : usage.cache_creation_input_tokens) === null;
|
|
8600
|
+
}
|
|
8601
|
+
function hasEmptyClaudeField(line, message) {
|
|
8602
|
+
const candidates = [
|
|
8603
|
+
line.sessionId,
|
|
8604
|
+
line.requestId,
|
|
8605
|
+
line.version,
|
|
8606
|
+
message == null ? void 0 : message.id,
|
|
8607
|
+
message == null ? void 0 : message.model
|
|
8608
|
+
];
|
|
8609
|
+
return candidates.some((value) => typeof value === "string" && value.trim() === "");
|
|
8610
|
+
}
|
|
8053
8611
|
|
|
8054
8612
|
const CODEBUFF_DEFAULT_MODEL = "codebuff-unknown";
|
|
8055
8613
|
const codebuffUsageAdapter = {
|
|
@@ -8090,41 +8648,38 @@ const codebuffUsageAdapter = {
|
|
|
8090
8648
|
}
|
|
8091
8649
|
const model = extracted.model || CODEBUFF_DEFAULT_MODEL;
|
|
8092
8650
|
const usage = toInteractionUsage({
|
|
8093
|
-
...
|
|
8651
|
+
...applyTotalUsageAsExtra({
|
|
8094
8652
|
cacheCreationTokens: extracted.cacheCreationTokens,
|
|
8095
8653
|
cacheReadTokens: extracted.cacheReadTokens,
|
|
8654
|
+
extraTotalTokens: extracted.extraTotalTokens,
|
|
8096
8655
|
inputTokens: extracted.inputTokens,
|
|
8097
8656
|
outputTokens: extracted.outputTokens,
|
|
8098
8657
|
totalTokens: extracted.totalTokens
|
|
8099
|
-
})
|
|
8100
|
-
costUSD: extracted.credits > 0 ? extracted.credits : calculateUsageCostFromCandidates(
|
|
8101
|
-
toInteractionUsage({
|
|
8102
|
-
...applyTotalUsageFallback({
|
|
8103
|
-
cacheCreationTokens: extracted.cacheCreationTokens,
|
|
8104
|
-
cacheReadTokens: extracted.cacheReadTokens,
|
|
8105
|
-
inputTokens: extracted.inputTokens,
|
|
8106
|
-
outputTokens: extracted.outputTokens,
|
|
8107
|
-
totalTokens: extracted.totalTokens
|
|
8108
|
-
})
|
|
8109
|
-
}),
|
|
8110
|
-
getCodebuffCandidates(model, inferCodebuffProvider(model)),
|
|
8111
|
-
resolvePricing
|
|
8112
|
-
)
|
|
8658
|
+
})
|
|
8113
8659
|
});
|
|
8114
8660
|
if (isZeroInteractionUsage(usage)) {
|
|
8115
8661
|
continue;
|
|
8116
8662
|
}
|
|
8663
|
+
const costUSD = calculateUsageCostFromCandidates(
|
|
8664
|
+
usage,
|
|
8665
|
+
getCodebuffCandidates(model, inferCodebuffProvider(model)),
|
|
8666
|
+
resolvePricing,
|
|
8667
|
+
{ includeExtraTotalAsOutput: true, includeReasoningAsOutput: false }
|
|
8668
|
+
);
|
|
8117
8669
|
const timestamp = (_a = getCodebuffMessageTimestamp(message)) != null ? _a : fallbackTimestamp;
|
|
8118
8670
|
addFragmentInteraction(fragment, {
|
|
8119
8671
|
content: "",
|
|
8120
|
-
costUSD
|
|
8672
|
+
costUSD,
|
|
8121
8673
|
dedupeKey: getCodebuffDedupeKey(message, sessionId, timestamp != null ? timestamp : "", model, usage, index),
|
|
8122
8674
|
index,
|
|
8123
8675
|
model,
|
|
8124
8676
|
role: "assistant",
|
|
8125
8677
|
timestamp,
|
|
8126
8678
|
type: normalizeStringValue(message.variant) || normalizeStringValue(message.role) || "assistant",
|
|
8127
|
-
usage
|
|
8679
|
+
usage: toInteractionUsage({
|
|
8680
|
+
...usage,
|
|
8681
|
+
costUSD
|
|
8682
|
+
})
|
|
8128
8683
|
});
|
|
8129
8684
|
}
|
|
8130
8685
|
return fragment.interactions.length > 0 ? [fragment] : [];
|
|
@@ -8195,7 +8750,7 @@ function parseCodebuffUsageRecord(value) {
|
|
|
8195
8750
|
if (!record) {
|
|
8196
8751
|
return null;
|
|
8197
8752
|
}
|
|
8198
|
-
const raw =
|
|
8753
|
+
const raw = applyTotalUsageAsExtra({
|
|
8199
8754
|
cacheCreationTokens: pickUsageNumber(record, ["cacheCreationInputTokens", "cache_creation_input_tokens", "cacheCreationTokens", "cache_creation_tokens", "cachedTokensCreated", "cached_tokens_created"]),
|
|
8200
8755
|
cacheReadTokens: Math.max(
|
|
8201
8756
|
pickUsageNumber(record, ["cacheReadInputTokens", "cache_read_input_tokens"]),
|
|
@@ -8210,10 +8765,11 @@ function parseCodebuffUsageRecord(value) {
|
|
|
8210
8765
|
cacheCreationTokens: raw.cacheCreationTokens,
|
|
8211
8766
|
cacheReadTokens: raw.cacheReadTokens,
|
|
8212
8767
|
credits: getFiniteNumber(record.credits),
|
|
8768
|
+
extraTotalTokens: raw.extraTotalTokens,
|
|
8213
8769
|
inputTokens: raw.inputTokens,
|
|
8214
8770
|
model: (_a = normalizeStringValue(record.model)) != null ? _a : null,
|
|
8215
8771
|
outputTokens: raw.outputTokens,
|
|
8216
|
-
totalTokens: raw.inputTokens + raw.outputTokens + raw.cacheCreationTokens + raw.cacheReadTokens + raw.
|
|
8772
|
+
totalTokens: raw.inputTokens + raw.outputTokens + raw.cacheCreationTokens + raw.cacheReadTokens + raw.extraTotalTokens
|
|
8217
8773
|
};
|
|
8218
8774
|
}
|
|
8219
8775
|
function emptyCodebuffUsage() {
|
|
@@ -8221,6 +8777,7 @@ function emptyCodebuffUsage() {
|
|
|
8221
8777
|
cacheCreationTokens: 0,
|
|
8222
8778
|
cacheReadTokens: 0,
|
|
8223
8779
|
credits: 0,
|
|
8780
|
+
extraTotalTokens: 0,
|
|
8224
8781
|
inputTokens: 0,
|
|
8225
8782
|
model: null,
|
|
8226
8783
|
outputTokens: 0,
|
|
@@ -8243,6 +8800,9 @@ function mergeCodebuffUsage(target, fallback) {
|
|
|
8243
8800
|
if (target.cacheReadTokens === 0) {
|
|
8244
8801
|
target.cacheReadTokens = fallback.cacheReadTokens;
|
|
8245
8802
|
}
|
|
8803
|
+
if (target.extraTotalTokens === 0) {
|
|
8804
|
+
target.extraTotalTokens = fallback.extraTotalTokens;
|
|
8805
|
+
}
|
|
8246
8806
|
if (target.totalTokens === 0) {
|
|
8247
8807
|
target.totalTokens = fallback.totalTokens;
|
|
8248
8808
|
}
|
|
@@ -8254,7 +8814,7 @@ function mergeCodebuffUsage(target, fallback) {
|
|
|
8254
8814
|
}
|
|
8255
8815
|
}
|
|
8256
8816
|
function hasCodebuffSignal(usage) {
|
|
8257
|
-
return usage.inputTokens > 0 || usage.outputTokens > 0 || usage.cacheCreationTokens > 0 || usage.cacheReadTokens > 0 || usage.totalTokens > 0 || usage.credits > 0;
|
|
8817
|
+
return usage.inputTokens > 0 || usage.outputTokens > 0 || usage.cacheCreationTokens > 0 || usage.cacheReadTokens > 0 || usage.extraTotalTokens > 0 || usage.totalTokens > 0 || usage.credits > 0;
|
|
8258
8818
|
}
|
|
8259
8819
|
function getCodebuffMessageTimestamp(message) {
|
|
8260
8820
|
var _a;
|
|
@@ -8294,6 +8854,7 @@ function getCodebuffCandidates(model, provider) {
|
|
|
8294
8854
|
return provider !== "unknown" && !model.startsWith(`${provider}/`) ? [model, `${provider}/${model}`] : [model];
|
|
8295
8855
|
}
|
|
8296
8856
|
function getCodebuffDedupeKey(message, sessionId, timestamp, model, usage, index) {
|
|
8857
|
+
var _a, _b, _c;
|
|
8297
8858
|
const messageId = normalizeStringValue(message.id);
|
|
8298
8859
|
if (messageId) {
|
|
8299
8860
|
return `codebuff:${sessionId}:${messageId}`;
|
|
@@ -8306,8 +8867,9 @@ function getCodebuffDedupeKey(message, sessionId, timestamp, model, usage, index
|
|
|
8306
8867
|
String(index),
|
|
8307
8868
|
String(usage.inputTokens),
|
|
8308
8869
|
String(usage.outputTokens),
|
|
8309
|
-
String(usage.
|
|
8310
|
-
String(usage.
|
|
8870
|
+
String((_a = usage.cacheReadTokens) != null ? _a : 0),
|
|
8871
|
+
String((_b = usage.cacheCreationTokens) != null ? _b : 0),
|
|
8872
|
+
String((_c = usage.extraTotalTokens) != null ? _c : 0)
|
|
8311
8873
|
].join(":");
|
|
8312
8874
|
}
|
|
8313
8875
|
function pickUsageNumber(record, keys) {
|
|
@@ -8321,11 +8883,12 @@ function getFiniteNumber(value) {
|
|
|
8321
8883
|
return typeof value === "number" && Number.isFinite(value) ? Math.max(0, Math.trunc(value)) : 0;
|
|
8322
8884
|
}
|
|
8323
8885
|
|
|
8886
|
+
const CODEX_DEFAULT_FAST_MULTIPLIER = 2;
|
|
8887
|
+
const CODEX_SPEED_CACHE_PREFIX = "codex-speed:";
|
|
8324
8888
|
const codexUsageAdapter = {
|
|
8325
8889
|
async createPricingResolver() {
|
|
8326
8890
|
return createLiteLLMPricingResolver({
|
|
8327
8891
|
aliases: CODEX_MODEL_ALIASES,
|
|
8328
|
-
fallbackModel: CODEX_FALLBACK_MODEL,
|
|
8329
8892
|
isZeroCostModel: isOpenRouterFreeModel
|
|
8330
8893
|
});
|
|
8331
8894
|
},
|
|
@@ -8338,16 +8901,17 @@ const codexUsageAdapter = {
|
|
|
8338
8901
|
absolute: true,
|
|
8339
8902
|
cwd: sessionsDir
|
|
8340
8903
|
});
|
|
8341
|
-
|
|
8904
|
+
const cacheSignature = getCodexConfigSignature(config.codexPath);
|
|
8905
|
+
return files.flatMap((filePath) => toDiscoveredUsageFile(filePath, "codex", cacheSignature));
|
|
8342
8906
|
},
|
|
8343
|
-
parseFile(filePath, resolvePricing) {
|
|
8344
|
-
var _a, _b, _c, _d, _e, _f, _g, _h
|
|
8907
|
+
parseFile(filePath, resolvePricing, file) {
|
|
8908
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
8345
8909
|
const lines = parseJsonlFile(filePath);
|
|
8346
|
-
const sessionMeta = (_a = lines.find((line) => line.type === "session_meta")) == null ? void 0 : _a.payload;
|
|
8910
|
+
const sessionMeta = normalizeUnknownRecord((_a = lines.find((line) => normalizeStringValue(line.type) === "session_meta")) == null ? void 0 : _a.payload);
|
|
8347
8911
|
const sessionId = getSessionId(filePath, normalizeStringValue(sessionMeta == null ? void 0 : sessionMeta.id));
|
|
8348
|
-
const startedAt = (_c =
|
|
8912
|
+
const startedAt = (_c = (_b = getCodexTimestamp(sessionMeta)) != null ? _b : lines.map((line) => getCodexTimestamp(line)).find(Boolean)) != null ? _c : getFileModifiedAtIso(filePath);
|
|
8349
8913
|
const project = getProjectName((_d = normalizeStringValue(sessionMeta == null ? void 0 : sessionMeta.cwd)) != null ? _d : "");
|
|
8350
|
-
const repository = normalizeRepositoryUrl((_e = sessionMeta == null ? void 0 : sessionMeta.git) == null ? void 0 : _e.repository_url) || `local/${project}`;
|
|
8914
|
+
const repository = normalizeRepositoryUrl(normalizeStringValue((_e = normalizeUnknownRecord(sessionMeta == null ? void 0 : sessionMeta.git)) == null ? void 0 : _e.repository_url)) || `local/${project}`;
|
|
8351
8915
|
const fragment = createSessionFragment({
|
|
8352
8916
|
project,
|
|
8353
8917
|
repository,
|
|
@@ -8355,26 +8919,28 @@ const codexUsageAdapter = {
|
|
|
8355
8919
|
startedAt,
|
|
8356
8920
|
threadName: `Session for ${project}`
|
|
8357
8921
|
});
|
|
8922
|
+
const speed = getCodexSpeedFromSignature(file.cacheSignature);
|
|
8358
8923
|
let previousTotals = null;
|
|
8359
8924
|
let currentModel;
|
|
8360
8925
|
let currentModelIsFallback = false;
|
|
8361
8926
|
for (let index = 0; index < lines.length; index += 1) {
|
|
8362
8927
|
const line = lines[index];
|
|
8363
|
-
|
|
8364
|
-
|
|
8928
|
+
const payload = normalizeUnknownRecord(line.payload);
|
|
8929
|
+
if (normalizeStringValue(line.type) === "turn_context") {
|
|
8930
|
+
const contextModel = extractModelName(payload);
|
|
8365
8931
|
if (contextModel) {
|
|
8366
8932
|
currentModel = contextModel;
|
|
8367
8933
|
currentModelIsFallback = false;
|
|
8368
8934
|
}
|
|
8369
8935
|
}
|
|
8370
|
-
const timestamp = (
|
|
8371
|
-
const extractedModel =
|
|
8936
|
+
const timestamp = (_f = getCodexTimestamp(line)) != null ? _f : getFileModifiedAtIso(filePath);
|
|
8937
|
+
const extractedModel = extractCodexModel(line);
|
|
8372
8938
|
if (extractedModel) {
|
|
8373
8939
|
currentModel = extractedModel;
|
|
8374
8940
|
currentModelIsFallback = false;
|
|
8375
8941
|
}
|
|
8376
8942
|
const rawUsage = getCodexRawUsage(line, previousTotals);
|
|
8377
|
-
const totalUsage = normalizeRawUsage((
|
|
8943
|
+
const totalUsage = normalizeRawUsage((_g = normalizeUnknownRecord(payload == null ? void 0 : payload.info)) == null ? void 0 : _g.total_token_usage);
|
|
8378
8944
|
if (totalUsage) {
|
|
8379
8945
|
previousTotals = totalUsage;
|
|
8380
8946
|
}
|
|
@@ -8388,65 +8954,234 @@ const codexUsageAdapter = {
|
|
|
8388
8954
|
} else if (!extractedModel && currentModelIsFallback) {
|
|
8389
8955
|
isFallbackModel = true;
|
|
8390
8956
|
}
|
|
8391
|
-
const usage = rawUsage ? getCodexInteractionUsage(rawUsage, model != null ? model : CODEX_FALLBACK_MODEL, resolvePricing) : null;
|
|
8957
|
+
const usage = rawUsage ? getCodexInteractionUsage(rawUsage, model != null ? model : CODEX_FALLBACK_MODEL, resolvePricing, speed) : null;
|
|
8392
8958
|
addFragmentInteraction(fragment, {
|
|
8393
8959
|
content: extractCodexContent(line),
|
|
8394
|
-
costUSD: (
|
|
8960
|
+
costUSD: (_h = usage == null ? void 0 : usage.costUSD) != null ? _h : 0,
|
|
8961
|
+
dedupeKey: usage && timestamp ? getCodexDedupeKey(timestamp, model != null ? model : CODEX_FALLBACK_MODEL, usage) : null,
|
|
8395
8962
|
index,
|
|
8396
8963
|
model: model != null ? model : null,
|
|
8397
|
-
role: getCodexRole(line),
|
|
8964
|
+
role: getCodexRole(line, rawUsage !== null),
|
|
8398
8965
|
timestamp,
|
|
8399
|
-
type: (
|
|
8966
|
+
type: normalizeStringValue(payload == null ? void 0 : payload.type) || normalizeStringValue(line.type) || "event",
|
|
8400
8967
|
usage: usage ? { ...usage, isFallbackModel } : null
|
|
8401
8968
|
});
|
|
8402
8969
|
}
|
|
8403
8970
|
return [fragment];
|
|
8404
8971
|
},
|
|
8405
8972
|
watchPatterns(config) {
|
|
8406
|
-
return [
|
|
8973
|
+
return [
|
|
8974
|
+
join(config.codexPath, "config.toml"),
|
|
8975
|
+
join(config.codexPath, "sessions", "**", "*.jsonl")
|
|
8976
|
+
];
|
|
8407
8977
|
}
|
|
8408
8978
|
};
|
|
8409
8979
|
function getCodexRawUsage(line, previousTotals) {
|
|
8410
|
-
|
|
8411
|
-
if (line.type
|
|
8412
|
-
|
|
8980
|
+
const payload = normalizeUnknownRecord(line.payload);
|
|
8981
|
+
if (normalizeStringValue(line.type) === "event_msg" && normalizeStringValue(payload == null ? void 0 : payload.type) === "token_count") {
|
|
8982
|
+
const info = normalizeUnknownRecord(payload == null ? void 0 : payload.info);
|
|
8983
|
+
const lastUsage = normalizeRawUsage(info == null ? void 0 : info.last_token_usage);
|
|
8984
|
+
const totalUsage = normalizeRawUsage(info == null ? void 0 : info.total_token_usage);
|
|
8985
|
+
return lastUsage != null ? lastUsage : totalUsage ? subtractRawUsage(totalUsage, previousTotals) : null;
|
|
8413
8986
|
}
|
|
8414
|
-
|
|
8415
|
-
const lastUsage = normalizeRawUsage(info == null ? void 0 : info.last_token_usage);
|
|
8416
|
-
const totalUsage = normalizeRawUsage(info == null ? void 0 : info.total_token_usage);
|
|
8417
|
-
return lastUsage != null ? lastUsage : totalUsage ? subtractRawUsage(totalUsage, previousTotals) : null;
|
|
8987
|
+
return getHeadlessCodexRawUsage(line);
|
|
8418
8988
|
}
|
|
8419
|
-
function getCodexInteractionUsage(rawUsage, model, resolvePricing) {
|
|
8989
|
+
function getCodexInteractionUsage(rawUsage, model, resolvePricing, speed) {
|
|
8420
8990
|
const usage = convertCodexRawUsage(rawUsage);
|
|
8421
8991
|
if (isZeroUsage(usage)) {
|
|
8422
8992
|
return null;
|
|
8423
8993
|
}
|
|
8424
8994
|
return {
|
|
8425
8995
|
...usage,
|
|
8426
|
-
costUSD: calculateUsageCostUSD(usage, resolvePricing(model)
|
|
8996
|
+
costUSD: calculateUsageCostUSD(usage, resolvePricing(model), {
|
|
8997
|
+
defaultFastMultiplier: CODEX_DEFAULT_FAST_MULTIPLIER,
|
|
8998
|
+
speed
|
|
8999
|
+
})
|
|
8427
9000
|
};
|
|
8428
9001
|
}
|
|
8429
|
-
function
|
|
8430
|
-
|
|
8431
|
-
|
|
8432
|
-
|
|
9002
|
+
function getCodexConfigSignature(codexPath) {
|
|
9003
|
+
return `${CODEX_SPEED_CACHE_PREFIX}${readCodexConfigSpeed(getCodexConfigPath(codexPath))}`;
|
|
9004
|
+
}
|
|
9005
|
+
function getCodexConfigPath(codexPath) {
|
|
9006
|
+
return join(codexPath, "config.toml");
|
|
9007
|
+
}
|
|
9008
|
+
function readCodexConfigSpeed(configPath) {
|
|
9009
|
+
var _a;
|
|
9010
|
+
try {
|
|
9011
|
+
return (_a = parseCodexConfigSpeed(readFileSync(configPath, "utf8"))) != null ? _a : "standard";
|
|
9012
|
+
} catch {
|
|
9013
|
+
return "standard";
|
|
9014
|
+
}
|
|
9015
|
+
}
|
|
9016
|
+
function getCodexSpeedFromSignature(cacheSignature) {
|
|
9017
|
+
return cacheSignature === `${CODEX_SPEED_CACHE_PREFIX}fast` ? "fast" : "standard";
|
|
9018
|
+
}
|
|
9019
|
+
const CODEX_CONFIG_ASSIGNMENT_REGEX = /^\s*([a-z_][\w-]*)\s*=\s*["']([^"']+)["']\s*(?:#.*)?$/i;
|
|
9020
|
+
const CODEX_CONFIG_SECTION_REGEX = /^\s*\[([^\]]+)\]\s*(?:#.*)?$/;
|
|
9021
|
+
function parseCodexConfigSpeed(content) {
|
|
9022
|
+
var _a;
|
|
9023
|
+
let activeProfile;
|
|
9024
|
+
let currentSection = null;
|
|
9025
|
+
let topLevelSpeed;
|
|
9026
|
+
const profileSpeeds = /* @__PURE__ */ new Map();
|
|
9027
|
+
for (const rawLine of content.split("\n")) {
|
|
9028
|
+
const sectionMatch = rawLine.match(CODEX_CONFIG_SECTION_REGEX);
|
|
9029
|
+
if (sectionMatch) {
|
|
9030
|
+
currentSection = sectionMatch[1].trim();
|
|
9031
|
+
continue;
|
|
9032
|
+
}
|
|
9033
|
+
const match = rawLine.match(CODEX_CONFIG_ASSIGNMENT_REGEX);
|
|
9034
|
+
if (!match) {
|
|
9035
|
+
continue;
|
|
9036
|
+
}
|
|
9037
|
+
const key = match[1];
|
|
9038
|
+
const value = match[2].trim();
|
|
9039
|
+
if (!currentSection) {
|
|
9040
|
+
if (key === "profile") {
|
|
9041
|
+
activeProfile = value;
|
|
9042
|
+
} else if (key === "service_tier") {
|
|
9043
|
+
topLevelSpeed = toCodexSpeed(value);
|
|
9044
|
+
}
|
|
9045
|
+
continue;
|
|
9046
|
+
}
|
|
9047
|
+
const profileName = getCodexProfileName(currentSection);
|
|
9048
|
+
if (profileName && key === "service_tier") {
|
|
9049
|
+
profileSpeeds.set(profileName, toCodexSpeed(value));
|
|
9050
|
+
}
|
|
9051
|
+
}
|
|
9052
|
+
return (_a = activeProfile ? profileSpeeds.get(activeProfile) : void 0) != null ? _a : topLevelSpeed;
|
|
9053
|
+
}
|
|
9054
|
+
function getCodexProfileName(section) {
|
|
9055
|
+
if (!section.startsWith("profiles.")) {
|
|
9056
|
+
return null;
|
|
8433
9057
|
}
|
|
8434
|
-
|
|
9058
|
+
return stripTomlQuotes(section.slice("profiles.".length).trim());
|
|
9059
|
+
}
|
|
9060
|
+
function stripTomlQuotes(value) {
|
|
9061
|
+
const quote = value[0];
|
|
9062
|
+
return quote && (quote === '"' || quote === "'") && value.endsWith(quote) ? value.slice(1, -1) : value;
|
|
9063
|
+
}
|
|
9064
|
+
function toCodexSpeed(value) {
|
|
9065
|
+
const normalized = value.trim().toLowerCase();
|
|
9066
|
+
return normalized === "priority" || normalized === "fast" ? "fast" : "standard";
|
|
9067
|
+
}
|
|
9068
|
+
function extractCodexContent(line) {
|
|
9069
|
+
const payload = normalizeUnknownRecord(line.payload);
|
|
9070
|
+
const data = normalizeUnknownRecord(line.data);
|
|
9071
|
+
const result = normalizeUnknownRecord(line.result);
|
|
9072
|
+
const response = normalizeUnknownRecord(line.response);
|
|
9073
|
+
const message = payload == null ? void 0 : payload.message;
|
|
8435
9074
|
if (typeof message === "string") {
|
|
8436
9075
|
return message;
|
|
8437
9076
|
}
|
|
8438
|
-
return normalizeStringValue(payload.text) || normalizeStringValue(payload.output) || normalizeStringValue(payload.content) || "";
|
|
9077
|
+
return normalizeStringValue(payload == null ? void 0 : payload.text) || normalizeStringValue(payload == null ? void 0 : payload.output) || normalizeStringValue(payload == null ? void 0 : payload.content) || normalizeStringValue(line.content) || normalizeStringValue(data == null ? void 0 : data.content) || normalizeStringValue(result == null ? void 0 : result.content) || normalizeStringValue(response == null ? void 0 : response.content) || "";
|
|
8439
9078
|
}
|
|
8440
|
-
function getCodexRole(line) {
|
|
8441
|
-
var _a
|
|
8442
|
-
const type = (
|
|
8443
|
-
if (type === "token_count") {
|
|
9079
|
+
function getCodexRole(line, hasUsage) {
|
|
9080
|
+
var _a;
|
|
9081
|
+
const type = normalizeStringValue((_a = normalizeUnknownRecord(line.payload)) == null ? void 0 : _a.type) || normalizeStringValue(line.type) || "";
|
|
9082
|
+
if (type === "token_count" || hasUsage) {
|
|
8444
9083
|
return "usage";
|
|
8445
9084
|
}
|
|
8446
9085
|
return normalizeRole(type);
|
|
8447
9086
|
}
|
|
8448
|
-
function getSessionId(filePath, sessionMetaId) {
|
|
8449
|
-
return (sessionMetaId == null ? void 0 : sessionMetaId.trim()) || basename$1(filePath, ".jsonl");
|
|
9087
|
+
function getSessionId(filePath, sessionMetaId) {
|
|
9088
|
+
return (sessionMetaId == null ? void 0 : sessionMetaId.trim()) || basename$1(filePath, ".jsonl");
|
|
9089
|
+
}
|
|
9090
|
+
function getHeadlessCodexRawUsage(line) {
|
|
9091
|
+
const usage = getHeadlessUsageRecord(line);
|
|
9092
|
+
if (!usage) {
|
|
9093
|
+
return null;
|
|
9094
|
+
}
|
|
9095
|
+
const normalizedUsage = readHeadlessCodexUsage(usage);
|
|
9096
|
+
return normalizedUsage && normalizedUsage.total_tokens > 0 ? normalizedUsage : normalizedUsage && (normalizedUsage.input_tokens > 0 || normalizedUsage.cached_input_tokens > 0 || normalizedUsage.output_tokens > 0 || normalizedUsage.reasoning_output_tokens > 0) ? normalizedUsage : null;
|
|
9097
|
+
}
|
|
9098
|
+
function getHeadlessUsageRecord(line) {
|
|
9099
|
+
var _a, _b, _c, _d;
|
|
9100
|
+
const candidates = [
|
|
9101
|
+
normalizeUnknownRecord(line.usage),
|
|
9102
|
+
normalizeUnknownRecord((_a = normalizeUnknownRecord(line.data)) == null ? void 0 : _a.usage),
|
|
9103
|
+
normalizeUnknownRecord((_b = normalizeUnknownRecord(line.result)) == null ? void 0 : _b.usage),
|
|
9104
|
+
normalizeUnknownRecord((_c = normalizeUnknownRecord(line.response)) == null ? void 0 : _c.usage)
|
|
9105
|
+
];
|
|
9106
|
+
return (_d = candidates.find(Boolean)) != null ? _d : null;
|
|
9107
|
+
}
|
|
9108
|
+
function readHeadlessCodexUsage(usage) {
|
|
9109
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
9110
|
+
const hasStandardUsageField = [
|
|
9111
|
+
"input_tokens",
|
|
9112
|
+
"cached_input_tokens",
|
|
9113
|
+
"cache_read_input_tokens",
|
|
9114
|
+
"output_tokens",
|
|
9115
|
+
"reasoning_output_tokens",
|
|
9116
|
+
"total_tokens"
|
|
9117
|
+
].some((key) => usage[key] !== void 0 && usage[key] !== null);
|
|
9118
|
+
if (hasStandardUsageField) {
|
|
9119
|
+
const normalized = normalizeRawUsage(usage);
|
|
9120
|
+
if (normalized) {
|
|
9121
|
+
return normalized;
|
|
9122
|
+
}
|
|
9123
|
+
}
|
|
9124
|
+
const inputTokens = Math.max(
|
|
9125
|
+
0,
|
|
9126
|
+
Math.trunc((_b = (_a = normalizeFiniteNumberOrNull(usage.input_tokens)) != null ? _a : normalizeFiniteNumberOrNull(usage.prompt_tokens)) != null ? _b : 0)
|
|
9127
|
+
);
|
|
9128
|
+
const cachedInputTokens = Math.max(
|
|
9129
|
+
0,
|
|
9130
|
+
Math.trunc((_d = (_c = normalizeFiniteNumberOrNull(usage.cached_input_tokens)) != null ? _c : normalizeFiniteNumberOrNull(usage.cached_tokens)) != null ? _d : 0)
|
|
9131
|
+
);
|
|
9132
|
+
const outputTokens = Math.max(
|
|
9133
|
+
0,
|
|
9134
|
+
Math.trunc((_f = (_e = normalizeFiniteNumberOrNull(usage.output_tokens)) != null ? _e : normalizeFiniteNumberOrNull(usage.completion_tokens)) != null ? _f : 0)
|
|
9135
|
+
);
|
|
9136
|
+
const reasoningOutputTokens = Math.max(0, Math.trunc((_g = normalizeFiniteNumberOrNull(usage.reasoning_output_tokens)) != null ? _g : 0));
|
|
9137
|
+
const totalTokens = Math.max(0, Math.trunc((_h = normalizeFiniteNumberOrNull(usage.total_tokens)) != null ? _h : 0));
|
|
9138
|
+
return {
|
|
9139
|
+
cached_input_tokens: cachedInputTokens,
|
|
9140
|
+
input_tokens: inputTokens,
|
|
9141
|
+
output_tokens: outputTokens,
|
|
9142
|
+
reasoning_output_tokens: reasoningOutputTokens,
|
|
9143
|
+
total_tokens: totalTokens > 0 ? totalTokens : inputTokens + outputTokens + reasoningOutputTokens
|
|
9144
|
+
};
|
|
9145
|
+
}
|
|
9146
|
+
function extractCodexModel(line) {
|
|
9147
|
+
const payload = normalizeUnknownRecord(line.payload);
|
|
9148
|
+
const candidates = [
|
|
9149
|
+
payload,
|
|
9150
|
+
line,
|
|
9151
|
+
normalizeUnknownRecord(line.data),
|
|
9152
|
+
normalizeUnknownRecord(line.result),
|
|
9153
|
+
normalizeUnknownRecord(line.response)
|
|
9154
|
+
];
|
|
9155
|
+
for (const candidate of candidates) {
|
|
9156
|
+
const model = extractModelName(candidate);
|
|
9157
|
+
if (model) {
|
|
9158
|
+
return model;
|
|
9159
|
+
}
|
|
9160
|
+
}
|
|
9161
|
+
return void 0;
|
|
9162
|
+
}
|
|
9163
|
+
function getCodexTimestamp(line) {
|
|
9164
|
+
if (!line) {
|
|
9165
|
+
return null;
|
|
9166
|
+
}
|
|
9167
|
+
const data = normalizeUnknownRecord(line.data);
|
|
9168
|
+
const result = normalizeUnknownRecord(line.result);
|
|
9169
|
+
const response = normalizeUnknownRecord(line.response);
|
|
9170
|
+
const payload = normalizeUnknownRecord(line.payload);
|
|
9171
|
+
return toIsoString(line.timestamp) || toIsoString(line.created_at) || toIsoString(line.createdAt) || toIsoString(payload == null ? void 0 : payload.timestamp) || toIsoString(data == null ? void 0 : data.timestamp) || toIsoString(data == null ? void 0 : data.created_at) || toIsoString(data == null ? void 0 : data.createdAt) || toIsoString(result == null ? void 0 : result.timestamp) || toIsoString(result == null ? void 0 : result.created_at) || toIsoString(result == null ? void 0 : result.createdAt) || toIsoString(response == null ? void 0 : response.timestamp) || toIsoString(response == null ? void 0 : response.created_at) || toIsoString(response == null ? void 0 : response.createdAt);
|
|
9172
|
+
}
|
|
9173
|
+
function getCodexDedupeKey(timestamp, model, usage) {
|
|
9174
|
+
const rawInputTokens = usage.inputTokens + usage.cachedInputTokens;
|
|
9175
|
+
return [
|
|
9176
|
+
"codex",
|
|
9177
|
+
timestamp,
|
|
9178
|
+
model,
|
|
9179
|
+
String(rawInputTokens),
|
|
9180
|
+
String(usage.cachedInputTokens),
|
|
9181
|
+
String(usage.outputTokens),
|
|
9182
|
+
String(usage.reasoningOutputTokens),
|
|
9183
|
+
String(usage.totalTokens)
|
|
9184
|
+
].join(":");
|
|
8450
9185
|
}
|
|
8451
9186
|
|
|
8452
9187
|
const COPILOT_MODEL_ATTRS = ["gen_ai.response.model", "gen_ai.request.model"];
|
|
@@ -8484,7 +9219,10 @@ const copilotUsageAdapter = {
|
|
|
8484
9219
|
const selectedCandidates = filterCopilotCandidates(candidates);
|
|
8485
9220
|
const fragments = /* @__PURE__ */ new Map();
|
|
8486
9221
|
for (const candidate of selectedCandidates) {
|
|
8487
|
-
const costUSD = calculateUsageCostFromCandidates(candidate.usage, [candidate.model], resolvePricing
|
|
9222
|
+
const costUSD = calculateUsageCostFromCandidates(candidate.usage, [candidate.model], resolvePricing, {
|
|
9223
|
+
includeExtraTotalAsOutput: true,
|
|
9224
|
+
includeReasoningAsOutput: false
|
|
9225
|
+
});
|
|
8488
9226
|
const fragment = (_a = fragments.get(candidate.sessionId)) != null ? _a : createSessionFragment({
|
|
8489
9227
|
project: "copilot",
|
|
8490
9228
|
repository: "local/copilot",
|
|
@@ -8551,21 +9289,22 @@ function getCopilotCandidate(record, index, fallbackTimestamp, traceContexts) {
|
|
|
8551
9289
|
if (!source) {
|
|
8552
9290
|
return null;
|
|
8553
9291
|
}
|
|
8554
|
-
const
|
|
8555
|
-
|
|
8556
|
-
|
|
8557
|
-
|
|
8558
|
-
|
|
8559
|
-
|
|
8560
|
-
|
|
8561
|
-
getCopilotAttributeNumber(attributes, "gen_ai.usage.
|
|
8562
|
-
|
|
8563
|
-
|
|
8564
|
-
|
|
8565
|
-
|
|
8566
|
-
|
|
9292
|
+
const usage = toInteractionUsage({
|
|
9293
|
+
...applyTotalUsageAsExtra({
|
|
9294
|
+
cacheCreationTokens: getCopilotAttributeNumberFirst(attributes, ["gen_ai.usage.cache_write.input_tokens", "gen_ai.usage.cache_creation.input_tokens"]),
|
|
9295
|
+
cacheReadTokens: getCopilotAttributeNumber(attributes, "gen_ai.usage.cache_read.input_tokens"),
|
|
9296
|
+
extraTotalTokens: getCopilotAttributeNumberFirst(attributes, ["gen_ai.usage.reasoning.output_tokens", "gen_ai.usage.reasoning_tokens"]),
|
|
9297
|
+
inputTokens: Math.max(
|
|
9298
|
+
0,
|
|
9299
|
+
getCopilotAttributeNumber(attributes, "gen_ai.usage.input_tokens") - Math.min(
|
|
9300
|
+
getCopilotAttributeNumber(attributes, "gen_ai.usage.input_tokens"),
|
|
9301
|
+
getCopilotAttributeNumber(attributes, "gen_ai.usage.cache_read.input_tokens")
|
|
9302
|
+
)
|
|
9303
|
+
),
|
|
9304
|
+
outputTokens: getCopilotAttributeNumber(attributes, "gen_ai.usage.output_tokens"),
|
|
9305
|
+
totalTokens: getCopilotAttributeNumberFirst(attributes, ["gen_ai.usage.total_tokens", "gen_ai.usage.total.token_count"])
|
|
9306
|
+
})
|
|
8567
9307
|
});
|
|
8568
|
-
const usage = toInteractionUsage(rawUsage);
|
|
8569
9308
|
if (isZeroInteractionUsage(usage)) {
|
|
8570
9309
|
return null;
|
|
8571
9310
|
}
|
|
@@ -8583,7 +9322,6 @@ function getCopilotCandidate(record, index, fallbackTimestamp, traceContexts) {
|
|
|
8583
9322
|
inputTokens: usage.inputTokens,
|
|
8584
9323
|
model,
|
|
8585
9324
|
outputTokens: usage.outputTokens,
|
|
8586
|
-
reasoningOutputTokens: usage.reasoningOutputTokens,
|
|
8587
9325
|
responseId,
|
|
8588
9326
|
sessionId,
|
|
8589
9327
|
source,
|
|
@@ -8710,7 +9448,7 @@ const droidUsageAdapter = {
|
|
|
8710
9448
|
const groups = await Promise.all(config.droidPaths.map((path) => glob(join(path, "**", "*.settings.json"), {
|
|
8711
9449
|
absolute: true
|
|
8712
9450
|
}).catch(() => [])));
|
|
8713
|
-
return groups.flat().flatMap((filePath) => toDiscoveredUsageFile(filePath, "droid"));
|
|
9451
|
+
return selectLatestDroidSettingsFiles(groups.flat()).flatMap((filePath) => toDiscoveredUsageFile(filePath, "droid"));
|
|
8714
9452
|
},
|
|
8715
9453
|
parseFile(filePath, resolvePricing) {
|
|
8716
9454
|
var _a, _b;
|
|
@@ -8720,15 +9458,16 @@ const droidUsageAdapter = {
|
|
|
8720
9458
|
if (!settings || !tokenUsage) {
|
|
8721
9459
|
return [];
|
|
8722
9460
|
}
|
|
9461
|
+
const extraTotalTokens = getNumber$7(tokenUsage.thinkingTokens);
|
|
8723
9462
|
const usage = toInteractionUsage({
|
|
8724
9463
|
...applyTotalUsageFallback({
|
|
8725
9464
|
cacheCreationTokens: getNumber$7(tokenUsage.cacheCreationTokens),
|
|
8726
9465
|
cacheReadTokens: getNumber$7(tokenUsage.cacheReadTokens),
|
|
8727
9466
|
inputTokens: getNumber$7(tokenUsage.inputTokens),
|
|
8728
9467
|
outputTokens: getNumber$7(tokenUsage.outputTokens),
|
|
8729
|
-
|
|
8730
|
-
|
|
8731
|
-
|
|
9468
|
+
totalTokens: Math.max(getNumber$7(tokenUsage.totalTokens) - extraTotalTokens, 0)
|
|
9469
|
+
}),
|
|
9470
|
+
extraTotalTokens
|
|
8732
9471
|
});
|
|
8733
9472
|
if (isZeroInteractionUsage(usage)) {
|
|
8734
9473
|
return [];
|
|
@@ -8876,12 +9615,29 @@ function extractDroidModelFromSidecar(settingsPath) {
|
|
|
8876
9615
|
function getNumber$7(value) {
|
|
8877
9616
|
return typeof value === "number" && Number.isFinite(value) ? Math.max(0, Math.trunc(value)) : 0;
|
|
8878
9617
|
}
|
|
9618
|
+
function selectLatestDroidSettingsFiles(filePaths) {
|
|
9619
|
+
const latestBySession = /* @__PURE__ */ new Map();
|
|
9620
|
+
for (const filePath of filePaths) {
|
|
9621
|
+
const sessionId = basename$1(filePath, ".settings.json");
|
|
9622
|
+
const timestamp = getDroidSnapshotTimestamp(filePath);
|
|
9623
|
+
const current = latestBySession.get(sessionId);
|
|
9624
|
+
if (!current || timestamp > current.timestamp) {
|
|
9625
|
+
latestBySession.set(sessionId, { filePath, timestamp });
|
|
9626
|
+
}
|
|
9627
|
+
}
|
|
9628
|
+
return Array.from(latestBySession.values()).map((item) => item.filePath).sort((a, b) => a.localeCompare(b));
|
|
9629
|
+
}
|
|
9630
|
+
function getDroidSnapshotTimestamp(filePath) {
|
|
9631
|
+
var _a;
|
|
9632
|
+
const settings = normalizeUnknownRecord(parseJsonFile(filePath));
|
|
9633
|
+
const timestamp = toIsoString(settings == null ? void 0 : settings.providerLockTimestamp);
|
|
9634
|
+
return timestamp ? Date.parse(timestamp) : Date.parse((_a = getFileModifiedAtIso(filePath)) != null ? _a : "") || 0;
|
|
9635
|
+
}
|
|
8879
9636
|
|
|
8880
9637
|
const geminiUsageAdapter = {
|
|
8881
9638
|
async createPricingResolver() {
|
|
8882
9639
|
return createLiteLLMPricingResolver({
|
|
8883
9640
|
aliases: GEMINI_MODEL_ALIASES,
|
|
8884
|
-
fallbackModel: GEMINI_FALLBACK_MODEL,
|
|
8885
9641
|
fallbackPricingTable: GEMINI_FALLBACK_PRICING_TABLE,
|
|
8886
9642
|
getLookupCandidates: getGeminiLookupCandidates
|
|
8887
9643
|
});
|
|
@@ -8944,20 +9700,25 @@ const geminiUsageAdapter = {
|
|
|
8944
9700
|
}
|
|
8945
9701
|
};
|
|
8946
9702
|
function getGeminiInteractionUsage(tokens, model, resolvePricing) {
|
|
8947
|
-
const
|
|
9703
|
+
const baseUsage = convertGeminiTokenUsage(tokens);
|
|
9704
|
+
const extraTotalTokens = normalizeNumber(tokens.thoughts);
|
|
9705
|
+
const usage = {
|
|
9706
|
+
...baseUsage,
|
|
9707
|
+
inputTokens: baseUsage.inputTokens + normalizeNumber(tokens.tool),
|
|
9708
|
+
reasoningOutputTokens: 0
|
|
9709
|
+
};
|
|
8948
9710
|
if (isZeroUsage(usage)) {
|
|
8949
9711
|
return null;
|
|
8950
9712
|
}
|
|
8951
|
-
const toolTokens = normalizeNumber(tokens.tool);
|
|
8952
9713
|
const costUSD = calculateUsageCostUSD({
|
|
8953
9714
|
cachedInputTokens: usage.cachedInputTokens,
|
|
8954
9715
|
inputTokens: usage.inputTokens,
|
|
8955
|
-
outputTokens: usage.outputTokens
|
|
9716
|
+
outputTokens: usage.outputTokens
|
|
8956
9717
|
}, resolvePricing(model));
|
|
8957
9718
|
return {
|
|
8958
9719
|
...usage,
|
|
8959
9720
|
costUSD,
|
|
8960
|
-
|
|
9721
|
+
extraTotalTokens
|
|
8961
9722
|
};
|
|
8962
9723
|
}
|
|
8963
9724
|
function getGeminiRole(message) {
|
|
@@ -9022,7 +9783,7 @@ const gooseUsageAdapter = {
|
|
|
9022
9783
|
addFragmentInteraction(fragment, {
|
|
9023
9784
|
content: "",
|
|
9024
9785
|
costUSD: entry.usage.costUSD,
|
|
9025
|
-
dedupeKey: `goose:${entry.sessionId}`,
|
|
9786
|
+
dedupeKey: `goose:${filePath}:${entry.sessionId}`,
|
|
9026
9787
|
index: 0,
|
|
9027
9788
|
model: entry.model,
|
|
9028
9789
|
role: "usage",
|
|
@@ -9053,11 +9814,11 @@ function parseGooseRow(row, resolvePricing) {
|
|
|
9053
9814
|
const inputTokens = getNumber$6(row.accumulated_input_tokens) || getNumber$6(row.input_tokens);
|
|
9054
9815
|
const outputTokens = getNumber$6(row.accumulated_output_tokens) || getNumber$6(row.output_tokens);
|
|
9055
9816
|
const totalTokens = getNumber$6(row.accumulated_total_tokens) || getNumber$6(row.total_tokens) || inputTokens + outputTokens;
|
|
9056
|
-
const
|
|
9817
|
+
const extraTotalTokens = Math.max(0, totalTokens - inputTokens - outputTokens);
|
|
9057
9818
|
const usage = toInteractionUsage({
|
|
9819
|
+
extraTotalTokens,
|
|
9058
9820
|
inputTokens,
|
|
9059
|
-
outputTokens
|
|
9060
|
-
reasoningOutputTokens
|
|
9821
|
+
outputTokens
|
|
9061
9822
|
});
|
|
9062
9823
|
if (isZeroInteractionUsage(usage)) {
|
|
9063
9824
|
return null;
|
|
@@ -9175,9 +9936,9 @@ function parseHermesRow(row, resolvePricing) {
|
|
|
9175
9936
|
const usage = toInteractionUsage({
|
|
9176
9937
|
cacheCreationTokens: toNumber(row.cache_write_tokens),
|
|
9177
9938
|
cacheReadTokens: toNumber(row.cache_read_tokens),
|
|
9939
|
+
extraTotalTokens: toNumber(row.reasoning_tokens),
|
|
9178
9940
|
inputTokens: toNumber(row.input_tokens),
|
|
9179
|
-
outputTokens: toNumber(row.output_tokens)
|
|
9180
|
-
reasoningOutputTokens: toNumber(row.reasoning_tokens)
|
|
9941
|
+
outputTokens: toNumber(row.output_tokens)
|
|
9181
9942
|
});
|
|
9182
9943
|
if (isZeroInteractionUsage(usage) && !toOptionalNumber(row.actual_cost_usd) && !toOptionalNumber(row.estimated_cost_usd)) {
|
|
9183
9944
|
return null;
|
|
@@ -9302,15 +10063,16 @@ function parseKiloMessage(value, row, filePath, resolvePricing) {
|
|
|
9302
10063
|
if (!tokens || !model || !timestamp) {
|
|
9303
10064
|
return null;
|
|
9304
10065
|
}
|
|
10066
|
+
const extraTotalTokens = getNumber$5(tokens.reasoning);
|
|
9305
10067
|
const usage = toInteractionUsage({
|
|
9306
10068
|
...applyTotalUsageFallback({
|
|
9307
10069
|
cacheCreationTokens: getNumber$5((_b = normalizeUnknownRecord(tokens.cache)) == null ? void 0 : _b.write),
|
|
9308
10070
|
cacheReadTokens: getNumber$5((_c = normalizeUnknownRecord(tokens.cache)) == null ? void 0 : _c.read),
|
|
9309
10071
|
inputTokens: getNumber$5(tokens.input),
|
|
9310
10072
|
outputTokens: getNumber$5(tokens.output),
|
|
9311
|
-
|
|
9312
|
-
|
|
9313
|
-
|
|
10073
|
+
totalTokens: Math.max(getNumber$5(tokens.total) - extraTotalTokens, 0)
|
|
10074
|
+
}),
|
|
10075
|
+
extraTotalTokens
|
|
9314
10076
|
});
|
|
9315
10077
|
if (isZeroInteractionUsage(usage)) {
|
|
9316
10078
|
return null;
|
|
@@ -9359,7 +10121,7 @@ const kimiUsageAdapter = {
|
|
|
9359
10121
|
return groups.flat().filter((filePath) => isKimiWireFile(join(dirname$1(dirname$1(dirname$1(filePath))), "sessions"), filePath)).flatMap((filePath) => toDiscoveredUsageFile(filePath, "kimi"));
|
|
9360
10122
|
},
|
|
9361
10123
|
parseFile(filePath, resolvePricing) {
|
|
9362
|
-
var _a;
|
|
10124
|
+
var _a, _b, _c, _d;
|
|
9363
10125
|
const sessionId = getKimiSessionId(filePath);
|
|
9364
10126
|
const model = getKimiModel(filePath);
|
|
9365
10127
|
const fallbackTimestamp = getFileModifiedAtIso(filePath);
|
|
@@ -9380,7 +10142,7 @@ const kimiUsageAdapter = {
|
|
|
9380
10142
|
continue;
|
|
9381
10143
|
}
|
|
9382
10144
|
const usage = toInteractionUsage({
|
|
9383
|
-
...
|
|
10145
|
+
...applyTotalUsageAsExtra({
|
|
9384
10146
|
cacheCreationTokens: getNumber$4(tokenUsage.input_cache_creation),
|
|
9385
10147
|
cacheReadTokens: getNumber$4(tokenUsage.input_cache_read),
|
|
9386
10148
|
inputTokens: getNumber$4(tokenUsage.input_other),
|
|
@@ -9401,7 +10163,11 @@ const kimiUsageAdapter = {
|
|
|
9401
10163
|
normalizeStringValue(payload.message_id) || "",
|
|
9402
10164
|
timestamp || "",
|
|
9403
10165
|
model,
|
|
9404
|
-
String(usage.
|
|
10166
|
+
String(usage.inputTokens),
|
|
10167
|
+
String(usage.outputTokens),
|
|
10168
|
+
String((_b = usage.cacheCreationTokens) != null ? _b : 0),
|
|
10169
|
+
String((_c = usage.cacheReadTokens) != null ? _c : 0),
|
|
10170
|
+
String((_d = usage.extraTotalTokens) != null ? _d : 0)
|
|
9405
10171
|
].join(":"),
|
|
9406
10172
|
index,
|
|
9407
10173
|
model,
|
|
@@ -9457,7 +10223,7 @@ const openClawUsageAdapter = {
|
|
|
9457
10223
|
return groups.flat().filter((filePath) => isOpenClawSessionFile(basename$1(filePath))).flatMap((filePath) => toDiscoveredUsageFile(filePath, "openclaw"));
|
|
9458
10224
|
},
|
|
9459
10225
|
parseFile(filePath) {
|
|
9460
|
-
var _a, _b, _c, _d, _e;
|
|
10226
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
9461
10227
|
const lines = readFileSync(filePath, "utf8").split("\n").map((line) => line.trim()).filter(Boolean);
|
|
9462
10228
|
const sessionId = getOpenClawSessionId(filePath);
|
|
9463
10229
|
const fragment = createSessionFragment({
|
|
@@ -9491,7 +10257,7 @@ const openClawUsageAdapter = {
|
|
|
9491
10257
|
continue;
|
|
9492
10258
|
}
|
|
9493
10259
|
const usage = toInteractionUsage({
|
|
9494
|
-
...
|
|
10260
|
+
...applyTotalUsageAsExtra({
|
|
9495
10261
|
cacheCreationTokens: getNumber$3(usageRecord.cacheWrite),
|
|
9496
10262
|
cacheReadTokens: getNumber$3(usageRecord.cacheRead),
|
|
9497
10263
|
inputTokens: getNumber$3(usageRecord.input),
|
|
@@ -9516,8 +10282,9 @@ const openClawUsageAdapter = {
|
|
|
9516
10282
|
rawModel,
|
|
9517
10283
|
String(usage.inputTokens),
|
|
9518
10284
|
String(usage.outputTokens),
|
|
9519
|
-
String(usage.
|
|
9520
|
-
String(usage.
|
|
10285
|
+
String((_f = usage.cacheCreationTokens) != null ? _f : 0),
|
|
10286
|
+
String((_g = usage.cacheReadTokens) != null ? _g : 0),
|
|
10287
|
+
String((_h = usage.extraTotalTokens) != null ? _h : 0),
|
|
9521
10288
|
String(usage.costUSD)
|
|
9522
10289
|
].join(":"),
|
|
9523
10290
|
index,
|
|
@@ -9625,8 +10392,12 @@ const openCodeUsageAdapter = {
|
|
|
9625
10392
|
}
|
|
9626
10393
|
const value = parseJsonFile(filePath);
|
|
9627
10394
|
const record = normalizeUnknownRecord(value);
|
|
10395
|
+
const interactionId = normalizeStringValue(record == null ? void 0 : record.id);
|
|
10396
|
+
if (interactionId && isDuplicatedByOpenCodeDatabase(filePath, interactionId)) {
|
|
10397
|
+
return [];
|
|
10398
|
+
}
|
|
9628
10399
|
const entry = record ? getOpenCodeMessageEntry(record, resolvePricing, {
|
|
9629
|
-
interactionId
|
|
10400
|
+
interactionId,
|
|
9630
10401
|
sessionId: normalizeStringValue(record.sessionID)
|
|
9631
10402
|
}) : null;
|
|
9632
10403
|
if (!entry) {
|
|
@@ -9679,7 +10450,7 @@ function getOpenCodeMessageEntry(value, resolvePricing, options = {}) {
|
|
|
9679
10450
|
return null;
|
|
9680
10451
|
}
|
|
9681
10452
|
const usage = toInteractionUsage({
|
|
9682
|
-
...
|
|
10453
|
+
...applyTotalUsageAsExtra({
|
|
9683
10454
|
cacheCreationTokens: getNumber$2((_b = normalizeUnknownRecord(tokens.cache)) == null ? void 0 : _b.write),
|
|
9684
10455
|
cacheReadTokens: getNumber$2((_c = normalizeUnknownRecord(tokens.cache)) == null ? void 0 : _c.read),
|
|
9685
10456
|
inputTokens: getNumber$2(tokens.input),
|
|
@@ -9696,7 +10467,10 @@ function getOpenCodeMessageEntry(value, resolvePricing, options = {}) {
|
|
|
9696
10467
|
}
|
|
9697
10468
|
const sessionId = options.sessionId || "unknown";
|
|
9698
10469
|
const directCost = normalizeFiniteNumberOrNull(value.cost);
|
|
9699
|
-
const costUSD = directCost && directCost > 0 ? directCost : calculateUsageCostFromCandidates(usage, getOpenCodeModelCandidates(model, provider), resolvePricing
|
|
10470
|
+
const costUSD = directCost && directCost > 0 ? directCost : calculateUsageCostFromCandidates(usage, getOpenCodeModelCandidates(model, provider), resolvePricing, {
|
|
10471
|
+
includeExtraTotalAsOutput: true,
|
|
10472
|
+
includeReasoningAsOutput: false
|
|
10473
|
+
});
|
|
9700
10474
|
return {
|
|
9701
10475
|
interactionId: options.interactionId || normalizeStringValue(value.id) || `${sessionId}:${timestamp}:${model}`,
|
|
9702
10476
|
model,
|
|
@@ -9712,6 +10486,25 @@ function getOpenCodeLookupCandidates(model) {
|
|
|
9712
10486
|
const normalizedModel = normalizeOpenCodeModelName(resolveOpenCodeModelName(model.trim()));
|
|
9713
10487
|
return [model.trim(), normalizedModel];
|
|
9714
10488
|
}
|
|
10489
|
+
function isDuplicatedByOpenCodeDatabase(filePath, interactionId) {
|
|
10490
|
+
const root = getOpenCodeRootFromMessageFile(filePath);
|
|
10491
|
+
if (!root) {
|
|
10492
|
+
return false;
|
|
10493
|
+
}
|
|
10494
|
+
const databaseFile = getOpenCodeDatabaseFileSync(root);
|
|
10495
|
+
if (!databaseFile) {
|
|
10496
|
+
return false;
|
|
10497
|
+
}
|
|
10498
|
+
const database = openSqliteDatabase(databaseFile, { readOnly: true });
|
|
10499
|
+
try {
|
|
10500
|
+
const row = database.prepare("SELECT id FROM message WHERE id = ? LIMIT 1").get(interactionId);
|
|
10501
|
+
return Boolean(row == null ? void 0 : row.id);
|
|
10502
|
+
} catch {
|
|
10503
|
+
return false;
|
|
10504
|
+
} finally {
|
|
10505
|
+
database.close();
|
|
10506
|
+
}
|
|
10507
|
+
}
|
|
9715
10508
|
function getOpenCodeModelCandidates(model, provider) {
|
|
9716
10509
|
const normalizedModel = normalizeOpenCodeModelName(resolveOpenCodeModelName(model));
|
|
9717
10510
|
const candidates = [model, normalizedModel];
|
|
@@ -9750,6 +10543,22 @@ function parseUnknownJson(value) {
|
|
|
9750
10543
|
return null;
|
|
9751
10544
|
}
|
|
9752
10545
|
}
|
|
10546
|
+
function getOpenCodeDatabaseFileSync(root) {
|
|
10547
|
+
var _a;
|
|
10548
|
+
const defaultPath = join(root, "opencode.db");
|
|
10549
|
+
if (existsSync(defaultPath)) {
|
|
10550
|
+
return defaultPath;
|
|
10551
|
+
}
|
|
10552
|
+
return (_a = readdirSync(root, { withFileTypes: true }).filter((entry) => entry.isFile() && isOpenCodeChannelDatabase(entry.name)).map((entry) => join(root, entry.name)).sort((left, right) => left.localeCompare(right))[0]) != null ? _a : null;
|
|
10553
|
+
}
|
|
10554
|
+
function getOpenCodeRootFromMessageFile(filePath) {
|
|
10555
|
+
const marker = `${join("storage", "message")}/`;
|
|
10556
|
+
const index = filePath.lastIndexOf(marker);
|
|
10557
|
+
return index >= 0 ? filePath.slice(0, index) : null;
|
|
10558
|
+
}
|
|
10559
|
+
function isOpenCodeChannelDatabase(name) {
|
|
10560
|
+
return /^opencode-[\w-]+\.db$/u.test(name);
|
|
10561
|
+
}
|
|
9753
10562
|
|
|
9754
10563
|
const piUsageAdapter = {
|
|
9755
10564
|
createPricingResolver: createZeroPricingResolver,
|
|
@@ -9760,7 +10569,7 @@ const piUsageAdapter = {
|
|
|
9760
10569
|
return groups.flat().flatMap((filePath) => toDiscoveredUsageFile(filePath, "pi"));
|
|
9761
10570
|
},
|
|
9762
10571
|
parseFile(filePath) {
|
|
9763
|
-
var _a, _b, _c;
|
|
10572
|
+
var _a, _b, _c, _d, _e, _f;
|
|
9764
10573
|
const lines = parseJsonlFile(filePath);
|
|
9765
10574
|
const sessionId = getPiSessionId(filePath);
|
|
9766
10575
|
const project = getPiProject(filePath);
|
|
@@ -9783,7 +10592,7 @@ const piUsageAdapter = {
|
|
|
9783
10592
|
continue;
|
|
9784
10593
|
}
|
|
9785
10594
|
const usage = toInteractionUsage({
|
|
9786
|
-
...
|
|
10595
|
+
...applyTotalUsageAsExtra({
|
|
9787
10596
|
cacheCreationTokens: getNumber$1(usageRecord.cacheWrite),
|
|
9788
10597
|
cacheReadTokens: getNumber$1(usageRecord.cacheRead),
|
|
9789
10598
|
inputTokens: getNumber$1(usageRecord.input),
|
|
@@ -9799,6 +10608,19 @@ const piUsageAdapter = {
|
|
|
9799
10608
|
addFragmentInteraction(fragment, {
|
|
9800
10609
|
content: "",
|
|
9801
10610
|
costUSD: usage.costUSD,
|
|
10611
|
+
dedupeKey: [
|
|
10612
|
+
"pi",
|
|
10613
|
+
project,
|
|
10614
|
+
sessionId,
|
|
10615
|
+
timestamp,
|
|
10616
|
+
rawModel || "",
|
|
10617
|
+
String(usage.inputTokens),
|
|
10618
|
+
String(usage.outputTokens),
|
|
10619
|
+
String((_d = usage.cacheCreationTokens) != null ? _d : 0),
|
|
10620
|
+
String((_e = usage.cacheReadTokens) != null ? _e : 0),
|
|
10621
|
+
String((_f = usage.extraTotalTokens) != null ? _f : 0),
|
|
10622
|
+
String(usage.costUSD)
|
|
10623
|
+
].join(":"),
|
|
9802
10624
|
index,
|
|
9803
10625
|
model: rawModel ? `[pi] ${rawModel}` : null,
|
|
9804
10626
|
role: "assistant",
|
|
@@ -9862,14 +10684,15 @@ const qwenUsageAdapter = {
|
|
|
9862
10684
|
if (!record || normalizeStringValue(record.type) !== "assistant" || !usageRecord) {
|
|
9863
10685
|
continue;
|
|
9864
10686
|
}
|
|
10687
|
+
const extraTotalTokens = getNumber(usageRecord.thoughtsTokenCount);
|
|
9865
10688
|
const usage = toInteractionUsage({
|
|
9866
10689
|
...applyTotalUsageFallback({
|
|
9867
10690
|
cacheReadTokens: getNumber(usageRecord.cachedContentTokenCount),
|
|
9868
10691
|
inputTokens: getNumber(usageRecord.promptTokenCount),
|
|
9869
10692
|
outputTokens: getNumber(usageRecord.candidatesTokenCount),
|
|
9870
|
-
|
|
9871
|
-
|
|
9872
|
-
|
|
10693
|
+
totalTokens: Math.max(getNumber(usageRecord.totalTokenCount) - extraTotalTokens, 0)
|
|
10694
|
+
}),
|
|
10695
|
+
extraTotalTokens
|
|
9873
10696
|
});
|
|
9874
10697
|
if (isZeroInteractionUsage(usage)) {
|
|
9875
10698
|
continue;
|
|
@@ -9950,7 +10773,7 @@ async function buildIncrementalUsageIndex(config, repository) {
|
|
|
9950
10773
|
const cachedFilesByPath = new Map(cachedFiles.map((file) => [file.path, file]));
|
|
9951
10774
|
const changedFiles = discoveredFiles.filter((file) => {
|
|
9952
10775
|
const cached = cachedFilesByPath.get(file.path);
|
|
9953
|
-
return !cached || cached.platform !== file.platform || cached.size !== file.size || cached.mtimeMs !== file.mtimeMs;
|
|
10776
|
+
return !cached || cached.platform !== file.platform || cached.cacheSignature !== file.cacheSignature || cached.size !== file.size || cached.mtimeMs !== file.mtimeMs;
|
|
9954
10777
|
});
|
|
9955
10778
|
const removedFiles = cachedFiles.filter((file) => !discoveredFiles.some((discovered) => discovered.path === file.path));
|
|
9956
10779
|
const affectedProjects = new Set(removedFiles.flatMap((file) => file.projectNames));
|
|
@@ -10014,8 +10837,9 @@ async function discoverUsageFiles(config) {
|
|
|
10014
10837
|
}
|
|
10015
10838
|
function parseUsageFile(file, pricingResolvers) {
|
|
10016
10839
|
const adapter = usagePlatformAdapters[file.platform];
|
|
10017
|
-
const payload = adapter.parseFile(file.path, pricingResolvers[file.platform]);
|
|
10840
|
+
const payload = adapter.parseFile(file.path, pricingResolvers[file.platform], file);
|
|
10018
10841
|
return {
|
|
10842
|
+
cacheSignature: file.cacheSignature,
|
|
10019
10843
|
mtimeMs: file.mtimeMs,
|
|
10020
10844
|
path: file.path,
|
|
10021
10845
|
payload,
|
|
@@ -10033,29 +10857,61 @@ function buildPlatformSessionsByPlatform(indexedFiles) {
|
|
|
10033
10857
|
function buildPlatformSessionsFromFiles(indexedFiles, platform) {
|
|
10034
10858
|
var _a;
|
|
10035
10859
|
const details = /* @__PURE__ */ new Map();
|
|
10036
|
-
const
|
|
10860
|
+
const selectedInteractions = selectDedupedInteractions(indexedFiles, platform);
|
|
10861
|
+
for (const { fragment, interaction } of selectedInteractions) {
|
|
10862
|
+
const detail = (_a = details.get(fragment.key)) != null ? _a : createSessionDetail(fragment);
|
|
10863
|
+
if (fragment.durationEndAt && (!detail.durationEndAt || Date.parse(fragment.durationEndAt) > Date.parse(detail.durationEndAt))) {
|
|
10864
|
+
detail.durationEndAt = fragment.durationEndAt;
|
|
10865
|
+
}
|
|
10866
|
+
addInteraction(detail, interaction);
|
|
10867
|
+
details.set(fragment.key, detail);
|
|
10868
|
+
}
|
|
10869
|
+
return Array.from(details.values()).map(finalizeSessionDetail).filter(hasBillableSessionDetail).map(toProjectSessionUsageItem).sort((a, b) => Date.parse(b.startedAt) - Date.parse(a.startedAt));
|
|
10870
|
+
}
|
|
10871
|
+
function selectDedupedInteractions(indexedFiles, platform) {
|
|
10872
|
+
const interactionsWithoutDedupeKey = [];
|
|
10873
|
+
const interactionsByDedupeKey = /* @__PURE__ */ new Map();
|
|
10037
10874
|
for (const file of indexedFiles) {
|
|
10038
10875
|
if (file.platform !== platform) {
|
|
10039
10876
|
continue;
|
|
10040
10877
|
}
|
|
10041
10878
|
for (const fragment of file.payload) {
|
|
10042
|
-
const detail = (_a = details.get(fragment.key)) != null ? _a : createSessionDetail(fragment);
|
|
10043
|
-
if (fragment.durationEndAt && (!detail.durationEndAt || Date.parse(fragment.durationEndAt) > Date.parse(detail.durationEndAt))) {
|
|
10044
|
-
detail.durationEndAt = fragment.durationEndAt;
|
|
10045
|
-
}
|
|
10046
10879
|
for (const interaction of fragment.interactions) {
|
|
10047
|
-
if (interaction.dedupeKey) {
|
|
10048
|
-
|
|
10049
|
-
|
|
10050
|
-
|
|
10051
|
-
|
|
10880
|
+
if (!interaction.dedupeKey) {
|
|
10881
|
+
interactionsWithoutDedupeKey.push({ fragment, interaction });
|
|
10882
|
+
continue;
|
|
10883
|
+
}
|
|
10884
|
+
const existing = interactionsByDedupeKey.get(interaction.dedupeKey);
|
|
10885
|
+
if (!existing) {
|
|
10886
|
+
interactionsByDedupeKey.set(interaction.dedupeKey, { fragment, interaction });
|
|
10887
|
+
} else if (shouldReplaceDedupedInteraction(interaction, existing.interaction)) {
|
|
10888
|
+
interactionsByDedupeKey.set(interaction.dedupeKey, { fragment: existing.fragment, interaction });
|
|
10052
10889
|
}
|
|
10053
|
-
addInteraction(detail, interaction);
|
|
10054
10890
|
}
|
|
10055
|
-
details.set(fragment.key, detail);
|
|
10056
10891
|
}
|
|
10057
10892
|
}
|
|
10058
|
-
return
|
|
10893
|
+
return [
|
|
10894
|
+
...interactionsWithoutDedupeKey,
|
|
10895
|
+
...interactionsByDedupeKey.values()
|
|
10896
|
+
];
|
|
10897
|
+
}
|
|
10898
|
+
function shouldReplaceDedupedInteraction(candidate, existing) {
|
|
10899
|
+
var _a, _b, _c, _d;
|
|
10900
|
+
const candidateTotal = (_b = (_a = candidate.usage) == null ? void 0 : _a.totalTokens) != null ? _b : 0;
|
|
10901
|
+
const existingTotal = (_d = (_c = existing.usage) == null ? void 0 : _c.totalTokens) != null ? _d : 0;
|
|
10902
|
+
if (candidateTotal !== existingTotal) {
|
|
10903
|
+
return candidateTotal > existingTotal;
|
|
10904
|
+
}
|
|
10905
|
+
const candidateIsFast = isFastModel(candidate.model);
|
|
10906
|
+
const existingIsFast = isFastModel(existing.model);
|
|
10907
|
+
if (candidateIsFast !== existingIsFast) {
|
|
10908
|
+
return candidateIsFast;
|
|
10909
|
+
}
|
|
10910
|
+
return candidate.costUSD > existing.costUSD;
|
|
10911
|
+
}
|
|
10912
|
+
function isFastModel(model) {
|
|
10913
|
+
var _a;
|
|
10914
|
+
return (_a = model == null ? void 0 : model.endsWith("-fast")) != null ? _a : false;
|
|
10059
10915
|
}
|
|
10060
10916
|
function createSessionDetail(fragment) {
|
|
10061
10917
|
var _a, _b;
|
|
@@ -10064,6 +10920,7 @@ function createSessionDetail(fragment) {
|
|
|
10064
10920
|
costUSD: 0,
|
|
10065
10921
|
durationEndAt: fragment.durationEndAt,
|
|
10066
10922
|
durationMinutes: 0,
|
|
10923
|
+
key: fragment.key,
|
|
10067
10924
|
inputTokens: 0,
|
|
10068
10925
|
interactions: [],
|
|
10069
10926
|
lastActivity: (_a = fragment.startedAt) != null ? _a : "",
|
|
@@ -10138,7 +10995,7 @@ function toProjectSessionUsageItem(detail) {
|
|
|
10138
10995
|
date: dateKey ? formatDateLabelFromDateKey(dateKey) : "",
|
|
10139
10996
|
duration: formatDuration(detail.durationMinutes),
|
|
10140
10997
|
durationMinutes: detail.durationMinutes,
|
|
10141
|
-
id: detail.
|
|
10998
|
+
id: detail.key,
|
|
10142
10999
|
inputTokens: detail.inputTokens,
|
|
10143
11000
|
interactions: detail.interactions.map(({ dedupeKey: _dedupeKey, ...interaction }) => ({
|
|
10144
11001
|
...interaction,
|
|
@@ -10222,7 +11079,8 @@ function buildProjectUsageCatalogItemsFromDetails(details) {
|
|
|
10222
11079
|
return Array.from(details).map(([label, detail]) => {
|
|
10223
11080
|
return {
|
|
10224
11081
|
label,
|
|
10225
|
-
|
|
11082
|
+
platforms: getProjectDetailPlatforms(detail),
|
|
11083
|
+
totalTokens: getProjectDetailTotalTokens(detail)
|
|
10226
11084
|
};
|
|
10227
11085
|
}).sort((a, b) => a.label.localeCompare(b.label));
|
|
10228
11086
|
}
|
|
@@ -10287,78 +11145,351 @@ function assertProjectUsageDataModule(module) {
|
|
|
10287
11145
|
throw new Error(`Unsupported project data module: ${module}.`);
|
|
10288
11146
|
}
|
|
10289
11147
|
}
|
|
10290
|
-
function assertProjectUsagePlatformScope(platform) {
|
|
10291
|
-
if (platform !== "all" && !PROJECT_USAGE_PLATFORMS.includes(platform)) {
|
|
10292
|
-
throw new Error(`Unsupported project data platform: ${platform}.`);
|
|
11148
|
+
function assertProjectUsagePlatformScope(platform) {
|
|
11149
|
+
if (platform !== "all" && !PROJECT_USAGE_PLATFORMS.includes(platform)) {
|
|
11150
|
+
throw new Error(`Unsupported project data platform: ${platform}.`);
|
|
11151
|
+
}
|
|
11152
|
+
}
|
|
11153
|
+
function getProjectDetailPlatforms(detail) {
|
|
11154
|
+
return PROJECT_USAGE_PLATFORMS.filter((platform) => {
|
|
11155
|
+
var _a;
|
|
11156
|
+
return ((_a = detail.analyzing[platform]) != null ? _a : createEmptyProjectPlatformUsage()).sessions.length > 0;
|
|
11157
|
+
});
|
|
11158
|
+
}
|
|
11159
|
+
function getProjectDetailTotalTokens(detail) {
|
|
11160
|
+
return getProjectDetailSessions(detail).reduce((sum, session) => sum + session.tokenTotal, 0);
|
|
11161
|
+
}
|
|
11162
|
+
function buildSessionListModulePayload(sessionRows, sessions) {
|
|
11163
|
+
const sessionList = sessions.map(({ interactions: _interactions, ...session }) => session);
|
|
11164
|
+
return {
|
|
11165
|
+
sessionRows,
|
|
11166
|
+
sessionUsage: sessionList,
|
|
11167
|
+
sessions: sessionList
|
|
11168
|
+
};
|
|
11169
|
+
}
|
|
11170
|
+
function buildProjectPlatformPayloadMap(detail, module) {
|
|
11171
|
+
return Object.fromEntries(
|
|
11172
|
+
PROJECT_USAGE_PLATFORMS.map((platform) => {
|
|
11173
|
+
var _a;
|
|
11174
|
+
return [
|
|
11175
|
+
platform,
|
|
11176
|
+
buildPlatformModulePayload((_a = detail.analyzing[platform]) != null ? _a : createEmptyProjectPlatformUsage(), module)
|
|
11177
|
+
];
|
|
11178
|
+
})
|
|
11179
|
+
);
|
|
11180
|
+
}
|
|
11181
|
+
function buildProjectLoadUsageResult(sessions, platform = "all") {
|
|
11182
|
+
const usage = buildLoadUsageResult(getProjectAggregateEvents(sessions), sessions, {
|
|
11183
|
+
aggregateOptions: {
|
|
11184
|
+
includeModel: (event) => platform !== "claudeCode" || event.model !== "<synthetic>"
|
|
11185
|
+
}
|
|
11186
|
+
});
|
|
11187
|
+
return {
|
|
11188
|
+
...usage,
|
|
11189
|
+
sessionUsage: sessions
|
|
11190
|
+
};
|
|
11191
|
+
}
|
|
11192
|
+
function getProjectAggregateEvents(sessions) {
|
|
11193
|
+
return sessions.flatMap((session) => session.interactions.filter((interaction) => interaction.usage && interaction.timestamp && hasBillableUsage(interaction.usage)).map((interaction) => {
|
|
11194
|
+
var _a, _b;
|
|
11195
|
+
return {
|
|
11196
|
+
cachedInputTokens: interaction.usage.cachedInputTokens,
|
|
11197
|
+
costUSD: interaction.usage.costUSD,
|
|
11198
|
+
inputTokens: interaction.usage.inputTokens,
|
|
11199
|
+
isFallbackModel: (_a = interaction.usage.isFallbackModel) != null ? _a : false,
|
|
11200
|
+
model: (_b = interaction.model) != null ? _b : session.model,
|
|
11201
|
+
outputTokens: interaction.usage.outputTokens,
|
|
11202
|
+
project: session.project,
|
|
11203
|
+
reasoningOutputTokens: interaction.usage.reasoningOutputTokens,
|
|
11204
|
+
repository: session.repository,
|
|
11205
|
+
sessionId: session.id,
|
|
11206
|
+
timestamp: interaction.timestamp,
|
|
11207
|
+
totalTokens: interaction.usage.totalTokens
|
|
11208
|
+
};
|
|
11209
|
+
})).sort((a, b) => Date.parse(a.timestamp) - Date.parse(b.timestamp));
|
|
11210
|
+
}
|
|
11211
|
+
function hasBillableUsage(usage) {
|
|
11212
|
+
return usage.totalTokens > 0 || usage.costUSD > 0;
|
|
11213
|
+
}
|
|
11214
|
+
function collectSessionModels(sessions) {
|
|
11215
|
+
return uniqueItems(sessions.flatMap((session) => session.models)).sort((a, b) => a.localeCompare(b));
|
|
11216
|
+
}
|
|
11217
|
+
function getEarliestStartedAt(sessions) {
|
|
11218
|
+
var _a;
|
|
11219
|
+
return (_a = sessions.map((session) => session.startedAt).filter((timestamp) => Number.isFinite(Date.parse(timestamp))).sort((a, b) => Date.parse(a) - Date.parse(b))[0]) != null ? _a : null;
|
|
11220
|
+
}
|
|
11221
|
+
|
|
11222
|
+
function buildHomeDashboardModules(dashboardsByPlatform, todayInsights = void 0) {
|
|
11223
|
+
const sessionUsage = buildSessionUsage(dashboardsByPlatform);
|
|
11224
|
+
const dailyTokenUsage = mergeDailyTokenUsage(
|
|
11225
|
+
PROJECT_USAGE_PLATFORMS.flatMap(
|
|
11226
|
+
(platform) => dashboardsByPlatform[platform].dailyTokenUsage.map((item) => {
|
|
11227
|
+
return {
|
|
11228
|
+
...item,
|
|
11229
|
+
platforms: {
|
|
11230
|
+
[platform]: {
|
|
11231
|
+
cachedInputTokens: item.cachedInputTokens,
|
|
11232
|
+
costUSD: item.costUSD,
|
|
11233
|
+
inputTokens: item.inputTokens,
|
|
11234
|
+
models: item.models,
|
|
11235
|
+
outputTokens: item.outputTokens,
|
|
11236
|
+
reasoningOutputTokens: item.reasoningOutputTokens,
|
|
11237
|
+
totalTokens: item.totalTokens
|
|
11238
|
+
}
|
|
11239
|
+
}
|
|
11240
|
+
};
|
|
11241
|
+
})
|
|
11242
|
+
)
|
|
11243
|
+
);
|
|
11244
|
+
const monthlyModelUsage = mergeMonthlyModelUsage(
|
|
11245
|
+
PROJECT_USAGE_PLATFORMS.flatMap((platform) => dashboardsByPlatform[platform].monthlyModelUsage)
|
|
11246
|
+
);
|
|
11247
|
+
const projectUsage = buildProjectUsage(sessionUsage);
|
|
11248
|
+
const totalCost = dailyTokenUsage.reduce((sum, item) => sum + item.costUSD, 0);
|
|
11249
|
+
const totalTokens = dailyTokenUsage.reduce((sum, item) => sum + item.totalTokens, 0);
|
|
11250
|
+
const inputTokens = dailyTokenUsage.reduce((sum, item) => sum + item.inputTokens, 0);
|
|
11251
|
+
const cachedInputTokens = dailyTokenUsage.reduce((sum, item) => sum + item.cachedInputTokens, 0);
|
|
11252
|
+
const outputTokens = dailyTokenUsage.reduce((sum, item) => sum + item.outputTokens, 0);
|
|
11253
|
+
const reasoningOutputTokens = dailyTokenUsage.reduce((sum, item) => sum + item.reasoningOutputTokens, 0);
|
|
11254
|
+
const totalSessions = sessionUsage.length;
|
|
11255
|
+
const efficiencyMetrics = buildEfficiencyMetrics({
|
|
11256
|
+
cachedInputTokens,
|
|
11257
|
+
inputTokens,
|
|
11258
|
+
outputTokens,
|
|
11259
|
+
reasoningOutputTokens,
|
|
11260
|
+
totalTokens
|
|
11261
|
+
});
|
|
11262
|
+
const homeTodayInsights = todayInsights != null ? todayInsights : buildHomeTodayInsights(dashboardsByPlatform);
|
|
11263
|
+
const todayDateKey = getDateKey(/* @__PURE__ */ new Date());
|
|
11264
|
+
const previousDayDateKey = getPreviousDateKey(todayDateKey);
|
|
11265
|
+
const todayUsage = dailyTokenUsage.find((item) => getDateKeyFromLabel(item.date) === todayDateKey);
|
|
11266
|
+
const previousUsage = dailyTokenUsage.find((item) => getDateKeyFromLabel(item.date) === previousDayDateKey);
|
|
11267
|
+
return {
|
|
11268
|
+
dailyTokenUsage,
|
|
11269
|
+
efficiencyMetrics,
|
|
11270
|
+
hotProjects: projectUsage,
|
|
11271
|
+
modelUsage: monthlyModelUsage,
|
|
11272
|
+
overviewCards: buildHomeOverviewCards({
|
|
11273
|
+
cachedInputTokens,
|
|
11274
|
+
inputTokens,
|
|
11275
|
+
previousPromptCount: homeTodayInsights.previousPromptCount,
|
|
11276
|
+
previousSessionCount: homeTodayInsights.previousSessionCount,
|
|
11277
|
+
previousUsage,
|
|
11278
|
+
promptCount: homeTodayInsights.promptCount,
|
|
11279
|
+
sessionCount: homeTodayInsights.sessionCount,
|
|
11280
|
+
todayHourlyUsage: homeTodayInsights.todayHourlyUsage,
|
|
11281
|
+
todayUsage,
|
|
11282
|
+
totalCost,
|
|
11283
|
+
totalSessions,
|
|
11284
|
+
totalTokens
|
|
11285
|
+
}),
|
|
11286
|
+
sessionAnalysis: {
|
|
11287
|
+
items: sessionUsage,
|
|
11288
|
+
totalSessions
|
|
11289
|
+
},
|
|
11290
|
+
todayHourlyUsage: homeTodayInsights.todayHourlyUsage
|
|
11291
|
+
};
|
|
11292
|
+
}
|
|
11293
|
+
function buildSessionUsage(dashboardsByPlatform) {
|
|
11294
|
+
return PROJECT_USAGE_PLATFORMS.flatMap((platform) => dashboardsByPlatform[platform].sessionUsage.map((session) => ({
|
|
11295
|
+
...session,
|
|
11296
|
+
id: `${platform}:${session.id}`,
|
|
11297
|
+
sessionId: `${platform}:${session.sessionId}`
|
|
11298
|
+
}))).sort((a, b) => Date.parse(b.startedAt) - Date.parse(a.startedAt));
|
|
11299
|
+
}
|
|
11300
|
+
function buildHomeOverviewCards(options) {
|
|
11301
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t;
|
|
11302
|
+
const tokenTrend = buildGrowthTrend(
|
|
11303
|
+
(_b = (_a = options.todayUsage) == null ? void 0 : _a.totalTokens) != null ? _b : 0,
|
|
11304
|
+
(_d = (_c = options.previousUsage) == null ? void 0 : _c.totalTokens) != null ? _d : 0,
|
|
11305
|
+
formatCompactNumber
|
|
11306
|
+
);
|
|
11307
|
+
const costTrend = buildGrowthTrend(
|
|
11308
|
+
(_f = (_e = options.todayUsage) == null ? void 0 : _e.costUSD) != null ? _f : 0,
|
|
11309
|
+
(_h = (_g = options.previousUsage) == null ? void 0 : _g.costUSD) != null ? _h : 0,
|
|
11310
|
+
formatCurrency
|
|
11311
|
+
);
|
|
11312
|
+
const sessionTrend = buildPercentTrend(options.sessionCount, options.previousSessionCount);
|
|
11313
|
+
const promptTrend = buildPercentTrend(options.promptCount, options.previousPromptCount);
|
|
11314
|
+
return [
|
|
11315
|
+
{
|
|
11316
|
+
detail: `${formatNumber((_j = (_i = options.todayUsage) == null ? void 0 : _i.totalTokens) != null ? _j : 0)} tokens today. Yesterday: ${formatNumber((_l = (_k = options.previousUsage) == null ? void 0 : _k.totalTokens) != null ? _l : 0)}.`,
|
|
11317
|
+
icon: "solar:cpu-line-duotone",
|
|
11318
|
+
name: "Today Tokens",
|
|
11319
|
+
subvalue: buildInputOutputTokenSubvalue(options.todayUsage),
|
|
11320
|
+
trend: tokenTrend.trend,
|
|
11321
|
+
trendTone: tokenTrend.trendTone,
|
|
11322
|
+
value: formatCompactNumber((_n = (_m = options.todayUsage) == null ? void 0 : _m.totalTokens) != null ? _n : 0)
|
|
11323
|
+
},
|
|
11324
|
+
{
|
|
11325
|
+
detail: `${formatCurrency((_p = (_o = options.todayUsage) == null ? void 0 : _o.costUSD) != null ? _p : 0)} spent today. Yesterday: ${formatCurrency((_r = (_q = options.previousUsage) == null ? void 0 : _q.costUSD) != null ? _r : 0)}.`,
|
|
11326
|
+
icon: "lucide:wallet",
|
|
11327
|
+
name: "Today Spend",
|
|
11328
|
+
subvalue: {
|
|
11329
|
+
items: [
|
|
11330
|
+
{
|
|
11331
|
+
value: `${options.todayHourlyUsage.filter((item) => item.totalTokens > 0).length} active hours`
|
|
11332
|
+
}
|
|
11333
|
+
]
|
|
11334
|
+
},
|
|
11335
|
+
trend: costTrend.trend,
|
|
11336
|
+
trendTone: costTrend.trendTone,
|
|
11337
|
+
value: formatCurrency((_t = (_s = options.todayUsage) == null ? void 0 : _s.costUSD) != null ? _t : 0)
|
|
11338
|
+
},
|
|
11339
|
+
{
|
|
11340
|
+
detail: `${formatNumber(options.sessionCount)} sessions started today. Yesterday: ${formatNumber(options.previousSessionCount)}.`,
|
|
11341
|
+
icon: "lucide:messages-square",
|
|
11342
|
+
name: "Today Sessions",
|
|
11343
|
+
trend: sessionTrend.label,
|
|
11344
|
+
trendTone: sessionTrend.tone,
|
|
11345
|
+
value: formatNumber(options.sessionCount)
|
|
11346
|
+
},
|
|
11347
|
+
{
|
|
11348
|
+
detail: `${formatNumber(options.promptCount)} prompts sent today. Yesterday: ${formatNumber(options.previousPromptCount)}.`,
|
|
11349
|
+
icon: "lucide:square-pen",
|
|
11350
|
+
name: "Prompt Count",
|
|
11351
|
+
trend: promptTrend.label,
|
|
11352
|
+
trendTone: promptTrend.tone,
|
|
11353
|
+
value: formatNumber(options.promptCount)
|
|
11354
|
+
},
|
|
11355
|
+
{
|
|
11356
|
+
detail: `${formatCurrency(options.totalCost)} total spend across all tools`,
|
|
11357
|
+
icon: "lucide:wallet",
|
|
11358
|
+
name: "Total Spend",
|
|
11359
|
+
trend: costTrend.trend,
|
|
11360
|
+
trendTone: costTrend.trendTone,
|
|
11361
|
+
value: formatCurrency(options.totalCost)
|
|
11362
|
+
},
|
|
11363
|
+
{
|
|
11364
|
+
detail: `${formatNumber(options.totalTokens)} total tokens across all tools`,
|
|
11365
|
+
icon: "solar:cpu-line-duotone",
|
|
11366
|
+
name: "Token Usage",
|
|
11367
|
+
trend: tokenTrend.trend,
|
|
11368
|
+
trendTone: tokenTrend.trendTone,
|
|
11369
|
+
value: formatCompactNumber(options.totalTokens)
|
|
11370
|
+
},
|
|
11371
|
+
{
|
|
11372
|
+
detail: `${formatNumber(options.cachedInputTokens)} of ${formatNumber(options.inputTokens)} input tokens were served from cache`,
|
|
11373
|
+
icon: "lucide:database-zap",
|
|
11374
|
+
name: "Cache Hit Rate",
|
|
11375
|
+
trend: `${formatCompactNumber(options.cachedInputTokens)} cached`,
|
|
11376
|
+
trendTone: "neutral",
|
|
11377
|
+
value: formatPercent(options.inputTokens > 0 ? options.cachedInputTokens / options.inputTokens : 0)
|
|
11378
|
+
},
|
|
11379
|
+
{
|
|
11380
|
+
detail: `${formatCurrency(options.totalCost)} across ${formatNumber(options.totalSessions)} sessions`,
|
|
11381
|
+
icon: "lucide:receipt-text",
|
|
11382
|
+
name: "Avg Session Cost",
|
|
11383
|
+
trend: "across all tools",
|
|
11384
|
+
trendTone: "neutral",
|
|
11385
|
+
value: formatCurrency(options.totalSessions > 0 ? options.totalCost / options.totalSessions : 0)
|
|
11386
|
+
}
|
|
11387
|
+
];
|
|
11388
|
+
}
|
|
11389
|
+
function buildHomeTodayInsights(dashboardsByPlatform) {
|
|
11390
|
+
var _a, _b;
|
|
11391
|
+
const todayDateKey = getDateKey(/* @__PURE__ */ new Date());
|
|
11392
|
+
const previousDayDateKey = getPreviousDateKey(todayDateKey);
|
|
11393
|
+
const hourlyUsage = /* @__PURE__ */ new Map();
|
|
11394
|
+
let promptCount = 0;
|
|
11395
|
+
let previousPromptCount = 0;
|
|
11396
|
+
let sessionCount = 0;
|
|
11397
|
+
let previousSessionCount = 0;
|
|
11398
|
+
for (const platform of PROJECT_USAGE_PLATFORMS) {
|
|
11399
|
+
for (const session of dashboardsByPlatform[platform].sessionUsage) {
|
|
11400
|
+
const startedAtDateKey = getDateKeyFromTimestamp(session.startedAt);
|
|
11401
|
+
if (startedAtDateKey === todayDateKey) {
|
|
11402
|
+
sessionCount += 1;
|
|
11403
|
+
} else if (startedAtDateKey === previousDayDateKey) {
|
|
11404
|
+
previousSessionCount += 1;
|
|
11405
|
+
}
|
|
11406
|
+
for (const interaction of session.interactions) {
|
|
11407
|
+
const interactionDateKey = getDateKeyFromTimestamp(interaction.timestamp);
|
|
11408
|
+
if (interaction.role === "user") {
|
|
11409
|
+
if (interactionDateKey === todayDateKey) {
|
|
11410
|
+
promptCount += 1;
|
|
11411
|
+
} else if (interactionDateKey === previousDayDateKey) {
|
|
11412
|
+
previousPromptCount += 1;
|
|
11413
|
+
}
|
|
11414
|
+
}
|
|
11415
|
+
if (!interaction.usage || interactionDateKey !== todayDateKey) {
|
|
11416
|
+
continue;
|
|
11417
|
+
}
|
|
11418
|
+
const interactionDate = new Date(interaction.timestamp);
|
|
11419
|
+
if (!Number.isFinite(interactionDate.getTime())) {
|
|
11420
|
+
continue;
|
|
11421
|
+
}
|
|
11422
|
+
const hour = interactionDate.getHours();
|
|
11423
|
+
const bucket = (_a = hourlyUsage.get(hour)) != null ? _a : {
|
|
11424
|
+
agents: /* @__PURE__ */ new Map(),
|
|
11425
|
+
costUSD: 0,
|
|
11426
|
+
totalTokens: 0
|
|
11427
|
+
};
|
|
11428
|
+
const agentUsage = (_b = bucket.agents.get(platform)) != null ? _b : {
|
|
11429
|
+
costUSD: 0,
|
|
11430
|
+
totalTokens: 0
|
|
11431
|
+
};
|
|
11432
|
+
bucket.costUSD = roundCurrency(bucket.costUSD + interaction.usage.costUSD);
|
|
11433
|
+
bucket.totalTokens += interaction.usage.totalTokens;
|
|
11434
|
+
agentUsage.costUSD = roundCurrency(agentUsage.costUSD + interaction.usage.costUSD);
|
|
11435
|
+
agentUsage.totalTokens += interaction.usage.totalTokens;
|
|
11436
|
+
bucket.agents.set(platform, agentUsage);
|
|
11437
|
+
hourlyUsage.set(hour, bucket);
|
|
11438
|
+
}
|
|
11439
|
+
}
|
|
10293
11440
|
}
|
|
10294
|
-
}
|
|
10295
|
-
|
|
10296
|
-
|
|
10297
|
-
|
|
10298
|
-
|
|
11441
|
+
const todayHourlyUsage = Array.from({ length: 24 }, (_, hour) => {
|
|
11442
|
+
var _a2, _b2, _c, _d, _e, _f;
|
|
11443
|
+
return {
|
|
11444
|
+
agents: Object.fromEntries((_b2 = (_a2 = hourlyUsage.get(hour)) == null ? void 0 : _a2.agents.entries()) != null ? _b2 : []),
|
|
11445
|
+
costUSD: (_d = (_c = hourlyUsage.get(hour)) == null ? void 0 : _c.costUSD) != null ? _d : 0,
|
|
11446
|
+
hour,
|
|
11447
|
+
label: `${String(hour).padStart(2, "0")}:00`,
|
|
11448
|
+
totalTokens: (_f = (_e = hourlyUsage.get(hour)) == null ? void 0 : _e.totalTokens) != null ? _f : 0
|
|
11449
|
+
};
|
|
10299
11450
|
});
|
|
10300
|
-
}
|
|
10301
|
-
function getProjectCatalogType(platforms) {
|
|
10302
|
-
return platforms.length === 1 ? platforms[0] : "mixed";
|
|
10303
|
-
}
|
|
10304
|
-
function buildSessionListModulePayload(sessionRows, sessions) {
|
|
10305
|
-
const sessionList = sessions.map(({ interactions: _interactions, ...session }) => session);
|
|
10306
11451
|
return {
|
|
10307
|
-
|
|
10308
|
-
|
|
10309
|
-
|
|
11452
|
+
previousPromptCount,
|
|
11453
|
+
previousSessionCount,
|
|
11454
|
+
promptCount,
|
|
11455
|
+
sessionCount,
|
|
11456
|
+
todayHourlyUsage
|
|
10310
11457
|
};
|
|
10311
11458
|
}
|
|
10312
|
-
function
|
|
10313
|
-
|
|
10314
|
-
|
|
10315
|
-
|
|
10316
|
-
|
|
10317
|
-
|
|
10318
|
-
buildPlatformModulePayload((_a = detail.analyzing[platform]) != null ? _a : createEmptyProjectPlatformUsage(), module)
|
|
10319
|
-
];
|
|
10320
|
-
})
|
|
10321
|
-
);
|
|
11459
|
+
function getDateKeyFromTimestamp(value) {
|
|
11460
|
+
if (!value) {
|
|
11461
|
+
return null;
|
|
11462
|
+
}
|
|
11463
|
+
const date = new Date(value);
|
|
11464
|
+
return Number.isFinite(date.getTime()) ? getDateKey(date) : null;
|
|
10322
11465
|
}
|
|
10323
|
-
function
|
|
10324
|
-
const
|
|
10325
|
-
|
|
10326
|
-
|
|
11466
|
+
function buildEfficiencyMetrics(options) {
|
|
11467
|
+
const cacheHitRate = options.cachedInputTokens > 0 ? options.inputTokens / options.cachedInputTokens : 0;
|
|
11468
|
+
const reasoningShare = options.reasoningOutputTokens > 0 ? options.totalTokens / options.reasoningOutputTokens : 0;
|
|
11469
|
+
const outputShare = options.outputTokens > 0 ? options.totalTokens / options.outputTokens : 0;
|
|
11470
|
+
return [
|
|
11471
|
+
{
|
|
11472
|
+
detail: `${formatCompactNumber(options.cachedInputTokens)} cached input tokens`,
|
|
11473
|
+
label: "Cache Hit Rate",
|
|
11474
|
+
percent: cacheHitRate * 100,
|
|
11475
|
+
tone: "green",
|
|
11476
|
+
value: formatPercent(cacheHitRate)
|
|
11477
|
+
},
|
|
11478
|
+
{
|
|
11479
|
+
detail: `${formatCompactNumber(options.reasoningOutputTokens)} reasoning output tokens`,
|
|
11480
|
+
label: "Reasoning Token Share",
|
|
11481
|
+
percent: reasoningShare * 100,
|
|
11482
|
+
tone: "amber",
|
|
11483
|
+
value: formatPercent(reasoningShare)
|
|
11484
|
+
},
|
|
11485
|
+
{
|
|
11486
|
+
detail: `${formatCompactNumber(options.outputTokens)} output tokens`,
|
|
11487
|
+
label: "Output Token Share",
|
|
11488
|
+
percent: outputShare * 100,
|
|
11489
|
+
tone: "sky",
|
|
11490
|
+
value: formatPercent(outputShare)
|
|
10327
11491
|
}
|
|
10328
|
-
|
|
10329
|
-
return {
|
|
10330
|
-
...usage,
|
|
10331
|
-
sessionUsage: sessions
|
|
10332
|
-
};
|
|
10333
|
-
}
|
|
10334
|
-
function getProjectAggregateEvents(sessions) {
|
|
10335
|
-
return sessions.flatMap((session) => session.interactions.filter((interaction) => interaction.usage && interaction.timestamp && hasBillableUsage(interaction.usage)).map((interaction) => {
|
|
10336
|
-
var _a, _b;
|
|
10337
|
-
return {
|
|
10338
|
-
cachedInputTokens: interaction.usage.cachedInputTokens,
|
|
10339
|
-
costUSD: interaction.usage.costUSD,
|
|
10340
|
-
inputTokens: interaction.usage.inputTokens,
|
|
10341
|
-
isFallbackModel: (_a = interaction.usage.isFallbackModel) != null ? _a : false,
|
|
10342
|
-
model: (_b = interaction.model) != null ? _b : session.model,
|
|
10343
|
-
outputTokens: interaction.usage.outputTokens,
|
|
10344
|
-
project: session.project,
|
|
10345
|
-
reasoningOutputTokens: interaction.usage.reasoningOutputTokens,
|
|
10346
|
-
repository: session.repository,
|
|
10347
|
-
sessionId: session.sessionId,
|
|
10348
|
-
timestamp: interaction.timestamp,
|
|
10349
|
-
totalTokens: interaction.usage.totalTokens
|
|
10350
|
-
};
|
|
10351
|
-
})).sort((a, b) => Date.parse(a.timestamp) - Date.parse(b.timestamp));
|
|
10352
|
-
}
|
|
10353
|
-
function hasBillableUsage(usage) {
|
|
10354
|
-
return usage.totalTokens > 0 || usage.costUSD > 0;
|
|
10355
|
-
}
|
|
10356
|
-
function collectSessionModels(sessions) {
|
|
10357
|
-
return uniqueItems(sessions.flatMap((session) => session.models)).sort((a, b) => a.localeCompare(b));
|
|
10358
|
-
}
|
|
10359
|
-
function getEarliestStartedAt(sessions) {
|
|
10360
|
-
var _a;
|
|
10361
|
-
return (_a = sessions.map((session) => session.startedAt).filter((timestamp) => Number.isFinite(Date.parse(timestamp))).sort((a, b) => Date.parse(a) - Date.parse(b))[0]) != null ? _a : null;
|
|
11492
|
+
];
|
|
10362
11493
|
}
|
|
10363
11494
|
|
|
10364
11495
|
var __defProp = Object.defineProperty;
|
|
@@ -10374,7 +11505,7 @@ class UsageDataRuntime {
|
|
|
10374
11505
|
bootstrap: null,
|
|
10375
11506
|
hydratedAt: 0,
|
|
10376
11507
|
projectCatalog: [],
|
|
10377
|
-
projectDetails:
|
|
11508
|
+
projectDetails: null,
|
|
10378
11509
|
refreshStartedAt: 0
|
|
10379
11510
|
});
|
|
10380
11511
|
__publicField(this, "initializePromise", null);
|
|
@@ -10389,7 +11520,6 @@ class UsageDataRuntime {
|
|
|
10389
11520
|
if (!this.initializePromise) {
|
|
10390
11521
|
this.initializePromise = this.hydrateFromRepository().finally(() => {
|
|
10391
11522
|
this.startWatcher();
|
|
10392
|
-
void this.refreshInBackground();
|
|
10393
11523
|
});
|
|
10394
11524
|
}
|
|
10395
11525
|
return this.initializePromise;
|
|
@@ -10405,7 +11535,7 @@ class UsageDataRuntime {
|
|
|
10405
11535
|
}
|
|
10406
11536
|
async getProjectCatalog() {
|
|
10407
11537
|
await this.initialize();
|
|
10408
|
-
if (this.state.projectCatalog.length === 0
|
|
11538
|
+
if (this.state.projectCatalog.length === 0) {
|
|
10409
11539
|
await this.refreshNow();
|
|
10410
11540
|
} else {
|
|
10411
11541
|
this.scheduleRefreshIfStale();
|
|
@@ -10417,12 +11547,18 @@ class UsageDataRuntime {
|
|
|
10417
11547
|
const bootstrap = await this.getBootstrap();
|
|
10418
11548
|
return (_a = bootstrap[platform]) != null ? _a : createEmptyLoadUsageResult();
|
|
10419
11549
|
}
|
|
11550
|
+
async getHomeDashboardModules() {
|
|
11551
|
+
return buildHomeDashboardModules(await this.getBootstrap(), this.repository.loadHomeDashboardTodayInsights());
|
|
11552
|
+
}
|
|
10420
11553
|
async getProjectDataModules(request) {
|
|
10421
11554
|
await this.initialize();
|
|
10422
11555
|
const projectLabel = (request.project || "").trim();
|
|
10423
11556
|
if (!projectLabel) {
|
|
10424
11557
|
throw new Error("Missing project name for project data request.");
|
|
10425
11558
|
}
|
|
11559
|
+
if (this.state.projectDetails === null) {
|
|
11560
|
+
this.state.projectDetails = this.repository.loadProjectDetails();
|
|
11561
|
+
}
|
|
10426
11562
|
const detail = this.state.projectDetails.get(projectLabel);
|
|
10427
11563
|
if (!detail) {
|
|
10428
11564
|
await this.refreshNow();
|
|
@@ -10443,10 +11579,8 @@ class UsageDataRuntime {
|
|
|
10443
11579
|
var _a, _b;
|
|
10444
11580
|
const bootstrap = this.repository.loadBootstrap();
|
|
10445
11581
|
const projectCatalog = this.repository.loadProjectCatalog();
|
|
10446
|
-
const projectDetails = this.repository.loadProjectDetails();
|
|
10447
11582
|
this.state.bootstrap = (_a = bootstrap == null ? void 0 : bootstrap.payload) != null ? _a : null;
|
|
10448
11583
|
this.state.projectCatalog = (_b = projectCatalog == null ? void 0 : projectCatalog.payload) != null ? _b : [];
|
|
10449
|
-
this.state.projectDetails = projectDetails;
|
|
10450
11584
|
this.state.hydratedAt = Math.max(
|
|
10451
11585
|
bootstrap ? Date.parse(bootstrap.updatedAt) : 0,
|
|
10452
11586
|
projectCatalog ? Date.parse(projectCatalog.updatedAt) : 0
|
|
@@ -10491,14 +11625,16 @@ class UsageDataRuntime {
|
|
|
10491
11625
|
),
|
|
10492
11626
|
version: this.config.version
|
|
10493
11627
|
};
|
|
10494
|
-
const projectDetails = this.state.projectDetails
|
|
11628
|
+
const projectDetails = this.state.projectDetails ? patchProjectDetails(this.state.projectDetails, indexed.removedProjects, indexed.affectedProjects, bootstrapByPlatform) : buildAllProjectDetails(bootstrapByPlatform);
|
|
10495
11629
|
const projectCatalog = buildProjectUsageCatalogItemsFromDetails(projectDetails.entries());
|
|
10496
11630
|
this.repository.saveBootstrap(bootstrap);
|
|
10497
11631
|
this.repository.saveProjectCatalog(projectCatalog);
|
|
10498
11632
|
this.repository.replaceProjectDetails(projectDetails);
|
|
10499
11633
|
this.state.bootstrap = bootstrap;
|
|
10500
11634
|
this.state.projectCatalog = projectCatalog;
|
|
10501
|
-
this.state.projectDetails
|
|
11635
|
+
if (this.state.projectDetails) {
|
|
11636
|
+
this.state.projectDetails = projectDetails;
|
|
11637
|
+
}
|
|
10502
11638
|
this.state.hydratedAt = Date.now();
|
|
10503
11639
|
}
|
|
10504
11640
|
dispose() {
|
|
@@ -10799,156 +11935,163 @@ const assets = {
|
|
|
10799
11935
|
"/logo.svg": {
|
|
10800
11936
|
"type": "image/svg+xml",
|
|
10801
11937
|
"etag": "\"1550-fwYFdULdJ83Qp0FjnnX31iQz9oI\"",
|
|
10802
|
-
"mtime": "2026-05-
|
|
11938
|
+
"mtime": "2026-05-26T08:31:48.218Z",
|
|
10803
11939
|
"size": 5456,
|
|
10804
11940
|
"path": "../public/logo.svg"
|
|
10805
11941
|
},
|
|
10806
11942
|
"/robots.txt": {
|
|
10807
11943
|
"type": "text/plain; charset=utf-8",
|
|
10808
11944
|
"etag": "\"18-j8OIsL9qGDmNZ+lHhp2tyH4XtaE\"",
|
|
10809
|
-
"mtime": "2026-05-
|
|
11945
|
+
"mtime": "2026-05-26T08:31:48.218Z",
|
|
10810
11946
|
"size": 24,
|
|
10811
11947
|
"path": "../public/robots.txt"
|
|
10812
11948
|
},
|
|
11949
|
+
"/_nuxt/37OOe3RF.js": {
|
|
11950
|
+
"type": "text/javascript; charset=utf-8",
|
|
11951
|
+
"etag": "\"433-9g1fS7jC4SfhMOz/zYtzEkjj3l4\"",
|
|
11952
|
+
"mtime": "2026-05-26T08:31:48.215Z",
|
|
11953
|
+
"size": 1075,
|
|
11954
|
+
"path": "../public/_nuxt/37OOe3RF.js"
|
|
11955
|
+
},
|
|
10813
11956
|
"/favicon.ico": {
|
|
10814
11957
|
"type": "image/vnd.microsoft.icon",
|
|
10815
11958
|
"etag": "\"1083e-LfyFZ+1JmdianDqe/sQN2Ou0IzQ\"",
|
|
10816
|
-
"mtime": "2026-05-
|
|
11959
|
+
"mtime": "2026-05-26T08:31:48.218Z",
|
|
10817
11960
|
"size": 67646,
|
|
10818
11961
|
"path": "../public/favicon.ico"
|
|
10819
11962
|
},
|
|
10820
|
-
"/_nuxt/
|
|
11963
|
+
"/_nuxt/65Ayv2XK.js": {
|
|
10821
11964
|
"type": "text/javascript; charset=utf-8",
|
|
10822
|
-
"etag": "\"
|
|
10823
|
-
"mtime": "2026-05-
|
|
10824
|
-
"size":
|
|
10825
|
-
"path": "../public/_nuxt/
|
|
11965
|
+
"etag": "\"bb0d-ldbgmGlpc1qx4bYEx4cXkSFSCg8\"",
|
|
11966
|
+
"mtime": "2026-05-26T08:31:48.215Z",
|
|
11967
|
+
"size": 47885,
|
|
11968
|
+
"path": "../public/_nuxt/65Ayv2XK.js"
|
|
10826
11969
|
},
|
|
10827
|
-
"/_nuxt/
|
|
11970
|
+
"/_nuxt/BOWwkrCY.js": {
|
|
10828
11971
|
"type": "text/javascript; charset=utf-8",
|
|
10829
|
-
"etag": "\"
|
|
10830
|
-
"mtime": "2026-05-
|
|
10831
|
-
"size":
|
|
10832
|
-
"path": "../public/_nuxt/
|
|
11972
|
+
"etag": "\"540a-Q/6WhDpXkujbyVqTxKp+MDIjyN8\"",
|
|
11973
|
+
"mtime": "2026-05-26T08:31:48.215Z",
|
|
11974
|
+
"size": 21514,
|
|
11975
|
+
"path": "../public/_nuxt/BOWwkrCY.js"
|
|
10833
11976
|
},
|
|
10834
|
-
"/_nuxt/
|
|
11977
|
+
"/_nuxt/D7qEPtpx.js": {
|
|
10835
11978
|
"type": "text/javascript; charset=utf-8",
|
|
10836
|
-
"etag": "\"
|
|
10837
|
-
"mtime": "2026-05-
|
|
10838
|
-
"size":
|
|
10839
|
-
"path": "../public/_nuxt/
|
|
11979
|
+
"etag": "\"eb4-cYfHtGVwvBnjUla1c7r6p8WQ+fU\"",
|
|
11980
|
+
"mtime": "2026-05-26T08:31:48.215Z",
|
|
11981
|
+
"size": 3764,
|
|
11982
|
+
"path": "../public/_nuxt/D7qEPtpx.js"
|
|
10840
11983
|
},
|
|
10841
|
-
"/_nuxt/
|
|
11984
|
+
"/_nuxt/D9-Yw1TR.js": {
|
|
10842
11985
|
"type": "text/javascript; charset=utf-8",
|
|
10843
|
-
"etag": "\"
|
|
10844
|
-
"mtime": "2026-05-
|
|
10845
|
-
"size":
|
|
10846
|
-
"path": "../public/_nuxt/
|
|
11986
|
+
"etag": "\"42dc-z2VCBVgr0YDv874MuLF5LmD+w6g\"",
|
|
11987
|
+
"mtime": "2026-05-26T08:31:48.215Z",
|
|
11988
|
+
"size": 17116,
|
|
11989
|
+
"path": "../public/_nuxt/D9-Yw1TR.js"
|
|
10847
11990
|
},
|
|
10848
|
-
"/_nuxt/
|
|
11991
|
+
"/_nuxt/DF2WsXH3.js": {
|
|
10849
11992
|
"type": "text/javascript; charset=utf-8",
|
|
10850
|
-
"etag": "\"
|
|
10851
|
-
"mtime": "2026-05-
|
|
10852
|
-
"size":
|
|
10853
|
-
"path": "../public/_nuxt/
|
|
11993
|
+
"etag": "\"101-2rfNy5z/IaUQM5ONN45oT3dPyOw\"",
|
|
11994
|
+
"mtime": "2026-05-26T08:31:48.215Z",
|
|
11995
|
+
"size": 257,
|
|
11996
|
+
"path": "../public/_nuxt/DF2WsXH3.js"
|
|
10854
11997
|
},
|
|
10855
|
-
"/_nuxt/
|
|
11998
|
+
"/_nuxt/C0GhHHgI.js": {
|
|
10856
11999
|
"type": "text/javascript; charset=utf-8",
|
|
10857
|
-
"etag": "\"
|
|
10858
|
-
"mtime": "2026-05-
|
|
10859
|
-
"size":
|
|
10860
|
-
"path": "../public/_nuxt/
|
|
12000
|
+
"etag": "\"cf91-HNazofOinHCfSBf403LLacaEnfc\"",
|
|
12001
|
+
"mtime": "2026-05-26T08:31:48.215Z",
|
|
12002
|
+
"size": 53137,
|
|
12003
|
+
"path": "../public/_nuxt/C0GhHHgI.js"
|
|
10861
12004
|
},
|
|
10862
|
-
"/_nuxt/
|
|
12005
|
+
"/_nuxt/DXWxIyGU.js": {
|
|
10863
12006
|
"type": "text/javascript; charset=utf-8",
|
|
10864
|
-
"etag": "\"
|
|
10865
|
-
"mtime": "2026-05-
|
|
10866
|
-
"size":
|
|
10867
|
-
"path": "../public/_nuxt/
|
|
12007
|
+
"etag": "\"d7b-TUo4s2vJwQ7SvlmJq8Lc5JpszPo\"",
|
|
12008
|
+
"mtime": "2026-05-26T08:31:48.216Z",
|
|
12009
|
+
"size": 3451,
|
|
12010
|
+
"path": "../public/_nuxt/DXWxIyGU.js"
|
|
12011
|
+
},
|
|
12012
|
+
"/_nuxt/De8DvPWL.js": {
|
|
12013
|
+
"type": "text/javascript; charset=utf-8",
|
|
12014
|
+
"etag": "\"14f9-ru/D4lCOWqCP3lvQM3EWGPMYRaw\"",
|
|
12015
|
+
"mtime": "2026-05-26T08:31:48.215Z",
|
|
12016
|
+
"size": 5369,
|
|
12017
|
+
"path": "../public/_nuxt/De8DvPWL.js"
|
|
10868
12018
|
},
|
|
10869
|
-
"/_nuxt/
|
|
12019
|
+
"/_nuxt/DKaPq50Z.js": {
|
|
10870
12020
|
"type": "text/javascript; charset=utf-8",
|
|
10871
|
-
"etag": "\"
|
|
10872
|
-
"mtime": "2026-05-
|
|
10873
|
-
"size":
|
|
10874
|
-
"path": "../public/_nuxt/
|
|
12021
|
+
"etag": "\"f34c-URgC7Dz0Xf+JUUuL4yo1mSHnYmQ\"",
|
|
12022
|
+
"mtime": "2026-05-26T08:31:48.216Z",
|
|
12023
|
+
"size": 62284,
|
|
12024
|
+
"path": "../public/_nuxt/DKaPq50Z.js"
|
|
10875
12025
|
},
|
|
10876
|
-
"/_nuxt/
|
|
12026
|
+
"/_nuxt/DxvuOJRP.js": {
|
|
10877
12027
|
"type": "text/javascript; charset=utf-8",
|
|
10878
|
-
"etag": "\"
|
|
10879
|
-
"mtime": "2026-05-
|
|
10880
|
-
"size":
|
|
10881
|
-
"path": "../public/_nuxt/
|
|
12028
|
+
"etag": "\"10890-8PgC64ZUxoVro0//XJbLva3lqK0\"",
|
|
12029
|
+
"mtime": "2026-05-26T08:31:48.216Z",
|
|
12030
|
+
"size": 67728,
|
|
12031
|
+
"path": "../public/_nuxt/DxvuOJRP.js"
|
|
10882
12032
|
},
|
|
10883
|
-
"/_nuxt/
|
|
12033
|
+
"/_nuxt/DgMMKsPE.js": {
|
|
10884
12034
|
"type": "text/javascript; charset=utf-8",
|
|
10885
|
-
"etag": "\"
|
|
10886
|
-
"mtime": "2026-05-
|
|
10887
|
-
"size":
|
|
10888
|
-
"path": "../public/_nuxt/
|
|
12035
|
+
"etag": "\"35763-ZIXCcb7yuHkNvDqXH2EEhwlcyV4\"",
|
|
12036
|
+
"mtime": "2026-05-26T08:31:48.216Z",
|
|
12037
|
+
"size": 218979,
|
|
12038
|
+
"path": "../public/_nuxt/DgMMKsPE.js"
|
|
10889
12039
|
},
|
|
10890
|
-
"/_nuxt/
|
|
12040
|
+
"/_nuxt/Jp5cgQZi.js": {
|
|
10891
12041
|
"type": "text/javascript; charset=utf-8",
|
|
10892
|
-
"etag": "\"
|
|
10893
|
-
"mtime": "2026-05-
|
|
10894
|
-
"size":
|
|
10895
|
-
"path": "../public/_nuxt/
|
|
12042
|
+
"etag": "\"3c6da-89AEgPN5OI/3SCYBdFqSxRLSihE\"",
|
|
12043
|
+
"mtime": "2026-05-26T08:31:48.216Z",
|
|
12044
|
+
"size": 247514,
|
|
12045
|
+
"path": "../public/_nuxt/Jp5cgQZi.js"
|
|
10896
12046
|
},
|
|
10897
12047
|
"/_nuxt/error-404.CFBEg71j.css": {
|
|
10898
12048
|
"type": "text/css; charset=utf-8",
|
|
10899
12049
|
"etag": "\"97e-GvhaEAryQvrSXyDcP4RiHXzYb5o\"",
|
|
10900
|
-
"mtime": "2026-05-
|
|
12050
|
+
"mtime": "2026-05-26T08:31:48.216Z",
|
|
10901
12051
|
"size": 2430,
|
|
10902
12052
|
"path": "../public/_nuxt/error-404.CFBEg71j.css"
|
|
10903
12053
|
},
|
|
10904
12054
|
"/_nuxt/error-500.BqCnH31G.css": {
|
|
10905
12055
|
"type": "text/css; charset=utf-8",
|
|
10906
12056
|
"etag": "\"773-Tpf6lA6A2FEDtjLyWUXKolBZ3hM\"",
|
|
10907
|
-
"mtime": "2026-05-
|
|
12057
|
+
"mtime": "2026-05-26T08:31:48.216Z",
|
|
10908
12058
|
"size": 1907,
|
|
10909
12059
|
"path": "../public/_nuxt/error-500.BqCnH31G.css"
|
|
10910
12060
|
},
|
|
10911
|
-
"/_nuxt/
|
|
12061
|
+
"/_nuxt/qXgLTL_3.js": {
|
|
10912
12062
|
"type": "text/javascript; charset=utf-8",
|
|
10913
|
-
"etag": "\"
|
|
10914
|
-
"mtime": "2026-05-
|
|
10915
|
-
"size":
|
|
10916
|
-
"path": "../public/_nuxt/
|
|
12063
|
+
"etag": "\"993e-F6dGXZ77Rf6Afn6RLLvwifZFe5Q\"",
|
|
12064
|
+
"mtime": "2026-05-26T08:31:48.216Z",
|
|
12065
|
+
"size": 39230,
|
|
12066
|
+
"path": "../public/_nuxt/qXgLTL_3.js"
|
|
12067
|
+
},
|
|
12068
|
+
"/_nuxt/y6mAKUDU.js": {
|
|
12069
|
+
"type": "text/javascript; charset=utf-8",
|
|
12070
|
+
"etag": "\"2c57-7lVqV+qTY/Dqb4M0PdxYAItocQw\"",
|
|
12071
|
+
"mtime": "2026-05-26T08:31:48.216Z",
|
|
12072
|
+
"size": 11351,
|
|
12073
|
+
"path": "../public/_nuxt/y6mAKUDU.js"
|
|
10917
12074
|
},
|
|
10918
12075
|
"/_nuxt/builds/latest.json": {
|
|
10919
12076
|
"type": "application/json",
|
|
10920
|
-
"etag": "\"47-
|
|
10921
|
-
"mtime": "2026-05-
|
|
12077
|
+
"etag": "\"47-yneWhd0H1nYqEdMbDKqzhQJ6sxE\"",
|
|
12078
|
+
"mtime": "2026-05-26T08:31:48.213Z",
|
|
10922
12079
|
"size": 71,
|
|
10923
12080
|
"path": "../public/_nuxt/builds/latest.json"
|
|
10924
12081
|
},
|
|
10925
|
-
"/_nuxt/builds/meta/
|
|
12082
|
+
"/_nuxt/builds/meta/7ce9c611-6071-4cbd-8926-1e53d9ef21bd.json": {
|
|
10926
12083
|
"type": "application/json",
|
|
10927
|
-
"etag": "\"58-
|
|
10928
|
-
"mtime": "2026-05-
|
|
12084
|
+
"etag": "\"58-ozcqeghbP4BbYZVRtP6bwTCHhN8\"",
|
|
12085
|
+
"mtime": "2026-05-26T08:31:48.211Z",
|
|
10929
12086
|
"size": 88,
|
|
10930
|
-
"path": "../public/_nuxt/builds/meta/
|
|
10931
|
-
},
|
|
10932
|
-
"/_nuxt/DgKrPjze.js": {
|
|
10933
|
-
"type": "text/javascript; charset=utf-8",
|
|
10934
|
-
"etag": "\"35466-BQwxEwkorZeoi3JtsQAovpFUAlE\"",
|
|
10935
|
-
"mtime": "2026-05-22T15:27:58.715Z",
|
|
10936
|
-
"size": 218214,
|
|
10937
|
-
"path": "../public/_nuxt/DgKrPjze.js"
|
|
12087
|
+
"path": "../public/_nuxt/builds/meta/7ce9c611-6071-4cbd-8926-1e53d9ef21bd.json"
|
|
10938
12088
|
},
|
|
10939
|
-
"/_nuxt/entry.
|
|
12089
|
+
"/_nuxt/entry.DnkKc-6G.css": {
|
|
10940
12090
|
"type": "text/css; charset=utf-8",
|
|
10941
|
-
"etag": "\"
|
|
10942
|
-
"mtime": "2026-05-
|
|
10943
|
-
"size":
|
|
10944
|
-
"path": "../public/_nuxt/entry.
|
|
10945
|
-
},
|
|
10946
|
-
"/_nuxt/DtbPvE6R.js": {
|
|
10947
|
-
"type": "text/javascript; charset=utf-8",
|
|
10948
|
-
"etag": "\"4135e-cTbNR7mK7vcfB4JteOXxth6FUlY\"",
|
|
10949
|
-
"mtime": "2026-05-22T15:27:58.716Z",
|
|
10950
|
-
"size": 267102,
|
|
10951
|
-
"path": "../public/_nuxt/DtbPvE6R.js"
|
|
12091
|
+
"etag": "\"1d8a6-KK9a3JMzAwbSGw5SnlSiODNKxHg\"",
|
|
12092
|
+
"mtime": "2026-05-26T08:31:48.216Z",
|
|
12093
|
+
"size": 120998,
|
|
12094
|
+
"path": "../public/_nuxt/entry.DnkKc-6G.css"
|
|
10952
12095
|
}
|
|
10953
12096
|
};
|
|
10954
12097
|
|
|
@@ -11444,9 +12587,13 @@ const inlineConfig = {
|
|
|
11444
12587
|
"wi",
|
|
11445
12588
|
"wpf",
|
|
11446
12589
|
"zmdi",
|
|
11447
|
-
"zondicons"
|
|
12590
|
+
"zondicons",
|
|
12591
|
+
"ai"
|
|
11448
12592
|
],
|
|
11449
|
-
"fetchTimeout": 1500
|
|
12593
|
+
"fetchTimeout": 1500,
|
|
12594
|
+
"customCollections": [
|
|
12595
|
+
"ai"
|
|
12596
|
+
]
|
|
11450
12597
|
}
|
|
11451
12598
|
};
|
|
11452
12599
|
|
|
@@ -11472,239 +12619,110 @@ function _deepFreeze(object) {
|
|
|
11472
12619
|
return Object.freeze(object);
|
|
11473
12620
|
}
|
|
11474
12621
|
|
|
11475
|
-
|
|
11476
|
-
|
|
11477
|
-
|
|
11478
|
-
|
|
11479
|
-
|
|
11480
|
-
|
|
11481
|
-
|
|
11482
|
-
PROJECT_USAGE_PLATFORMS.flatMap((platform) => getPlatformDashboard(dashboardsByPlatform, platform).monthlyModelUsage)
|
|
11483
|
-
);
|
|
11484
|
-
const projectUsage = buildProjectUsage(sessionUsage);
|
|
11485
|
-
const totalCost = dailyTokenUsage.reduce((sum, item) => sum + item.costUSD, 0);
|
|
11486
|
-
const totalTokens = dailyTokenUsage.reduce((sum, item) => sum + item.totalTokens, 0);
|
|
11487
|
-
const inputTokens = dailyTokenUsage.reduce((sum, item) => sum + item.inputTokens, 0);
|
|
11488
|
-
const cachedInputTokens = dailyTokenUsage.reduce((sum, item) => sum + item.cachedInputTokens, 0);
|
|
11489
|
-
const outputTokens = dailyTokenUsage.reduce((sum, item) => sum + item.outputTokens, 0);
|
|
11490
|
-
const reasoningOutputTokens = dailyTokenUsage.reduce((sum, item) => sum + item.reasoningOutputTokens, 0);
|
|
11491
|
-
const totalSessions = sessionUsage.length;
|
|
11492
|
-
const todayDateKey = getDateKey(/* @__PURE__ */ new Date());
|
|
11493
|
-
const previousDayDateKey = getPreviousDateKey(todayDateKey);
|
|
11494
|
-
const todayDailyUsage = dailyTokenUsage.find((item) => getDateKeyFromLabel(item.date) === todayDateKey);
|
|
11495
|
-
const previousDayDailyUsage = dailyTokenUsage.find((item) => getDateKeyFromLabel(item.date) === previousDayDateKey);
|
|
11496
|
-
const costGrowthTrend = buildGrowthTrend(
|
|
11497
|
-
(_a = todayDailyUsage == null ? void 0 : todayDailyUsage.costUSD) != null ? _a : 0,
|
|
11498
|
-
(_b = previousDayDailyUsage == null ? void 0 : previousDayDailyUsage.costUSD) != null ? _b : 0,
|
|
11499
|
-
formatCurrency
|
|
11500
|
-
);
|
|
11501
|
-
const tokenGrowthTrend = buildGrowthTrend(
|
|
11502
|
-
(_c = todayDailyUsage == null ? void 0 : todayDailyUsage.totalTokens) != null ? _c : 0,
|
|
11503
|
-
(_d = previousDayDailyUsage == null ? void 0 : previousDayDailyUsage.totalTokens) != null ? _d : 0,
|
|
11504
|
-
formatCompactNumber
|
|
11505
|
-
);
|
|
11506
|
-
const efficiencyMetrics = buildEfficiencyMetrics({
|
|
11507
|
-
cachedInputTokens,
|
|
11508
|
-
inputTokens,
|
|
11509
|
-
outputTokens,
|
|
11510
|
-
reasoningOutputTokens,
|
|
11511
|
-
totalTokens
|
|
11512
|
-
});
|
|
11513
|
-
return {
|
|
11514
|
-
dailyTokenUsage,
|
|
11515
|
-
efficiencyMetrics,
|
|
11516
|
-
hotProjects: projectUsage,
|
|
11517
|
-
modelUsage: monthlyModelUsage,
|
|
11518
|
-
overviewCards: buildHomeOverviewCards({
|
|
11519
|
-
cachedInputTokens,
|
|
11520
|
-
costGrowthTrend,
|
|
11521
|
-
inputTokens,
|
|
11522
|
-
tokenGrowthTrend,
|
|
11523
|
-
totalCost,
|
|
11524
|
-
totalSessions,
|
|
11525
|
-
totalTokens
|
|
11526
|
-
}),
|
|
11527
|
-
sessionAnalysis: {
|
|
11528
|
-
items: sessionUsage,
|
|
11529
|
-
totalSessions
|
|
11530
|
-
}
|
|
11531
|
-
};
|
|
11532
|
-
}
|
|
11533
|
-
function getPlatformDashboard(dashboardsByPlatform, platform) {
|
|
11534
|
-
return dashboardsByPlatform[platform];
|
|
11535
|
-
}
|
|
11536
|
-
function buildSessionUsage(dashboardsByPlatform) {
|
|
11537
|
-
return PROJECT_USAGE_PLATFORMS.flatMap((platform) => getPlatformDashboard(dashboardsByPlatform, platform).sessionUsage.map((session) => ({
|
|
11538
|
-
...session,
|
|
11539
|
-
id: `${platform}:${session.id}`,
|
|
11540
|
-
sessionId: `${platform}:${session.sessionId}`
|
|
11541
|
-
}))).sort((a, b) => Date.parse(b.startedAt) - Date.parse(a.startedAt));
|
|
11542
|
-
}
|
|
11543
|
-
function buildHomeOverviewCards(options) {
|
|
11544
|
-
return [
|
|
11545
|
-
{
|
|
11546
|
-
detail: `${formatCurrency(options.totalCost)} total spend across all tools`,
|
|
11547
|
-
icon: "lucide:wallet",
|
|
11548
|
-
name: "Total Spend",
|
|
11549
|
-
trend: options.costGrowthTrend.trend,
|
|
11550
|
-
trendTone: options.costGrowthTrend.trendTone,
|
|
11551
|
-
value: formatCurrency(options.totalCost)
|
|
11552
|
-
},
|
|
11553
|
-
{
|
|
11554
|
-
detail: `${formatNumber(options.totalTokens)} total tokens across all tools`,
|
|
11555
|
-
icon: "solar:cpu-line-duotone",
|
|
11556
|
-
name: "Token Usage",
|
|
11557
|
-
trend: options.tokenGrowthTrend.trend,
|
|
11558
|
-
trendTone: options.tokenGrowthTrend.trendTone,
|
|
11559
|
-
value: formatCompactNumber(options.totalTokens)
|
|
11560
|
-
},
|
|
11561
|
-
{
|
|
11562
|
-
detail: `${formatNumber(options.cachedInputTokens)} of ${formatNumber(options.inputTokens)} input tokens were served from cache`,
|
|
11563
|
-
icon: "lucide:database-zap",
|
|
11564
|
-
name: "Cache Hit Rate",
|
|
11565
|
-
trend: `${formatCompactNumber(options.cachedInputTokens)} cached`,
|
|
11566
|
-
trendTone: "neutral",
|
|
11567
|
-
value: formatPercent(options.inputTokens > 0 ? options.cachedInputTokens / options.inputTokens : 0)
|
|
11568
|
-
},
|
|
11569
|
-
{
|
|
11570
|
-
detail: `${formatCurrency(options.totalCost)} across ${formatNumber(options.totalSessions)} sessions`,
|
|
11571
|
-
icon: "lucide:receipt-text",
|
|
11572
|
-
name: "Avg Session Cost",
|
|
11573
|
-
trend: "across all tools",
|
|
11574
|
-
trendTone: "neutral",
|
|
11575
|
-
value: formatCurrency(options.totalSessions > 0 ? options.totalCost / options.totalSessions : 0)
|
|
11576
|
-
}
|
|
11577
|
-
];
|
|
11578
|
-
}
|
|
11579
|
-
function buildEfficiencyMetrics(options) {
|
|
11580
|
-
const cacheHitRate = safeRatio(options.cachedInputTokens, options.inputTokens);
|
|
11581
|
-
const reasoningShare = safeRatio(options.reasoningOutputTokens, options.totalTokens);
|
|
11582
|
-
const outputShare = safeRatio(options.outputTokens, options.totalTokens);
|
|
11583
|
-
return [
|
|
11584
|
-
{
|
|
11585
|
-
detail: `${formatCompactNumber(options.cachedInputTokens)} cached input tokens`,
|
|
11586
|
-
label: "Cache Hit Rate",
|
|
11587
|
-
percent: cacheHitRate * 100,
|
|
11588
|
-
tone: "green",
|
|
11589
|
-
value: formatPercent(cacheHitRate)
|
|
11590
|
-
},
|
|
11591
|
-
{
|
|
11592
|
-
detail: `${formatCompactNumber(options.reasoningOutputTokens)} reasoning output tokens`,
|
|
11593
|
-
label: "Reasoning Token Share",
|
|
11594
|
-
percent: reasoningShare * 100,
|
|
11595
|
-
tone: "amber",
|
|
11596
|
-
value: formatPercent(reasoningShare)
|
|
11597
|
-
},
|
|
11598
|
-
{
|
|
11599
|
-
detail: `${formatCompactNumber(options.outputTokens)} output tokens`,
|
|
11600
|
-
label: "Output Token Share",
|
|
11601
|
-
percent: outputShare * 100,
|
|
11602
|
-
tone: "sky",
|
|
11603
|
-
value: formatPercent(outputShare)
|
|
11604
|
-
}
|
|
11605
|
-
];
|
|
11606
|
-
}
|
|
11607
|
-
function safeRatio(numerator, denominator) {
|
|
11608
|
-
return denominator > 0 ? numerator / denominator : 0;
|
|
11609
|
-
}
|
|
12622
|
+
const ANALYSIS_AGENT_TOKEN_TYPES = ["day", "week", "month", "session"];
|
|
12623
|
+
const ANALYSIS_AGENT_TOKEN_ROW_KEYS = {
|
|
12624
|
+
day: "dailyRows",
|
|
12625
|
+
month: "monthlyRows",
|
|
12626
|
+
session: "sessionRows",
|
|
12627
|
+
week: "weeklyRows"
|
|
12628
|
+
};
|
|
11610
12629
|
|
|
11611
12630
|
const PROJECT_USAGE_PLATFORM_META = {
|
|
11612
12631
|
amp: {
|
|
11613
|
-
aiIcon: "amp",
|
|
12632
|
+
aiIcon: "ai:amp",
|
|
11614
12633
|
color: "#f34e3f",
|
|
11615
12634
|
label: "Amp",
|
|
11616
12635
|
slug: "amp"
|
|
11617
12636
|
},
|
|
11618
12637
|
claudeCode: {
|
|
11619
|
-
aiIcon: "
|
|
12638
|
+
aiIcon: "ai:claude-code",
|
|
11620
12639
|
color: "#d97757",
|
|
11621
12640
|
label: "Claude Code",
|
|
11622
12641
|
slug: "claude_code"
|
|
11623
12642
|
},
|
|
11624
12643
|
codebuff: {
|
|
11625
|
-
aiIcon: "codebuff",
|
|
12644
|
+
aiIcon: "ai:codebuff",
|
|
11626
12645
|
color: "#14b8a6",
|
|
11627
12646
|
label: "Codebuff",
|
|
11628
12647
|
slug: "codebuff"
|
|
11629
12648
|
},
|
|
11630
12649
|
codex: {
|
|
11631
|
-
aiIcon: "codex",
|
|
12650
|
+
aiIcon: "ai:codex",
|
|
11632
12651
|
color: "#111827",
|
|
11633
12652
|
label: "Codex",
|
|
11634
12653
|
slug: "codex"
|
|
11635
12654
|
},
|
|
11636
12655
|
copilot: {
|
|
11637
|
-
aiIcon: "copilot",
|
|
12656
|
+
aiIcon: "ai:copilot",
|
|
11638
12657
|
color: "#0f766e",
|
|
11639
12658
|
label: "GitHub Copilot",
|
|
11640
12659
|
slug: "copilot"
|
|
11641
12660
|
},
|
|
11642
12661
|
droid: {
|
|
11643
|
-
aiIcon: "droid",
|
|
12662
|
+
aiIcon: "ai:droid",
|
|
11644
12663
|
color: "#06b6d4",
|
|
11645
12664
|
label: "Droid",
|
|
11646
12665
|
slug: "droid"
|
|
11647
12666
|
},
|
|
11648
12667
|
gemini: {
|
|
11649
|
-
aiIcon: "gemini",
|
|
12668
|
+
aiIcon: "ai:gemini",
|
|
11650
12669
|
color: "#0ea5e9",
|
|
11651
12670
|
label: "Gemini",
|
|
11652
12671
|
slug: "gemini"
|
|
11653
12672
|
},
|
|
11654
12673
|
goose: {
|
|
11655
|
-
aiIcon: "goose",
|
|
12674
|
+
aiIcon: "ai:goose",
|
|
11656
12675
|
color: "#22c55e",
|
|
11657
12676
|
label: "Goose",
|
|
11658
12677
|
slug: "goose"
|
|
11659
12678
|
},
|
|
11660
12679
|
hermes: {
|
|
11661
|
-
aiIcon: "
|
|
12680
|
+
aiIcon: "ai:hermesagent",
|
|
11662
12681
|
color: "#8b5cf6",
|
|
11663
12682
|
label: "Hermes",
|
|
11664
12683
|
slug: "hermes"
|
|
11665
12684
|
},
|
|
11666
12685
|
kilo: {
|
|
11667
|
-
aiIcon: "kilo",
|
|
12686
|
+
aiIcon: "ai:kilo",
|
|
11668
12687
|
color: "#f97316",
|
|
11669
12688
|
label: "Kilo",
|
|
11670
12689
|
slug: "kilo"
|
|
11671
12690
|
},
|
|
11672
12691
|
kimi: {
|
|
11673
|
-
aiIcon: "
|
|
12692
|
+
aiIcon: "ai:kimi",
|
|
11674
12693
|
color: "#2563eb",
|
|
11675
12694
|
label: "Kimi",
|
|
11676
12695
|
slug: "kimi"
|
|
11677
12696
|
},
|
|
11678
12697
|
openclaw: {
|
|
11679
|
-
aiIcon: "openclaw",
|
|
12698
|
+
aiIcon: "ai:openclaw",
|
|
11680
12699
|
color: "#ec4899",
|
|
11681
12700
|
label: "OpenClaw",
|
|
11682
12701
|
slug: "openclaw"
|
|
11683
12702
|
},
|
|
11684
12703
|
opencode: {
|
|
11685
|
-
aiIcon: "
|
|
12704
|
+
aiIcon: "ai:open-code",
|
|
11686
12705
|
color: "#4f46e5",
|
|
11687
12706
|
label: "OpenCode",
|
|
11688
12707
|
slug: "opencode"
|
|
11689
12708
|
},
|
|
11690
12709
|
pi: {
|
|
11691
|
-
aiIcon: "pi",
|
|
12710
|
+
aiIcon: "ai:pi",
|
|
11692
12711
|
color: "#a855f7",
|
|
11693
12712
|
label: "Pi",
|
|
11694
12713
|
slug: "pi"
|
|
11695
12714
|
},
|
|
11696
12715
|
qwen: {
|
|
11697
|
-
aiIcon: "
|
|
12716
|
+
aiIcon: "ai:qwen",
|
|
11698
12717
|
color: "#623ae7",
|
|
11699
12718
|
label: "Qwen",
|
|
11700
12719
|
slug: "qwen"
|
|
11701
12720
|
}
|
|
11702
12721
|
};
|
|
11703
|
-
const
|
|
12722
|
+
const platformBySlug = new Map(PROJECT_USAGE_PLATFORMS.map((platform) => [
|
|
11704
12723
|
PROJECT_USAGE_PLATFORM_META[platform].slug,
|
|
11705
12724
|
platform
|
|
11706
|
-
]);
|
|
11707
|
-
const platformBySlug = new Map(platformSlugEntries);
|
|
12725
|
+
]));
|
|
11708
12726
|
function resolveProjectUsagePlatform(value) {
|
|
11709
12727
|
var _a;
|
|
11710
12728
|
const normalizedValue = value == null ? void 0 : value.trim();
|
|
@@ -11717,14 +12735,6 @@ function resolveProjectUsagePlatform(value) {
|
|
|
11717
12735
|
return (_a = platformBySlug.get(normalizedValue)) != null ? _a : null;
|
|
11718
12736
|
}
|
|
11719
12737
|
|
|
11720
|
-
const ANALYSIS_AGENT_TOKEN_TYPES = ["day", "week", "month", "session"];
|
|
11721
|
-
const ANALYSIS_AGENT_TOKEN_ROW_KEYS = {
|
|
11722
|
-
day: "dailyRows",
|
|
11723
|
-
month: "monthlyRows",
|
|
11724
|
-
session: "sessionRows",
|
|
11725
|
-
week: "weeklyRows"
|
|
11726
|
-
};
|
|
11727
|
-
|
|
11728
12738
|
function getAnalysisRuntime(event) {
|
|
11729
12739
|
const runtimeConfig = useRuntimeConfig(event);
|
|
11730
12740
|
const config = resolveConfig(runtimeConfig.public);
|
|
@@ -11791,7 +12801,7 @@ function defineRequiredAgentAnalysisHandler(select) {
|
|
|
11791
12801
|
});
|
|
11792
12802
|
}
|
|
11793
12803
|
async function getHomeAnalysisModules(event) {
|
|
11794
|
-
return
|
|
12804
|
+
return getAnalysisRuntime(event).getHomeDashboardModules();
|
|
11795
12805
|
}
|
|
11796
12806
|
function normalizeQueryString(value) {
|
|
11797
12807
|
if (Array.isArray(value)) {
|
|
@@ -11867,6 +12877,7 @@ const _lazy_NXGH0G = () => import('../routes/api/analysis/overview-cards.json.mj
|
|
|
11867
12877
|
const _lazy_FZJ5Wh = () => import('../routes/api/analysis/session.json.mjs');
|
|
11868
12878
|
const _lazy_k5j8NN = () => import('../routes/api/analysis/token.json.mjs');
|
|
11869
12879
|
const _lazy_wkSLy3 = () => import('../routes/api/analysis/token/daily.json.mjs');
|
|
12880
|
+
const _lazy_Vzep2h = () => import('../routes/api/analysis/token/today-hourly.json.mjs');
|
|
11870
12881
|
const _lazy_x_4o7G = () => import('../routes/api/payload.json.mjs');
|
|
11871
12882
|
const _lazy_slsjW6 = () => import('../routes/api/projects/_project/modules.get.mjs');
|
|
11872
12883
|
const _lazy_K00scR = () => import('../routes/api/projects/catalog.get.mjs');
|
|
@@ -11884,6 +12895,7 @@ const handlers = [
|
|
|
11884
12895
|
{ route: '/api/analysis/session.json', handler: _lazy_FZJ5Wh, lazy: true, middleware: false, method: undefined },
|
|
11885
12896
|
{ route: '/api/analysis/token.json', handler: _lazy_k5j8NN, lazy: true, middleware: false, method: undefined },
|
|
11886
12897
|
{ route: '/api/analysis/token/daily.json', handler: _lazy_wkSLy3, lazy: true, middleware: false, method: undefined },
|
|
12898
|
+
{ route: '/api/analysis/token/today-hourly.json', handler: _lazy_Vzep2h, lazy: true, middleware: false, method: undefined },
|
|
11887
12899
|
{ route: '/api/payload.json', handler: _lazy_x_4o7G, lazy: true, middleware: false, method: undefined },
|
|
11888
12900
|
{ route: '/api/projects/:project/modules', handler: _lazy_slsjW6, lazy: true, middleware: false, method: "get" },
|
|
11889
12901
|
{ route: '/api/projects/catalog', handler: _lazy_K00scR, lazy: true, middleware: false, method: "get" },
|
|
@@ -12041,4 +13053,4 @@ const websocket = nitroApp.h3App.websocket ;
|
|
|
12041
13053
|
const handler = listener;
|
|
12042
13054
|
trapUnhandledNodeErrors();
|
|
12043
13055
|
|
|
12044
|
-
export { ANALYSIS_AGENT_TOKEN_ROW_KEYS as A, defineHomeAnalysisHandler as a, defineScopedAnalysisHandler as b,
|
|
13056
|
+
export { ANALYSIS_AGENT_TOKEN_ROW_KEYS as A, websocket as B, defineHomeAnalysisHandler as a, defineScopedAnalysisHandler as b, buildOverviewCardsWithTodayTokenBreakdown as c, defineRequiredAgentAnalysisHandler as d, defineEventHandler as e, getUsageDataRuntime as f, getRequiredAnalysisAgentTokenType as g, getRouterParam as h, getQuery as i, normalizeStringList as j, defineWebSocketHandler as k, buildAssetsURL as l, getResponseStatusText as m, normalizeStringValue as n, getResponseStatus as o, defineRenderHandler as p, publicAssetsURL as q, resolveConfig as r, createError$1 as s, destr as t, useRuntimeConfig as u, getRouteRules as v, joinURL as w, useNitroApp as x, handler as y, listener as z };
|