@animalabs/context-manager 0.5.2 → 0.5.4

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.
Files changed (110) hide show
  1. package/dist/src/adaptive/index.d.ts +6 -0
  2. package/dist/src/adaptive/index.d.ts.map +1 -1
  3. package/dist/src/adaptive/index.js +8 -0
  4. package/dist/src/adaptive/index.js.map +1 -1
  5. package/dist/src/adaptive/kv-cache-sim.d.ts +128 -0
  6. package/dist/src/adaptive/kv-cache-sim.d.ts.map +1 -0
  7. package/dist/src/adaptive/kv-cache-sim.js +0 -0
  8. package/dist/src/adaptive/kv-cache-sim.js.map +1 -0
  9. package/dist/src/adaptive/kv-control.d.ts +152 -0
  10. package/dist/src/adaptive/kv-control.d.ts.map +1 -0
  11. package/dist/src/adaptive/kv-control.js +368 -0
  12. package/dist/src/adaptive/kv-control.js.map +1 -0
  13. package/dist/src/adaptive/kv-replay.d.ts +76 -0
  14. package/dist/src/adaptive/kv-replay.d.ts.map +1 -0
  15. package/dist/src/adaptive/kv-replay.js +175 -0
  16. package/dist/src/adaptive/kv-replay.js.map +1 -0
  17. package/dist/src/adaptive/render-offsets.d.ts +61 -0
  18. package/dist/src/adaptive/render-offsets.d.ts.map +1 -0
  19. package/dist/src/adaptive/render-offsets.js +88 -0
  20. package/dist/src/adaptive/render-offsets.js.map +1 -0
  21. package/dist/src/adaptive/strategies/kv-stable.d.ts +48 -0
  22. package/dist/src/adaptive/strategies/kv-stable.d.ts.map +1 -0
  23. package/dist/src/adaptive/strategies/kv-stable.js +102 -0
  24. package/dist/src/adaptive/strategies/kv-stable.js.map +1 -0
  25. package/dist/src/adaptive/summary-tree.d.ts +98 -0
  26. package/dist/src/adaptive/summary-tree.d.ts.map +1 -0
  27. package/dist/src/adaptive/summary-tree.js +214 -0
  28. package/dist/src/adaptive/summary-tree.js.map +1 -0
  29. package/dist/src/context-log.d.ts.map +1 -1
  30. package/dist/src/context-log.js +7 -2
  31. package/dist/src/context-log.js.map +1 -1
  32. package/dist/src/index.d.ts +1 -1
  33. package/dist/src/index.d.ts.map +1 -1
  34. package/dist/src/index.js +1 -1
  35. package/dist/src/index.js.map +1 -1
  36. package/dist/src/message-store.js +1 -1
  37. package/dist/src/message-store.js.map +1 -1
  38. package/dist/src/normalize-tool-messages.d.ts +33 -0
  39. package/dist/src/normalize-tool-messages.d.ts.map +1 -1
  40. package/dist/src/normalize-tool-messages.js +59 -0
  41. package/dist/src/normalize-tool-messages.js.map +1 -1
  42. package/dist/src/strategies/autobiographical.d.ts +101 -39
  43. package/dist/src/strategies/autobiographical.d.ts.map +1 -1
  44. package/dist/src/strategies/autobiographical.js +398 -222
  45. package/dist/src/strategies/autobiographical.js.map +1 -1
  46. package/dist/src/types/strategy.d.ts +40 -1
  47. package/dist/src/types/strategy.d.ts.map +1 -1
  48. package/dist/src/types/strategy.js +2 -0
  49. package/dist/src/types/strategy.js.map +1 -1
  50. package/dist/test/adaptive/kv-cache-sim.test.d.ts +16 -0
  51. package/dist/test/adaptive/kv-cache-sim.test.d.ts.map +1 -0
  52. package/dist/test/adaptive/kv-cache-sim.test.js +173 -0
  53. package/dist/test/adaptive/kv-cache-sim.test.js.map +1 -0
  54. package/dist/test/adaptive/kv-control.test.d.ts +14 -0
  55. package/dist/test/adaptive/kv-control.test.d.ts.map +1 -0
  56. package/dist/test/adaptive/kv-control.test.js +130 -0
  57. package/dist/test/adaptive/kv-control.test.js.map +1 -0
  58. package/dist/test/adaptive/kv-replay.test.d.ts +15 -0
  59. package/dist/test/adaptive/kv-replay.test.d.ts.map +1 -0
  60. package/dist/test/adaptive/kv-replay.test.js +112 -0
  61. package/dist/test/adaptive/kv-replay.test.js.map +1 -0
  62. package/dist/test/adaptive/kv-stable-strategy.test.d.ts +10 -0
  63. package/dist/test/adaptive/kv-stable-strategy.test.d.ts.map +1 -0
  64. package/dist/test/adaptive/kv-stable-strategy.test.js +89 -0
  65. package/dist/test/adaptive/kv-stable-strategy.test.js.map +1 -0
  66. package/dist/test/adaptive/render-offsets.test.d.ts +11 -0
  67. package/dist/test/adaptive/render-offsets.test.d.ts.map +1 -0
  68. package/dist/test/adaptive/render-offsets.test.js +85 -0
  69. package/dist/test/adaptive/render-offsets.test.js.map +1 -0
  70. package/dist/test/adaptive/summary-tree.test.d.ts +5 -0
  71. package/dist/test/adaptive/summary-tree.test.d.ts.map +1 -0
  72. package/dist/test/adaptive/summary-tree.test.js +72 -0
  73. package/dist/test/adaptive/summary-tree.test.js.map +1 -0
  74. package/dist/test/chunker-tool-boundary.test.d.ts +12 -0
  75. package/dist/test/chunker-tool-boundary.test.d.ts.map +1 -0
  76. package/dist/test/chunker-tool-boundary.test.js +89 -0
  77. package/dist/test/chunker-tool-boundary.test.js.map +1 -0
  78. package/dist/test/compression-shape-invariants.test.d.ts +22 -0
  79. package/dist/test/compression-shape-invariants.test.d.ts.map +1 -0
  80. package/dist/test/compression-shape-invariants.test.js +312 -0
  81. package/dist/test/compression-shape-invariants.test.js.map +1 -0
  82. package/dist/test/image-strip-render-stats.test.d.ts +2 -0
  83. package/dist/test/image-strip-render-stats.test.d.ts.map +1 -0
  84. package/dist/test/image-strip-render-stats.test.js +130 -0
  85. package/dist/test/image-strip-render-stats.test.js.map +1 -0
  86. package/dist/test/image-stripping.test.d.ts +13 -0
  87. package/dist/test/image-stripping.test.d.ts.map +1 -0
  88. package/dist/test/image-stripping.test.js +104 -0
  89. package/dist/test/image-stripping.test.js.map +1 -0
  90. package/dist/test/normalize-tool-messages.test.js +61 -1
  91. package/dist/test/normalize-tool-messages.test.js.map +1 -1
  92. package/dist/test/render-stats.test.d.ts +2 -0
  93. package/dist/test/render-stats.test.d.ts.map +1 -0
  94. package/dist/test/render-stats.test.js +91 -0
  95. package/dist/test/render-stats.test.js.map +1 -0
  96. package/dist/tsconfig.tsbuildinfo +1 -1
  97. package/package.json +2 -2
  98. package/src/adaptive/index.ts +48 -0
  99. package/src/adaptive/kv-cache-sim.ts +0 -0
  100. package/src/adaptive/kv-control.ts +497 -0
  101. package/src/adaptive/kv-replay.ts +238 -0
  102. package/src/adaptive/render-offsets.ts +116 -0
  103. package/src/adaptive/strategies/kv-stable.ts +123 -0
  104. package/src/adaptive/summary-tree.ts +252 -0
  105. package/src/context-log.ts +7 -2
  106. package/src/index.ts +1 -1
  107. package/src/message-store.ts +1 -1
  108. package/src/normalize-tool-messages.ts +61 -0
  109. package/src/strategies/autobiographical.ts +414 -271
  110. package/src/types/strategy.ts +40 -1
@@ -0,0 +1,368 @@
1
+ /**
2
+ * KV-stable context controller (see `docs/kv-stable-context-control.md`).
3
+ *
4
+ * A receding-horizon policy that replaces the `value − λ·KVcost` solve. One
5
+ * objective — minimize real billed recompute — under a constraint hierarchy with
6
+ * a single hard wall (the physical window W) and shaped soft constraints
7
+ * (flat zone, perturbation cap, pins/saliency, operating budget). State (the
8
+ * carried frontier + the persistent cache) makes it a controller, not a
9
+ * per-turn solve.
10
+ *
11
+ * This prototype uses a hysteresis band [LW, HW] as the controllable operating
12
+ * point on the cost↔continuity frontier:
13
+ * - append every turn; if rendered tokens exceed HW, shed down to ≤ LW;
14
+ * otherwise do nothing (pure append → zero perturbation, full cache hit);
15
+ * - shed oldest-first, leveled (L1 groups, then L2, then L3), each chunk
16
+ * capped by the saliency field (log-age + flat zone + pins) — base-k
17
+ * grouping driven by budget, not a fixed clock;
18
+ * - W is the only hard wall; if folding everything to its cap can't fit under
19
+ * W, escalate (don't thrash).
20
+ *
21
+ * Pure and deterministic.
22
+ */
23
+ import { SummaryTree } from './summary-tree.js';
24
+ import { renderLayout } from './render-offsets.js';
25
+ import { placeMarkers, CacheStore } from './kv-cache-sim.js';
26
+ /** Provider price multipliers relative to base input tokens (Anthropic-ish). */
27
+ export const PRICE = { miss: 1.0, cacheRead: 0.1, cacheWrite: 1.25 };
28
+ /** Deepest fold level the saliency field will ever allow. */
29
+ export const MAX_FOLD_LEVEL = 3;
30
+ /**
31
+ * Per-chunk maximum fold depth from the saliency field: flat zone and pins are
32
+ * raw (0); otherwise log-age banded against the base-k geometry. The "finest
33
+ * requirement wins" — this is the cap the shedder may not exceed.
34
+ */
35
+ export function foldDepthCap(chunk, now, flatZone, flatZoneChunks, mergeThreshold) {
36
+ if (chunk.pinned || flatZone.has(chunk.id))
37
+ return 0;
38
+ const age = Math.max(0, now - chunk.sequence);
39
+ const ratio = age / Math.max(1, flatZoneChunks);
40
+ if (ratio < 1)
41
+ return 0; // just outside the flat zone → still raw
42
+ const band = Math.floor(Math.log(ratio) / Math.log(Math.max(2, mergeThreshold))) + 1;
43
+ return Math.max(0, Math.min(MAX_FOLD_LEVEL, band));
44
+ }
45
+ /**
46
+ * Deepen `frontier` in place to bring rendered tokens ≤ `target`, leveled
47
+ * (L1 groups, then L2, then L3) and oldest-first *within the reach window*. A
48
+ * chunk is editable this turn only if the raw tokens newer than it are <
49
+ * `reachTokens` — this bounds the divergence depth (and thus the per-turn KV
50
+ * perturbation) to ≈ reach. Each chunk is bounded by its saliency cap;
51
+ * flat-zone/pinned chunks (cap 0) are never touched.
52
+ *
53
+ * `reachTokens` is the soft cap P; `windowTokens` is the hard wall W. If folding
54
+ * within reach can't fit under W, reach is lifted (emergency) and folding
55
+ * continues to caps — yielding P minimally to keep W. Returns final tokens.
56
+ */
57
+ function shedToTarget(frontier, inputs, tree, ordered, caps, target, reachTokens, windowTokens) {
58
+ // Raw tokens strictly newer than each chunk (its distance from the live end).
59
+ const newerTokens = new Map();
60
+ let acc = 0;
61
+ for (let i = ordered.length - 1; i >= 0; i--) {
62
+ newerTokens.set(ordered[i].id, acc);
63
+ acc += ordered[i].rawTokens;
64
+ }
65
+ const foldWithinReach = (reach) => {
66
+ for (let level = 1; level <= MAX_FOLD_LEVEL; level++) {
67
+ for (const c of ordered) {
68
+ // oldest-first within reach
69
+ if ((newerTokens.get(c.id) ?? 0) >= reach)
70
+ continue;
71
+ if ((frontier.get(c.id) ?? 0) >= level)
72
+ continue;
73
+ const ancestor = tree.ancestorAt(c.id, level);
74
+ if (!ancestor)
75
+ continue; // summary not produced yet → can't fold here
76
+ // Group-consistency + reach: fold the WHOLE group to `level` only if
77
+ // every covered leaf permits it (cap ≥ level) and is within reach. The
78
+ // picker raises whole groups, so a partially-eligible group would be an
79
+ // unreachable target (it oscillates). A uniform fold keeps the frontier
80
+ // group-consistent and the picker convergent.
81
+ let eligible = true;
82
+ for (const leafId of ancestor.leafChunkIds) {
83
+ if ((caps.get(leafId) ?? 0) < level || (newerTokens.get(leafId) ?? 0) >= reach) {
84
+ eligible = false;
85
+ break;
86
+ }
87
+ }
88
+ if (!eligible)
89
+ continue;
90
+ for (const leafId of ancestor.leafChunkIds) {
91
+ if ((frontier.get(leafId) ?? 0) < level)
92
+ frontier.set(leafId, level);
93
+ }
94
+ if (renderLayout(inputs, tree, frontier).totalTokens <= target)
95
+ return true;
96
+ }
97
+ }
98
+ return false;
99
+ };
100
+ foldWithinReach(reachTokens);
101
+ let tokens = renderLayout(inputs, tree, frontier).totalTokens;
102
+ // Hard wall: yield the reach cap (P) only as far as needed to keep under W.
103
+ if (tokens > windowTokens) {
104
+ foldWithinReach(Infinity);
105
+ tokens = renderLayout(inputs, tree, frontier).totalTokens;
106
+ }
107
+ return tokens;
108
+ }
109
+ /**
110
+ * Raise `frontier` resolution in place (UN-fold toward raw) to fill up to
111
+ * `target`, leveled (L3→L2, L2→L1, L1→raw) and **youngest-first within the reach
112
+ * window** — the mirror image of `shedToTarget`. Un-folding is a prefix
113
+ * perturbation too, so it obeys the same reach cap (bounded divergence) and only
114
+ * lowers whole groups (group-consistent → the picker reaches it via `lower`
115
+ * ops). Youngest-first spends the budget on the most recent foldable content
116
+ * (highest value, shallowest divergence). Stops before exceeding `target`.
117
+ * rawZone/frozen chunks are never touched. Returns final tokens.
118
+ */
119
+ function expandToTarget(frontier, inputs, tree, ordered, target, reachTokens, rawZone, frozen) {
120
+ const newerTokens = new Map();
121
+ let acc = 0;
122
+ for (let i = ordered.length - 1; i >= 0; i--) {
123
+ newerTokens.set(ordered[i].id, acc);
124
+ acc += ordered[i].rawTokens;
125
+ }
126
+ let tokens = renderLayout(inputs, tree, frontier).totalTokens;
127
+ for (let level = MAX_FOLD_LEVEL; level >= 1 && tokens < target; level--) {
128
+ for (let oi = ordered.length - 1; oi >= 0; oi--) {
129
+ if (tokens >= target)
130
+ break;
131
+ const c = ordered[oi]; // youngest-first
132
+ if ((frontier.get(c.id) ?? 0) !== level)
133
+ continue;
134
+ if (rawZone.has(c.id) || frozen.has(c.id))
135
+ continue;
136
+ if ((newerTokens.get(c.id) ?? 0) >= reachTokens)
137
+ continue;
138
+ const node = tree.ancestorAt(c.id, level);
139
+ if (!node)
140
+ continue;
141
+ // Lower the WHOLE group to level-1 only if every covered leaf is at this
142
+ // level and within reach (group-consistent + reach-bounded).
143
+ let eligible = true;
144
+ for (const leafId of node.leafChunkIds) {
145
+ if ((frontier.get(leafId) ?? 0) !== level ||
146
+ rawZone.has(leafId) || frozen.has(leafId) ||
147
+ (newerTokens.get(leafId) ?? 0) >= reachTokens) {
148
+ eligible = false;
149
+ break;
150
+ }
151
+ }
152
+ if (!eligible)
153
+ continue;
154
+ for (const leafId of node.leafChunkIds)
155
+ frontier.set(leafId, level - 1);
156
+ const nt = renderLayout(inputs, tree, frontier).totalTokens;
157
+ if (nt <= target)
158
+ tokens = nt; // accept the un-fold
159
+ else
160
+ for (const leafId of node.leafChunkIds)
161
+ frontier.set(leafId, level); // overshoot → revert
162
+ }
163
+ }
164
+ return tokens;
165
+ }
166
+ /** Earliest source sequence whose resolution changed `prev → next`. */
167
+ function earliestChangedSequence(prev, next, ordered) {
168
+ for (const c of ordered) {
169
+ if ((prev.get(c.id) ?? 0) !== (next.get(c.id) ?? 0))
170
+ return c.sequence;
171
+ }
172
+ return Number.MAX_SAFE_INTEGER;
173
+ }
174
+ function unitsBeforeSequence(layout, tree, boundary) {
175
+ let count = 0;
176
+ for (const u of layout.units) {
177
+ const seq = u.kind === 'raw' ? tree.leaf(u.key)?.sequence ?? 0
178
+ : u.kind === 'recall' ? tree.summary(u.key)?.firstSequence ?? 0
179
+ : u.kind === 'head' ? -1
180
+ : Number.MAX_SAFE_INTEGER;
181
+ if (seq < boundary)
182
+ count++;
183
+ else
184
+ break;
185
+ }
186
+ return count;
187
+ }
188
+ function rawTailSet(ordered, tailTokens) {
189
+ const s = new Set();
190
+ if (tailTokens <= 0)
191
+ return s;
192
+ let used = 0;
193
+ for (let i = ordered.length - 1; i >= 0; i--) {
194
+ s.add(ordered[i].id);
195
+ used += ordered[i].rawTokens;
196
+ if (used >= tailTokens)
197
+ break;
198
+ }
199
+ return s;
200
+ }
201
+ const EMPTY_SET = new Set();
202
+ /**
203
+ * Plan one turn's frontier under the controller policy — shared by the replay
204
+ * harness (`replayControlled`) and `KvStableStrategy`. Carries F_prev forward,
205
+ * holds the raw zone raw and the frozen set fixed, then drives the rendered size
206
+ * toward `targetTokens` from EITHER side, both bounded by the `reachTokens`
207
+ * divergence cap (KV-continuity preserving in both directions):
208
+ * - over `foldAtTokens` → deepen, oldest-first, under the log-age saliency
209
+ * caps, yielding the reach cap only as needed to stay under the hard wall W;
210
+ * - under `expandAtTokens` → un-fold, youngest-first, to use budget headroom.
211
+ * The [expandAt, foldAt] dead band leaves F_prev untouched (zero perturbation)
212
+ * when already in range. Pure and deterministic.
213
+ */
214
+ export function planControlledFrontier(inputs, tree, p) {
215
+ const ordered = [...inputs.chunks].sort((a, b) => a.sequence - b.sequence);
216
+ const frozen = p.frozen ?? EMPTY_SET;
217
+ const mergeThreshold = p.mergeThreshold ?? 6;
218
+ const reach = p.reachTokens ?? p.windowTokens;
219
+ const expandAt = p.expandAtTokens ?? p.targetTokens;
220
+ const F = new Map();
221
+ for (const c of ordered) {
222
+ if (p.rawZone.has(c.id))
223
+ F.set(c.id, 0);
224
+ else if (frozen.has(c.id))
225
+ F.set(c.id, p.previous.get(c.id) ?? c.currentResolution);
226
+ else
227
+ F.set(c.id, p.previous.get(c.id) ?? 0);
228
+ }
229
+ let tokens = renderLayout(inputs, tree, F).totalTokens;
230
+ const before = tokens;
231
+ let folded = false;
232
+ let expanded = false;
233
+ let escalated = false;
234
+ if (tokens > p.foldAtTokens) {
235
+ const flatZoneChunks = p.rawZone.size;
236
+ const caps = new Map();
237
+ for (const c of ordered) {
238
+ caps.set(c.id, p.rawZone.has(c.id) || frozen.has(c.id)
239
+ ? 0
240
+ : foldDepthCap(c, p.now, p.rawZone, flatZoneChunks, mergeThreshold));
241
+ }
242
+ tokens = shedToTarget(F, inputs, tree, ordered, caps, p.targetTokens, reach, p.windowTokens);
243
+ folded = tokens !== before; // a real fold only if it actually changed the render
244
+ if (tokens > p.windowTokens)
245
+ escalated = true;
246
+ }
247
+ else if (tokens < expandAt) {
248
+ tokens = expandToTarget(F, inputs, tree, ordered, p.targetTokens, reach, p.rawZone, frozen);
249
+ expanded = tokens !== before; // a real un-fold only if it actually changed
250
+ }
251
+ return { resolutions: F, tokens, folded, expanded, escalated };
252
+ }
253
+ /**
254
+ * Run the controller over a session (the exported PickerInputs snapshot) as
255
+ * growing history, measuring billed recompute and KV perturbation per turn.
256
+ */
257
+ export function replayControlled(fullInputs, opts) {
258
+ const mergeThreshold = opts.mergeThreshold ?? 6;
259
+ const markerCount = opts.markerCount ?? 4;
260
+ const targetSteps = Math.max(1, opts.targetSteps ?? 120);
261
+ const HW = opts.highWatermark ?? opts.budgetTokens;
262
+ const LW = opts.lowWatermark ?? Math.round(0.8 * opts.budgetTokens);
263
+ const reachTokens = opts.reachTokens ?? opts.budgetTokens;
264
+ const fullTree = new SummaryTree(fullInputs);
265
+ const availableAt = new Map();
266
+ for (const s of fullTree.allSummaries())
267
+ availableAt.set(s.id, s.lastSequence);
268
+ const allChunks = [...fullInputs.chunks].sort((a, b) => a.sequence - b.sequence);
269
+ const seqValues = allChunks.map((c) => c.sequence);
270
+ const stride = Math.max(1, Math.ceil(seqValues.length / targetSteps));
271
+ const stepSeqs = [];
272
+ for (let i = 0; i < seqValues.length; i += stride)
273
+ stepSeqs.push(seqValues[i]);
274
+ const last = seqValues[seqValues.length - 1];
275
+ if (stepSeqs[stepSeqs.length - 1] !== last)
276
+ stepSeqs.push(last);
277
+ const steps = [];
278
+ let fprev = new Map();
279
+ const cache = new CacheStore({ ttlSteps: opts.cacheTtlSteps });
280
+ let prevNow = -1;
281
+ let totalRecomputed = 0;
282
+ let totalBilled = 0;
283
+ let totalCached = 0;
284
+ let totalRendered = 0;
285
+ let sumSqPerturb = 0;
286
+ let maxPerturbation = 0;
287
+ let foldEvents = 0;
288
+ let escalations = 0;
289
+ for (const now of stepSeqs) {
290
+ const visible = allChunks.filter((c) => c.sequence <= now);
291
+ const summaries = new Map();
292
+ const recallPairTokens = new Map();
293
+ for (const [id, s] of fullInputs.summaries) {
294
+ const lastSeq = availableAt.get(id);
295
+ if (lastSeq !== undefined && lastSeq >= 0 && lastSeq <= now) {
296
+ summaries.set(id, s);
297
+ const rp = fullInputs.recallPairTokens?.get(id);
298
+ if (rp !== undefined)
299
+ recallPairTokens.set(id, rp);
300
+ }
301
+ }
302
+ const inputs = {
303
+ chunks: visible, summaries, recallPairTokens,
304
+ headTokens: 0, tailTokens: 0, headChunkIds: new Set(), tailChunkIds: new Set(),
305
+ };
306
+ const tree = new SummaryTree(inputs);
307
+ const flatZone = rawTailSet(visible, opts.attendedWindowTokens);
308
+ // Plan this turn's frontier via the shared controller policy (the same code
309
+ // KvStableStrategy runs): carry F_prev, hold the flat zone raw, fold to LW
310
+ // when over HW, and un-fold to LW when under it — both reach-bounded, with
311
+ // [LW, HW] a no-op dead band; never past the hard wall W.
312
+ const plan = planControlledFrontier(inputs, tree, {
313
+ previous: fprev, foldAtTokens: HW, expandAtTokens: LW, targetTokens: LW,
314
+ windowTokens: opts.windowTokens, reachTokens, rawZone: flatZone, now, mergeThreshold,
315
+ });
316
+ const F = plan.resolutions;
317
+ const folded = plan.folded || plan.expanded; // any active prefix change this turn
318
+ const escalated = plan.escalated;
319
+ const layout = renderLayout(inputs, tree, F);
320
+ const hit = cache.read(layout);
321
+ const recomputed = layout.totalTokens - hit.cachedTokens;
322
+ // Perturbation = recompute beyond genuinely new content (prefix churn).
323
+ let newContent = 0;
324
+ for (const c of visible)
325
+ if (c.sequence > prevNow)
326
+ newContent += c.rawTokens;
327
+ const perturbation = Math.max(0, recomputed - newContent);
328
+ const billed = PRICE.miss * recomputed + PRICE.cacheRead * hit.cachedTokens;
329
+ // Write breakpoints for future turns, hinting at the change boundary.
330
+ const boundarySeq = earliestChangedSequence(fprev, F, visible);
331
+ const boundaryUnitIndex = unitsBeforeSequence(layout, tree, boundarySeq);
332
+ cache.write(layout, placeMarkers(layout, markerCount, { boundaryUnitIndex }));
333
+ cache.tick();
334
+ let deepestLevel = 0;
335
+ for (const lvl of F.values())
336
+ if (lvl > deepestLevel)
337
+ deepestLevel = lvl;
338
+ steps.push({
339
+ now, numChunks: visible.length, renderedTokens: layout.totalTokens,
340
+ cachedTokens: hit.cachedTokens, recomputedTokens: recomputed, billed,
341
+ perturbation, folded, escalated, deepestLevel,
342
+ });
343
+ totalRecomputed += recomputed;
344
+ totalBilled += billed;
345
+ totalCached += hit.cachedTokens;
346
+ totalRendered += layout.totalTokens;
347
+ sumSqPerturb += perturbation * perturbation;
348
+ if (perturbation > maxPerturbation)
349
+ maxPerturbation = perturbation;
350
+ if (folded)
351
+ foldEvents++;
352
+ if (escalated)
353
+ escalations++;
354
+ fprev = F;
355
+ prevNow = now;
356
+ }
357
+ return {
358
+ steps,
359
+ totalRecomputed,
360
+ totalBilled,
361
+ overallHitRate: totalRendered > 0 ? totalCached / totalRendered : 0,
362
+ maxPerturbation,
363
+ rmsPerturbation: Math.sqrt(sumSqPerturb / Math.max(1, steps.length)),
364
+ foldEvents,
365
+ escalations,
366
+ };
367
+ }
368
+ //# sourceMappingURL=kv-control.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kv-control.js","sourceRoot":"","sources":["../../../src/adaptive/kv-control.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Session replay for measuring REAL KV-cache stability.
3
+ *
4
+ * `replaySession` is the BASELINE: the production-default `FlatProfileStrategy`
5
+ * (level-equalizing) run through the real `Picker`, replayed over a growing
6
+ * session. Compare it against `replayControlled` (the KV-stable controller) to
7
+ * see what minimizing prefix churn actually buys. (Prior to the half-life/λ
8
+ * solver's removal this line ran `solveStableFrontier`; the λ value model was
9
+ * retired — see docs/kv-stable-context-control.md.)
10
+ *
11
+ * At each step it:
12
+ * 1. exposes only the chunks/summaries that existed by that point
13
+ * (a summary is available once its youngest covered message has happened —
14
+ * `SummaryNode.lastSequence <= now`; compression is bottom-up over time);
15
+ * 2. folds the middle to a FIXED token cap, carrying F_prev forward, with the
16
+ * newest `rawTailTokens` pinned raw (the flat zone);
17
+ * 3. READS a PERSISTENT provider cache (`CacheStore`, Anthropic ≤4
18
+ * breakpoints) for the longest live stored prefix still byte-identical to
19
+ * this render — entries written ANY prior turn — then WRITES this render's
20
+ * breakpoints back. A prefix frozen many turns ago is still a hit today.
21
+ *
22
+ * Pure and deterministic.
23
+ */
24
+ import type { PickerInputs } from './picker.js';
25
+ export interface ReplayOptions {
26
+ /** Fixed context-window cap each step folds against (tokens). */
27
+ budgetTokens: number;
28
+ /** Cache breakpoints to place per step (1…4). Default 4. */
29
+ markerCount?: number;
30
+ /** Newest-N tokens kept raw (the protected flat zone). */
31
+ rawTailTokens?: number;
32
+ /** Approximate number of replay steps (history is down-sampled to this).
33
+ * Default 120. */
34
+ targetSteps?: number;
35
+ /** Cache entries older than this many steps are evicted (provider TTL).
36
+ * Default Infinity (keep all — the faithful upper bound on reuse). */
37
+ cacheTtlSteps?: number;
38
+ }
39
+ export interface ReplayStep {
40
+ /** Newest visible source sequence at this step. */
41
+ now: number;
42
+ /** Visible chunk count. */
43
+ numChunks: number;
44
+ /** Rendered tokens of this step's frontier. */
45
+ renderedTokens: number;
46
+ /** Tokens served from the simulated provider cache this step. */
47
+ cachedTokens: number;
48
+ /** Tokens recomputed this step (cache miss). */
49
+ recomputedTokens: number;
50
+ /** cachedTokens / renderedTokens, in [0, 1]. */
51
+ hitRate: number;
52
+ /** Source sequence at/after which the frontier was re-optimized. */
53
+ boundarySequence: number;
54
+ /** Solver could not fit under the cap this step. */
55
+ overBudget: boolean;
56
+ /** Deepest fold level present in the rendered frontier (0 = all raw). */
57
+ deepestLevel: number;
58
+ /** Age (in steps) of the cache entry that served this step's hit — evidence
59
+ * the hit came from an older write, not just the previous turn. −1 = miss. */
60
+ cacheAgeSteps: number;
61
+ }
62
+ export interface ReplayResult {
63
+ steps: ReplayStep[];
64
+ /** Σ renderedTokens over all steps. */
65
+ totalRendered: number;
66
+ /** Σ recomputedTokens over all steps (the cache-miss bill). */
67
+ totalRecomputed: number;
68
+ /** (totalRendered − totalRecomputed) / totalRendered, in [0, 1]. */
69
+ overallHitRate: number;
70
+ }
71
+ /**
72
+ * Replay a full session (the exported PickerInputs snapshot) as growing
73
+ * history, measuring per-step provider-cache hit under a fixed budget.
74
+ */
75
+ export declare function replaySession(fullInputs: PickerInputs, opts: ReplayOptions): ReplayResult;
76
+ //# sourceMappingURL=kv-replay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kv-replay.d.ts","sourceRoot":"","sources":["../../../src/adaptive/kv-replay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAe,MAAM,aAAa,CAAC;AAQ7D,MAAM,WAAW,aAAa;IAC5B,iEAAiE;IACjE,YAAY,EAAE,MAAM,CAAC;IACrB,4DAA4D;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0DAA0D;IAC1D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;uBACmB;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;2EACuE;IACvE,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IACzB,mDAAmD;IACnD,GAAG,EAAE,MAAM,CAAC;IACZ,2BAA2B;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,+CAA+C;IAC/C,cAAc,EAAE,MAAM,CAAC;IACvB,iEAAiE;IACjE,YAAY,EAAE,MAAM,CAAC;IACrB,gDAAgD;IAChD,gBAAgB,EAAE,MAAM,CAAC;IACzB,gDAAgD;IAChD,OAAO,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,gBAAgB,EAAE,MAAM,CAAC;IACzB,oDAAoD;IACpD,UAAU,EAAE,OAAO,CAAC;IACpB,yEAAyE;IACzE,YAAY,EAAE,MAAM,CAAC;IACrB;mFAC+E;IAC/E,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,uCAAuC;IACvC,aAAa,EAAE,MAAM,CAAC;IACtB,+DAA+D;IAC/D,eAAe,EAAE,MAAM,CAAC;IACxB,oEAAoE;IACpE,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,GAAG,YAAY,CAsGzF"}
@@ -0,0 +1,175 @@
1
+ /**
2
+ * Session replay for measuring REAL KV-cache stability.
3
+ *
4
+ * `replaySession` is the BASELINE: the production-default `FlatProfileStrategy`
5
+ * (level-equalizing) run through the real `Picker`, replayed over a growing
6
+ * session. Compare it against `replayControlled` (the KV-stable controller) to
7
+ * see what minimizing prefix churn actually buys. (Prior to the half-life/λ
8
+ * solver's removal this line ran `solveStableFrontier`; the λ value model was
9
+ * retired — see docs/kv-stable-context-control.md.)
10
+ *
11
+ * At each step it:
12
+ * 1. exposes only the chunks/summaries that existed by that point
13
+ * (a summary is available once its youngest covered message has happened —
14
+ * `SummaryNode.lastSequence <= now`; compression is bottom-up over time);
15
+ * 2. folds the middle to a FIXED token cap, carrying F_prev forward, with the
16
+ * newest `rawTailTokens` pinned raw (the flat zone);
17
+ * 3. READS a PERSISTENT provider cache (`CacheStore`, Anthropic ≤4
18
+ * breakpoints) for the longest live stored prefix still byte-identical to
19
+ * this render — entries written ANY prior turn — then WRITES this render's
20
+ * breakpoints back. A prefix frozen many turns ago is still a hit today.
21
+ *
22
+ * Pure and deterministic.
23
+ */
24
+ import { SummaryTree } from './summary-tree.js';
25
+ import { Picker } from './picker.js';
26
+ import { FlatProfileStrategy } from './strategies/flat-profile.js';
27
+ import { renderLayout } from './render-offsets.js';
28
+ import { placeMarkers, CacheStore } from './kv-cache-sim.js';
29
+ /**
30
+ * Replay a full session (the exported PickerInputs snapshot) as growing
31
+ * history, measuring per-step provider-cache hit under a fixed budget.
32
+ */
33
+ export function replaySession(fullInputs, opts) {
34
+ const markerCount = opts.markerCount ?? 4;
35
+ const targetSteps = Math.max(1, opts.targetSteps ?? 120);
36
+ // Availability threshold per summary: youngest covered leaf sequence.
37
+ // Built once over the full tree; a summary is usable at `now` iff <= now.
38
+ const fullTree = new SummaryTree(fullInputs);
39
+ const availableAt = new Map();
40
+ for (const s of fullTree.allSummaries())
41
+ availableAt.set(s.id, s.lastSequence);
42
+ const allChunks = [...fullInputs.chunks].sort((a, b) => a.sequence - b.sequence);
43
+ const seqValues = allChunks.map((c) => c.sequence);
44
+ // Down-sample to ~targetSteps growth points (always include the final state).
45
+ const stride = Math.max(1, Math.ceil(seqValues.length / targetSteps));
46
+ const stepSeqs = [];
47
+ for (let i = 0; i < seqValues.length; i += stride)
48
+ stepSeqs.push(seqValues[i]);
49
+ const last = seqValues[seqValues.length - 1];
50
+ if (stepSeqs[stepSeqs.length - 1] !== last)
51
+ stepSeqs.push(last);
52
+ const steps = [];
53
+ let fprev = new Map();
54
+ const cache = new CacheStore({ ttlSteps: opts.cacheTtlSteps });
55
+ let totalRendered = 0;
56
+ let totalRecomputed = 0;
57
+ for (const now of stepSeqs) {
58
+ const visiblePlain = allChunks.filter((c) => c.sequence <= now);
59
+ const tailIds = rawTailSet(visiblePlain, opts.rawTailTokens ?? 0);
60
+ // Pin the flat zone so flat-profile won't fold it AND it renders as
61
+ // individual raw units — not collapsed into one fixed-key 'tail' unit,
62
+ // which would falsely match across turns in the cache.
63
+ const visible = visiblePlain.map((c) => (tailIds.has(c.id) ? { ...c, pinned: true } : c));
64
+ const summaries = new Map();
65
+ const recallPairTokens = new Map();
66
+ for (const [id, s] of fullInputs.summaries) {
67
+ const lastSeq = availableAt.get(id);
68
+ if (lastSeq !== undefined && lastSeq >= 0 && lastSeq <= now) {
69
+ summaries.set(id, s);
70
+ const rp = fullInputs.recallPairTokens?.get(id);
71
+ if (rp !== undefined)
72
+ recallPairTokens.set(id, rp);
73
+ }
74
+ }
75
+ const inputs = {
76
+ chunks: visible,
77
+ summaries,
78
+ recallPairTokens,
79
+ headTokens: 0,
80
+ tailTokens: 0,
81
+ headChunkIds: new Set(),
82
+ tailChunkIds: new Set(),
83
+ };
84
+ const tree = new SummaryTree(inputs);
85
+ // Baseline policy: the production default, FlatProfileStrategy, via the real
86
+ // Picker — folds the middle to the budget, leaving the pinned flat zone raw.
87
+ const result = new Picker(new FlatProfileStrategy()).run(inputs, {
88
+ totalBudget: opts.budgetTokens,
89
+ targetBudget: opts.budgetTokens,
90
+ slack: 0,
91
+ });
92
+ const resolutions = result.finalResolutions;
93
+ const layout = renderLayout(inputs, tree, resolutions);
94
+ // READ the persistent cache: longest live stored prefix that still matches.
95
+ const hit = cache.read(layout);
96
+ const recomputedTokens = layout.totalTokens - hit.cachedTokens;
97
+ // WRITE this render's breakpoints back (hinting at the earliest change vs
98
+ // F_prev), then advance the turn clock so future reads see this write.
99
+ const boundarySeq = earliestChangedSequence(fprev, resolutions, visible);
100
+ const boundaryUnitIndex = unitsBeforeSequence(layout, tree, boundarySeq);
101
+ cache.write(layout, placeMarkers(layout, markerCount, { boundaryUnitIndex }));
102
+ cache.tick();
103
+ let deepestLevel = 0;
104
+ for (const lvl of resolutions.values())
105
+ if (lvl > deepestLevel)
106
+ deepestLevel = lvl;
107
+ steps.push({
108
+ now,
109
+ numChunks: visible.length,
110
+ renderedTokens: layout.totalTokens,
111
+ cachedTokens: hit.cachedTokens,
112
+ recomputedTokens,
113
+ hitRate: layout.totalTokens > 0 ? hit.cachedTokens / layout.totalTokens : 0,
114
+ boundarySequence: boundarySeq,
115
+ overBudget: result.finalTokens > opts.budgetTokens,
116
+ deepestLevel,
117
+ cacheAgeSteps: hit.ageSteps,
118
+ });
119
+ totalRendered += layout.totalTokens;
120
+ totalRecomputed += recomputedTokens;
121
+ fprev = resolutions;
122
+ }
123
+ return {
124
+ steps,
125
+ totalRendered,
126
+ totalRecomputed,
127
+ overallHitRate: totalRendered > 0 ? (totalRendered - totalRecomputed) / totalRendered : 0,
128
+ };
129
+ }
130
+ // ---------------------------------------------------------------------------
131
+ /** Earliest source sequence whose resolution changed `prev → next` (the marker
132
+ * hint / churn boundary). MAX_SAFE_INTEGER when nothing changed. */
133
+ function earliestChangedSequence(prev, next, ordered) {
134
+ for (const c of ordered) {
135
+ if ((prev.get(c.id) ?? 0) !== (next.get(c.id) ?? 0))
136
+ return c.sequence;
137
+ }
138
+ return Number.MAX_SAFE_INTEGER;
139
+ }
140
+ /** Chunk ids within the newest `tailTokens` of raw content (kept non-foldable). */
141
+ function rawTailSet(orderedChunks, tailTokens) {
142
+ const s = new Set();
143
+ if (tailTokens <= 0)
144
+ return s;
145
+ let used = 0;
146
+ for (let i = orderedChunks.length - 1; i >= 0; i--) {
147
+ s.add(orderedChunks[i].id);
148
+ used += orderedChunks[i].rawTokens;
149
+ if (used >= tailTokens)
150
+ break;
151
+ }
152
+ return s;
153
+ }
154
+ /** Number of leading rendered units whose start sequence is < `boundary` (the
155
+ * frozen-prefix length → a natural cache breakpoint). */
156
+ function unitsBeforeSequence(layout, tree, boundary) {
157
+ let count = 0;
158
+ for (const u of layout.units) {
159
+ if (unitStartSeq(u, tree) < boundary)
160
+ count++;
161
+ else
162
+ break;
163
+ }
164
+ return count;
165
+ }
166
+ function unitStartSeq(u, tree) {
167
+ if (u.kind === 'raw')
168
+ return tree.leaf(u.key)?.sequence ?? 0;
169
+ if (u.kind === 'recall')
170
+ return tree.summary(u.key)?.firstSequence ?? 0;
171
+ if (u.kind === 'head')
172
+ return -1;
173
+ return Number.MAX_SAFE_INTEGER; // tail
174
+ }
175
+ //# sourceMappingURL=kv-replay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kv-replay.js","sourceRoot":"","sources":["../../../src/adaptive/kv-replay.ts"],"names":[],"mappings":"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"}