agent-cache-optimizer 0.5.0 → 0.5.1
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/src/core.ts +5 -2
- package/src/heuristics.ts +1 -1
- package/src/index.ts +25 -1
- package/src/types.ts +2 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-cache-optimizer",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "Content-agnostic KV cache optimizer for LLM CLI agents — boosts prompt cache hit rate by 40-88% through automatic stability tracking and block reordering",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"kv-cache",
|
package/src/core.ts
CHANGED
|
@@ -24,6 +24,7 @@ export function emptyDB(): StabilityDB {
|
|
|
24
24
|
scores: {},
|
|
25
25
|
contentIndex: {},
|
|
26
26
|
contentScores: {},
|
|
27
|
+
contentObservations: 0,
|
|
27
28
|
observations: 0,
|
|
28
29
|
updated: 0,
|
|
29
30
|
}
|
|
@@ -71,9 +72,11 @@ export function updateContentDB(db: StabilityDB, blocks: string[]): StabilityDB
|
|
|
71
72
|
}
|
|
72
73
|
}
|
|
73
74
|
|
|
74
|
-
// Recompute content scores
|
|
75
|
+
// Recompute content scores using contentObservations (not observations)
|
|
76
|
+
db.contentObservations++
|
|
77
|
+
const obs = Math.max(1, db.contentObservations)
|
|
75
78
|
for (const fp of Object.values(db.contentIndex)) {
|
|
76
|
-
db.contentScores[fp.hash] = Math.min(1.0, fp.count /
|
|
79
|
+
db.contentScores[fp.hash] = Math.min(1.0, fp.count / obs)
|
|
77
80
|
}
|
|
78
81
|
|
|
79
82
|
return db
|
package/src/heuristics.ts
CHANGED
|
@@ -78,7 +78,7 @@ export function classify(
|
|
|
78
78
|
|
|
79
79
|
// Priority 2: content-addressed score (primary)
|
|
80
80
|
const contentScore = lookupContentScore(db, hash)
|
|
81
|
-
if (contentScore !== null && db.
|
|
81
|
+
if (contentScore !== null && db.contentObservations >= 2) {
|
|
82
82
|
if (contentScore >= 0.7) { result.stable.push(item); continue }
|
|
83
83
|
if (contentScore <= 0.2) { result.dynamic.push(item); continue }
|
|
84
84
|
}
|
package/src/index.ts
CHANGED
|
@@ -37,7 +37,31 @@ function warmCachePath(): string {
|
|
|
37
37
|
|
|
38
38
|
function loadDB(agent: string): StabilityDB {
|
|
39
39
|
try {
|
|
40
|
-
|
|
40
|
+
const raw = readFileSync(dbPath(agent), "utf-8")
|
|
41
|
+
const db = JSON.parse(raw) as StabilityDB
|
|
42
|
+
// Migrate from pre-0.5.0: rebuild contentIndex from position data
|
|
43
|
+
if (
|
|
44
|
+
(!db.contentIndex || Object.keys(db.contentIndex).length === 0) &&
|
|
45
|
+
db.positions &&
|
|
46
|
+
Object.keys(db.positions).length > 0
|
|
47
|
+
) {
|
|
48
|
+
db.contentIndex = {}
|
|
49
|
+
for (const fps of Object.values(db.positions)) {
|
|
50
|
+
for (const fp of fps) {
|
|
51
|
+
const existing = db.contentIndex[fp.hash]
|
|
52
|
+
if (existing) {
|
|
53
|
+
existing.count = Math.max(existing.count, fp.count)
|
|
54
|
+
if (fp.lastSeen > existing.lastSeen) existing.lastSeen = fp.lastSeen
|
|
55
|
+
} else {
|
|
56
|
+
db.contentIndex[fp.hash] = { ...fp }
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
db.contentScores = {}
|
|
61
|
+
db.contentObservations = 0 // warm from scratch for accurate scores
|
|
62
|
+
saveDB(agent, db)
|
|
63
|
+
}
|
|
64
|
+
return db
|
|
41
65
|
} catch {
|
|
42
66
|
return emptyDB()
|
|
43
67
|
}
|
package/src/types.ts
CHANGED
|
@@ -24,6 +24,8 @@ export interface StabilityDB {
|
|
|
24
24
|
contentIndex: Record<string, ContentFingerprint>
|
|
25
25
|
/** Content-addressed scores */
|
|
26
26
|
contentScores: Record<string, number>
|
|
27
|
+
/** Number of calls that contributed to contentIndex */
|
|
28
|
+
contentObservations: number
|
|
27
29
|
/** Total observations */
|
|
28
30
|
observations: number
|
|
29
31
|
/** Last write timestamp */
|