mirror of
https://github.com/teamchong/pxpipe.git
synced 2026-07-22 02:02:51 +02:00
fix(sessions): complete honest cache-math warmth gate
b9418bfrepriced cr>0-but-no-prior turns warm in dashboard.ts (update + replay) but left the identical gate in sessions.ts unfixed — so the Sessions panel still fabricated inflated savings after a restart/eviction or on the first tracked turn (a cr>0 turn priced cold bills the text counterfactual a 1.25x create on a prefix we KNOW was cached). Mirror the dashboard fix so "honest cache math" holds on every panel. - sessions.ts: warm follows the observed read (cr>0) alone; with no fresh prior, assume the cacheable prefix was fully reused (prevCacheable = cacheable) rather than mispricing a known-warm read. - sessions.test.ts: the "real prefix compression" case had cr=100 on its first turn (observably warm) yet asserted the cold-priced 22490 fabrication; corrected to the honest 1790 (warm) + 95 = 1885. Now a regression guard for this fix. - dashboard.ts: drop the stale "no per-session state" replay comment — replay now mirrors update()'s per-session warmth. Found by adversarial review ofb9418bf. 462 tests pass; tsc clean.
This commit is contained in:
+2
-2
@@ -901,8 +901,8 @@ export class DashboardState {
|
||||
/* skip malformed line */
|
||||
}
|
||||
}
|
||||
// Warmth-free baseline (see core/baseline.ts): no per-session state, so this
|
||||
// replay produces byte-identical per-row numbers to the live update() path.
|
||||
// Replay mirrors the live update() warmth logic (per-session baselineWarmth,
|
||||
// cr-grounded) so it produces byte-identical per-row numbers to update().
|
||||
for (const t of tail) {
|
||||
const inp = t.input_tokens ?? 0;
|
||||
const out = t.output_tokens ?? 0;
|
||||
|
||||
+11
-2
@@ -198,7 +198,16 @@ export async function aggregateSessions(
|
||||
const prev = warmth.get(id);
|
||||
// cr-grounded warmth: only price text warm if a warm cache was actually
|
||||
// observed (cr > 0). A miss within the TTL window was cold for both paths.
|
||||
const warm = cr > 0 && prev !== undefined && tsSec - prev.ts < CACHE_TTL_SEC;
|
||||
// cr-grounded warmth follows the OBSERVED read ALONE, not our in-memory map
|
||||
// (a restart/eviction wipes it, and it can't see a session that was warm
|
||||
// before this process booted). Mirrors dashboard.ts: pricing a cr>0 turn cold
|
||||
// because the prior is missing would bill text the 1.25× create on a prefix we
|
||||
// KNOW was cached — fabricating the inflated "saved" row. The map only refines
|
||||
// the reused-vs-grown split; with no fresh prior, assume the cached prefix was
|
||||
// fully reused (prevCacheable = cacheable → no fabricated growth).
|
||||
const warm = cr > 0;
|
||||
const warmFresh = prev !== undefined && tsSec - prev.ts < CACHE_TTL_SEC;
|
||||
const prevCacheable = warm ? (warmFresh ? prev!.cacheable : cacheable) : 0;
|
||||
const baselineEff = computeBaselineInputEff(
|
||||
baseline,
|
||||
cacheable,
|
||||
@@ -206,7 +215,7 @@ export async function aggregateSessions(
|
||||
cc,
|
||||
cr,
|
||||
warm,
|
||||
warm ? prev!.cacheable : 0,
|
||||
prevCacheable,
|
||||
);
|
||||
const actualEff = computeActualInputEff(inp, cc, cr);
|
||||
const tokensSaved = baselineEff - actualEff;
|
||||
|
||||
+10
-7
@@ -131,10 +131,13 @@ describe('aggregateSessions', () => {
|
||||
|
||||
it('credits the real prefix compression (image prefix fewer tokens than text prefix)', async () => {
|
||||
writeEvents(tmp, [
|
||||
// First turn of the session => COLD: text would re-create the whole
|
||||
// cacheable prefix at 1.25x, not read it. 18000*1.25 + 2000 cold tail
|
||||
// = 22500 + 2000 = 24500. actual = 1000 + 800*1.25 + 100*0.1 = 2010.
|
||||
// saved = 24500 - 2010 = 22490.
|
||||
// First TRACKED turn, but cr=100 > 0 ⇒ the cache was OBSERVABLY warm (pxpipe
|
||||
// started mid-session / the prefix was warmed before this process booted).
|
||||
// Honest math prices the text counterfactual WARM too — not cold. With no
|
||||
// fresh in-memory prior we assume the cacheable prefix was fully reused:
|
||||
// baseline_eff = 18000*0.1 (reused) + 2000 cold tail = 3800.
|
||||
// actual = 1000 + 800*1.25 + 100*0.1 = 2010. saved = 3800 - 2010 = 1790.
|
||||
// (Pre-fix, a missing prior forced this cr>0 turn cold → fabricated 22490.)
|
||||
ev({
|
||||
first_user_sha8: 'aaaaaaaa',
|
||||
compressed: true,
|
||||
@@ -174,9 +177,9 @@ describe('aggregateSessions', () => {
|
||||
]);
|
||||
const { sessions } = await aggregateSessions(tmp);
|
||||
const s = sessions.get('aaaaaaaa')!;
|
||||
// 22490 (cold) + 95 (warm) + 0 (probe miss) = 22585
|
||||
expect(s.tokensSavedEst).toBe(22_585);
|
||||
expect(s.charsSaved).toBe(22_585 * 4);
|
||||
// 1790 (warm, no prior) + 95 (warm) + 0 (probe miss) = 1885
|
||||
expect(s.tokensSavedEst).toBe(1_885);
|
||||
expect(s.charsSaved).toBe(1_885 * 4);
|
||||
expect(s.requestCount).toBe(4);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user