codebuddy-stats 1.3.6 → 1.4.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.js +2 -1
- package/dist/lib/data-loader.js +24 -3
- package/dist/lib/pricing.js +1 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -195,9 +195,10 @@ async function main() {
|
|
|
195
195
|
function updateContent() {
|
|
196
196
|
const t0 = prof ? performance.now() : 0;
|
|
197
197
|
const width = Number(screen.width) || 80;
|
|
198
|
+
const estimatedRate = formatPercent(state.data.ideEstimatedCacheHitRate ?? 0.9);
|
|
198
199
|
const note = state.currentSource === 'code'
|
|
199
200
|
? `针对 CodeBuddy Code < 2.20.0 版本产生的数据,由于没有请求级别的 model ID,用量是基于当前 CodeBuddy Code 设置的 model ID(${state.data.defaultModelId})计算价格的`
|
|
200
|
-
:
|
|
201
|
+
: `IDE 的数据有缺,成本根据 Code 最近 90 天的平均缓存命中率估算(当前为 ${estimatedRate})`;
|
|
201
202
|
const screenHeight = Number(screen.height) || 24;
|
|
202
203
|
const contentBoxHeight = Math.max(1, screenHeight - 5); // 对应 contentBox: height = '100%-5'
|
|
203
204
|
const paddingTop = Number(contentBox.padding?.top ?? 0);
|
package/dist/lib/data-loader.js
CHANGED
|
@@ -12,6 +12,8 @@ import { compareByCostThenTokens } from './utils.js';
|
|
|
12
12
|
import { loadWorkspaceMappings, resolveProjectName } from './workspace-resolver.js';
|
|
13
13
|
export const BASE_DIR = getProjectsDir();
|
|
14
14
|
const memoryCache = new Map();
|
|
15
|
+
const IDE_CACHE_HIT_RATE_LOOKBACK_DAYS = 90;
|
|
16
|
+
const IDE_CACHE_HIT_RATE_FALLBACK = 0.9;
|
|
15
17
|
function getCacheKey(source, days) {
|
|
16
18
|
return `${source}:${days ?? 'all'}`;
|
|
17
19
|
}
|
|
@@ -461,6 +463,23 @@ async function loadCodeUsageData(options = {}) {
|
|
|
461
463
|
}
|
|
462
464
|
return data;
|
|
463
465
|
}
|
|
466
|
+
async function resolveIdeEstimatedCacheHitRate() {
|
|
467
|
+
try {
|
|
468
|
+
const codeData = await loadCodeUsageData({ days: IDE_CACHE_HIT_RATE_LOOKBACK_DAYS });
|
|
469
|
+
const hitTokens = codeData.grandTotal.cacheHitTokens;
|
|
470
|
+
const missTokens = codeData.grandTotal.cacheMissTokens;
|
|
471
|
+
const totalTokens = hitTokens + missTokens;
|
|
472
|
+
if (totalTokens <= 0)
|
|
473
|
+
return IDE_CACHE_HIT_RATE_FALLBACK;
|
|
474
|
+
const rate = hitTokens / totalTokens;
|
|
475
|
+
if (!Number.isFinite(rate))
|
|
476
|
+
return IDE_CACHE_HIT_RATE_FALLBACK;
|
|
477
|
+
return Math.min(1, Math.max(0, rate));
|
|
478
|
+
}
|
|
479
|
+
catch {
|
|
480
|
+
return IDE_CACHE_HIT_RATE_FALLBACK;
|
|
481
|
+
}
|
|
482
|
+
}
|
|
464
483
|
async function findIdeHistoryDirs() {
|
|
465
484
|
const root = getIdeDataDir();
|
|
466
485
|
const out = new Set();
|
|
@@ -565,6 +584,7 @@ async function loadIdeUsageData(options = {}) {
|
|
|
565
584
|
const t0 = prof ? performance.now() : 0;
|
|
566
585
|
const defaultModelId = await loadModelFromSettings();
|
|
567
586
|
const minDate = computeMinDate(options.days);
|
|
587
|
+
const estimatedCacheHitRate = await resolveIdeEstimatedCacheHitRate();
|
|
568
588
|
// 加载工作区映射
|
|
569
589
|
const workspaceMappings = await loadWorkspaceMappings();
|
|
570
590
|
const dailyData = {};
|
|
@@ -581,7 +601,7 @@ async function loadIdeUsageData(options = {}) {
|
|
|
581
601
|
// 同进程内存缓存(不落盘):refresh 时如果 IDE 索引未变,直接复用结果
|
|
582
602
|
const sortedHistoryDirs = [...historyDirs].sort();
|
|
583
603
|
const ideHash = createHash('sha1');
|
|
584
|
-
ideHash.update(`ide|defaultModelId=${defaultModelId}|minDate=${minDate ?? ''}|historyDirs=${sortedHistoryDirs.length}\n`);
|
|
604
|
+
ideHash.update(`ide|defaultModelId=${defaultModelId}|minDate=${minDate ?? ''}|historyDirs=${sortedHistoryDirs.length}|ideEstimatedCacheHitRate=${estimatedCacheHitRate.toFixed(6)}|lookbackDays=${IDE_CACHE_HIT_RATE_LOOKBACK_DAYS}\n`);
|
|
585
605
|
const mappingKeys = [...workspaceMappings.keys()].sort();
|
|
586
606
|
ideHash.update(`mappings=${mappingKeys.length}\n`);
|
|
587
607
|
for (const k of mappingKeys) {
|
|
@@ -682,9 +702,9 @@ async function loadIdeUsageData(options = {}) {
|
|
|
682
702
|
continue;
|
|
683
703
|
const inferredModelId = await inferIdeModelIdForRequest(conversationDir, req, messageModelCache);
|
|
684
704
|
const usedModelId = inferredModelId || defaultModelId;
|
|
685
|
-
// IDE 的 usage 不包含缓存 token
|
|
705
|
+
// IDE 的 usage 不包含缓存 token 明细,按 CBC 最近 90 天平均命中率估算(无数据回退 90%)
|
|
686
706
|
const safeInput = Math.max(0, inputTokens);
|
|
687
|
-
const estimatedCacheHit = Math.round(safeInput *
|
|
707
|
+
const estimatedCacheHit = Math.round(safeInput * estimatedCacheHitRate);
|
|
688
708
|
const estimatedCacheMiss = safeInput - estimatedCacheHit;
|
|
689
709
|
const rawUsage = {
|
|
690
710
|
prompt_tokens: safeInput,
|
|
@@ -721,6 +741,7 @@ async function loadIdeUsageData(options = {}) {
|
|
|
721
741
|
}
|
|
722
742
|
}
|
|
723
743
|
const data = finalizeAnalysis(defaultModelId, dailyData, modelTotals, projectTotals, grandTotal, workspaceMappings);
|
|
744
|
+
data.ideEstimatedCacheHitRate = estimatedCacheHitRate;
|
|
724
745
|
cacheSet('ide', options.days, { fingerprint, data });
|
|
725
746
|
if (profLog) {
|
|
726
747
|
const ms = performance.now() - t0;
|
package/dist/lib/pricing.js
CHANGED
|
@@ -25,6 +25,7 @@ export const MODEL_PRICING = {
|
|
|
25
25
|
"gpt-5-nano": createPricing(0.05, 0.005, 0.4),
|
|
26
26
|
"gpt-5.1-chat-latest": createPricing(1.25, 0.125, 10.0),
|
|
27
27
|
"gpt-5-chat-latest": createPricing(1.25, 0.125, 10.0),
|
|
28
|
+
"gpt-5.3-codex": createPricing(1.75, 0.175, 14.0),
|
|
28
29
|
"gpt-5.2-codex": createPricing(1.75, 0.175, 14.0),
|
|
29
30
|
"gpt-5.1-codex": createPricing(1.25, 0.125, 10.0),
|
|
30
31
|
"gpt-5.1-codex-max": createPricing(1.25, 0.125, 10.0),
|