cc-context-stats 1.9.1 → 1.10.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/package.json +1 -1
- package/scripts/context-stats.sh +1 -1
- package/scripts/statusline.js +35 -55
package/package.json
CHANGED
package/scripts/context-stats.sh
CHANGED
package/scripts/statusline.js
CHANGED
|
@@ -37,49 +37,48 @@ const ROTATION_THRESHOLD = 10000;
|
|
|
37
37
|
const ROTATION_KEEP = 5000;
|
|
38
38
|
|
|
39
39
|
// Model Intelligence constants (hardcoded, not configurable)
|
|
40
|
-
const
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
const
|
|
40
|
+
const MI_GREEN_THRESHOLD = 0.70;
|
|
41
|
+
const MI_YELLOW_THRESHOLD = 0.40;
|
|
42
|
+
|
|
43
|
+
// Per-model degradation profiles: beta controls curve shape
|
|
44
|
+
// Higher beta = quality retained longer (degradation happens later)
|
|
45
|
+
const MODEL_PROFILES = {
|
|
46
|
+
opus: 1.8,
|
|
47
|
+
sonnet: 1.5,
|
|
48
|
+
haiku: 1.2,
|
|
49
|
+
default: 1.5,
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Match model_id to degradation beta.
|
|
54
|
+
*/
|
|
55
|
+
function getModelProfile(modelId) {
|
|
56
|
+
const lower = (modelId || '').toLowerCase();
|
|
57
|
+
for (const family of ['opus', 'sonnet', 'haiku']) {
|
|
58
|
+
if (lower.includes(family)) return MODEL_PROFILES[family];
|
|
59
|
+
}
|
|
60
|
+
return MODEL_PROFILES.default;
|
|
61
|
+
}
|
|
46
62
|
|
|
47
63
|
/**
|
|
48
64
|
* Compute Model Intelligence score.
|
|
49
|
-
*
|
|
65
|
+
* MI(u) = max(0, 1 - u^beta) where beta is model-specific.
|
|
66
|
+
* Returns { mi }.
|
|
50
67
|
*/
|
|
51
|
-
function computeMI(usedTokens, contextWindowSize,
|
|
52
|
-
deltaLines, deltaOutput, beta = 1.5) {
|
|
68
|
+
function computeMI(usedTokens, contextWindowSize, modelId, betaOverride) {
|
|
53
69
|
// Guard clause
|
|
54
70
|
if (contextWindowSize === 0) {
|
|
55
|
-
return { mi: 1.0
|
|
71
|
+
return { mi: 1.0 };
|
|
56
72
|
}
|
|
57
73
|
|
|
58
|
-
|
|
59
|
-
const
|
|
60
|
-
const cps = u > 0 ? Math.max(0, 1 - Math.pow(u, beta)) : 1.0;
|
|
61
|
-
|
|
62
|
-
// ES
|
|
63
|
-
let es;
|
|
64
|
-
if (totalContext === 0) {
|
|
65
|
-
es = 1.0;
|
|
66
|
-
} else {
|
|
67
|
-
const cacheHitRatio = cacheRead / totalContext;
|
|
68
|
-
es = 0.3 + 0.7 * cacheHitRatio;
|
|
69
|
-
}
|
|
74
|
+
const betaFromProfile = getModelProfile(modelId || '');
|
|
75
|
+
const beta = (betaOverride && betaOverride > 0) ? betaOverride : betaFromProfile;
|
|
70
76
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
if (deltaOutput === null || deltaOutput === undefined || deltaOutput <= 0) {
|
|
74
|
-
ps = 0.5;
|
|
75
|
-
} else {
|
|
76
|
-
const ratio = deltaLines / deltaOutput;
|
|
77
|
-
const normalized = Math.min(1.0, ratio / MI_PRODUCTIVITY_TARGET);
|
|
78
|
-
ps = 0.2 + 0.8 * normalized;
|
|
79
|
-
}
|
|
77
|
+
const u = usedTokens / contextWindowSize;
|
|
78
|
+
if (u <= 0) return { mi: 1.0 };
|
|
80
79
|
|
|
81
|
-
const mi =
|
|
82
|
-
return { mi
|
|
80
|
+
const mi = Math.max(0, 1 - Math.pow(u, beta));
|
|
81
|
+
return { mi };
|
|
83
82
|
}
|
|
84
83
|
|
|
85
84
|
/**
|
|
@@ -292,7 +291,7 @@ function readConfig() {
|
|
|
292
291
|
showIoTokens: true,
|
|
293
292
|
reducedMotion: false,
|
|
294
293
|
showMI: true,
|
|
295
|
-
miCurveBeta:
|
|
294
|
+
miCurveBeta: 0,
|
|
296
295
|
colors: {},
|
|
297
296
|
};
|
|
298
297
|
const configPath = path.join(os.homedir(), '.claude', 'statusline.conf');
|
|
@@ -515,9 +514,6 @@ process.stdin.on('end', () => {
|
|
|
515
514
|
const stateFile = path.join(stateDir, stateFileName);
|
|
516
515
|
let hasPrev = false;
|
|
517
516
|
let prevTokens = 0;
|
|
518
|
-
let prevOutputTokens = 0;
|
|
519
|
-
let prevLinesAdded = 0;
|
|
520
|
-
let prevLinesRemoved = 0;
|
|
521
517
|
try {
|
|
522
518
|
if (fs.existsSync(stateFile)) {
|
|
523
519
|
hasPrev = true;
|
|
@@ -535,9 +531,6 @@ process.stdin.on('end', () => {
|
|
|
535
531
|
const prevCacheRead = parseInt(parts[6], 10) || 0;
|
|
536
532
|
prevTokens = prevCurInput + prevCacheCreation + prevCacheRead;
|
|
537
533
|
// For MI productivity score
|
|
538
|
-
prevOutputTokens = parseInt(parts[2], 10) || 0;
|
|
539
|
-
prevLinesAdded = parseInt(parts[8], 10) || 0;
|
|
540
|
-
prevLinesRemoved = parseInt(parts[9], 10) || 0;
|
|
541
534
|
} else {
|
|
542
535
|
// Old format - single value
|
|
543
536
|
prevTokens = parseInt(lastLine, 10) || 0;
|
|
@@ -563,22 +556,9 @@ process.stdin.on('end', () => {
|
|
|
563
556
|
|
|
564
557
|
// Calculate and display MI score if enabled
|
|
565
558
|
if (showMI) {
|
|
566
|
-
|
|
567
|
-
if (hasPrev) {
|
|
568
|
-
const deltaLA = linesAdded - prevLinesAdded;
|
|
569
|
-
const deltaLR = linesRemoved - prevLinesRemoved;
|
|
570
|
-
deltaLines = deltaLA + deltaLR;
|
|
571
|
-
deltaOutput = totalOutputTokens - prevOutputTokens;
|
|
572
|
-
} else {
|
|
573
|
-
deltaLines = 0;
|
|
574
|
-
deltaOutput = null;
|
|
575
|
-
}
|
|
576
|
-
const miResult = computeMI(
|
|
577
|
-
usedTokens, totalSize, cacheRead, usedTokens,
|
|
578
|
-
deltaLines, deltaOutput, miCurveBeta
|
|
579
|
-
);
|
|
559
|
+
const miResult = computeMI(usedTokens, totalSize, modelId, miCurveBeta);
|
|
580
560
|
const miColor = getMIColor(miResult.mi, cGreen, cYellow, cRed);
|
|
581
|
-
miInfo = ` ${miColor}MI:${miResult.mi.toFixed(
|
|
561
|
+
miInfo = ` ${miColor}MI:${miResult.mi.toFixed(3)}${RESET}`;
|
|
582
562
|
}
|
|
583
563
|
|
|
584
564
|
// Only append if context usage changed (avoid duplicates from multiple refreshes)
|