@animalabs/context-manager 0.5.4 → 0.5.9

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 (128) hide show
  1. package/dist/src/adaptive/kv-control.d.ts +84 -33
  2. package/dist/src/adaptive/kv-control.d.ts.map +1 -1
  3. package/dist/src/adaptive/kv-control.js +510 -145
  4. package/dist/src/adaptive/kv-control.js.map +1 -1
  5. package/dist/src/adaptive/picker.d.ts +21 -0
  6. package/dist/src/adaptive/picker.d.ts.map +1 -1
  7. package/dist/src/adaptive/picker.js.map +1 -1
  8. package/dist/src/adaptive/strategies/kv-stable.d.ts +12 -4
  9. package/dist/src/adaptive/strategies/kv-stable.d.ts.map +1 -1
  10. package/dist/src/adaptive/strategies/kv-stable.js +67 -7
  11. package/dist/src/adaptive/strategies/kv-stable.js.map +1 -1
  12. package/dist/src/context-log.d.ts.map +1 -1
  13. package/dist/src/context-log.js +11 -0
  14. package/dist/src/context-log.js.map +1 -1
  15. package/dist/src/context-manager.d.ts +38 -6
  16. package/dist/src/context-manager.d.ts.map +1 -1
  17. package/dist/src/context-manager.js +51 -0
  18. package/dist/src/context-manager.js.map +1 -1
  19. package/dist/src/index.d.ts +4 -2
  20. package/dist/src/index.d.ts.map +1 -1
  21. package/dist/src/index.js +3 -0
  22. package/dist/src/index.js.map +1 -1
  23. package/dist/src/message-store.d.ts +60 -0
  24. package/dist/src/message-store.d.ts.map +1 -1
  25. package/dist/src/message-store.js +165 -10
  26. package/dist/src/message-store.js.map +1 -1
  27. package/dist/src/phase-channel.d.ts +13 -0
  28. package/dist/src/phase-channel.d.ts.map +1 -0
  29. package/dist/src/phase-channel.js +55 -0
  30. package/dist/src/phase-channel.js.map +1 -0
  31. package/dist/src/strategies/autobiographical.d.ts +247 -8
  32. package/dist/src/strategies/autobiographical.d.ts.map +1 -1
  33. package/dist/src/strategies/autobiographical.js +1419 -141
  34. package/dist/src/strategies/autobiographical.js.map +1 -1
  35. package/dist/src/strategies/index.d.ts +1 -1
  36. package/dist/src/strategies/index.d.ts.map +1 -1
  37. package/dist/src/strategies/index.js.map +1 -1
  38. package/dist/src/strategies/knowledge.d.ts +8 -0
  39. package/dist/src/strategies/knowledge.d.ts.map +1 -1
  40. package/dist/src/strategies/knowledge.js +23 -1
  41. package/dist/src/strategies/knowledge.js.map +1 -1
  42. package/dist/src/types/index.d.ts +1 -1
  43. package/dist/src/types/index.d.ts.map +1 -1
  44. package/dist/src/types/index.js.map +1 -1
  45. package/dist/src/types/strategy.d.ts +112 -11
  46. package/dist/src/types/strategy.d.ts.map +1 -1
  47. package/dist/src/types/strategy.js.map +1 -1
  48. package/dist/test/adaptive/doc-plus-chat.test.js +7 -3
  49. package/dist/test/adaptive/doc-plus-chat.test.js.map +1 -1
  50. package/dist/test/adaptive/hard-fail.test.js +22 -0
  51. package/dist/test/adaptive/hard-fail.test.js.map +1 -1
  52. package/dist/test/adaptive/ingestion.test.js +3 -1
  53. package/dist/test/adaptive/ingestion.test.js.map +1 -1
  54. package/dist/test/adaptive/kv-control.test.js +17 -11
  55. package/dist/test/adaptive/kv-control.test.js.map +1 -1
  56. package/dist/test/adaptive/pin-at-level.test.d.ts +16 -0
  57. package/dist/test/adaptive/pin-at-level.test.d.ts.map +1 -0
  58. package/dist/test/adaptive/pin-at-level.test.js +133 -0
  59. package/dist/test/adaptive/pin-at-level.test.js.map +1 -0
  60. package/dist/test/adaptive/single-path-solve.test.d.ts +16 -0
  61. package/dist/test/adaptive/single-path-solve.test.d.ts.map +1 -0
  62. package/dist/test/adaptive/single-path-solve.test.js +204 -0
  63. package/dist/test/adaptive/single-path-solve.test.js.map +1 -0
  64. package/dist/test/anti-redundancy-budget.test.d.ts +17 -0
  65. package/dist/test/anti-redundancy-budget.test.d.ts.map +1 -0
  66. package/dist/test/anti-redundancy-budget.test.js +197 -0
  67. package/dist/test/anti-redundancy-budget.test.js.map +1 -0
  68. package/dist/test/chunk-persistence.test.d.ts +29 -0
  69. package/dist/test/chunk-persistence.test.d.ts.map +1 -0
  70. package/dist/test/chunk-persistence.test.js +290 -0
  71. package/dist/test/chunk-persistence.test.js.map +1 -0
  72. package/dist/test/compression-dedup.test.d.ts +20 -0
  73. package/dist/test/compression-dedup.test.d.ts.map +1 -0
  74. package/dist/test/compression-dedup.test.js +92 -0
  75. package/dist/test/compression-dedup.test.js.map +1 -0
  76. package/dist/test/compression-shape-invariants.test.js +40 -3
  77. package/dist/test/compression-shape-invariants.test.js.map +1 -1
  78. package/dist/test/head-window-order.test.d.ts +19 -0
  79. package/dist/test/head-window-order.test.d.ts.map +1 -0
  80. package/dist/test/head-window-order.test.js +159 -0
  81. package/dist/test/head-window-order.test.js.map +1 -0
  82. package/dist/test/image-strip-render-stats.test.js +25 -3
  83. package/dist/test/image-strip-render-stats.test.js.map +1 -1
  84. package/dist/test/knowledge-tool-boundary.test.d.ts +14 -0
  85. package/dist/test/knowledge-tool-boundary.test.d.ts.map +1 -0
  86. package/dist/test/knowledge-tool-boundary.test.js +93 -0
  87. package/dist/test/knowledge-tool-boundary.test.js.map +1 -0
  88. package/dist/test/l1-holdback.test.d.ts +15 -0
  89. package/dist/test/l1-holdback.test.d.ts.map +1 -0
  90. package/dist/test/l1-holdback.test.js +119 -0
  91. package/dist/test/l1-holdback.test.js.map +1 -0
  92. package/dist/test/merge-contiguity.test.d.ts +11 -0
  93. package/dist/test/merge-contiguity.test.d.ts.map +1 -0
  94. package/dist/test/merge-contiguity.test.js +74 -0
  95. package/dist/test/merge-contiguity.test.js.map +1 -0
  96. package/dist/test/message-store-window.test.d.ts +13 -0
  97. package/dist/test/message-store-window.test.d.ts.map +1 -0
  98. package/dist/test/message-store-window.test.js +177 -0
  99. package/dist/test/message-store-window.test.js.map +1 -0
  100. package/dist/test/pins.test.js +40 -0
  101. package/dist/test/pins.test.js.map +1 -1
  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 +179 -3
  105. package/dist/test/speculation-cap.test.js.map +1 -1
  106. package/dist/test/summary-log-consistency.test.d.ts +18 -0
  107. package/dist/test/summary-log-consistency.test.d.ts.map +1 -0
  108. package/dist/test/summary-log-consistency.test.js +97 -0
  109. package/dist/test/summary-log-consistency.test.js.map +1 -0
  110. package/dist/test/tool-pairing-invariant.test.d.ts +15 -0
  111. package/dist/test/tool-pairing-invariant.test.d.ts.map +1 -0
  112. package/dist/test/tool-pairing-invariant.test.js +225 -0
  113. package/dist/test/tool-pairing-invariant.test.js.map +1 -0
  114. package/dist/tsconfig.tsbuildinfo +1 -1
  115. package/package.json +11 -3
  116. package/src/adaptive/kv-control.ts +554 -152
  117. package/src/adaptive/picker.ts +21 -0
  118. package/src/adaptive/strategies/kv-stable.ts +62 -12
  119. package/src/context-log.ts +11 -0
  120. package/src/context-manager.ts +61 -4
  121. package/src/index.ts +6 -2
  122. package/src/message-store.ts +202 -9
  123. package/src/phase-channel.ts +57 -0
  124. package/src/strategies/autobiographical.ts +1482 -167
  125. package/src/strategies/index.ts +1 -1
  126. package/src/strategies/knowledge.ts +25 -1
  127. package/src/types/index.ts +1 -0
  128. package/src/types/strategy.ts +120 -7
@@ -0,0 +1,15 @@
1
+ /**
2
+ * L1 production holdback (`l1HoldbackChunks`, default 1).
3
+ *
4
+ * Speculative L1 production is supply-driven: a chunk is queued for
5
+ * compression the moment it closes, and the background drain produces its
6
+ * summary ahead of any fold demand. The holdback keeps the newest N closed
7
+ * chunks OUT of that speculative queue — the chunk at the live edge is the
8
+ * one most likely to still be in motion — releasing each automatically once
9
+ * a newer chunk closes behind it (the queue is rebuilt on every message).
10
+ *
11
+ * Demand overrides: a picker `produce` op (enqueueL1ForRange) marks the
12
+ * chunk demanded, and demanded chunks are never held back.
13
+ */
14
+ export {};
15
+ //# sourceMappingURL=l1-holdback.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"l1-holdback.test.d.ts","sourceRoot":"","sources":["../../test/l1-holdback.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG"}
@@ -0,0 +1,119 @@
1
+ /**
2
+ * L1 production holdback (`l1HoldbackChunks`, default 1).
3
+ *
4
+ * Speculative L1 production is supply-driven: a chunk is queued for
5
+ * compression the moment it closes, and the background drain produces its
6
+ * summary ahead of any fold demand. The holdback keeps the newest N closed
7
+ * chunks OUT of that speculative queue — the chunk at the live edge is the
8
+ * one most likely to still be in motion — releasing each automatically once
9
+ * a newer chunk closes behind it (the queue is rebuilt on every message).
10
+ *
11
+ * Demand overrides: a picker `produce` op (enqueueL1ForRange) marks the
12
+ * chunk demanded, and demanded chunks are never held back.
13
+ */
14
+ import { describe, it, before, after, beforeEach } from 'node:test';
15
+ import assert from 'node:assert';
16
+ import { rmSync, existsSync } from 'node:fs';
17
+ import { ContextManager, AutobiographicalStrategy } from '../src/index.js';
18
+ const TEST_STORE_PATH = './test-l1-holdback';
19
+ function cleanup() {
20
+ if (existsSync(TEST_STORE_PATH)) {
21
+ rmSync(TEST_STORE_PATH, { recursive: true, force: true });
22
+ }
23
+ }
24
+ function textBlock(text) {
25
+ return [{ type: 'text', text }];
26
+ }
27
+ class InspectableStrategy extends AutobiographicalStrategy {
28
+ queuedChunkIndices() {
29
+ return [...this.compressionQueue];
30
+ }
31
+ closedChunks() {
32
+ return this.chunks;
33
+ }
34
+ demandRange(firstId, lastId) {
35
+ this.enqueueL1ForRange(firstId, lastId);
36
+ }
37
+ }
38
+ /** Feed enough small messages to close `n` chunks (targetChunkTokens=20,
39
+ * recentWindowTokens=5 keeps only the newest message out of the
40
+ * compressible region). */
41
+ async function closeChunks(manager, strategy, n) {
42
+ let guard = 0;
43
+ while (strategy.closedChunks().length < n && guard++ < 200) {
44
+ manager.addMessage('user', textBlock(`m-${guard} hello world padding`));
45
+ await new Promise((r) => setTimeout(r, 1));
46
+ }
47
+ assert.strictEqual(strategy.closedChunks().length >= n, true, `expected ≥${n} closed chunks`);
48
+ }
49
+ function makeStrategy(overrides = {}) {
50
+ return new InspectableStrategy({
51
+ headWindowTokens: 0,
52
+ recentWindowTokens: 5,
53
+ targetChunkTokens: 20,
54
+ autoTickOnNewMessage: false, // inspect the queue without draining it
55
+ ...overrides,
56
+ });
57
+ }
58
+ describe('AutobiographicalStrategy — L1 holdback', () => {
59
+ before(cleanup);
60
+ after(cleanup);
61
+ beforeEach(cleanup);
62
+ it('default: the newest closed chunk is held out of the speculative queue', async () => {
63
+ const strategy = makeStrategy();
64
+ const manager = await ContextManager.open({ path: TEST_STORE_PATH, strategy });
65
+ await closeChunks(manager, strategy, 2);
66
+ const total = strategy.closedChunks().length;
67
+ const queued = strategy.queuedChunkIndices();
68
+ assert.ok(!queued.includes(total - 1), 'newest closed chunk must be held back');
69
+ assert.ok(queued.includes(0), 'older chunks must be queued speculatively');
70
+ manager.close();
71
+ });
72
+ it('a held-back chunk is released once a newer chunk closes behind it', async () => {
73
+ const strategy = makeStrategy();
74
+ const manager = await ContextManager.open({ path: TEST_STORE_PATH, strategy });
75
+ await closeChunks(manager, strategy, 2);
76
+ const heldIndex = strategy.closedChunks().length - 1;
77
+ assert.ok(!strategy.queuedChunkIndices().includes(heldIndex), 'sanity: held at first');
78
+ await closeChunks(manager, strategy, strategy.closedChunks().length + 1);
79
+ assert.ok(strategy.queuedChunkIndices().includes(heldIndex), 'previously-held chunk must be queued once it ages out of the holdback window');
80
+ manager.close();
81
+ });
82
+ it('l1HoldbackChunks: 0 restores compress-at-close', async () => {
83
+ const strategy = makeStrategy({ l1HoldbackChunks: 0 });
84
+ const manager = await ContextManager.open({ path: TEST_STORE_PATH, strategy });
85
+ await closeChunks(manager, strategy, 1);
86
+ const total = strategy.closedChunks().length;
87
+ assert.ok(strategy.queuedChunkIndices().includes(total - 1), 'with holdback disabled the newest chunk queues at close');
88
+ manager.close();
89
+ });
90
+ it('l1HoldbackChunks: 2 holds the two newest closed chunks', async () => {
91
+ const strategy = makeStrategy({ l1HoldbackChunks: 2 });
92
+ const manager = await ContextManager.open({ path: TEST_STORE_PATH, strategy });
93
+ await closeChunks(manager, strategy, 3);
94
+ const total = strategy.closedChunks().length;
95
+ const queued = strategy.queuedChunkIndices();
96
+ assert.ok(!queued.includes(total - 1), 'newest held');
97
+ assert.ok(!queued.includes(total - 2), 'second-newest held');
98
+ assert.ok(queued.includes(total - 3) || total - 3 < 0, 'third-newest queued');
99
+ manager.close();
100
+ });
101
+ it('demand (enqueueL1ForRange) overrides the holdback — and survives a rebuild', async () => {
102
+ const strategy = makeStrategy();
103
+ const manager = await ContextManager.open({ path: TEST_STORE_PATH, strategy });
104
+ await closeChunks(manager, strategy, 2);
105
+ const chunks = strategy.closedChunks();
106
+ const newest = chunks[chunks.length - 1];
107
+ assert.ok(!strategy.queuedChunkIndices().includes(newest.index), 'sanity: held before demand');
108
+ strategy.demandRange(newest.messages[0].id, newest.messages[newest.messages.length - 1].id);
109
+ assert.ok(strategy.queuedChunkIndices().includes(newest.index), 'demanded chunk enters the queue immediately');
110
+ // A new message rebuilds the queue from scratch — the demanded chunk must
111
+ // NOT be filtered back out by the holdback window.
112
+ manager.addMessage('user', textBlock('another message'));
113
+ await new Promise((r) => setTimeout(r, 5));
114
+ const stillNewest = strategy.closedChunks()[newest.index];
115
+ assert.ok(strategy.queuedChunkIndices().includes(stillNewest.index) || stillNewest.compressed, 'demanded chunk stays queued across rebuilds');
116
+ manager.close();
117
+ });
118
+ });
119
+ //# sourceMappingURL=l1-holdback.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"l1-holdback.test.js","sourceRoot":"","sources":["../../test/l1-holdback.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Merge-grouping contiguity (2026-07-12 fix) — regression tests.
3
+ *
4
+ * The old rule merged "whatever N are unmerged" in creation order, which
5
+ * minted merge groups bridging months of already-merged history (mythos
6
+ * L3-415 spanning 0-3853 of 3995 live messages). Such a group straddles the
7
+ * recent window, and group-atomic folding then blocks its entire lineage —
8
+ * the fold floor stops fitting the budget.
9
+ */
10
+ export {};
11
+ //# sourceMappingURL=merge-contiguity.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge-contiguity.test.d.ts","sourceRoot":"","sources":["../../test/merge-contiguity.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Merge-grouping contiguity (2026-07-12 fix) — regression tests.
3
+ *
4
+ * The old rule merged "whatever N are unmerged" in creation order, which
5
+ * minted merge groups bridging months of already-merged history (mythos
6
+ * L3-415 spanning 0-3853 of 3995 live messages). Such a group straddles the
7
+ * recent window, and group-atomic folding then blocks its entire lineage —
8
+ * the fold floor stops fitting the budget.
9
+ */
10
+ import { test } from 'node:test';
11
+ import assert from 'node:assert/strict';
12
+ import { AutobiographicalStrategy } from '../src/strategies/autobiographical.js';
13
+ /** Expose the protected candidate selector + injectable chunks. */
14
+ class Probe extends AutobiographicalStrategy {
15
+ setChunks(messageIds) {
16
+ this.chunks = [
17
+ { messages: messageIds.map((id) => ({ id })) },
18
+ ];
19
+ }
20
+ pick(unmerged, threshold) {
21
+ return this.contiguousMergeCandidates(unmerged, threshold);
22
+ }
23
+ }
24
+ function summary(id, first, last) {
25
+ return {
26
+ id, level: 2, content: `s ${id}`, tokens: 100, sourceLevel: 1,
27
+ sourceIds: [`x-${id}`],
28
+ sourceRange: { first: `m-${first}`, last: `m-${last}` },
29
+ created: 1,
30
+ };
31
+ }
32
+ function probe() {
33
+ const p = new Probe({ adaptiveResolution: true, autoTickOnNewMessage: false });
34
+ p.setChunks(Array.from({ length: 4000 }, (_, i) => `m-${i}`));
35
+ return p;
36
+ }
37
+ test('contiguous run merges; a cross-era candidate is left out', () => {
38
+ const p = probe();
39
+ // Six contiguous June-era candidates + one July-era outlier that the old
40
+ // creation-order rule would have grouped in.
41
+ const unmerged = [
42
+ summary('july', 3800, 3900), // creation-order FIRST — old code took it
43
+ summary('a', 0, 50), summary('b', 51, 170), summary('c', 171, 290),
44
+ summary('d', 291, 350), summary('e', 351, 512), summary('f', 513, 572),
45
+ ];
46
+ const run = p.pick(unmerged, 6);
47
+ assert.ok(run, 'a qualifying run exists');
48
+ assert.deepEqual(run.map((s) => s.id).sort(), ['a', 'b', 'c', 'd', 'e', 'f'], 'contiguous six, no bridge');
49
+ });
50
+ test('small holes bridge; cross-era gaps break the run', () => {
51
+ const p = probe();
52
+ const unmerged = [
53
+ summary('a', 0, 50), summary('b', 120, 200), // 70-message hole: fine
54
+ summary('c', 201, 300), summary('d', 301, 400),
55
+ summary('e', 401, 500),
56
+ summary('f', 3000, 3100), // 2500-message gap: breaks
57
+ ];
58
+ assert.equal(p.pick(unmerged, 6), null, 'five contiguous + one distant ≠ a run of six');
59
+ assert.ok(p.pick(unmerged, 5), 'the contiguous five qualify at threshold 5');
60
+ });
61
+ test('wide-span (replay-era) candidates are quarantined from any run', () => {
62
+ const p = probe();
63
+ const unmerged = [
64
+ summary('replay', 0, 3853), // spans the whole chronicle — the L2-411 shape
65
+ summary('a', 0, 50), summary('b', 51, 170), summary('c', 171, 290),
66
+ summary('d', 291, 350), summary('e', 351, 512),
67
+ ];
68
+ // Without quarantine the replay span would bridge everything into a run of
69
+ // six; with it there are only five eligible → no merge.
70
+ assert.equal(p.pick(unmerged, 6), null, 'wide-span candidate cannot complete a run');
71
+ const five = p.pick(unmerged, 5);
72
+ assert.ok(five && !five.some((s) => s.id === 'replay'), 'replay stays on the frontier');
73
+ });
74
+ //# sourceMappingURL=merge-contiguity.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge-contiguity.test.js","sourceRoot":"","sources":["../../test/merge-contiguity.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Tests for MessageStore.getWindow — the O(window) read path added for the
3
+ * webui interiority viewer (windowed welcome + history paging).
4
+ *
5
+ * Covers:
6
+ * - window bounds & clamping (empty store, offset past end, limit <= 0)
7
+ * - getTail/getFrom equivalence with their old getAll().slice() semantics
8
+ * - bodyGroup edge alignment (windows never split a shard run when asked)
9
+ * - the no-getStateSlice fallback path (chronicle <= 0.2.1 boxes)
10
+ * - resolveBlobs: false passes blob_ref placeholders through un-inflated
11
+ */
12
+ export {};
13
+ //# sourceMappingURL=message-store-window.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-store-window.test.d.ts","sourceRoot":"","sources":["../../test/message-store-window.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG"}
@@ -0,0 +1,177 @@
1
+ /**
2
+ * Tests for MessageStore.getWindow — the O(window) read path added for the
3
+ * webui interiority viewer (windowed welcome + history paging).
4
+ *
5
+ * Covers:
6
+ * - window bounds & clamping (empty store, offset past end, limit <= 0)
7
+ * - getTail/getFrom equivalence with their old getAll().slice() semantics
8
+ * - bodyGroup edge alignment (windows never split a shard run when asked)
9
+ * - the no-getStateSlice fallback path (chronicle <= 0.2.1 boxes)
10
+ * - resolveBlobs: false passes blob_ref placeholders through un-inflated
11
+ */
12
+ import { describe, it, beforeEach, after } from 'node:test';
13
+ import assert from 'node:assert';
14
+ import { rmSync, existsSync } from 'node:fs';
15
+ import { JsStore } from '@animalabs/chronicle';
16
+ import { MessageStore } from '../src/index.js';
17
+ const TEST_STORE_PATH = './test-message-store-window';
18
+ function cleanup() {
19
+ if (existsSync(TEST_STORE_PATH)) {
20
+ rmSync(TEST_STORE_PATH, { recursive: true, force: true });
21
+ }
22
+ }
23
+ function textBlock(text) {
24
+ return [{ type: 'text', text }];
25
+ }
26
+ function openStore() {
27
+ const store = JsStore.openOrCreate({ path: TEST_STORE_PATH });
28
+ try {
29
+ MessageStore.register(store);
30
+ }
31
+ catch { }
32
+ return { store, messages: new MessageStore(store) };
33
+ }
34
+ function textOf(msg) {
35
+ const b = msg.content[0];
36
+ return b && b.type === 'text' ? b.text : '';
37
+ }
38
+ describe('MessageStore.getWindow', () => {
39
+ beforeEach(cleanup);
40
+ after(cleanup);
41
+ it('returns the requested window with correct startIndex/totalCount', () => {
42
+ const { store, messages } = openStore();
43
+ for (let i = 0; i < 10; i++)
44
+ messages.append('user', textBlock(`m${i}`));
45
+ const win = messages.getWindow(3, 4);
46
+ assert.equal(win.totalCount, 10);
47
+ assert.equal(win.startIndex, 3);
48
+ assert.deepEqual(win.messages.map(textOf), ['m3', 'm4', 'm5', 'm6']);
49
+ // Window contents must match the equivalent getAll() slice exactly (ids too).
50
+ const all = messages.getAll();
51
+ assert.deepEqual(win.messages.map((m) => m.id), all.slice(3, 7).map((m) => m.id));
52
+ store.close();
53
+ });
54
+ it('clamps: empty store, offset past end, limit <= 0, window past end', () => {
55
+ const { store, messages } = openStore();
56
+ // Empty store
57
+ let win = messages.getWindow(0, 10);
58
+ assert.deepEqual(win, { messages: [], startIndex: 0, totalCount: 0 });
59
+ for (let i = 0; i < 5; i++)
60
+ messages.append('user', textBlock(`m${i}`));
61
+ // Offset past end
62
+ win = messages.getWindow(99, 10);
63
+ assert.equal(win.messages.length, 0);
64
+ assert.equal(win.totalCount, 5);
65
+ // limit <= 0
66
+ win = messages.getWindow(2, 0);
67
+ assert.equal(win.messages.length, 0);
68
+ win = messages.getWindow(2, -3);
69
+ assert.equal(win.messages.length, 0);
70
+ // Window running past the end is truncated, not an error
71
+ win = messages.getWindow(3, 100);
72
+ assert.deepEqual(win.messages.map(textOf), ['m3', 'm4']);
73
+ assert.equal(win.startIndex, 3);
74
+ store.close();
75
+ });
76
+ it('getTail/getFrom preserve their old getAll().slice() semantics', () => {
77
+ const { store, messages } = openStore();
78
+ for (let i = 0; i < 8; i++)
79
+ messages.append('user', textBlock(`m${i}`));
80
+ const all = messages.getAll();
81
+ // getTail
82
+ for (const n of [0, 1, 3, 8, 99]) {
83
+ assert.deepEqual(messages.getTail(n).map((m) => m.id), all.slice(Math.max(0, all.length - n)).map((m) => m.id), `getTail(${n})`);
84
+ }
85
+ // getFrom, including the negative-index slice behavior
86
+ for (const idx of [0, 2, 7, 8, 99, -3]) {
87
+ assert.deepEqual(messages.getFrom(idx).map((m) => m.id), all.slice(idx).map((m) => m.id), `getFrom(${idx})`);
88
+ }
89
+ store.close();
90
+ });
91
+ it('alignToBodyGroups extends window edges to whole shard runs', () => {
92
+ const { store, messages } = openStore();
93
+ // Layout: m0 m1 [g1s0 g1s1 g1s2] m5 [g2s0 g2s1] m8
94
+ messages.append('user', textBlock('m0'));
95
+ messages.append('user', textBlock('m1'));
96
+ for (let s = 0; s < 3; s++) {
97
+ messages.append('user', textBlock(`g1s${s}`), undefined, undefined, {
98
+ bodyGroupId: 'g1',
99
+ shardIndex: s,
100
+ });
101
+ }
102
+ messages.append('user', textBlock('m5'));
103
+ for (let s = 0; s < 2; s++) {
104
+ messages.append('user', textBlock(`g2s${s}`), undefined, undefined, {
105
+ bodyGroupId: 'g2',
106
+ shardIndex: s,
107
+ });
108
+ }
109
+ messages.append('user', textBlock('m8'));
110
+ // Unaligned: bisects both groups.
111
+ let win = messages.getWindow(3, 4);
112
+ assert.deepEqual(win.messages.map(textOf), ['g1s1', 'g1s2', 'm5', 'g2s0']);
113
+ // Aligned: start walks back to g1s0 (index 2), end walks forward to g2s1 (index 7).
114
+ win = messages.getWindow(3, 4, { alignToBodyGroups: true });
115
+ assert.equal(win.startIndex, 2);
116
+ assert.deepEqual(win.messages.map(textOf), ['g1s0', 'g1s1', 'g1s2', 'm5', 'g2s0', 'g2s1']);
117
+ // Alignment can walk all the way to index 0.
118
+ const { store: s2, messages: m2 } = (() => {
119
+ store.close();
120
+ cleanup();
121
+ return openStore();
122
+ })();
123
+ for (let s = 0; s < 3; s++) {
124
+ m2.append('user', textBlock(`h s${s}`), undefined, undefined, {
125
+ bodyGroupId: 'h',
126
+ shardIndex: s,
127
+ });
128
+ }
129
+ const w2 = m2.getWindow(2, 1, { alignToBodyGroups: true });
130
+ assert.equal(w2.startIndex, 0);
131
+ assert.equal(w2.messages.length, 3);
132
+ // Edges without bodyGroupId are untouched.
133
+ const w3 = m2.getWindow(0, 3, { alignToBodyGroups: true });
134
+ assert.equal(w3.startIndex, 0);
135
+ assert.equal(w3.messages.length, 3);
136
+ s2.close();
137
+ });
138
+ it('falls back to full materialization when getStateSlice is unavailable (chronicle <= 0.2.1)', () => {
139
+ const { store, messages } = openStore();
140
+ for (let i = 0; i < 6; i++)
141
+ messages.append('user', textBlock(`m${i}`));
142
+ // Same store, but with getStateSlice hidden — simulates an old chronicle.
143
+ const legacyStore = new Proxy(store, {
144
+ get(target, prop, receiver) {
145
+ if (prop === 'getStateSlice')
146
+ return undefined;
147
+ const v = Reflect.get(target, prop, receiver);
148
+ return typeof v === 'function' ? v.bind(target) : v;
149
+ },
150
+ });
151
+ const legacyMessages = new MessageStore(legacyStore);
152
+ const modern = messages.getWindow(2, 3);
153
+ const legacy = legacyMessages.getWindow(2, 3);
154
+ assert.deepEqual(legacy.messages.map((m) => m.id), modern.messages.map((m) => m.id));
155
+ assert.equal(legacy.startIndex, modern.startIndex);
156
+ assert.equal(legacy.totalCount, modern.totalCount);
157
+ store.close();
158
+ });
159
+ it('resolveBlobs: false passes blob_ref placeholders through un-inflated', () => {
160
+ const { store, messages } = openStore();
161
+ const png = Buffer.from('89504e470d0a1a0a0000000d49484452', 'hex').toString('base64');
162
+ messages.append('user', [
163
+ { type: 'text', text: 'look at this' },
164
+ { type: 'image', source: { type: 'base64', mediaType: 'image/png', data: png } },
165
+ ]);
166
+ // Default: blob is re-inlined as an image block.
167
+ const resolved = messages.getWindow(0, 1);
168
+ assert.ok(resolved.messages[0].content.some((b) => b.type === 'image'));
169
+ // resolveBlobs: false — the stored blob_ref placeholder survives.
170
+ const raw = messages.getWindow(0, 1, { resolveBlobs: false });
171
+ const kinds = raw.messages[0].content.map((b) => b.type);
172
+ assert.ok(kinds.includes('blob_ref'), `expected blob_ref in ${JSON.stringify(kinds)}`);
173
+ assert.ok(!kinds.includes('image'));
174
+ store.close();
175
+ });
176
+ });
177
+ //# sourceMappingURL=message-store-window.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-store-window.test.js","sourceRoot":"","sources":["../../test/message-store-window.test.ts"],"names":[],"mappings":"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"}
@@ -160,5 +160,45 @@ describe('AutobiographicalStrategy — pins / documents (gap #3)', () => {
160
160
  assert.ok(!mainPins.some(p => p.id === forkPin), 'main must NOT see the fork-only pin');
161
161
  manager.close();
162
162
  });
163
+ // ---- V2 dynamic pins: pin-at-level-k / pin-max-level (additive, opt-in) ----
164
+ it('pinAtLevel / level / maxLevel round-trip through listPins and validate', async () => {
165
+ const strategy = new TestableStrategy({ headWindowTokens: 0, recentWindowTokens: 5 });
166
+ const manager = await ContextManager.open({ path: TEST_STORE_PATH, strategy });
167
+ const m1 = manager.addMessage('user', textBlock('fix me at L2'));
168
+ const m2 = manager.addMessage('user', textBlock('cap me at L1'));
169
+ manager.addMessage('user', textBlock('latest'));
170
+ const atId = manager.pinAtLevel(m1, m1, 2, { name: 'at-2' });
171
+ const capId = manager.pinRange(m2, m2, { maxLevel: 1 });
172
+ // Invalid bounds are dropped (a classic raw pin), not persisted as junk.
173
+ const rawId = manager.markDocument(m2, { level: -3 });
174
+ const byId = new Map(manager.listPins().map((p) => [p.id, p]));
175
+ assert.equal(byId.get(atId)?.level, 2, 'pin-at-level stores level');
176
+ assert.equal(byId.get(atId)?.maxLevel, undefined, 'level suppresses maxLevel');
177
+ assert.equal(byId.get(capId)?.maxLevel, 1, 'pin-max-level stores maxLevel');
178
+ assert.equal(byId.get(capId)?.level, undefined, 'no fixed level on a cap pin');
179
+ assert.equal(byId.get(rawId)?.level, undefined, 'invalid level dropped → classic pin');
180
+ assert.equal(byId.get(rawId)?.maxLevel, undefined, 'invalid level dropped → classic pin');
181
+ manager.close();
182
+ });
183
+ it('level bound survives close/reopen', async () => {
184
+ let atId;
185
+ {
186
+ const strategy = new TestableStrategy({ headWindowTokens: 0, recentWindowTokens: 5 });
187
+ const manager = await ContextManager.open({ path: TEST_STORE_PATH, strategy });
188
+ const m1 = manager.addMessage('user', textBlock('survive at L3'));
189
+ manager.addMessage('user', textBlock('latest'));
190
+ atId = manager.pinAtLevel(m1, m1, 3);
191
+ manager.sync();
192
+ manager.close();
193
+ }
194
+ {
195
+ const strategy = new TestableStrategy({ headWindowTokens: 0, recentWindowTokens: 5 });
196
+ const manager = await ContextManager.open({ path: TEST_STORE_PATH, strategy });
197
+ const pin = manager.listPins().find((p) => p.id === atId);
198
+ assert.ok(pin, 'leveled pin reloads');
199
+ assert.equal(pin.level, 3, 'level bound persisted across reopen');
200
+ manager.close();
201
+ }
202
+ });
163
203
  });
164
204
  //# sourceMappingURL=pins.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pins.test.js","sourceRoot":"","sources":["../../test/pins.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pins.test.js","sourceRoot":"","sources":["../../test/pins.test.ts"],"names":[],"mappings":"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"}
@@ -7,9 +7,15 @@
7
7
  * speculatively-built L1s before there was any real budget pressure.
8
8
  *
9
9
  * Post-fix:
10
- * - `maxSpeculativeL1s` caps the count of (unmerged L1s + queued chunks).
11
- * When at cap, `onNewMessage` defers auto-tick — chunks still queue,
12
- * but compression doesn't fire until an explicit tick() / compile().
10
+ * - `maxSpeculativeL1s` caps the count of *produced, unmerged* L1 summaries.
11
+ * When at cap, `onNewMessage` defers auto-tick L1 production — chunks still
12
+ * queue, but compression doesn't fire until merges bring the unmerged count
13
+ * back under the cap (or an explicit tick() / compile()).
14
+ * - The cap does NOT count the pending compression backlog and does NOT gate
15
+ * merges: merges consolidate L1s into L_{k+1} and REDUCE the unmerged count,
16
+ * so gating them would deadlock (too many unmerged L1s blocks the merges that
17
+ * would relieve the cap, and a large backlog blocks the compression that
18
+ * would drain it). See the "does not deadlock" regression suite below.
13
19
  * - `shouldCompressPreflight()` is overridable so subclasses can add
14
20
  * custom predictive scheduling.
15
21
  */
@@ -1 +1 @@
1
- {"version":3,"file":"speculation-cap.test.d.ts","sourceRoot":"","sources":["../../test/speculation-cap.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG"}
1
+ {"version":3,"file":"speculation-cap.test.d.ts","sourceRoot":"","sources":["../../test/speculation-cap.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG"}