@animalabs/context-manager 0.5.3 → 0.5.5

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 (123) 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 +166 -0
  10. package/dist/src/adaptive/kv-control.d.ts.map +1 -0
  11. package/dist/src/adaptive/kv-control.js +434 -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/picker.d.ts +13 -0
  18. package/dist/src/adaptive/picker.d.ts.map +1 -1
  19. package/dist/src/adaptive/picker.js.map +1 -1
  20. package/dist/src/adaptive/render-offsets.d.ts +61 -0
  21. package/dist/src/adaptive/render-offsets.d.ts.map +1 -0
  22. package/dist/src/adaptive/render-offsets.js +88 -0
  23. package/dist/src/adaptive/render-offsets.js.map +1 -0
  24. package/dist/src/adaptive/strategies/kv-stable.d.ts +48 -0
  25. package/dist/src/adaptive/strategies/kv-stable.d.ts.map +1 -0
  26. package/dist/src/adaptive/strategies/kv-stable.js +153 -0
  27. package/dist/src/adaptive/strategies/kv-stable.js.map +1 -0
  28. package/dist/src/adaptive/summary-tree.d.ts +98 -0
  29. package/dist/src/adaptive/summary-tree.d.ts.map +1 -0
  30. package/dist/src/adaptive/summary-tree.js +214 -0
  31. package/dist/src/adaptive/summary-tree.js.map +1 -0
  32. package/dist/src/context-log.d.ts.map +1 -1
  33. package/dist/src/context-log.js +7 -2
  34. package/dist/src/context-log.js.map +1 -1
  35. package/dist/src/context-manager.d.ts +10 -5
  36. package/dist/src/context-manager.d.ts.map +1 -1
  37. package/dist/src/context-manager.js +9 -0
  38. package/dist/src/context-manager.js.map +1 -1
  39. package/dist/src/index.d.ts +1 -0
  40. package/dist/src/index.d.ts.map +1 -1
  41. package/dist/src/index.js +2 -0
  42. package/dist/src/index.js.map +1 -1
  43. package/dist/src/message-store.js +1 -1
  44. package/dist/src/message-store.js.map +1 -1
  45. package/dist/src/phase-channel.d.ts +13 -0
  46. package/dist/src/phase-channel.d.ts.map +1 -0
  47. package/dist/src/phase-channel.js +55 -0
  48. package/dist/src/phase-channel.js.map +1 -0
  49. package/dist/src/strategies/autobiographical.d.ts +107 -44
  50. package/dist/src/strategies/autobiographical.d.ts.map +1 -1
  51. package/dist/src/strategies/autobiographical.js +437 -230
  52. package/dist/src/strategies/autobiographical.js.map +1 -1
  53. package/dist/src/types/index.d.ts +1 -1
  54. package/dist/src/types/index.d.ts.map +1 -1
  55. package/dist/src/types/index.js.map +1 -1
  56. package/dist/src/types/strategy.d.ts +70 -7
  57. package/dist/src/types/strategy.d.ts.map +1 -1
  58. package/dist/src/types/strategy.js +2 -0
  59. package/dist/src/types/strategy.js.map +1 -1
  60. package/dist/test/adaptive/kv-cache-sim.test.d.ts +16 -0
  61. package/dist/test/adaptive/kv-cache-sim.test.d.ts.map +1 -0
  62. package/dist/test/adaptive/kv-cache-sim.test.js +173 -0
  63. package/dist/test/adaptive/kv-cache-sim.test.js.map +1 -0
  64. package/dist/test/adaptive/kv-control.test.d.ts +14 -0
  65. package/dist/test/adaptive/kv-control.test.d.ts.map +1 -0
  66. package/dist/test/adaptive/kv-control.test.js +130 -0
  67. package/dist/test/adaptive/kv-control.test.js.map +1 -0
  68. package/dist/test/adaptive/kv-replay.test.d.ts +15 -0
  69. package/dist/test/adaptive/kv-replay.test.d.ts.map +1 -0
  70. package/dist/test/adaptive/kv-replay.test.js +112 -0
  71. package/dist/test/adaptive/kv-replay.test.js.map +1 -0
  72. package/dist/test/adaptive/kv-stable-strategy.test.d.ts +10 -0
  73. package/dist/test/adaptive/kv-stable-strategy.test.d.ts.map +1 -0
  74. package/dist/test/adaptive/kv-stable-strategy.test.js +89 -0
  75. package/dist/test/adaptive/kv-stable-strategy.test.js.map +1 -0
  76. package/dist/test/adaptive/pin-at-level.test.d.ts +16 -0
  77. package/dist/test/adaptive/pin-at-level.test.d.ts.map +1 -0
  78. package/dist/test/adaptive/pin-at-level.test.js +133 -0
  79. package/dist/test/adaptive/pin-at-level.test.js.map +1 -0
  80. package/dist/test/adaptive/render-offsets.test.d.ts +11 -0
  81. package/dist/test/adaptive/render-offsets.test.d.ts.map +1 -0
  82. package/dist/test/adaptive/render-offsets.test.js +85 -0
  83. package/dist/test/adaptive/render-offsets.test.js.map +1 -0
  84. package/dist/test/adaptive/summary-tree.test.d.ts +5 -0
  85. package/dist/test/adaptive/summary-tree.test.d.ts.map +1 -0
  86. package/dist/test/adaptive/summary-tree.test.js +72 -0
  87. package/dist/test/adaptive/summary-tree.test.js.map +1 -0
  88. package/dist/test/image-strip-render-stats.test.d.ts +2 -0
  89. package/dist/test/image-strip-render-stats.test.d.ts.map +1 -0
  90. package/dist/test/image-strip-render-stats.test.js +130 -0
  91. package/dist/test/image-strip-render-stats.test.js.map +1 -0
  92. package/dist/test/image-stripping.test.d.ts +13 -0
  93. package/dist/test/image-stripping.test.d.ts.map +1 -0
  94. package/dist/test/image-stripping.test.js +104 -0
  95. package/dist/test/image-stripping.test.js.map +1 -0
  96. package/dist/test/pins.test.js +40 -0
  97. package/dist/test/pins.test.js.map +1 -1
  98. package/dist/test/render-stats.test.d.ts +2 -0
  99. package/dist/test/render-stats.test.d.ts.map +1 -0
  100. package/dist/test/render-stats.test.js +91 -0
  101. package/dist/test/render-stats.test.js.map +1 -0
  102. package/dist/test/speculation-cap.test.d.ts +9 -3
  103. package/dist/test/speculation-cap.test.d.ts.map +1 -1
  104. package/dist/test/speculation-cap.test.js +175 -3
  105. package/dist/test/speculation-cap.test.js.map +1 -1
  106. package/dist/tsconfig.tsbuildinfo +1 -1
  107. package/package.json +2 -2
  108. package/src/adaptive/index.ts +48 -0
  109. package/src/adaptive/kv-cache-sim.ts +0 -0
  110. package/src/adaptive/kv-control.ts +574 -0
  111. package/src/adaptive/kv-replay.ts +238 -0
  112. package/src/adaptive/picker.ts +13 -0
  113. package/src/adaptive/render-offsets.ts +116 -0
  114. package/src/adaptive/strategies/kv-stable.ts +161 -0
  115. package/src/adaptive/summary-tree.ts +252 -0
  116. package/src/context-log.ts +7 -2
  117. package/src/context-manager.ts +13 -2
  118. package/src/index.ts +3 -0
  119. package/src/message-store.ts +1 -1
  120. package/src/phase-channel.ts +57 -0
  121. package/src/strategies/autobiographical.ts +453 -282
  122. package/src/types/index.ts +1 -0
  123. package/src/types/strategy.ts +71 -3
@@ -0,0 +1,434 @@
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, maxLevel = MAX_FOLD_LEVEL) {
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(maxLevel, band));
44
+ }
45
+ /** Deepest summary level that actually exists in the tree (0 if none). The
46
+ * fold depth is bounded by this — NOT a hardcoded constant — so the controller
47
+ * uses L4/L5… summaries when production has built them (else it floors at L3 and
48
+ * refuses deeper summaries that exist; cf. the lab L3-floor-with-L4-present). */
49
+ function maxAvailableLevel(tree) {
50
+ let m = 0;
51
+ for (const s of tree.allSummaries())
52
+ if (s.level > m)
53
+ m = s.level;
54
+ return m;
55
+ }
56
+ /**
57
+ * Deepen `frontier` in place to bring rendered tokens ≤ `target`, leveled
58
+ * (L1 groups, then L2, then L3) and oldest-first *within the reach window*. A
59
+ * chunk is editable this turn only if the raw tokens newer than it are <
60
+ * `reachTokens` — this bounds the divergence depth (and thus the per-turn KV
61
+ * perturbation) to ≈ reach. Each chunk is bounded by its saliency cap;
62
+ * flat-zone/pinned chunks (cap 0) are never touched.
63
+ *
64
+ * `reachTokens` is the soft cap P; `windowTokens` is the hard wall W. If folding
65
+ * within reach can't fit under W, reach is lifted (emergency) and folding
66
+ * continues to caps — yielding P minimally to keep W. Returns final tokens.
67
+ */
68
+ function shedToTarget(frontier, inputs, tree, ordered, caps, target, reachTokens, windowTokens, maxFoldLevel, pinCaps) {
69
+ // Raw tokens strictly newer than each chunk (its distance from the live end).
70
+ const newerTokens = new Map();
71
+ let acc = 0;
72
+ for (let i = ordered.length - 1; i >= 0; i--) {
73
+ newerTokens.set(ordered[i].id, acc);
74
+ acc += ordered[i].rawTokens;
75
+ }
76
+ const foldWithinReach = (reach, ignoreCaps = false) => {
77
+ for (let level = 1; level <= maxFoldLevel; level++) {
78
+ for (const c of ordered) {
79
+ // oldest-first within reach
80
+ if ((newerTokens.get(c.id) ?? 0) >= reach)
81
+ continue;
82
+ if ((frontier.get(c.id) ?? 0) >= level)
83
+ continue;
84
+ const ancestor = tree.ancestorAt(c.id, level);
85
+ if (!ancestor)
86
+ continue; // summary not produced yet → can't fold here
87
+ // Group-consistency + reach: fold the WHOLE group to `level` only if
88
+ // every covered leaf permits it (within the saliency cap unless
89
+ // `ignoreCaps`, and within reach). The picker raises whole groups, so a
90
+ // partially-eligible group would be an unreachable target (it
91
+ // oscillates). A uniform fold keeps the frontier group-consistent and
92
+ // the picker convergent. `rawZone`/`frozen` always block (their cap is 0
93
+ // and stays 0 even under ignoreCaps).
94
+ let eligible = true;
95
+ for (const leafId of ancestor.leafChunkIds) {
96
+ const cap = caps.get(leafId) ?? 0;
97
+ // A V2 pin-max-level is a HARD cap: never fold a pinned chunk deeper
98
+ // than its bound, even in the W emergency (pins are hard-protected).
99
+ const pinCap = pinCaps.get(leafId);
100
+ if (pinCap !== undefined && level > pinCap) {
101
+ eligible = false;
102
+ break;
103
+ }
104
+ // Normal: respect the saliency depth cap. Emergency (ignoreCaps): only
105
+ // the hard-protected set (cap = −1: flat zone / pins / locked) blocks;
106
+ // the age-extended-raw band (cap 0) and shallower-than-cap content all
107
+ // become foldable to fit under W.
108
+ const capBlocks = ignoreCaps ? cap < 0 : cap < level;
109
+ if (capBlocks || (newerTokens.get(leafId) ?? 0) >= reach) {
110
+ eligible = false;
111
+ break;
112
+ }
113
+ }
114
+ if (!eligible)
115
+ continue;
116
+ for (const leafId of ancestor.leafChunkIds) {
117
+ if ((frontier.get(leafId) ?? 0) < level)
118
+ frontier.set(leafId, level);
119
+ }
120
+ if (renderLayout(inputs, tree, frontier).totalTokens <= target)
121
+ return true;
122
+ }
123
+ }
124
+ return false;
125
+ };
126
+ foldWithinReach(reachTokens);
127
+ let tokens = renderLayout(inputs, tree, frontier).totalTokens;
128
+ // Hard wall: W is the only hard constraint. If folding within reach + caps
129
+ // still exceeds W, the emergency lifts BOTH the reach cap (P) AND the saliency
130
+ // depth cap — the cap is a soft *relevance* shaper, never a feasibility wall.
131
+ // It still never folds rawZone/frozen (their cap stays 0). (docs
132
+ // adaptive-resolution-design.md §12.4: fixes OverBudgetError-at-L2 when deeper
133
+ // summaries exist and would fit.)
134
+ if (tokens > windowTokens) {
135
+ foldWithinReach(Infinity, /* ignoreCaps */ true);
136
+ tokens = renderLayout(inputs, tree, frontier).totalTokens;
137
+ }
138
+ return tokens;
139
+ }
140
+ /**
141
+ * Raise `frontier` resolution in place (UN-fold toward raw) to fill up to
142
+ * `target`, leveled (L3→L2, L2→L1, L1→raw) and **youngest-first within the reach
143
+ * window** — the mirror image of `shedToTarget`. Un-folding is a prefix
144
+ * perturbation too, so it obeys the same reach cap (bounded divergence) and only
145
+ * lowers whole groups (group-consistent → the picker reaches it via `lower`
146
+ * ops). Youngest-first spends the budget on the most recent foldable content
147
+ * (highest value, shallowest divergence). Stops before exceeding `target`.
148
+ * rawZone/frozen chunks are never touched. Returns final tokens.
149
+ */
150
+ function expandToTarget(frontier, inputs, tree, ordered, target, reachTokens, rawZone, immovable, maxFoldLevel) {
151
+ const newerTokens = new Map();
152
+ let acc = 0;
153
+ for (let i = ordered.length - 1; i >= 0; i--) {
154
+ newerTokens.set(ordered[i].id, acc);
155
+ acc += ordered[i].rawTokens;
156
+ }
157
+ let tokens = renderLayout(inputs, tree, frontier).totalTokens;
158
+ for (let level = maxFoldLevel; level >= 1 && tokens < target; level--) {
159
+ for (let oi = ordered.length - 1; oi >= 0; oi--) {
160
+ if (tokens >= target)
161
+ break;
162
+ const c = ordered[oi]; // youngest-first
163
+ if ((frontier.get(c.id) ?? 0) !== level)
164
+ continue;
165
+ if (rawZone.has(c.id) || immovable.has(c.id))
166
+ continue;
167
+ if ((newerTokens.get(c.id) ?? 0) >= reachTokens)
168
+ continue;
169
+ const node = tree.ancestorAt(c.id, level);
170
+ if (!node)
171
+ continue;
172
+ // Lower the WHOLE group to level-1 only if every covered leaf is at this
173
+ // level and within reach (group-consistent + reach-bounded).
174
+ let eligible = true;
175
+ for (const leafId of node.leafChunkIds) {
176
+ if ((frontier.get(leafId) ?? 0) !== level ||
177
+ rawZone.has(leafId) || immovable.has(leafId) ||
178
+ (newerTokens.get(leafId) ?? 0) >= reachTokens) {
179
+ eligible = false;
180
+ break;
181
+ }
182
+ }
183
+ if (!eligible)
184
+ continue;
185
+ for (const leafId of node.leafChunkIds)
186
+ frontier.set(leafId, level - 1);
187
+ const nt = renderLayout(inputs, tree, frontier).totalTokens;
188
+ if (nt <= target)
189
+ tokens = nt; // accept the un-fold
190
+ else
191
+ for (const leafId of node.leafChunkIds)
192
+ frontier.set(leafId, level); // overshoot → revert
193
+ }
194
+ }
195
+ return tokens;
196
+ }
197
+ /** Earliest source sequence whose resolution changed `prev → next`. */
198
+ function earliestChangedSequence(prev, next, ordered) {
199
+ for (const c of ordered) {
200
+ if ((prev.get(c.id) ?? 0) !== (next.get(c.id) ?? 0))
201
+ return c.sequence;
202
+ }
203
+ return Number.MAX_SAFE_INTEGER;
204
+ }
205
+ function unitsBeforeSequence(layout, tree, boundary) {
206
+ let count = 0;
207
+ for (const u of layout.units) {
208
+ const seq = u.kind === 'raw' ? tree.leaf(u.key)?.sequence ?? 0
209
+ : u.kind === 'recall' ? tree.summary(u.key)?.firstSequence ?? 0
210
+ : u.kind === 'head' ? -1
211
+ : Number.MAX_SAFE_INTEGER;
212
+ if (seq < boundary)
213
+ count++;
214
+ else
215
+ break;
216
+ }
217
+ return count;
218
+ }
219
+ function rawTailSet(ordered, tailTokens) {
220
+ const s = new Set();
221
+ if (tailTokens <= 0)
222
+ return s;
223
+ let used = 0;
224
+ for (let i = ordered.length - 1; i >= 0; i--) {
225
+ s.add(ordered[i].id);
226
+ used += ordered[i].rawTokens;
227
+ if (used >= tailTokens)
228
+ break;
229
+ }
230
+ return s;
231
+ }
232
+ const EMPTY_SET = new Set();
233
+ const EMPTY_LEVEL_MAP = new Map();
234
+ /**
235
+ * Plan one turn's frontier under the controller policy — shared by the replay
236
+ * harness (`replayControlled`) and `KvStableStrategy`. Carries F_prev forward,
237
+ * holds the raw zone raw and the frozen set fixed, then drives the rendered size
238
+ * toward `targetTokens` from EITHER side, both bounded by the `reachTokens`
239
+ * divergence cap (KV-continuity preserving in both directions):
240
+ * - over `foldAtTokens` → deepen, oldest-first, under the log-age saliency
241
+ * caps, yielding the reach cap only as needed to stay under the hard wall W;
242
+ * - under `expandAtTokens` → un-fold, youngest-first, to use budget headroom.
243
+ * The [expandAt, foldAt] dead band leaves F_prev untouched (zero perturbation)
244
+ * when already in range. Pure and deterministic.
245
+ */
246
+ export function planControlledFrontier(inputs, tree, p) {
247
+ const ordered = [...inputs.chunks].sort((a, b) => a.sequence - b.sequence);
248
+ const frozen = p.frozen ?? EMPTY_SET;
249
+ const fixedLevels = p.fixedLevels ?? EMPTY_LEVEL_MAP;
250
+ const pinCaps = p.pinCaps ?? EMPTY_LEVEL_MAP;
251
+ const mergeThreshold = p.mergeThreshold ?? 6;
252
+ const reach = p.reachTokens ?? p.windowTokens;
253
+ const expandAt = p.expandAtTokens ?? p.targetTokens;
254
+ // Fold as deep as the tree actually goes (L4/L5… when produced), not a constant.
255
+ const maxFoldLevel = maxAvailableLevel(tree);
256
+ // Immovable = never folded OR un-folded by the shed/expand passes: the locked
257
+ // (frozen) set plus V2 pin-at-level-k chunks (held at their fixed level).
258
+ const immovable = new Set(frozen);
259
+ for (const id of fixedLevels.keys())
260
+ immovable.add(id);
261
+ const F = new Map();
262
+ for (const c of ordered) {
263
+ if (p.rawZone.has(c.id)) {
264
+ F.set(c.id, 0);
265
+ }
266
+ else if (fixedLevels.has(c.id)) {
267
+ // Pin-at-k: fix to exactly k, clamped to the deepest produced level for
268
+ // this chunk (can't render at a level whose summary doesn't exist yet).
269
+ const k = Math.max(0, fixedLevels.get(c.id));
270
+ F.set(c.id, k === 0 ? 0 : Math.min(k, tree.maxLevel(c.id)));
271
+ }
272
+ else if (frozen.has(c.id)) {
273
+ F.set(c.id, p.previous.get(c.id) ?? c.currentResolution);
274
+ }
275
+ else {
276
+ // Carry F_prev, but enforce a pin-max-level immediately: un-fold anything
277
+ // carried deeper than its cap down to the cap (shallower summaries — its
278
+ // ancestors — are guaranteed to exist). This is the intended divergence
279
+ // cost of adding/tightening a pin (design §7).
280
+ let lvl = p.previous.get(c.id) ?? 0;
281
+ const cap = pinCaps.get(c.id);
282
+ if (cap !== undefined && lvl > cap)
283
+ lvl = Math.max(0, cap);
284
+ F.set(c.id, lvl);
285
+ }
286
+ }
287
+ let tokens = renderLayout(inputs, tree, F).totalTokens;
288
+ const before = tokens;
289
+ let folded = false;
290
+ let expanded = false;
291
+ let escalated = false;
292
+ if (tokens > p.foldAtTokens) {
293
+ const flatZoneChunks = p.rawZone.size;
294
+ const caps = new Map();
295
+ for (const c of ordered) {
296
+ let cap;
297
+ if (p.rawZone.has(c.id) || immovable.has(c.id)) {
298
+ cap = -1; // hard-protected sentinel: never fold, even in the W emergency
299
+ }
300
+ else {
301
+ cap = foldDepthCap(c, p.now, p.rawZone, flatZoneChunks, mergeThreshold, maxFoldLevel);
302
+ const pinCap = pinCaps.get(c.id);
303
+ if (pinCap !== undefined)
304
+ cap = Math.min(cap, Math.max(0, pinCap));
305
+ }
306
+ caps.set(c.id, cap);
307
+ }
308
+ tokens = shedToTarget(F, inputs, tree, ordered, caps, p.targetTokens, reach, p.windowTokens, maxFoldLevel, pinCaps);
309
+ folded = tokens !== before; // a real fold only if it actually changed the render
310
+ if (tokens > p.windowTokens)
311
+ escalated = true;
312
+ }
313
+ else if (tokens < expandAt) {
314
+ tokens = expandToTarget(F, inputs, tree, ordered, p.targetTokens, reach, p.rawZone, immovable, maxFoldLevel);
315
+ expanded = tokens !== before; // a real un-fold only if it actually changed
316
+ }
317
+ return { resolutions: F, tokens, folded, expanded, escalated };
318
+ }
319
+ /**
320
+ * Run the controller over a session (the exported PickerInputs snapshot) as
321
+ * growing history, measuring billed recompute and KV perturbation per turn.
322
+ */
323
+ export function replayControlled(fullInputs, opts) {
324
+ const mergeThreshold = opts.mergeThreshold ?? 6;
325
+ const markerCount = opts.markerCount ?? 4;
326
+ const targetSteps = Math.max(1, opts.targetSteps ?? 120);
327
+ const HW = opts.highWatermark ?? opts.budgetTokens;
328
+ const LW = opts.lowWatermark ?? Math.round(0.8 * opts.budgetTokens);
329
+ const reachTokens = opts.reachTokens ?? opts.budgetTokens;
330
+ const fullTree = new SummaryTree(fullInputs);
331
+ const availableAt = new Map();
332
+ for (const s of fullTree.allSummaries())
333
+ availableAt.set(s.id, s.lastSequence);
334
+ const allChunks = [...fullInputs.chunks].sort((a, b) => a.sequence - b.sequence);
335
+ const seqValues = allChunks.map((c) => c.sequence);
336
+ const stride = Math.max(1, Math.ceil(seqValues.length / targetSteps));
337
+ const stepSeqs = [];
338
+ for (let i = 0; i < seqValues.length; i += stride)
339
+ stepSeqs.push(seqValues[i]);
340
+ const last = seqValues[seqValues.length - 1];
341
+ if (stepSeqs[stepSeqs.length - 1] !== last)
342
+ stepSeqs.push(last);
343
+ const steps = [];
344
+ let fprev = new Map();
345
+ const cache = new CacheStore({ ttlSteps: opts.cacheTtlSteps });
346
+ let prevNow = -1;
347
+ let totalRecomputed = 0;
348
+ let totalBilled = 0;
349
+ let totalCached = 0;
350
+ let totalRendered = 0;
351
+ let sumSqPerturb = 0;
352
+ let maxPerturbation = 0;
353
+ let foldEvents = 0;
354
+ let escalations = 0;
355
+ for (const now of stepSeqs) {
356
+ const visible = allChunks.filter((c) => c.sequence <= now);
357
+ const summaries = new Map();
358
+ const recallPairTokens = new Map();
359
+ for (const [id, s] of fullInputs.summaries) {
360
+ const lastSeq = availableAt.get(id);
361
+ if (lastSeq !== undefined && lastSeq >= 0 && lastSeq <= now) {
362
+ summaries.set(id, s);
363
+ const rp = fullInputs.recallPairTokens?.get(id);
364
+ if (rp !== undefined)
365
+ recallPairTokens.set(id, rp);
366
+ }
367
+ }
368
+ const inputs = {
369
+ chunks: visible, summaries, recallPairTokens,
370
+ headTokens: 0, tailTokens: 0, headChunkIds: new Set(), tailChunkIds: new Set(),
371
+ };
372
+ const tree = new SummaryTree(inputs);
373
+ const flatZone = rawTailSet(visible, opts.attendedWindowTokens);
374
+ // Plan this turn's frontier via the shared controller policy (the same code
375
+ // KvStableStrategy runs): carry F_prev, hold the flat zone raw, fold to LW
376
+ // when over HW, and un-fold to LW when under it — both reach-bounded, with
377
+ // [LW, HW] a no-op dead band; never past the hard wall W.
378
+ const plan = planControlledFrontier(inputs, tree, {
379
+ previous: fprev, foldAtTokens: HW, expandAtTokens: LW, targetTokens: LW,
380
+ windowTokens: opts.windowTokens, reachTokens, rawZone: flatZone, now, mergeThreshold,
381
+ });
382
+ const F = plan.resolutions;
383
+ const folded = plan.folded || plan.expanded; // any active prefix change this turn
384
+ const escalated = plan.escalated;
385
+ const layout = renderLayout(inputs, tree, F);
386
+ const hit = cache.read(layout);
387
+ const recomputed = layout.totalTokens - hit.cachedTokens;
388
+ // Perturbation = recompute beyond genuinely new content (prefix churn).
389
+ let newContent = 0;
390
+ for (const c of visible)
391
+ if (c.sequence > prevNow)
392
+ newContent += c.rawTokens;
393
+ const perturbation = Math.max(0, recomputed - newContent);
394
+ const billed = PRICE.miss * recomputed + PRICE.cacheRead * hit.cachedTokens;
395
+ // Write breakpoints for future turns, hinting at the change boundary.
396
+ const boundarySeq = earliestChangedSequence(fprev, F, visible);
397
+ const boundaryUnitIndex = unitsBeforeSequence(layout, tree, boundarySeq);
398
+ cache.write(layout, placeMarkers(layout, markerCount, { boundaryUnitIndex }));
399
+ cache.tick();
400
+ let deepestLevel = 0;
401
+ for (const lvl of F.values())
402
+ if (lvl > deepestLevel)
403
+ deepestLevel = lvl;
404
+ steps.push({
405
+ now, numChunks: visible.length, renderedTokens: layout.totalTokens,
406
+ cachedTokens: hit.cachedTokens, recomputedTokens: recomputed, billed,
407
+ perturbation, folded, escalated, deepestLevel,
408
+ });
409
+ totalRecomputed += recomputed;
410
+ totalBilled += billed;
411
+ totalCached += hit.cachedTokens;
412
+ totalRendered += layout.totalTokens;
413
+ sumSqPerturb += perturbation * perturbation;
414
+ if (perturbation > maxPerturbation)
415
+ maxPerturbation = perturbation;
416
+ if (folded)
417
+ foldEvents++;
418
+ if (escalated)
419
+ escalations++;
420
+ fprev = F;
421
+ prevNow = now;
422
+ }
423
+ return {
424
+ steps,
425
+ totalRecomputed,
426
+ totalBilled,
427
+ overallHitRate: totalRendered > 0 ? totalCached / totalRendered : 0,
428
+ maxPerturbation,
429
+ rmsPerturbation: Math.sqrt(sumSqPerturb / Math.max(1, steps.length)),
430
+ foldEvents,
431
+ escalations,
432
+ };
433
+ }
434
+ //# 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"}