@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.
- package/dist/src/adaptive/index.d.ts +6 -0
- package/dist/src/adaptive/index.d.ts.map +1 -1
- package/dist/src/adaptive/index.js +8 -0
- package/dist/src/adaptive/index.js.map +1 -1
- package/dist/src/adaptive/kv-cache-sim.d.ts +128 -0
- package/dist/src/adaptive/kv-cache-sim.d.ts.map +1 -0
- package/dist/src/adaptive/kv-cache-sim.js +0 -0
- package/dist/src/adaptive/kv-cache-sim.js.map +1 -0
- package/dist/src/adaptive/kv-control.d.ts +166 -0
- package/dist/src/adaptive/kv-control.d.ts.map +1 -0
- package/dist/src/adaptive/kv-control.js +434 -0
- package/dist/src/adaptive/kv-control.js.map +1 -0
- package/dist/src/adaptive/kv-replay.d.ts +76 -0
- package/dist/src/adaptive/kv-replay.d.ts.map +1 -0
- package/dist/src/adaptive/kv-replay.js +175 -0
- package/dist/src/adaptive/kv-replay.js.map +1 -0
- package/dist/src/adaptive/picker.d.ts +13 -0
- package/dist/src/adaptive/picker.d.ts.map +1 -1
- package/dist/src/adaptive/picker.js.map +1 -1
- package/dist/src/adaptive/render-offsets.d.ts +61 -0
- package/dist/src/adaptive/render-offsets.d.ts.map +1 -0
- package/dist/src/adaptive/render-offsets.js +88 -0
- package/dist/src/adaptive/render-offsets.js.map +1 -0
- package/dist/src/adaptive/strategies/kv-stable.d.ts +48 -0
- package/dist/src/adaptive/strategies/kv-stable.d.ts.map +1 -0
- package/dist/src/adaptive/strategies/kv-stable.js +153 -0
- package/dist/src/adaptive/strategies/kv-stable.js.map +1 -0
- package/dist/src/adaptive/summary-tree.d.ts +98 -0
- package/dist/src/adaptive/summary-tree.d.ts.map +1 -0
- package/dist/src/adaptive/summary-tree.js +214 -0
- package/dist/src/adaptive/summary-tree.js.map +1 -0
- package/dist/src/context-log.d.ts.map +1 -1
- package/dist/src/context-log.js +7 -2
- package/dist/src/context-log.js.map +1 -1
- package/dist/src/context-manager.d.ts +10 -5
- package/dist/src/context-manager.d.ts.map +1 -1
- package/dist/src/context-manager.js +9 -0
- package/dist/src/context-manager.js.map +1 -1
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/message-store.js +1 -1
- package/dist/src/message-store.js.map +1 -1
- package/dist/src/phase-channel.d.ts +13 -0
- package/dist/src/phase-channel.d.ts.map +1 -0
- package/dist/src/phase-channel.js +55 -0
- package/dist/src/phase-channel.js.map +1 -0
- package/dist/src/strategies/autobiographical.d.ts +107 -44
- package/dist/src/strategies/autobiographical.d.ts.map +1 -1
- package/dist/src/strategies/autobiographical.js +437 -230
- package/dist/src/strategies/autobiographical.js.map +1 -1
- package/dist/src/types/index.d.ts +1 -1
- package/dist/src/types/index.d.ts.map +1 -1
- package/dist/src/types/index.js.map +1 -1
- package/dist/src/types/strategy.d.ts +70 -7
- package/dist/src/types/strategy.d.ts.map +1 -1
- package/dist/src/types/strategy.js +2 -0
- package/dist/src/types/strategy.js.map +1 -1
- package/dist/test/adaptive/kv-cache-sim.test.d.ts +16 -0
- package/dist/test/adaptive/kv-cache-sim.test.d.ts.map +1 -0
- package/dist/test/adaptive/kv-cache-sim.test.js +173 -0
- package/dist/test/adaptive/kv-cache-sim.test.js.map +1 -0
- package/dist/test/adaptive/kv-control.test.d.ts +14 -0
- package/dist/test/adaptive/kv-control.test.d.ts.map +1 -0
- package/dist/test/adaptive/kv-control.test.js +130 -0
- package/dist/test/adaptive/kv-control.test.js.map +1 -0
- package/dist/test/adaptive/kv-replay.test.d.ts +15 -0
- package/dist/test/adaptive/kv-replay.test.d.ts.map +1 -0
- package/dist/test/adaptive/kv-replay.test.js +112 -0
- package/dist/test/adaptive/kv-replay.test.js.map +1 -0
- package/dist/test/adaptive/kv-stable-strategy.test.d.ts +10 -0
- package/dist/test/adaptive/kv-stable-strategy.test.d.ts.map +1 -0
- package/dist/test/adaptive/kv-stable-strategy.test.js +89 -0
- package/dist/test/adaptive/kv-stable-strategy.test.js.map +1 -0
- package/dist/test/adaptive/pin-at-level.test.d.ts +16 -0
- package/dist/test/adaptive/pin-at-level.test.d.ts.map +1 -0
- package/dist/test/adaptive/pin-at-level.test.js +133 -0
- package/dist/test/adaptive/pin-at-level.test.js.map +1 -0
- package/dist/test/adaptive/render-offsets.test.d.ts +11 -0
- package/dist/test/adaptive/render-offsets.test.d.ts.map +1 -0
- package/dist/test/adaptive/render-offsets.test.js +85 -0
- package/dist/test/adaptive/render-offsets.test.js.map +1 -0
- package/dist/test/adaptive/summary-tree.test.d.ts +5 -0
- package/dist/test/adaptive/summary-tree.test.d.ts.map +1 -0
- package/dist/test/adaptive/summary-tree.test.js +72 -0
- package/dist/test/adaptive/summary-tree.test.js.map +1 -0
- package/dist/test/image-strip-render-stats.test.d.ts +2 -0
- package/dist/test/image-strip-render-stats.test.d.ts.map +1 -0
- package/dist/test/image-strip-render-stats.test.js +130 -0
- package/dist/test/image-strip-render-stats.test.js.map +1 -0
- package/dist/test/image-stripping.test.d.ts +13 -0
- package/dist/test/image-stripping.test.d.ts.map +1 -0
- package/dist/test/image-stripping.test.js +104 -0
- package/dist/test/image-stripping.test.js.map +1 -0
- package/dist/test/pins.test.js +40 -0
- package/dist/test/pins.test.js.map +1 -1
- package/dist/test/render-stats.test.d.ts +2 -0
- package/dist/test/render-stats.test.d.ts.map +1 -0
- package/dist/test/render-stats.test.js +91 -0
- package/dist/test/render-stats.test.js.map +1 -0
- package/dist/test/speculation-cap.test.d.ts +9 -3
- package/dist/test/speculation-cap.test.d.ts.map +1 -1
- package/dist/test/speculation-cap.test.js +175 -3
- package/dist/test/speculation-cap.test.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/adaptive/index.ts +48 -0
- package/src/adaptive/kv-cache-sim.ts +0 -0
- package/src/adaptive/kv-control.ts +574 -0
- package/src/adaptive/kv-replay.ts +238 -0
- package/src/adaptive/picker.ts +13 -0
- package/src/adaptive/render-offsets.ts +116 -0
- package/src/adaptive/strategies/kv-stable.ts +161 -0
- package/src/adaptive/summary-tree.ts +252 -0
- package/src/context-log.ts +7 -2
- package/src/context-manager.ts +13 -2
- package/src/index.ts +3 -0
- package/src/message-store.ts +1 -1
- package/src/phase-channel.ts +57 -0
- package/src/strategies/autobiographical.ts +453 -282
- package/src/types/index.ts +1 -0
- package/src/types/strategy.ts +71 -3
|
@@ -161,12 +161,8 @@ export declare function isResettableStrategy(s: ContextStrategy): s is Resettabl
|
|
|
161
161
|
* original chronological position. Implemented by AutobiographicalStrategy.
|
|
162
162
|
*/
|
|
163
163
|
export interface PinnableStrategy extends ContextStrategy {
|
|
164
|
-
pinRange(firstMessageId: string, lastMessageId: string, opts?:
|
|
165
|
-
|
|
166
|
-
}): string;
|
|
167
|
-
markDocument(messageId: string, opts?: {
|
|
168
|
-
name?: string;
|
|
169
|
-
}): string;
|
|
164
|
+
pinRange(firstMessageId: string, lastMessageId: string, opts?: PinLevelOptions): string;
|
|
165
|
+
markDocument(messageId: string, opts?: PinLevelOptions): string;
|
|
170
166
|
unpin(pinId: string): boolean;
|
|
171
167
|
listPins(): ReadonlyArray<ProtectedRange>;
|
|
172
168
|
}
|
|
@@ -223,6 +219,17 @@ export interface RenderStats {
|
|
|
223
219
|
messages: number;
|
|
224
220
|
tokens: number;
|
|
225
221
|
};
|
|
222
|
+
/**
|
|
223
|
+
* Raw (L0) messages the renderer kept verbatim in the MIDDLE region — i.e.
|
|
224
|
+
* neither head nor tail. Under adaptive resolution the picker routinely keeps
|
|
225
|
+
* older messages raw at a resolution gradient; these are real context tokens
|
|
226
|
+
* that the head/tail/summary buckets don't capture. (Empty for a pure
|
|
227
|
+
* hierarchical render with no pinned/uncompressed-middle messages.)
|
|
228
|
+
*/
|
|
229
|
+
middleRaw: {
|
|
230
|
+
messages: number;
|
|
231
|
+
tokens: number;
|
|
232
|
+
};
|
|
226
233
|
summaries: {
|
|
227
234
|
l1: {
|
|
228
235
|
count: number;
|
|
@@ -241,6 +248,14 @@ export interface RenderStats {
|
|
|
241
248
|
chunks: number;
|
|
242
249
|
merges: number;
|
|
243
250
|
};
|
|
251
|
+
/**
|
|
252
|
+
* Sum across all buckets — the actual rendered context size. A summary is a
|
|
253
|
+
* Q/A pair, so it counts as 2 messages here.
|
|
254
|
+
*/
|
|
255
|
+
total: {
|
|
256
|
+
messages: number;
|
|
257
|
+
tokens: number;
|
|
258
|
+
};
|
|
244
259
|
}
|
|
245
260
|
/**
|
|
246
261
|
* Strategy that can produce render-time observability stats. Implemented by
|
|
@@ -284,6 +299,16 @@ export interface AutobiographicalConfig {
|
|
|
284
299
|
/** Maximum tokens per individual message in compiled output. Messages exceeding
|
|
285
300
|
* this limit have their text/tool_result content truncated. 0 = no limit. */
|
|
286
301
|
maxMessageTokens: number;
|
|
302
|
+
/** Maximum number of images kept "live" (sent as real image blocks) in the
|
|
303
|
+
* compiled context. Counted newest-first across the whole window; images
|
|
304
|
+
* beyond this many are replaced with a text placeholder. 0 = unlimited.
|
|
305
|
+
* A hard ceiling for dense bursts that pack many images into the live window. */
|
|
306
|
+
maxLiveImages?: number;
|
|
307
|
+
/** Token depth from the newest message beyond which images are stripped to a
|
|
308
|
+
* text placeholder, even though the surrounding text stays verbatim. Measured
|
|
309
|
+
* the same way as recentWindowTokens (cumulative tokens walked from the tail).
|
|
310
|
+
* Typically much shallower than recentWindowTokens. 0 = never strip by depth. */
|
|
311
|
+
imageStripDepthTokens?: number;
|
|
287
312
|
/** @deprecated Use summarySystemPrompt */
|
|
288
313
|
diarySystemPrompt?: string;
|
|
289
314
|
/** @deprecated Use summaryUserPrompt */
|
|
@@ -406,9 +431,19 @@ export interface AutobiographicalConfig {
|
|
|
406
431
|
* Folding strategy name when adaptiveResolution is on. One of:
|
|
407
432
|
* 'flat-profile' (default) — level-equalizing
|
|
408
433
|
* 'oldest-first' — chronological
|
|
434
|
+
* 'kv-stable' — the KV-stable context controller: minimizes real prefix
|
|
435
|
+
* churn directly (flat zone + per-turn reach cap; no λ). Built per-compile
|
|
436
|
+
* from the live PickerInputs. See docs/kv-stable-context-control.md.
|
|
409
437
|
* Custom strategies can be plugged in by the host application.
|
|
410
438
|
*/
|
|
411
|
-
foldingStrategy?: 'flat-profile' | 'oldest-first';
|
|
439
|
+
foldingStrategy?: 'flat-profile' | 'oldest-first' | 'kv-stable';
|
|
440
|
+
/**
|
|
441
|
+
* Per-turn divergence reach (tokens) for `foldingStrategy: 'kv-stable'` — the
|
|
442
|
+
* structural KV-perturbation cap P. Smaller = gentler per-turn cache churn but
|
|
443
|
+
* less efficient compression; exceeded only to stay under the hard budget.
|
|
444
|
+
* Default: unbounded within the budget.
|
|
445
|
+
*/
|
|
446
|
+
kvStableReachTokens?: number;
|
|
412
447
|
/**
|
|
413
448
|
* Slack ratio (hysteresis) for the picker. The picker folds until total
|
|
414
449
|
* tokens ≤ budget * (1 - slack), and stays quiet while between slack
|
|
@@ -506,6 +541,34 @@ export interface ProtectedRange {
|
|
|
506
541
|
name?: string;
|
|
507
542
|
/** Creation timestamp (ms since epoch). */
|
|
508
543
|
created: number;
|
|
544
|
+
/**
|
|
545
|
+
* Pin-AT-level-k (V2 dynamic pins, `docs/best-fit-frontier-resolution.md` §7).
|
|
546
|
+
* Fix the covered chunks to render at EXACTLY this fold level (0 = raw): the
|
|
547
|
+
* frontier cut passes through the L_k node — neither folded deeper nor
|
|
548
|
+
* un-folded shallower. When set, this range is NOT a classic force-raw pin.
|
|
549
|
+
* Takes precedence over `maxLevel`. Omitted → not a fixed-level pin.
|
|
550
|
+
*
|
|
551
|
+
* Honored only by the KV-stable controller (`foldingStrategy: 'kv-stable'`);
|
|
552
|
+
* other strategies fall back to treating the range as raw (a safe superset).
|
|
553
|
+
*/
|
|
554
|
+
level?: number;
|
|
555
|
+
/**
|
|
556
|
+
* Pin-max-level (V2 dynamic pins): the covered chunks may fold no DEEPER than
|
|
557
|
+
* this level — raw..L_k allowed, deeper forbidden — a hard cap honored even
|
|
558
|
+
* under the window-pressure emergency. `maxLevel: 0` ≡ classic pin-raw.
|
|
559
|
+
* Ignored when `level` is set. Omitted → this pin imposes no depth cap.
|
|
560
|
+
*
|
|
561
|
+
* Honored only by the KV-stable controller; see `level`.
|
|
562
|
+
*/
|
|
563
|
+
maxLevel?: number;
|
|
564
|
+
}
|
|
565
|
+
/** Optional fold-depth bounds for a V2 dynamic pin (see `ProtectedRange`). */
|
|
566
|
+
export interface PinLevelOptions {
|
|
567
|
+
name?: string;
|
|
568
|
+
/** Pin AT exactly this level (0 = raw). Fixes the cut through the L_k node. */
|
|
569
|
+
level?: number;
|
|
570
|
+
/** Fold no deeper than this level (hard cap; `0` ≡ classic pin-raw). */
|
|
571
|
+
maxLevel?: number;
|
|
509
572
|
}
|
|
510
573
|
/**
|
|
511
574
|
* Phase type for knowledge extraction workflows.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"strategy.d.ts","sourceRoot":"","sources":["../../../src/types/strategy.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"strategy.d.ts","sourceRoot":"","sources":["../../../src/types/strategy.ts"],"names":[],"mappings":"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"}
|
|
@@ -54,6 +54,8 @@ Write naturally, as recollection of what you experienced.`,
|
|
|
54
54
|
summaryContextLabel: 'What do you remember from earlier?',
|
|
55
55
|
summaryParticipant: 'Claude',
|
|
56
56
|
maxMessageTokens: 0,
|
|
57
|
+
maxLiveImages: 6,
|
|
58
|
+
imageStripDepthTokens: 30000,
|
|
57
59
|
positionedRecallPairs: true,
|
|
58
60
|
recallHeaderTemplate: '[Recall {id}]',
|
|
59
61
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"strategy.js","sourceRoot":"","sources":["../../../src/types/strategy.ts"],"names":[],"mappings":"AA+KA;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,CAAkB;IACrD,OAAO,iBAAiB,IAAI,CAAC,IAAI,OAAQ,CAAwB,CAAC,eAAe,KAAK,UAAU,CAAC;AACnG,CAAC;AAcD,+DAA+D;AAC/D,MAAM,UAAU,kBAAkB,CAAC,CAAkB;IACnD,OAAO,CACL,UAAU,IAAI,CAAC;QACf,OAAQ,CAAsB,CAAC,QAAQ,KAAK,UAAU;QACtD,OAAO,IAAI,CAAC;QACZ,OAAQ,CAAsB,CAAC,KAAK,KAAK,UAAU,CACpD,CAAC;AACJ,CAAC;AAsCD,qDAAqD;AACrD,MAAM,UAAU,oBAAoB,CAAC,CAAkB;IACrD,OAAO,CACL,iBAAiB,IAAI,CAAC;QACtB,OAAQ,CAAwB,CAAC,eAAe,KAAK,UAAU;QAC/D,YAAY,IAAI,CAAC;QACjB,OAAQ,CAAwB,CAAC,UAAU,KAAK,UAAU,CAC3D,CAAC;AACJ,CAAC;
|
|
1
|
+
{"version":3,"file":"strategy.js","sourceRoot":"","sources":["../../../src/types/strategy.ts"],"names":[],"mappings":"AA+KA;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,CAAkB;IACrD,OAAO,iBAAiB,IAAI,CAAC,IAAI,OAAQ,CAAwB,CAAC,eAAe,KAAK,UAAU,CAAC;AACnG,CAAC;AAcD,+DAA+D;AAC/D,MAAM,UAAU,kBAAkB,CAAC,CAAkB;IACnD,OAAO,CACL,UAAU,IAAI,CAAC;QACf,OAAQ,CAAsB,CAAC,QAAQ,KAAK,UAAU;QACtD,OAAO,IAAI,CAAC;QACZ,OAAQ,CAAsB,CAAC,KAAK,KAAK,UAAU,CACpD,CAAC;AACJ,CAAC;AAsCD,qDAAqD;AACrD,MAAM,UAAU,oBAAoB,CAAC,CAAkB;IACrD,OAAO,CACL,iBAAiB,IAAI,CAAC;QACtB,OAAQ,CAAwB,CAAC,eAAe,KAAK,UAAU;QAC/D,YAAY,IAAI,CAAC;QACjB,OAAQ,CAAwB,CAAC,UAAU,KAAK,UAAU,CAC3D,CAAC;AACJ,CAAC;AA0CD,2DAA2D;AAC3D,MAAM,UAAU,oBAAoB,CAAC,CAAkB;IACrD,OAAO,CACL,gBAAgB,IAAI,CAAC;QACrB,OAAQ,CAAgC,CAAC,cAAc,KAAK,UAAU,CACvE,CAAC;AACJ,CAAC;AAiRD;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,CAAe;IAChD,OAAO,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,UAAU,CAAC;AACpC,CAAC;AA4FD;;GAEG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAA2B;IACrE,iBAAiB,EAAE,IAAI;IACvB,kBAAkB,EAAE,KAAK;IACzB,gBAAgB,EAAE,CAAC;IACnB,sBAAsB,EAAE,IAAI;IAC5B,qBAAqB,EAAE,IAAI;IAC3B,oBAAoB,EAAE,KAAK;IAC3B,mBAAmB,EAAE,qMAAqM;IAC1N,iBAAiB,EAAE;;;;;;;;;0DASqC;IACxD,mBAAmB,EAAE,oCAAoC;IACzD,kBAAkB,EAAE,QAAQ;IAC5B,gBAAgB,EAAE,CAAC;IACnB,aAAa,EAAE,CAAC;IAChB,qBAAqB,EAAE,KAAK;IAC5B,qBAAqB,EAAE,IAAI;IAC3B,oBAAoB,EAAE,eAAe;CACtC,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for the Anthropic-style KV cache simulation (kv-cache-sim.ts).
|
|
3
|
+
*
|
|
4
|
+
* Load-bearing properties:
|
|
5
|
+
* - placeMarkers never exceeds the breakpoint budget, stays in-bounds, and
|
|
6
|
+
* always offers the end (pure-append) breakpoint;
|
|
7
|
+
* - a pure append (identical prefix, longer next) is a full cache hit when an
|
|
8
|
+
* end marker exists — only the appended tail is recomputed;
|
|
9
|
+
* - a mid-prefix change caches up to the largest marker at/under the
|
|
10
|
+
* divergence point;
|
|
11
|
+
* - the discrete-marker cache never beats the idealized longest-prefix bound,
|
|
12
|
+
* and with a marker on every unit it equals the divergence offset (the same
|
|
13
|
+
* quantity render-offsets.kvCost is built on).
|
|
14
|
+
*/
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=kv-cache-sim.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kv-cache-sim.test.d.ts","sourceRoot":"","sources":["../../../test/adaptive/kv-cache-sim.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG"}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for the Anthropic-style KV cache simulation (kv-cache-sim.ts).
|
|
3
|
+
*
|
|
4
|
+
* Load-bearing properties:
|
|
5
|
+
* - placeMarkers never exceeds the breakpoint budget, stays in-bounds, and
|
|
6
|
+
* always offers the end (pure-append) breakpoint;
|
|
7
|
+
* - a pure append (identical prefix, longer next) is a full cache hit when an
|
|
8
|
+
* end marker exists — only the appended tail is recomputed;
|
|
9
|
+
* - a mid-prefix change caches up to the largest marker at/under the
|
|
10
|
+
* divergence point;
|
|
11
|
+
* - the discrete-marker cache never beats the idealized longest-prefix bound,
|
|
12
|
+
* and with a marker on every unit it equals the divergence offset (the same
|
|
13
|
+
* quantity render-offsets.kvCost is built on).
|
|
14
|
+
*/
|
|
15
|
+
import { test } from 'node:test';
|
|
16
|
+
import assert from 'node:assert/strict';
|
|
17
|
+
import { renderLayout, kvCost } from '../../src/adaptive/render-offsets.js';
|
|
18
|
+
import { placeMarkers, evaluateCacheHit, CacheStore, MAX_CACHE_MARKERS, } from '../../src/adaptive/kv-cache-sim.js';
|
|
19
|
+
import { SummaryTree } from '../../src/adaptive/summary-tree.js';
|
|
20
|
+
import { buildChronicleWithChain } from './harness.js';
|
|
21
|
+
/** A bare layout from explicit unit token sizes (kinds/keys are synthetic). */
|
|
22
|
+
function layoutOf(units) {
|
|
23
|
+
let offset = 0;
|
|
24
|
+
const out = units.map((u) => {
|
|
25
|
+
const unit = { kind: u.kind ?? 'raw', key: u.key, tokens: u.tokens, offset };
|
|
26
|
+
offset += u.tokens;
|
|
27
|
+
return unit;
|
|
28
|
+
});
|
|
29
|
+
return { units: out, totalTokens: offset };
|
|
30
|
+
}
|
|
31
|
+
/** A marker per unit boundary (the idealized, no-breakpoint-limit cache). */
|
|
32
|
+
function perUnitMarkers(layout) {
|
|
33
|
+
const out = [];
|
|
34
|
+
for (let i = 1; i <= layout.units.length; i++) {
|
|
35
|
+
out.push({ unitIndex: i, offset: i < layout.units.length ? layout.units[i].offset : layout.totalTokens });
|
|
36
|
+
}
|
|
37
|
+
return out;
|
|
38
|
+
}
|
|
39
|
+
test('placeMarkers: respects budget, stays in-bounds, includes the end marker', () => {
|
|
40
|
+
const layout = layoutOf([
|
|
41
|
+
{ key: 'head', tokens: 100, kind: 'head' },
|
|
42
|
+
{ key: 'a', tokens: 50 },
|
|
43
|
+
{ key: 'b', tokens: 50 },
|
|
44
|
+
{ key: 'c', tokens: 50 },
|
|
45
|
+
{ key: 'd', tokens: 50 },
|
|
46
|
+
{ key: 'e', tokens: 50 },
|
|
47
|
+
]);
|
|
48
|
+
for (const count of [1, 2, 3, 4, 9]) {
|
|
49
|
+
const markers = placeMarkers(layout, count, { boundaryUnitIndex: 4 });
|
|
50
|
+
assert.ok(markers.length <= Math.min(count, MAX_CACHE_MARKERS), `≤${count} markers`);
|
|
51
|
+
assert.ok(markers.every((m) => m.unitIndex >= 1 && m.unitIndex <= layout.units.length), 'in bounds');
|
|
52
|
+
const idxs = markers.map((m) => m.unitIndex);
|
|
53
|
+
assert.deepEqual([...idxs].sort((a, b) => a - b), idxs, 'sorted ascending');
|
|
54
|
+
assert.ok(idxs.includes(layout.units.length), 'end (pure-append) marker present');
|
|
55
|
+
// offsets are consistent with the layout
|
|
56
|
+
for (const m of markers) {
|
|
57
|
+
const expected = m.unitIndex < layout.units.length ? layout.units[m.unitIndex].offset : layout.totalTokens;
|
|
58
|
+
assert.equal(m.offset, expected);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
test('pure append: identical prefix + appended tail → only the tail recomputes', () => {
|
|
63
|
+
const prev = layoutOf([{ key: 'a', tokens: 100 }, { key: 'b', tokens: 100 }]);
|
|
64
|
+
const next = layoutOf([{ key: 'a', tokens: 100 }, { key: 'b', tokens: 100 }, { key: 'c', tokens: 60 }]);
|
|
65
|
+
const markers = placeMarkers(prev, 4); // includes end-of-prev (unitIndex 2)
|
|
66
|
+
const hit = evaluateCacheHit(prev, markers, next);
|
|
67
|
+
assert.equal(hit.cachedTokens, 200, 'whole prev prefix served from cache');
|
|
68
|
+
assert.equal(hit.recomputedTokens, 60, 'only appended tail recomputed');
|
|
69
|
+
assert.equal(hit.markerUnitIndex, 2);
|
|
70
|
+
assert.ok(hit.hitRate > 0.76 && hit.hitRate < 0.77);
|
|
71
|
+
});
|
|
72
|
+
test('mid-prefix change: cache stops at the largest marker ≤ divergence', () => {
|
|
73
|
+
const prev = layoutOf([
|
|
74
|
+
{ key: 'a', tokens: 50 }, { key: 'b', tokens: 50 }, { key: 'c', tokens: 50 },
|
|
75
|
+
{ key: 'd', tokens: 50 }, { key: 'e', tokens: 50 },
|
|
76
|
+
]);
|
|
77
|
+
// next diverges at unit index 3 (a,b,c identical; d→X).
|
|
78
|
+
const next = layoutOf([
|
|
79
|
+
{ key: 'a', tokens: 50 }, { key: 'b', tokens: 50 }, { key: 'c', tokens: 50 },
|
|
80
|
+
{ key: 'X', tokens: 70 }, { key: 'e', tokens: 50 },
|
|
81
|
+
]);
|
|
82
|
+
// Markers at unit indices 2 and 5 (end). Largest ≤ divergence(3) is 2 → 100 tokens.
|
|
83
|
+
const markers = [
|
|
84
|
+
{ unitIndex: 2, offset: prev.units[2].offset },
|
|
85
|
+
{ unitIndex: 5, offset: prev.totalTokens },
|
|
86
|
+
];
|
|
87
|
+
const hit = evaluateCacheHit(prev, markers, next);
|
|
88
|
+
assert.equal(hit.divergenceUnits, 3);
|
|
89
|
+
assert.equal(hit.markerUnitIndex, 2);
|
|
90
|
+
assert.equal(hit.cachedTokens, 100);
|
|
91
|
+
assert.equal(hit.recomputedTokens, next.totalTokens - 100);
|
|
92
|
+
});
|
|
93
|
+
test('no marker at/under divergence → full recompute', () => {
|
|
94
|
+
const prev = layoutOf([{ key: 'a', tokens: 50 }, { key: 'b', tokens: 50 }, { key: 'c', tokens: 50 }]);
|
|
95
|
+
const next = layoutOf([{ key: 'X', tokens: 50 }, { key: 'b', tokens: 50 }, { key: 'c', tokens: 50 }]);
|
|
96
|
+
// Only an end marker; divergence is at unit 0, so nothing is cached.
|
|
97
|
+
const markers = [{ unitIndex: 3, offset: prev.totalTokens }];
|
|
98
|
+
const hit = evaluateCacheHit(prev, markers, next);
|
|
99
|
+
assert.equal(hit.divergenceUnits, 0);
|
|
100
|
+
assert.equal(hit.markerUnitIndex, -1);
|
|
101
|
+
assert.equal(hit.cachedTokens, 0);
|
|
102
|
+
assert.equal(hit.recomputedTokens, next.totalTokens);
|
|
103
|
+
});
|
|
104
|
+
test('discrete markers never beat the idealized longest-prefix bound; per-unit markers equal it', () => {
|
|
105
|
+
// Real-ish layouts from a small chronicle, two different frontiers.
|
|
106
|
+
const ch = buildChronicleWithChain({ chunkCount: 18, tokensPerChunk: 500, mergeThreshold: 6, recallPairTokens: 120 });
|
|
107
|
+
const inputs = {
|
|
108
|
+
chunks: ch.chunks, summaries: ch.summaries, recallPairTokens: ch.recallPairTokens,
|
|
109
|
+
headTokens: 0, tailTokens: 0, headChunkIds: new Set(), tailChunkIds: new Set(),
|
|
110
|
+
};
|
|
111
|
+
const tree = new SummaryTree(inputs);
|
|
112
|
+
const allRaw = new Map(ch.chunks.map((c) => [c.id, 0]));
|
|
113
|
+
const folded = new Map(ch.chunks.map((c, i) => [c.id, i < 12 ? 1 : 0])); // fold the old half to L1
|
|
114
|
+
const prev = renderLayout(inputs, tree, allRaw);
|
|
115
|
+
const next = renderLayout(inputs, tree, folded);
|
|
116
|
+
// Idealized: longest byte-identical prefix is cached → cached = total − kvCost.
|
|
117
|
+
const idealCached = next.totalTokens - kvCost(prev, next);
|
|
118
|
+
// Discrete ≤4 markers can only cache a prefix at one of its breakpoints → ≤ ideal.
|
|
119
|
+
const fourHit = evaluateCacheHit(prev, placeMarkers(prev, 4), next);
|
|
120
|
+
assert.ok(fourHit.cachedTokens <= idealCached, '≤4 markers ≤ idealized prefix');
|
|
121
|
+
// A marker on every unit recovers the idealized bound exactly.
|
|
122
|
+
const idealHit = evaluateCacheHit(prev, perUnitMarkers(prev), next);
|
|
123
|
+
assert.equal(idealHit.cachedTokens, idealCached, 'per-unit markers == longest prefix');
|
|
124
|
+
});
|
|
125
|
+
// ---- CacheStore: persistent, cross-turn cache ----
|
|
126
|
+
const A = layoutOf([{ key: 'a', tokens: 50 }, { key: 'b', tokens: 50 }, { key: 'c', tokens: 50 }, { key: 'd', tokens: 50 }, { key: 'e', tokens: 50 }]);
|
|
127
|
+
const B = layoutOf([{ key: 'a', tokens: 50 }, { key: 'b', tokens: 50 }, { key: 'X', tokens: 70 }, { key: 'd', tokens: 50 }, { key: 'e', tokens: 50 }]);
|
|
128
|
+
test('CacheStore: cold read misses; write then read identical is a full hit', () => {
|
|
129
|
+
const store = new CacheStore();
|
|
130
|
+
assert.equal(store.read(A).cachedTokens, 0, 'cold cache = full recompute');
|
|
131
|
+
store.write(A, placeMarkers(A, 4));
|
|
132
|
+
const hit = store.read(A);
|
|
133
|
+
assert.equal(hit.cachedUnits, A.units.length, 'whole render served from cache');
|
|
134
|
+
assert.equal(hit.cachedTokens, A.totalTokens);
|
|
135
|
+
assert.equal(hit.ageSteps, 0, 'written this step');
|
|
136
|
+
});
|
|
137
|
+
test('CacheStore: remembers a prefix written turns ago across an intervening divergence (the revert case)', () => {
|
|
138
|
+
const store = new CacheStore();
|
|
139
|
+
// step 0: render A, cache its breakpoints (incl. the full-length end marker).
|
|
140
|
+
store.write(A, placeMarkers(A, 4));
|
|
141
|
+
store.tick();
|
|
142
|
+
// step 1: render B diverges from A at unit 2; cache B's breakpoints.
|
|
143
|
+
store.write(B, placeMarkers(B, 4));
|
|
144
|
+
store.tick();
|
|
145
|
+
// step 2: the frontier reverts to A. A persistent cache still has A's full
|
|
146
|
+
// entry from step 0 — a single-turn "compare to previous render (B)" check
|
|
147
|
+
// would only credit the shared [a,b) prefix.
|
|
148
|
+
const hit = store.read(A);
|
|
149
|
+
assert.equal(hit.cachedUnits, A.units.length, 'full A prefix recovered from step-0 write');
|
|
150
|
+
assert.equal(hit.cachedTokens, A.totalTokens);
|
|
151
|
+
assert.equal(hit.ageSteps, 2, 'hit served by a 2-step-old entry');
|
|
152
|
+
// Contrast: the single-turn check against B can only credit the prefix shared
|
|
153
|
+
// with B (up to the divergence), never the full A entry the store recovered.
|
|
154
|
+
const single = evaluateCacheHit(B, placeMarkers(B, 4), A);
|
|
155
|
+
assert.ok(single.cachedTokens < hit.cachedTokens, 'single-turn check cannot see the old entry');
|
|
156
|
+
assert.ok(single.cachedTokens <= 100, 'single-turn limited to the shared a,b prefix');
|
|
157
|
+
});
|
|
158
|
+
test('CacheStore: TTL evicts stale entries', () => {
|
|
159
|
+
const store = new CacheStore({ ttlSteps: 1 });
|
|
160
|
+
store.write(A, placeMarkers(A, 4));
|
|
161
|
+
store.tick(); // step 1: age 1, still within ttl
|
|
162
|
+
assert.equal(store.read(A).cachedUnits, A.units.length, 'age 1 ≤ ttl → still live');
|
|
163
|
+
store.tick(); // step 2: age 2 > ttl → evicted
|
|
164
|
+
assert.equal(store.read(A).cachedTokens, 0, 'expired entry no longer hits');
|
|
165
|
+
});
|
|
166
|
+
test('CacheStore: a longer live entry wins over a shorter one', () => {
|
|
167
|
+
const store = new CacheStore();
|
|
168
|
+
// Two writes of the same render: one with only a short marker, then full.
|
|
169
|
+
store.write(A, [{ unitIndex: 2, offset: A.units[2].offset }]);
|
|
170
|
+
store.write(A, [{ unitIndex: A.units.length, offset: A.totalTokens }]);
|
|
171
|
+
assert.equal(store.read(A).cachedUnits, A.units.length, 'longest matching prefix served');
|
|
172
|
+
});
|
|
173
|
+
//# sourceMappingURL=kv-cache-sim.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kv-cache-sim.test.js","sourceRoot":"","sources":["../../../test/adaptive/kv-cache-sim.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for the KV-stable context controller (kv-control.ts).
|
|
3
|
+
*
|
|
4
|
+
* Load-bearing properties:
|
|
5
|
+
* - under budget → pure append (no fold, zero perturbation, full cache);
|
|
6
|
+
* - the flat zone (attended window) and pins are never folded;
|
|
7
|
+
* - W is the only hard wall: the controller escalates rather than exceeding it;
|
|
8
|
+
* - amortization: a NARROWER hysteresis band lowers the worst-case per-turn
|
|
9
|
+
* perturbation (gentler continuity) at the cost of more fold events — i.e.
|
|
10
|
+
* the band width really is the cost↔continuity operating knob;
|
|
11
|
+
* - deterministic.
|
|
12
|
+
*/
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=kv-control.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kv-control.test.d.ts","sourceRoot":"","sources":["../../../test/adaptive/kv-control.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for the KV-stable context controller (kv-control.ts).
|
|
3
|
+
*
|
|
4
|
+
* Load-bearing properties:
|
|
5
|
+
* - under budget → pure append (no fold, zero perturbation, full cache);
|
|
6
|
+
* - the flat zone (attended window) and pins are never folded;
|
|
7
|
+
* - W is the only hard wall: the controller escalates rather than exceeding it;
|
|
8
|
+
* - amortization: a NARROWER hysteresis band lowers the worst-case per-turn
|
|
9
|
+
* perturbation (gentler continuity) at the cost of more fold events — i.e.
|
|
10
|
+
* the band width really is the cost↔continuity operating knob;
|
|
11
|
+
* - deterministic.
|
|
12
|
+
*/
|
|
13
|
+
import { test } from 'node:test';
|
|
14
|
+
import assert from 'node:assert/strict';
|
|
15
|
+
import { SummaryTree } from '../../src/adaptive/summary-tree.js';
|
|
16
|
+
import { replayControlled, planControlledFrontier, foldDepthCap, } from '../../src/adaptive/kv-control.js';
|
|
17
|
+
import { buildChronicleWithChain } from './harness.js';
|
|
18
|
+
function inputsOf(ch) {
|
|
19
|
+
return {
|
|
20
|
+
chunks: ch.chunks, summaries: ch.summaries, recallPairTokens: ch.recallPairTokens,
|
|
21
|
+
headTokens: 0, tailTokens: 0, headChunkIds: new Set(), tailChunkIds: new Set(),
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function session() {
|
|
25
|
+
return inputsOf(buildChronicleWithChain({
|
|
26
|
+
chunkCount: 90, tokensPerChunk: 1000, mergeThreshold: 6, recallPairTokens: 200,
|
|
27
|
+
}));
|
|
28
|
+
}
|
|
29
|
+
const BASE = {
|
|
30
|
+
windowTokens: 60_000,
|
|
31
|
+
budgetTokens: 30_000,
|
|
32
|
+
attendedWindowTokens: 6_000,
|
|
33
|
+
mergeThreshold: 6,
|
|
34
|
+
markerCount: 4,
|
|
35
|
+
targetSteps: 90,
|
|
36
|
+
};
|
|
37
|
+
test('under budget → pure append: no folds, zero perturbation, full cache', () => {
|
|
38
|
+
// 12 small chunks, generous budget → never folds.
|
|
39
|
+
const ch = buildChronicleWithChain({ chunkCount: 12, tokensPerChunk: 500, mergeThreshold: 6, recallPairTokens: 200 });
|
|
40
|
+
const r = replayControlled(inputsOf(ch), { ...BASE, budgetTokens: 1_000_000, windowTokens: 2_000_000, highWatermark: 1_000_000 });
|
|
41
|
+
assert.equal(r.foldEvents, 0, 'never folds under budget');
|
|
42
|
+
assert.equal(r.maxPerturbation, 0, 'no prefix churn');
|
|
43
|
+
for (let i = 1; i < r.steps.length; i++) {
|
|
44
|
+
assert.equal(r.steps[i].perturbation, 0, `step ${i} pure append`);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
test('flat zone and pins are never folded', () => {
|
|
48
|
+
const ch = buildChronicleWithChain({ chunkCount: 90, tokensPerChunk: 1000, mergeThreshold: 6, recallPairTokens: 200 });
|
|
49
|
+
// Pin a deep-old chunk that the controller would otherwise fold.
|
|
50
|
+
ch.chunks[3].pinned = true;
|
|
51
|
+
const inputs = inputsOf(ch);
|
|
52
|
+
const r = replayControlled(inputs, { ...BASE });
|
|
53
|
+
assert.ok(r.foldEvents > 0, 'fixture should force folding');
|
|
54
|
+
// foldDepthCap must report 0 for the pin and for the flat zone, at any age.
|
|
55
|
+
const tree = new SummaryTree(inputs);
|
|
56
|
+
const flat = new Set([ch.chunks[89].id]);
|
|
57
|
+
assert.equal(foldDepthCap(ch.chunks[3], 89, new Set(), 6, 6), 0, 'pinned chunk cap 0');
|
|
58
|
+
assert.equal(foldDepthCap(ch.chunks[89], 89, flat, 6, 6), 0, 'flat-zone chunk cap 0');
|
|
59
|
+
// An old un-pinned chunk should be allowed to fold.
|
|
60
|
+
assert.ok(foldDepthCap(ch.chunks[10], 89, new Set(), 6, 6) >= 1, 'old chunk foldable');
|
|
61
|
+
void tree;
|
|
62
|
+
});
|
|
63
|
+
test('W is the only hard wall: escalates instead of exceeding it', () => {
|
|
64
|
+
// Tiny window, lots of pinned (unfoldable) content → cannot fit under W.
|
|
65
|
+
const ch = buildChronicleWithChain({ chunkCount: 60, tokensPerChunk: 1000, mergeThreshold: 6, recallPairTokens: 200 });
|
|
66
|
+
for (const c of ch.chunks)
|
|
67
|
+
c.pinned = true; // nothing may fold
|
|
68
|
+
const r = replayControlled(inputsOf(ch), {
|
|
69
|
+
...BASE, windowTokens: 20_000, budgetTokens: 10_000, highWatermark: 10_000, attendedWindowTokens: 2_000,
|
|
70
|
+
});
|
|
71
|
+
assert.ok(r.escalations > 0, 'unfoldable content over W must escalate, not silently overflow');
|
|
72
|
+
});
|
|
73
|
+
test('reach cap is the cost↔continuity knob: tighter reach = gentler + less recompute', () => {
|
|
74
|
+
const inputs = session();
|
|
75
|
+
// Small reach bounds per-turn divergence (gentle KV) but compresses less
|
|
76
|
+
// efficiently; large reach reaches deep. The robust signals are average
|
|
77
|
+
// per-turn perturbation (RMS) and total recompute. (Worst-case maxPert and
|
|
78
|
+
// fold *frequency* are noisy — a too-tight reach can trip an emergency deep
|
|
79
|
+
// fold to stay under W.)
|
|
80
|
+
const shallow = replayControlled(inputs, { ...BASE, reachTokens: 8_000 });
|
|
81
|
+
const deep = replayControlled(inputs, { ...BASE, reachTokens: 60_000 });
|
|
82
|
+
assert.equal(shallow.escalations, 0, 'tight reach stays feasible here');
|
|
83
|
+
assert.equal(deep.escalations, 0, 'wide reach stays feasible here');
|
|
84
|
+
assert.ok(shallow.rmsPerturbation < deep.rmsPerturbation, `tighter reach → lower average per-turn perturbation (${shallow.rmsPerturbation.toFixed(0)} < ${deep.rmsPerturbation.toFixed(0)})`);
|
|
85
|
+
assert.ok(shallow.totalRecomputed <= deep.totalRecomputed, `tighter reach → no more total recompute (${shallow.totalRecomputed} ≤ ${deep.totalRecomputed})`);
|
|
86
|
+
});
|
|
87
|
+
test('bidirectional: under budget with a folded F_prev, un-folds to use headroom', () => {
|
|
88
|
+
const inputs = session(); // 72 chunks × 1000 = 72k raw
|
|
89
|
+
const tree = new SummaryTree(inputs);
|
|
90
|
+
const now = 71;
|
|
91
|
+
// 1) Fold tight (expandAt 0 → fold-only this call).
|
|
92
|
+
const folded = planControlledFrontier(inputs, tree, {
|
|
93
|
+
previous: new Map(), foldAtTokens: 18_000, expandAtTokens: 0, targetTokens: 18_000,
|
|
94
|
+
windowTokens: 72_000, rawZone: new Set(), now, mergeThreshold: 6,
|
|
95
|
+
});
|
|
96
|
+
assert.ok(folded.folded && !folded.expanded, 'first call folds down');
|
|
97
|
+
// 2) From that folded state, a generous budget should UN-FOLD to use headroom.
|
|
98
|
+
const expanded = planControlledFrontier(inputs, tree, {
|
|
99
|
+
previous: folded.resolutions, foldAtTokens: 50_000, expandAtTokens: 50_000, targetTokens: 50_000,
|
|
100
|
+
windowTokens: 72_000, rawZone: new Set(), now, mergeThreshold: 6,
|
|
101
|
+
});
|
|
102
|
+
assert.ok(expanded.expanded && !expanded.folded, 'un-folds, does not fold');
|
|
103
|
+
assert.ok(expanded.tokens > folded.tokens, `used headroom: ${expanded.tokens} > ${folded.tokens}`);
|
|
104
|
+
assert.ok(expanded.tokens <= 50_000, `stays within target: ${expanded.tokens} ≤ 50000`);
|
|
105
|
+
// 3) Dead band: within [expandAt, foldAt] nothing changes (zero perturbation).
|
|
106
|
+
const quiet = planControlledFrontier(inputs, tree, {
|
|
107
|
+
previous: expanded.resolutions, foldAtTokens: 60_000, expandAtTokens: 40_000, targetTokens: 50_000,
|
|
108
|
+
windowTokens: 72_000, rawZone: new Set(), now, mergeThreshold: 6,
|
|
109
|
+
});
|
|
110
|
+
assert.ok(!quiet.folded && !quiet.expanded, 'in-band → no perturbation');
|
|
111
|
+
});
|
|
112
|
+
test('controller is deterministic', () => {
|
|
113
|
+
const inputs = session();
|
|
114
|
+
const a = replayControlled(inputs, { ...BASE });
|
|
115
|
+
const b = replayControlled(inputs, { ...BASE });
|
|
116
|
+
assert.deepEqual(a, b);
|
|
117
|
+
});
|
|
118
|
+
test('foldDepthCap is monotone non-decreasing in age and capped', () => {
|
|
119
|
+
const mk = (seq) => ({
|
|
120
|
+
id: `c${seq}`, sequence: seq, rawTokens: 100, currentResolution: 0, lockedByAgent: false, pinned: false,
|
|
121
|
+
});
|
|
122
|
+
let prev = -1;
|
|
123
|
+
for (let age = 0; age <= 5000; age += 50) {
|
|
124
|
+
const cap = foldDepthCap(mk(0), age, new Set(), 10, 6);
|
|
125
|
+
assert.ok(cap >= 0 && cap <= 3, 'cap in [0,3]');
|
|
126
|
+
assert.ok(cap >= prev, 'non-decreasing in age');
|
|
127
|
+
prev = cap;
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
//# sourceMappingURL=kv-control.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kv-control.test.js","sourceRoot":"","sources":["../../../test/adaptive/kv-control.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for session replay (kv-replay.ts) — the flat-profile BASELINE replay.
|
|
3
|
+
*
|
|
4
|
+
* Load-bearing properties:
|
|
5
|
+
* - deterministic: same inputs → identical ReplayResult;
|
|
6
|
+
* - growth is monotonic (visible chunks never shrink) and the cold start has
|
|
7
|
+
* no cache;
|
|
8
|
+
* - the availability rule holds: never folds a chunk to a level whose summary
|
|
9
|
+
* couldn't exist yet (lastSequence > now);
|
|
10
|
+
* - per-step bounds: 0 ≤ recomputed ≤ rendered, hitRate ∈ [0, 1];
|
|
11
|
+
* - the controller (replayControlled) is no worse than the flat baseline on
|
|
12
|
+
* average per-turn perturbation under the same budget.
|
|
13
|
+
*/
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=kv-replay.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kv-replay.test.d.ts","sourceRoot":"","sources":["../../../test/adaptive/kv-replay.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG"}
|