Download packages/coding-agent/test/cache-stats.test.ts from SaylorTwift/pi: direct link, hf CLI and curl.
- Browser
- Download file 5.09 kB
-
https://huggingface.co/SaylorTwift/pi/resolve/main/packages/coding-agent/test/cache-stats.test.ts
- Command line
-
hf download hf://SaylorTwift/pi/packages/coding-agent/test/cache-stats.test.ts
-
curl -L -o cache-stats.test.ts https://huggingface.co/SaylorTwift/pi/resolve/main/packages/coding-agent/test/cache-stats.test.ts
5.09 kB
| import type { AssistantMessage } from "@earendil-works/pi-ai"; | |
| import { describe, expect, it } from "vitest"; | |
| import { | |
| collectCacheMisses, | |
| computeCacheWaste, | |
| detectCacheMiss, | |
| type ModelPriceSource, | |
| } from "../src/core/cache-stats.ts"; | |
| import type { SessionEntry } from "../src/core/session-manager.ts"; | |
| const zeroCost = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }; | |
| const models: ModelPriceSource = { | |
| // $/million tokens; used as cache-read price fallback on full-miss turns | |
| getModel: () => ({ cost: { cacheRead: 0.3 } }), | |
| }; | |
| function assistant(options: { | |
| input?: number; | |
| cacheRead?: number; | |
| cacheWrite?: number; | |
| cost?: Partial<typeof zeroCost>; | |
| model?: string; | |
| timestamp?: number; | |
| }): AssistantMessage { | |
| return { | |
| role: "assistant", | |
| content: [], | |
| api: "anthropic-messages", | |
| provider: "test", | |
| model: options.model ?? "test-model", | |
| usage: { | |
| input: options.input ?? 0, | |
| output: 10, | |
| cacheRead: options.cacheRead ?? 0, | |
| cacheWrite: options.cacheWrite ?? 0, | |
| totalTokens: 0, | |
| cost: { ...zeroCost, ...options.cost }, | |
| }, | |
| stopReason: "stop", | |
| timestamp: options.timestamp ?? 0, | |
| } as AssistantMessage; | |
| } | |
| function entry(message: AssistantMessage): SessionEntry { | |
| return { type: "message", id: "x", parentId: null, timestamp: "", message } as SessionEntry; | |
| } | |
| // Turn 1: fresh 100k cache write at $3.75/M | |
| const turn1 = assistant({ cacheWrite: 100_000, cost: { cacheWrite: 0.375 }, timestamp: 0 }); | |
| // Turn 2: healthy, everything read back at $0.30/M | |
| const turn2 = assistant({ | |
| cacheRead: 100_000, | |
| cacheWrite: 5_000, | |
| cost: { cacheRead: 0.03, cacheWrite: 0.019 }, | |
| timestamp: 60_000, | |
| }); | |
| describe("computeCacheWaste", () => { | |
| it("accumulates missed tokens and cost across turns", () => { | |
| // Turn 3: full miss, previous 105k prompt re-billed at $3.75/M write | |
| const turn3 = assistant({ cacheWrite: 110_000, cost: { cacheWrite: 0.4125 }, timestamp: 120_000 }); | |
| const totals = computeCacheWaste([entry(turn1), entry(turn2), entry(turn3)], models); | |
| expect(totals.missedTokens).toBe(105_000); | |
| // 105k at ($3.75 - $0.30)/M | |
| expect(totals.missedCost).toBeCloseTo(0.36225, 5); | |
| }); | |
| it("counts nothing for healthy sessions", () => { | |
| const totals = computeCacheWaste([entry(turn1), entry(turn2)], models); | |
| expect(totals.missedTokens).toBe(0); | |
| expect(totals.missedCost).toBe(0); | |
| }); | |
| it("skips the turn after a compaction reset", () => { | |
| const reset = { type: "compaction", id: "c", parentId: null, timestamp: "" } as SessionEntry; | |
| const afterReset = assistant({ cacheWrite: 20_000, cost: { cacheWrite: 0.075 } }); | |
| const totals = computeCacheWaste([entry(turn1), reset, entry(afterReset)], models); | |
| expect(totals.missedTokens).toBe(0); | |
| }); | |
| it("counts misses caused by model switches", () => { | |
| const otherModel = assistant({ cacheWrite: 100_000, cost: { cacheWrite: 0.375 }, model: "other-model" }); | |
| const totals = computeCacheWaste([entry(turn1), entry(otherModel)], models); | |
| expect(totals.missedTokens).toBe(100_000); | |
| expect(totals.missCount).toBe(1); | |
| }); | |
| it("skips providers that report no cache activity", () => { | |
| const a = assistant({ input: 100_000 }); | |
| const b = assistant({ input: 110_000 }); | |
| const totals = computeCacheWaste([entry(a), entry(b)], models); | |
| expect(totals.missedTokens).toBe(0); | |
| }); | |
| }); | |
| describe("collectCacheMisses", () => { | |
| it("maps counted misses to their assistant messages by reference", () => { | |
| const missTurn = assistant({ cacheWrite: 110_000, cost: { cacheWrite: 0.4125 }, timestamp: 120_000 }); | |
| const misses = collectCacheMisses([entry(turn1), entry(turn2), entry(missTurn)], models); | |
| expect(misses.size).toBe(1); | |
| expect(misses.get(missTurn)?.missedTokens).toBe(105_000); | |
| }); | |
| }); | |
| describe("detectCacheMiss", () => { | |
| it("detects a miss on a just-completed message with idle time", () => { | |
| const missMessage = assistant({ cacheWrite: 110_000, cost: { cacheWrite: 0.4125 }, timestamp: 600_000 }); | |
| const miss = detectCacheMiss([entry(turn1), entry(turn2)], missMessage, models); | |
| expect(miss).toBeDefined(); | |
| expect(miss?.missedTokens).toBe(105_000); | |
| expect(miss?.missedCost).toBeCloseTo(0.36225, 5); | |
| // 600s - 60s since the previous request | |
| expect(miss?.idleMs).toBe(540_000); | |
| expect(miss?.modelChanged).toBe(false); | |
| }); | |
| it("flags model switches on detected misses", () => { | |
| const otherModel = assistant({ | |
| cacheWrite: 110_000, | |
| cost: { cacheWrite: 0.4125 }, | |
| model: "other-model", | |
| timestamp: 120_000, | |
| }); | |
| const miss = detectCacheMiss([entry(turn1), entry(turn2)], otherModel, models); | |
| expect(miss?.missedTokens).toBe(105_000); | |
| expect(miss?.modelChanged).toBe(true); | |
| }); | |
| it("returns undefined for healthy turns", () => { | |
| const healthy = assistant({ | |
| cacheRead: 105_000, | |
| cacheWrite: 2_000, | |
| cost: { cacheRead: 0.0315, cacheWrite: 0.0075 }, | |
| timestamp: 120_000, | |
| }); | |
| expect(detectCacheMiss([entry(turn1), entry(turn2)], healthy, models)).toBeUndefined(); | |
| }); | |
| it("returns undefined for the first turn of a session", () => { | |
| expect(detectCacheMiss([], turn1, models)).toBeUndefined(); | |
| }); | |
| }); | |