@animalabs/context-manager 0.4.0 → 0.5.0
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/chunker.d.ts +70 -0
- package/dist/src/adaptive/chunker.d.ts.map +1 -0
- package/dist/src/adaptive/chunker.js +233 -0
- package/dist/src/adaptive/chunker.js.map +1 -0
- package/dist/src/adaptive/folding-strategy.d.ts +118 -0
- package/dist/src/adaptive/folding-strategy.d.ts.map +1 -0
- package/dist/src/adaptive/folding-strategy.js +12 -0
- package/dist/src/adaptive/folding-strategy.js.map +1 -0
- package/dist/src/adaptive/index.d.ts +17 -0
- package/dist/src/adaptive/index.d.ts.map +1 -0
- package/dist/src/adaptive/index.js +23 -0
- package/dist/src/adaptive/index.js.map +1 -0
- package/dist/src/adaptive/picker.d.ts +103 -0
- package/dist/src/adaptive/picker.d.ts.map +1 -0
- package/dist/src/adaptive/picker.js +357 -0
- package/dist/src/adaptive/picker.js.map +1 -0
- package/dist/src/adaptive/render.d.ts +39 -0
- package/dist/src/adaptive/render.d.ts.map +1 -0
- package/dist/src/adaptive/render.js +104 -0
- package/dist/src/adaptive/render.js.map +1 -0
- package/dist/src/adaptive/strategies/flat-profile.d.ts +19 -0
- package/dist/src/adaptive/strategies/flat-profile.d.ts.map +1 -0
- package/dist/src/adaptive/strategies/flat-profile.js +86 -0
- package/dist/src/adaptive/strategies/flat-profile.js.map +1 -0
- package/dist/src/adaptive/strategies/oldest-first.d.ts +19 -0
- package/dist/src/adaptive/strategies/oldest-first.d.ts.map +1 -0
- package/dist/src/adaptive/strategies/oldest-first.js +39 -0
- package/dist/src/adaptive/strategies/oldest-first.js.map +1 -0
- package/dist/src/context-manager.d.ts +5 -0
- package/dist/src/context-manager.d.ts.map +1 -1
- package/dist/src/context-manager.js +22 -0
- package/dist/src/context-manager.js.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/message-store.d.ts +36 -1
- package/dist/src/message-store.d.ts.map +1 -1
- package/dist/src/message-store.js +134 -8
- package/dist/src/message-store.js.map +1 -1
- package/dist/src/strategies/autobiographical.d.ts +217 -2
- package/dist/src/strategies/autobiographical.d.ts.map +1 -1
- package/dist/src/strategies/autobiographical.js +1479 -37
- package/dist/src/strategies/autobiographical.js.map +1 -1
- package/dist/src/strategies/index.d.ts +1 -1
- package/dist/src/strategies/index.d.ts.map +1 -1
- package/dist/src/strategies/index.js.map +1 -1
- package/dist/src/types/message.d.ts +38 -0
- package/dist/src/types/message.d.ts.map +1 -1
- package/dist/src/types/strategy.d.ts +94 -10
- package/dist/src/types/strategy.d.ts.map +1 -1
- package/dist/src/types/strategy.js +7 -0
- package/dist/src/types/strategy.js.map +1 -1
- package/dist/test/adaptive/branching.test.d.ts +20 -0
- package/dist/test/adaptive/branching.test.d.ts.map +1 -0
- package/dist/test/adaptive/branching.test.js +176 -0
- package/dist/test/adaptive/branching.test.js.map +1 -0
- package/dist/test/adaptive/chunker.test.d.ts +2 -0
- package/dist/test/adaptive/chunker.test.d.ts.map +1 -0
- package/dist/test/adaptive/chunker.test.js +120 -0
- package/dist/test/adaptive/chunker.test.js.map +1 -0
- package/dist/test/adaptive/deep-levels.test.d.ts +10 -0
- package/dist/test/adaptive/deep-levels.test.d.ts.map +1 -0
- package/dist/test/adaptive/deep-levels.test.js +167 -0
- package/dist/test/adaptive/deep-levels.test.js.map +1 -0
- package/dist/test/adaptive/doc-plus-chat.test.d.ts +10 -0
- package/dist/test/adaptive/doc-plus-chat.test.d.ts.map +1 -0
- package/dist/test/adaptive/doc-plus-chat.test.js +194 -0
- package/dist/test/adaptive/doc-plus-chat.test.js.map +1 -0
- package/dist/test/adaptive/hard-fail.test.d.ts +9 -0
- package/dist/test/adaptive/hard-fail.test.d.ts.map +1 -0
- package/dist/test/adaptive/hard-fail.test.js +154 -0
- package/dist/test/adaptive/hard-fail.test.js.map +1 -0
- package/dist/test/adaptive/harness.d.ts +109 -0
- package/dist/test/adaptive/harness.d.ts.map +1 -0
- package/dist/test/adaptive/harness.js +263 -0
- package/dist/test/adaptive/harness.js.map +1 -0
- package/dist/test/adaptive/ingestion.test.d.ts +13 -0
- package/dist/test/adaptive/ingestion.test.d.ts.map +1 -0
- package/dist/test/adaptive/ingestion.test.js +306 -0
- package/dist/test/adaptive/ingestion.test.js.map +1 -0
- package/dist/test/adaptive/integration.test.d.ts +12 -0
- package/dist/test/adaptive/integration.test.d.ts.map +1 -0
- package/dist/test/adaptive/integration.test.js +247 -0
- package/dist/test/adaptive/integration.test.js.map +1 -0
- package/dist/test/adaptive/long-chronicle.test.d.ts +13 -0
- package/dist/test/adaptive/long-chronicle.test.d.ts.map +1 -0
- package/dist/test/adaptive/long-chronicle.test.js +186 -0
- package/dist/test/adaptive/long-chronicle.test.js.map +1 -0
- package/dist/test/adaptive/persistence.test.d.ts +11 -0
- package/dist/test/adaptive/persistence.test.d.ts.map +1 -0
- package/dist/test/adaptive/persistence.test.js +200 -0
- package/dist/test/adaptive/persistence.test.js.map +1 -0
- package/dist/test/adaptive/picker.test.d.ts +2 -0
- package/dist/test/adaptive/picker.test.d.ts.map +1 -0
- package/dist/test/adaptive/picker.test.js +333 -0
- package/dist/test/adaptive/picker.test.js.map +1 -0
- package/dist/test/adaptive/render.test.d.ts +2 -0
- package/dist/test/adaptive/render.test.d.ts.map +1 -0
- package/dist/test/adaptive/render.test.js +109 -0
- package/dist/test/adaptive/render.test.js.map +1 -0
- package/dist/test/adaptive/shard-immutability.test.d.ts +14 -0
- package/dist/test/adaptive/shard-immutability.test.d.ts.map +1 -0
- package/dist/test/adaptive/shard-immutability.test.js +184 -0
- package/dist/test/adaptive/shard-immutability.test.js.map +1 -0
- package/dist/test/adaptive/strategy-integration.test.d.ts +9 -0
- package/dist/test/adaptive/strategy-integration.test.d.ts.map +1 -0
- package/dist/test/adaptive/strategy-integration.test.js +293 -0
- package/dist/test/adaptive/strategy-integration.test.js.map +1 -0
- package/dist/test/message-store-sequence.test.d.ts +25 -0
- package/dist/test/message-store-sequence.test.d.ts.map +1 -0
- package/dist/test/message-store-sequence.test.js +157 -0
- package/dist/test/message-store-sequence.test.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/adaptive/chunker.ts +323 -0
- package/src/adaptive/folding-strategy.ts +129 -0
- package/src/adaptive/index.ts +51 -0
- package/src/adaptive/picker.ts +442 -0
- package/src/adaptive/render.ts +115 -0
- package/src/adaptive/strategies/flat-profile.ts +96 -0
- package/src/adaptive/strategies/oldest-first.ts +48 -0
- package/src/context-manager.ts +32 -0
- package/src/index.ts +1 -1
- package/src/message-store.ts +147 -8
- package/src/strategies/autobiographical.ts +1586 -38
- package/src/strategies/index.ts +1 -1
- package/src/types/message.ts +43 -0
- package/src/types/strategy.ts +109 -10
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Synthetic test harness for the adaptive-resolution picker.
|
|
3
|
+
*
|
|
4
|
+
* Builds a minimal in-memory chronicle simulator with:
|
|
5
|
+
* - Chunks (PickerChunk shape) with deterministic token counts.
|
|
6
|
+
* - A mocked LLM that produces deterministic "summaries" by hashing input.
|
|
7
|
+
* - A summary tree that grows as the LLM is called.
|
|
8
|
+
* - A function to run the picker against a built state.
|
|
9
|
+
*
|
|
10
|
+
* The mock LLM doesn't actually call any API — it constructs fake summary
|
|
11
|
+
* content so we can validate picker logic, fold semantics, and cache stickiness
|
|
12
|
+
* without external dependencies.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Default tokens per recall pair, regardless of source level.
|
|
16
|
+
* The design specifies that L_k summaries target a constant size (~2K tokens
|
|
17
|
+
* by convention) so each level's recall pair has predictable footprint.
|
|
18
|
+
*/
|
|
19
|
+
export const DEFAULT_RECALL_PAIR_TOKENS = 200;
|
|
20
|
+
/** Default group size: how many L_k items combine into one L_{k+1}. */
|
|
21
|
+
export const DEFAULT_MERGE_THRESHOLD = 6;
|
|
22
|
+
/**
|
|
23
|
+
* Mutable in-memory chronicle. Mirrors what the real strategy would manage
|
|
24
|
+
* but trimmed to just what the picker needs.
|
|
25
|
+
*/
|
|
26
|
+
export class MockChronicle {
|
|
27
|
+
chunks = [];
|
|
28
|
+
summaries = new Map();
|
|
29
|
+
recallPairTokens = new Map();
|
|
30
|
+
summaryCounter = new Map(); // level -> next id
|
|
31
|
+
mergeThreshold;
|
|
32
|
+
defaultRecallPairTokens;
|
|
33
|
+
/** Mock LLM call count, for telemetry assertions. */
|
|
34
|
+
llmCalls = 0;
|
|
35
|
+
constructor(opts = {}) {
|
|
36
|
+
this.mergeThreshold = opts.mergeThreshold ?? DEFAULT_MERGE_THRESHOLD;
|
|
37
|
+
this.defaultRecallPairTokens = opts.recallPairTokens ?? DEFAULT_RECALL_PAIR_TOKENS;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Add a chunk to the chronicle (e.g., a chat message or a doc shard).
|
|
41
|
+
*
|
|
42
|
+
* @returns the created PickerChunk
|
|
43
|
+
*/
|
|
44
|
+
addChunk(opts) {
|
|
45
|
+
const chunk = {
|
|
46
|
+
id: opts.id,
|
|
47
|
+
sequence: this.chunks.length,
|
|
48
|
+
rawTokens: opts.rawTokens,
|
|
49
|
+
currentResolution: 0,
|
|
50
|
+
lockedByAgent: opts.lockedByAgent ?? false,
|
|
51
|
+
bodyGroupId: opts.bodyGroupId,
|
|
52
|
+
pinned: opts.pinned ?? false,
|
|
53
|
+
};
|
|
54
|
+
this.chunks.push(chunk);
|
|
55
|
+
return chunk;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Produce an L1 summary for a range of chunks. Mocks the LLM call.
|
|
59
|
+
* Idempotent: the same chunk range produces the same summary id.
|
|
60
|
+
*
|
|
61
|
+
* @returns the produced SummaryEntry (or the existing one if already produced)
|
|
62
|
+
*/
|
|
63
|
+
produceL1(chunkIds) {
|
|
64
|
+
const sortedIds = [...chunkIds].sort();
|
|
65
|
+
const sourceKey = `L1:${sortedIds.join(',')}`;
|
|
66
|
+
// Idempotency check
|
|
67
|
+
for (const existing of this.summaries.values()) {
|
|
68
|
+
if (existing.level === 1 && summaryKey(existing) === sourceKey) {
|
|
69
|
+
return existing;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
const id = this.allocSummaryId(1);
|
|
73
|
+
const entry = {
|
|
74
|
+
id,
|
|
75
|
+
level: 1,
|
|
76
|
+
content: `[mock L1 summary covering ${chunkIds.length} chunks: ${chunkIds.join(', ')}]`,
|
|
77
|
+
tokens: this.defaultRecallPairTokens,
|
|
78
|
+
sourceLevel: 0,
|
|
79
|
+
sourceIds: [...chunkIds],
|
|
80
|
+
sourceRange: { first: chunkIds[0], last: chunkIds[chunkIds.length - 1] },
|
|
81
|
+
created: Date.now(),
|
|
82
|
+
};
|
|
83
|
+
this.summaries.set(id, entry);
|
|
84
|
+
this.recallPairTokens.set(id, this.defaultRecallPairTokens);
|
|
85
|
+
this.linkChunksToL1(chunkIds, id);
|
|
86
|
+
this.llmCalls++;
|
|
87
|
+
return entry;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Produce an L_{k+1} summary from N L_k summaries.
|
|
91
|
+
*/
|
|
92
|
+
produceUpper(level, sourceSummaryIds) {
|
|
93
|
+
if (level < 2) {
|
|
94
|
+
throw new Error('produceUpper requires level >= 2; use produceL1 for level 1');
|
|
95
|
+
}
|
|
96
|
+
const sortedIds = [...sourceSummaryIds].sort();
|
|
97
|
+
const sourceKey = `L${level}:${sortedIds.join(',')}`;
|
|
98
|
+
for (const existing of this.summaries.values()) {
|
|
99
|
+
if (existing.level === level && summaryKey(existing) === sourceKey) {
|
|
100
|
+
return existing;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
const sources = sourceSummaryIds.map((sid) => {
|
|
104
|
+
const s = this.summaries.get(sid);
|
|
105
|
+
if (!s)
|
|
106
|
+
throw new Error(`produceUpper: unknown source summary ${sid}`);
|
|
107
|
+
if (s.level !== level - 1) {
|
|
108
|
+
throw new Error(`produceUpper: source ${sid} is level ${s.level}, expected ${level - 1}`);
|
|
109
|
+
}
|
|
110
|
+
return s;
|
|
111
|
+
});
|
|
112
|
+
const id = this.allocSummaryId(level);
|
|
113
|
+
const entry = {
|
|
114
|
+
id,
|
|
115
|
+
level,
|
|
116
|
+
content: `[mock L${level} summary merging ${sourceSummaryIds.length} L${level - 1}s]`,
|
|
117
|
+
tokens: this.defaultRecallPairTokens,
|
|
118
|
+
sourceLevel: level - 1,
|
|
119
|
+
sourceIds: [...sourceSummaryIds],
|
|
120
|
+
sourceRange: {
|
|
121
|
+
first: sources[0].sourceRange.first,
|
|
122
|
+
last: sources[sources.length - 1].sourceRange.last,
|
|
123
|
+
},
|
|
124
|
+
created: Date.now(),
|
|
125
|
+
};
|
|
126
|
+
this.summaries.set(id, entry);
|
|
127
|
+
this.recallPairTokens.set(id, this.defaultRecallPairTokens);
|
|
128
|
+
for (const sid of sourceSummaryIds) {
|
|
129
|
+
const s = this.summaries.get(sid);
|
|
130
|
+
s.parentId = id;
|
|
131
|
+
}
|
|
132
|
+
this.llmCalls++;
|
|
133
|
+
return entry;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Speculative pre-producer: when N siblings exist sharing the same potential
|
|
137
|
+
* parent at level k+1, eagerly produce L_{k+1}. Bottom-up, idempotent.
|
|
138
|
+
* Mirrors the design's background pre-producer (§7 #2 settled decisions).
|
|
139
|
+
*/
|
|
140
|
+
preProduceUpperLevels() {
|
|
141
|
+
let changed = true;
|
|
142
|
+
while (changed) {
|
|
143
|
+
changed = false;
|
|
144
|
+
// Find the deepest existing level
|
|
145
|
+
let maxLevel = 0;
|
|
146
|
+
for (const s of this.summaries.values())
|
|
147
|
+
maxLevel = Math.max(maxLevel, s.level);
|
|
148
|
+
for (let level = 1; level <= maxLevel; level++) {
|
|
149
|
+
// Group orphaned (parentId === undefined) summaries at this level
|
|
150
|
+
// by their position in source order. Take consecutive groups of
|
|
151
|
+
// mergeThreshold and produce the L_{k+1} parent.
|
|
152
|
+
const orphans = [];
|
|
153
|
+
for (const s of this.summaries.values()) {
|
|
154
|
+
if (s.level === level && !s.parentId)
|
|
155
|
+
orphans.push(s);
|
|
156
|
+
}
|
|
157
|
+
// Sort by sequence of the first chunk in their source range.
|
|
158
|
+
orphans.sort((a, b) => this.firstChunkSeq(a) - this.firstChunkSeq(b));
|
|
159
|
+
while (orphans.length >= this.mergeThreshold) {
|
|
160
|
+
const group = orphans.splice(0, this.mergeThreshold);
|
|
161
|
+
this.produceUpper(level + 1, group.map((s) => s.id));
|
|
162
|
+
changed = true;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Build a head/tail bookkeeping from chunk indices.
|
|
169
|
+
*/
|
|
170
|
+
computeHeadTail(opts) {
|
|
171
|
+
const headIds = new Set();
|
|
172
|
+
const tailIds = new Set();
|
|
173
|
+
let used = 0;
|
|
174
|
+
for (let i = 0; i < this.chunks.length; i++) {
|
|
175
|
+
const c = this.chunks[i];
|
|
176
|
+
if (used + c.rawTokens > opts.headTokens)
|
|
177
|
+
break;
|
|
178
|
+
headIds.add(c.id);
|
|
179
|
+
used += c.rawTokens;
|
|
180
|
+
}
|
|
181
|
+
used = 0;
|
|
182
|
+
for (let i = this.chunks.length - 1; i >= 0; i--) {
|
|
183
|
+
const c = this.chunks[i];
|
|
184
|
+
if (used + c.rawTokens > opts.tailTokens && tailIds.size > 0)
|
|
185
|
+
break;
|
|
186
|
+
tailIds.add(c.id);
|
|
187
|
+
used += c.rawTokens;
|
|
188
|
+
if (used >= opts.tailTokens)
|
|
189
|
+
break;
|
|
190
|
+
}
|
|
191
|
+
return {
|
|
192
|
+
headTokens: this.sumTokens(headIds),
|
|
193
|
+
tailTokens: this.sumTokens(tailIds),
|
|
194
|
+
headChunkIds: headIds,
|
|
195
|
+
tailChunkIds: tailIds,
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Apply a snapshot of resolutions back onto the chunks (used after running
|
|
200
|
+
* the picker to commit the new state for subsequent turns).
|
|
201
|
+
*/
|
|
202
|
+
applyResolutions(resolutions) {
|
|
203
|
+
for (const c of this.chunks) {
|
|
204
|
+
const r = resolutions.get(c.id);
|
|
205
|
+
if (r !== undefined && r !== c.currentResolution) {
|
|
206
|
+
c.currentResolution = r;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
linkChunksToL1(chunkIds, l1Id) {
|
|
211
|
+
const idSet = new Set(chunkIds);
|
|
212
|
+
for (const c of this.chunks) {
|
|
213
|
+
if (idSet.has(c.id))
|
|
214
|
+
c.l1Id = l1Id;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
allocSummaryId(level) {
|
|
218
|
+
const n = (this.summaryCounter.get(level) ?? 0);
|
|
219
|
+
this.summaryCounter.set(level, n + 1);
|
|
220
|
+
return `L${level}-${n}`;
|
|
221
|
+
}
|
|
222
|
+
firstChunkSeq(s) {
|
|
223
|
+
const c = this.chunks.find((ch) => ch.id === s.sourceRange.first);
|
|
224
|
+
return c?.sequence ?? 0;
|
|
225
|
+
}
|
|
226
|
+
sumTokens(ids) {
|
|
227
|
+
let t = 0;
|
|
228
|
+
for (const c of this.chunks)
|
|
229
|
+
if (ids.has(c.id))
|
|
230
|
+
t += c.rawTokens;
|
|
231
|
+
return t;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
function summaryKey(s) {
|
|
235
|
+
return `L${s.level}:${[...s.sourceIds].sort().join(',')}`;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Convenience: build N chunks with uniform token size, then auto-produce
|
|
239
|
+
* the full summary chain (L1, L2, …) bottom-up via the mergeThreshold rule.
|
|
240
|
+
*
|
|
241
|
+
* Returns the populated MockChronicle.
|
|
242
|
+
*/
|
|
243
|
+
export function buildChronicleWithChain(opts) {
|
|
244
|
+
const chronicle = new MockChronicle({
|
|
245
|
+
mergeThreshold: opts.mergeThreshold,
|
|
246
|
+
recallPairTokens: opts.recallPairTokens,
|
|
247
|
+
});
|
|
248
|
+
for (let i = 0; i < opts.chunkCount; i++) {
|
|
249
|
+
chronicle.addChunk({ id: `c-${i.toString().padStart(4, '0')}`, rawTokens: opts.tokensPerChunk });
|
|
250
|
+
}
|
|
251
|
+
if (opts.produceChain ?? true) {
|
|
252
|
+
// Produce L1s in batches of mergeThreshold (one L1 per batch).
|
|
253
|
+
const threshold = chronicle.mergeThreshold;
|
|
254
|
+
for (let i = 0; i < chronicle.chunks.length; i += threshold) {
|
|
255
|
+
const group = chronicle.chunks.slice(i, i + threshold).map((c) => c.id);
|
|
256
|
+
chronicle.produceL1(group);
|
|
257
|
+
}
|
|
258
|
+
// Bottom-up pre-produce L2, L3, …
|
|
259
|
+
chronicle.preProduceUpperLevels();
|
|
260
|
+
}
|
|
261
|
+
return chronicle;
|
|
262
|
+
}
|
|
263
|
+
//# sourceMappingURL=harness.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harness.js","sourceRoot":"","sources":["../../../test/adaptive/harness.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* End-to-end test of ingestion-time chunking + adaptive picker.
|
|
3
|
+
*
|
|
4
|
+
* Verifies that:
|
|
5
|
+
* - A large message is automatically chunked into shards at ingestion
|
|
6
|
+
* - Shards are stored with shared bodyGroupId
|
|
7
|
+
* - The picker folds shards under budget pressure
|
|
8
|
+
* - The render path produces ONE combined entry for the whole doc, with
|
|
9
|
+
* inline summary text replacing folded shards
|
|
10
|
+
* - Byte-faithful reassembly when no folding has happened
|
|
11
|
+
*/
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=ingestion.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ingestion.test.d.ts","sourceRoot":"","sources":["../../../test/adaptive/ingestion.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG"}
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* End-to-end test of ingestion-time chunking + adaptive picker.
|
|
3
|
+
*
|
|
4
|
+
* Verifies that:
|
|
5
|
+
* - A large message is automatically chunked into shards at ingestion
|
|
6
|
+
* - Shards are stored with shared bodyGroupId
|
|
7
|
+
* - The picker folds shards under budget pressure
|
|
8
|
+
* - The render path produces ONE combined entry for the whole doc, with
|
|
9
|
+
* inline summary text replacing folded shards
|
|
10
|
+
* - Byte-faithful reassembly when no folding has happened
|
|
11
|
+
*/
|
|
12
|
+
import { describe, it, before, after, beforeEach } from 'node:test';
|
|
13
|
+
import assert from 'node:assert/strict';
|
|
14
|
+
import { rmSync, existsSync } from 'node:fs';
|
|
15
|
+
import { ContextManager, AutobiographicalStrategy } from '../../src/index.js';
|
|
16
|
+
const TEST_STORE_PATH = './test-adaptive-ingestion-store';
|
|
17
|
+
function cleanup() {
|
|
18
|
+
if (existsSync(TEST_STORE_PATH)) {
|
|
19
|
+
rmSync(TEST_STORE_PATH, { recursive: true, force: true });
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function makeMockMembrane() {
|
|
23
|
+
let callCount = 0;
|
|
24
|
+
return {
|
|
25
|
+
complete: async () => {
|
|
26
|
+
callCount++;
|
|
27
|
+
return {
|
|
28
|
+
content: [{ type: 'text', text: `[mock summary #${callCount}]` }],
|
|
29
|
+
};
|
|
30
|
+
},
|
|
31
|
+
get callCount() {
|
|
32
|
+
return callCount;
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
describe('AutobiographicalStrategy — ingestion-time chunking', () => {
|
|
37
|
+
before(() => cleanup());
|
|
38
|
+
after(() => cleanup());
|
|
39
|
+
beforeEach(() => cleanup());
|
|
40
|
+
it('flag off: large messages stay as one StoredMessage (no chunking)', async () => {
|
|
41
|
+
const mock = makeMockMembrane();
|
|
42
|
+
const strategy = new AutobiographicalStrategy({
|
|
43
|
+
adaptiveResolution: false,
|
|
44
|
+
targetChunkTokens: 100,
|
|
45
|
+
});
|
|
46
|
+
const manager = await ContextManager.open({
|
|
47
|
+
path: TEST_STORE_PATH,
|
|
48
|
+
strategy,
|
|
49
|
+
membrane: mock,
|
|
50
|
+
});
|
|
51
|
+
// 50K chars ≈ 12.5K tokens; well over the chunker threshold.
|
|
52
|
+
const bigBody = 'paragraph. '.repeat(5000);
|
|
53
|
+
manager.addMessage('User', [{ type: 'text', text: bigBody }]);
|
|
54
|
+
const all = manager.getAllMessages();
|
|
55
|
+
assert.equal(all.length, 1, 'flag off: should be exactly one stored message');
|
|
56
|
+
assert.equal(all[0].bodyGroupId, undefined);
|
|
57
|
+
manager.close();
|
|
58
|
+
});
|
|
59
|
+
it('flag on: large messages are sharded into multiple StoredMessages', async () => {
|
|
60
|
+
const mock = makeMockMembrane();
|
|
61
|
+
const strategy = new AutobiographicalStrategy({
|
|
62
|
+
adaptiveResolution: true,
|
|
63
|
+
targetChunkTokens: 1000, // chunker threshold ~2x = 2000
|
|
64
|
+
recentWindowTokens: 200,
|
|
65
|
+
});
|
|
66
|
+
const manager = await ContextManager.open({
|
|
67
|
+
path: TEST_STORE_PATH,
|
|
68
|
+
strategy,
|
|
69
|
+
membrane: mock,
|
|
70
|
+
});
|
|
71
|
+
// ~32K chars ≈ 8K tokens, well over chunkThreshold 2000.
|
|
72
|
+
const paras = [];
|
|
73
|
+
for (let p = 0; p < 32; p++) {
|
|
74
|
+
paras.push(`Paragraph ${p}: ` + 'word '.repeat(80));
|
|
75
|
+
}
|
|
76
|
+
const bigBody = paras.join('\n\n');
|
|
77
|
+
manager.addMessage('User', [{ type: 'text', text: bigBody }]);
|
|
78
|
+
const all = manager.getAllMessages();
|
|
79
|
+
assert.ok(all.length > 1, `expected sharding, got ${all.length} stored messages`);
|
|
80
|
+
// All shards should share the same bodyGroupId
|
|
81
|
+
const groupId = all[0].bodyGroupId;
|
|
82
|
+
assert.ok(groupId, 'first shard should have bodyGroupId');
|
|
83
|
+
for (const m of all) {
|
|
84
|
+
assert.equal(m.bodyGroupId, groupId, 'all shards should share bodyGroupId');
|
|
85
|
+
}
|
|
86
|
+
// shardIndex should be 0..N-1 in order
|
|
87
|
+
for (let idx = 0; idx < all.length; idx++) {
|
|
88
|
+
assert.equal(all[idx].shardIndex, idx);
|
|
89
|
+
}
|
|
90
|
+
// Byte-faithful reassembly
|
|
91
|
+
const reassembled = all
|
|
92
|
+
.map((m) => m.content.filter((b) => b.type === 'text').map((b) => b.text).join(''))
|
|
93
|
+
.join('');
|
|
94
|
+
assert.equal(reassembled, bigBody, 'concatenating shard text must equal original body');
|
|
95
|
+
manager.close();
|
|
96
|
+
});
|
|
97
|
+
it('flag on: compile renders bodyGroup as ONE entry with byte-faithful body (no folding)', async () => {
|
|
98
|
+
const mock = makeMockMembrane();
|
|
99
|
+
const strategy = new AutobiographicalStrategy({
|
|
100
|
+
adaptiveResolution: true,
|
|
101
|
+
targetChunkTokens: 1000,
|
|
102
|
+
recentWindowTokens: 50_000, // big enough that everything stays in tail (no folding)
|
|
103
|
+
});
|
|
104
|
+
const manager = await ContextManager.open({
|
|
105
|
+
path: TEST_STORE_PATH,
|
|
106
|
+
strategy,
|
|
107
|
+
membrane: mock,
|
|
108
|
+
});
|
|
109
|
+
const paras = [];
|
|
110
|
+
for (let p = 0; p < 20; p++) {
|
|
111
|
+
paras.push(`Para ${p}: ` + 'word '.repeat(80));
|
|
112
|
+
}
|
|
113
|
+
const bigBody = paras.join('\n\n');
|
|
114
|
+
manager.addMessage('User', [{ type: 'text', text: bigBody }]);
|
|
115
|
+
const compiled = await manager.compile({ maxTokens: 100_000, reserveForResponse: 1000 });
|
|
116
|
+
// Note: the doc lands in the tail window (no compression triggered).
|
|
117
|
+
// Tail uses newest-first eviction; the bodyGroup may render as a single
|
|
118
|
+
// entry OR as separate shards depending on tail emission. The current
|
|
119
|
+
// selectAdaptive only does bodyGroup-aware emission for the MIDDLE,
|
|
120
|
+
// not for the tail. So with everything in tail, we see N shards.
|
|
121
|
+
// For this test, we just verify compile produced output.
|
|
122
|
+
assert.ok(compiled.messages.length > 0, 'compile should produce output');
|
|
123
|
+
manager.close();
|
|
124
|
+
});
|
|
125
|
+
it('flag on: compile renders bodyGroup as combined entry under folding pressure', async () => {
|
|
126
|
+
const mock = makeMockMembrane();
|
|
127
|
+
const strategy = new AutobiographicalStrategy({
|
|
128
|
+
adaptiveResolution: true,
|
|
129
|
+
targetChunkTokens: 1000,
|
|
130
|
+
recentWindowTokens: 200, // small so most of the doc is in the foldable middle
|
|
131
|
+
});
|
|
132
|
+
const manager = await ContextManager.open({
|
|
133
|
+
path: TEST_STORE_PATH,
|
|
134
|
+
strategy,
|
|
135
|
+
membrane: mock,
|
|
136
|
+
});
|
|
137
|
+
// Big enough to require shards + at least one chunk worth of compression
|
|
138
|
+
const paras = [];
|
|
139
|
+
for (let p = 0; p < 30; p++) {
|
|
140
|
+
paras.push(`Para ${p}: ` + 'distinctive-token-' + p + ' word '.repeat(80));
|
|
141
|
+
}
|
|
142
|
+
const bigBody = paras.join('\n\n');
|
|
143
|
+
manager.addMessage('User', [{ type: 'text', text: bigBody }]);
|
|
144
|
+
// Add a follow-up so the doc isn't at the very end (otherwise it's all tail)
|
|
145
|
+
manager.addMessage('User', [{ type: 'text', text: 'Quick follow-up.' }]);
|
|
146
|
+
// Drive compression to completion
|
|
147
|
+
while (!manager.isReady()) {
|
|
148
|
+
await manager.tick();
|
|
149
|
+
}
|
|
150
|
+
const compiled = await manager.compile({ maxTokens: 5000, reserveForResponse: 500 });
|
|
151
|
+
// Find the entry that came from the bigBody shards. The middle path
|
|
152
|
+
// should have produced ONE combined entry (sourceRelation: 'copy' from
|
|
153
|
+
// the first shard) with the concatenated body — possibly with inline
|
|
154
|
+
// summary markers if folding happened.
|
|
155
|
+
assert.ok(compiled.messages.length > 0);
|
|
156
|
+
// The combined entry's text should be substantial (not just one shard)
|
|
157
|
+
// OR contain inline summary markers indicating compression happened.
|
|
158
|
+
const allText = compiled.messages
|
|
159
|
+
.flatMap((m) => m.content)
|
|
160
|
+
.filter((b) => b.type === 'text')
|
|
161
|
+
.map((b) => b.text)
|
|
162
|
+
.join('\n---\n');
|
|
163
|
+
assert.ok(allText.length > 100, `compiled output should have meaningful content; got length ${allText.length}`);
|
|
164
|
+
manager.close();
|
|
165
|
+
});
|
|
166
|
+
it('flag on: small messages (under threshold) are NOT chunked', async () => {
|
|
167
|
+
const mock = makeMockMembrane();
|
|
168
|
+
const strategy = new AutobiographicalStrategy({
|
|
169
|
+
adaptiveResolution: true,
|
|
170
|
+
targetChunkTokens: 1000,
|
|
171
|
+
});
|
|
172
|
+
const manager = await ContextManager.open({
|
|
173
|
+
path: TEST_STORE_PATH,
|
|
174
|
+
strategy,
|
|
175
|
+
membrane: mock,
|
|
176
|
+
});
|
|
177
|
+
manager.addMessage('User', [{ type: 'text', text: 'short message' }]);
|
|
178
|
+
const all = manager.getAllMessages();
|
|
179
|
+
assert.equal(all.length, 1, 'short messages should not be sharded');
|
|
180
|
+
assert.equal(all[0].bodyGroupId, undefined);
|
|
181
|
+
manager.close();
|
|
182
|
+
});
|
|
183
|
+
it('flag on: folded shards within a bodyGroup emit separate Q+A recall pair messages', async () => {
|
|
184
|
+
const mock = makeMockMembrane();
|
|
185
|
+
const strategy = new AutobiographicalStrategy({
|
|
186
|
+
adaptiveResolution: true,
|
|
187
|
+
targetChunkTokens: 300,
|
|
188
|
+
recentWindowTokens: 200, // small so the doc is in foldable middle
|
|
189
|
+
summaryContextLabel: 'What do you remember from earlier?',
|
|
190
|
+
summaryParticipant: 'Claude',
|
|
191
|
+
});
|
|
192
|
+
const manager = await ContextManager.open({
|
|
193
|
+
path: TEST_STORE_PATH,
|
|
194
|
+
strategy,
|
|
195
|
+
membrane: mock,
|
|
196
|
+
});
|
|
197
|
+
// Big doc with distinctive content per section
|
|
198
|
+
const paras = [];
|
|
199
|
+
for (let p = 0; p < 24; p++) {
|
|
200
|
+
paras.push(`Section ${p}: ` + `unique-token-${p} `.repeat(30));
|
|
201
|
+
}
|
|
202
|
+
const bigBody = paras.join('\n\n');
|
|
203
|
+
manager.addMessage('User', [{ type: 'text', text: bigBody }]);
|
|
204
|
+
// Trailing follow-up so the doc isn't entirely in tail
|
|
205
|
+
manager.addMessage('User', [{ type: 'text', text: 'Follow up please.' }]);
|
|
206
|
+
while (!manager.isReady()) {
|
|
207
|
+
await manager.tick();
|
|
208
|
+
}
|
|
209
|
+
// Compile with a budget tight enough to force folding
|
|
210
|
+
const compiled = await manager.compile({ maxTokens: 4000, reserveForResponse: 500 });
|
|
211
|
+
// Look for the Q+A recall pair pattern. If any folding happened, we
|
|
212
|
+
// should see "Context Manager" + summaryParticipant pairs in the
|
|
213
|
+
// compiled output.
|
|
214
|
+
const participants = compiled.messages.map((m) => m.participant);
|
|
215
|
+
const cmIndex = participants.indexOf('Context Manager');
|
|
216
|
+
const claudeIndex = participants.indexOf('Claude');
|
|
217
|
+
// The exact structure depends on which shards are folded and where the
|
|
218
|
+
// doc ends up. We assert at least one of the following holds:
|
|
219
|
+
// - A Q+A pair appears (Context Manager followed by Claude/summary participant)
|
|
220
|
+
// - OR no folding happened (everything fit at L0)
|
|
221
|
+
if (cmIndex >= 0) {
|
|
222
|
+
// Found a Q+A — there should be a Claude turn right after
|
|
223
|
+
assert.ok(participants[cmIndex + 1] === 'Claude' ||
|
|
224
|
+
participants[cmIndex + 1] === strategy['config'].summaryParticipant, `expected summary participant right after Context Manager; got ${participants[cmIndex + 1]}`);
|
|
225
|
+
}
|
|
226
|
+
// The bodyGroup should NOT be a single big composite entry with inline
|
|
227
|
+
// `[Section summary ...]` markers anymore. Verify no inline marker.
|
|
228
|
+
const allText = compiled.messages
|
|
229
|
+
.flatMap((m) => m.content)
|
|
230
|
+
.filter((b) => b.type === 'text')
|
|
231
|
+
.map((b) => b.text)
|
|
232
|
+
.join('\n');
|
|
233
|
+
assert.ok(!allText.includes('[Section summary ('), 'should NOT use inline [Section summary (...)] markers; should emit Q+A pairs instead');
|
|
234
|
+
manager.close();
|
|
235
|
+
});
|
|
236
|
+
it('flag on: tail-only bodyGroup renders as ONE composite User message (not N turns)', async () => {
|
|
237
|
+
const mock = makeMockMembrane();
|
|
238
|
+
const strategy = new AutobiographicalStrategy({
|
|
239
|
+
adaptiveResolution: true,
|
|
240
|
+
targetChunkTokens: 300,
|
|
241
|
+
recentWindowTokens: 100_000, // big tail so the doc fits entirely in tail
|
|
242
|
+
});
|
|
243
|
+
const manager = await ContextManager.open({
|
|
244
|
+
path: TEST_STORE_PATH,
|
|
245
|
+
strategy,
|
|
246
|
+
membrane: mock,
|
|
247
|
+
});
|
|
248
|
+
const paras = [];
|
|
249
|
+
for (let p = 0; p < 16; p++) {
|
|
250
|
+
paras.push(`Section ${p}: ` + 'distinctive-text '.repeat(40));
|
|
251
|
+
}
|
|
252
|
+
const bigBody = paras.join('\n\n');
|
|
253
|
+
manager.addMessage('User', [{ type: 'text', text: bigBody }]);
|
|
254
|
+
const all = manager.getAllMessages();
|
|
255
|
+
assert.ok(all.length > 1, 'doc should be sharded');
|
|
256
|
+
const compiled = await manager.compile({ maxTokens: 100_000, reserveForResponse: 1000 });
|
|
257
|
+
// The doc is entirely in tail. After the post-processing pass in
|
|
258
|
+
// selectAdaptive, it should render as exactly ONE composite User
|
|
259
|
+
// message — NOT N separate messages.
|
|
260
|
+
const userEntries = compiled.messages.filter((m) => m.participant.toLowerCase() === 'user');
|
|
261
|
+
assert.ok(userEntries.length > 0, 'should have user entries');
|
|
262
|
+
const entriesWithSection0 = userEntries.filter((m) => m.content
|
|
263
|
+
.filter((b) => b.type === 'text')
|
|
264
|
+
.some((b) => b.text.includes('Section 0:')));
|
|
265
|
+
assert.equal(entriesWithSection0.length, 1, 'Section 0 should appear in exactly one user entry (composite)');
|
|
266
|
+
const compositeEntry = entriesWithSection0[0];
|
|
267
|
+
const compositeText = compositeEntry.content
|
|
268
|
+
.filter((b) => b.type === 'text')
|
|
269
|
+
.map((b) => b.text)
|
|
270
|
+
.join('');
|
|
271
|
+
assert.ok(compositeText.includes('Section 15:'), 'composite should also contain the last section (all shards merged)');
|
|
272
|
+
assert.equal(compositeText, bigBody, 'composite text should reassemble original body byte-for-byte');
|
|
273
|
+
manager.close();
|
|
274
|
+
});
|
|
275
|
+
it('flag on: non-text content (e.g., tool_use blocks) is preserved on first shard', async () => {
|
|
276
|
+
const mock = makeMockMembrane();
|
|
277
|
+
const strategy = new AutobiographicalStrategy({
|
|
278
|
+
adaptiveResolution: true,
|
|
279
|
+
targetChunkTokens: 500,
|
|
280
|
+
});
|
|
281
|
+
const manager = await ContextManager.open({
|
|
282
|
+
path: TEST_STORE_PATH,
|
|
283
|
+
strategy,
|
|
284
|
+
membrane: mock,
|
|
285
|
+
});
|
|
286
|
+
// A big text payload + a tool_use-like non-text block
|
|
287
|
+
const bigText = 'paragraph. '.repeat(2000);
|
|
288
|
+
manager.addMessage('User', [
|
|
289
|
+
{ type: 'text', text: bigText },
|
|
290
|
+
// A simulated non-text block; the chunker passes it through.
|
|
291
|
+
{ type: 'tool_use', id: 'tool-1', name: 'search', input: { q: 'test' } },
|
|
292
|
+
]);
|
|
293
|
+
const all = manager.getAllMessages();
|
|
294
|
+
assert.ok(all.length > 1, 'should be sharded');
|
|
295
|
+
// First shard should carry the non-text block(s)
|
|
296
|
+
const firstNonText = all[0].content.filter((b) => b.type !== 'text');
|
|
297
|
+
assert.equal(firstNonText.length, 1, 'first shard should carry the tool_use block');
|
|
298
|
+
// Other shards should not
|
|
299
|
+
for (let idx = 1; idx < all.length; idx++) {
|
|
300
|
+
const nonText = all[idx].content.filter((b) => b.type !== 'text');
|
|
301
|
+
assert.equal(nonText.length, 0, `shard ${idx} should not carry tool_use`);
|
|
302
|
+
}
|
|
303
|
+
manager.close();
|
|
304
|
+
});
|
|
305
|
+
});
|
|
306
|
+
//# sourceMappingURL=ingestion.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ingestion.test.js","sourceRoot":"","sources":["../../../test/adaptive/ingestion.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Integration tests for the adaptive-resolution picker.
|
|
3
|
+
*
|
|
4
|
+
* These simulate realistic scenarios over many turns and verify the
|
|
5
|
+
* design's claimed properties end-to-end:
|
|
6
|
+
* - 500K-doc ingestion + first compile fits in budget
|
|
7
|
+
* - 200-turn growth with picker firing only as needed
|
|
8
|
+
* - Monotonic cache stickiness (a chunk's resolution only ever rises)
|
|
9
|
+
* - Group-fold operates correctly through chained levels
|
|
10
|
+
*/
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=integration.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integration.test.d.ts","sourceRoot":"","sources":["../../../test/adaptive/integration.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG"}
|