@animalabs/context-manager 0.4.0 → 0.5.1
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 +1525 -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 +106 -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 +1635 -38
- package/src/strategies/index.ts +1 -1
- package/src/types/message.ts +43 -0
- package/src/types/strategy.ts +122 -10
package/src/strategies/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { PassthroughStrategy } from './passthrough.js';
|
|
2
|
-
export { AutobiographicalStrategy } from './autobiographical.js';
|
|
2
|
+
export { AutobiographicalStrategy, type AutobiographicalProgressSnapshot } from './autobiographical.js';
|
package/src/types/message.ts
CHANGED
|
@@ -47,6 +47,40 @@ export interface StoredMessage {
|
|
|
47
47
|
timestamp: Date;
|
|
48
48
|
/** IDs of messages that caused this one (from Chronicle causation) */
|
|
49
49
|
causedBy?: MessageId[];
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* If this message is a shard of a larger logical message (chunked at
|
|
53
|
+
* ingestion because it exceeded `chunkThreshold`), this is the stable
|
|
54
|
+
* group id shared with sibling shards. Shards with the same id are
|
|
55
|
+
* concatenated into one API message at render time. Null/undefined
|
|
56
|
+
* for messages that fit in a single chunk. See
|
|
57
|
+
* `docs/adaptive-resolution-design.md` §3.6.
|
|
58
|
+
*/
|
|
59
|
+
bodyGroupId?: string;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* The shard's order within its bodyGroup, starting at 0. Only meaningful
|
|
63
|
+
* when `bodyGroupId` is set. Used to reassemble shards into byte-faithful
|
|
64
|
+
* order at render time.
|
|
65
|
+
*/
|
|
66
|
+
shardIndex?: number;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Current display resolution for this chunk:
|
|
70
|
+
* - 0 = render raw content
|
|
71
|
+
* - k>0 = render the L_k summary that covers this chunk
|
|
72
|
+
*
|
|
73
|
+
* Set by the picker (or the agent in V2). Default 0. See
|
|
74
|
+
* `docs/adaptive-resolution-design.md` §3.3.
|
|
75
|
+
*/
|
|
76
|
+
currentResolution?: number;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* If true, the picker must not change `currentResolution` for this chunk.
|
|
80
|
+
* Set by `lockChunk()` (programmatic API) or, in V2, by the agent's
|
|
81
|
+
* `unfold` tool. Default false.
|
|
82
|
+
*/
|
|
83
|
+
lockedByAgent?: boolean;
|
|
50
84
|
}
|
|
51
85
|
|
|
52
86
|
/**
|
|
@@ -85,6 +119,15 @@ export interface StoredMessageInternal {
|
|
|
85
119
|
metadata?: MessageMetadata;
|
|
86
120
|
timestamp: number; // Unix timestamp for storage
|
|
87
121
|
causedBy?: MessageId[];
|
|
122
|
+
|
|
123
|
+
/** See StoredMessage.bodyGroupId */
|
|
124
|
+
bodyGroupId?: string;
|
|
125
|
+
/** See StoredMessage.shardIndex */
|
|
126
|
+
shardIndex?: number;
|
|
127
|
+
/** See StoredMessage.currentResolution */
|
|
128
|
+
currentResolution?: number;
|
|
129
|
+
/** See StoredMessage.lockedByAgent */
|
|
130
|
+
lockedByAgent?: boolean;
|
|
88
131
|
}
|
|
89
132
|
|
|
90
133
|
/**
|
package/src/types/strategy.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { JsStore } from '@animalabs/chronicle';
|
|
2
|
-
import type { Membrane } from '@animalabs/membrane';
|
|
2
|
+
import type { Membrane, ContentBlock } from '@animalabs/membrane';
|
|
3
3
|
import type { StoredMessage, MessageId, Sequence } from './message.js';
|
|
4
4
|
import type { ContextEntry, TokenBudget, PendingWork } from './context.js';
|
|
5
5
|
|
|
@@ -125,6 +125,41 @@ export interface ContextStrategy {
|
|
|
125
125
|
log: ContextLogView,
|
|
126
126
|
budget: TokenBudget
|
|
127
127
|
): ContextEntry[];
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Optional: at ingestion time, decide whether to split this incoming
|
|
131
|
+
* message into multiple shards (because it's too large to be a single
|
|
132
|
+
* fold unit). If returned, the framework stores each shard as a separate
|
|
133
|
+
* StoredMessage with the shared `bodyGroupId` and per-shard `shardIndex`,
|
|
134
|
+
* and the render path will reassemble them into one API message at
|
|
135
|
+
* compile time.
|
|
136
|
+
*
|
|
137
|
+
* Return null or undefined to skip chunking (message stored as one record).
|
|
138
|
+
*
|
|
139
|
+
* See `docs/adaptive-resolution-design.md` §3.6.
|
|
140
|
+
*/
|
|
141
|
+
chunkIngressMessage?(
|
|
142
|
+
participant: string,
|
|
143
|
+
content: ContentBlock[]
|
|
144
|
+
): IngressChunkResult | null;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Result of a strategy's ingestion-time chunking decision.
|
|
149
|
+
*/
|
|
150
|
+
export interface IngressChunkResult {
|
|
151
|
+
/** Stable id shared by all shards of this message. */
|
|
152
|
+
bodyGroupId: string;
|
|
153
|
+
/**
|
|
154
|
+
* The shards in source order. Each becomes a separate StoredMessage.
|
|
155
|
+
* Concatenating the shards' text content must reproduce the original
|
|
156
|
+
* message body byte-for-byte.
|
|
157
|
+
*/
|
|
158
|
+
shards: Array<{
|
|
159
|
+
content: ContentBlock[];
|
|
160
|
+
/** Order within the bodyGroup, starting at 0. */
|
|
161
|
+
shardIndex: number;
|
|
162
|
+
}>;
|
|
128
163
|
}
|
|
129
164
|
|
|
130
165
|
/**
|
|
@@ -302,6 +337,19 @@ export interface AutobiographicalConfig {
|
|
|
302
337
|
/** Token budget for L1 summaries in select() (default: 30000) */
|
|
303
338
|
l1BudgetTokens?: number;
|
|
304
339
|
|
|
340
|
+
/**
|
|
341
|
+
* Cap on the total tokens of recall-pair prior-summary content
|
|
342
|
+
* included in each chunk compression request (default: 150000).
|
|
343
|
+
*
|
|
344
|
+
* Defends against the case where the unmerged frontier itself is
|
|
345
|
+
* large enough to overflow the API window. The cap walks summaries
|
|
346
|
+
* newest-first so proximate context survives; the kept set is then
|
|
347
|
+
* re-sorted chronologically. Set higher (or to Infinity) if you want
|
|
348
|
+
* to surface overflow via a 400 rather than silently drop oldest
|
|
349
|
+
* memories from the compression context.
|
|
350
|
+
*/
|
|
351
|
+
compressionRecallBudgetTokens?: number;
|
|
352
|
+
|
|
305
353
|
/**
|
|
306
354
|
* When true (default), each selected summary emits as its own positioned
|
|
307
355
|
* Q/A recall pair, sorted chronologically by source range. When false,
|
|
@@ -379,35 +427,91 @@ export interface AutobiographicalConfig {
|
|
|
379
427
|
* that overflow is rare, and when it does happen you want to know.
|
|
380
428
|
*/
|
|
381
429
|
enforceBudget?: boolean;
|
|
430
|
+
|
|
431
|
+
// --- Adaptive resolution (per docs/adaptive-resolution-design.md) ---
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* Enable picker-driven adaptive resolution. When true, `select()` uses
|
|
435
|
+
* the FoldingStrategy + Picker to choose per-message resolution under
|
|
436
|
+
* token-budget pressure rather than the threshold-driven `checkMergeThreshold`
|
|
437
|
+
* path. Default: false (existing hierarchical behavior preserved).
|
|
438
|
+
*/
|
|
439
|
+
adaptiveResolution?: boolean;
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* Folding strategy name when adaptiveResolution is on. One of:
|
|
443
|
+
* 'flat-profile' (default) — level-equalizing
|
|
444
|
+
* 'oldest-first' — chronological
|
|
445
|
+
* Custom strategies can be plugged in by the host application.
|
|
446
|
+
*/
|
|
447
|
+
foldingStrategy?: 'flat-profile' | 'oldest-first';
|
|
448
|
+
|
|
449
|
+
/**
|
|
450
|
+
* Slack ratio (hysteresis) for the picker. The picker folds until total
|
|
451
|
+
* tokens ≤ budget * (1 - slack), and stays quiet while between slack
|
|
452
|
+
* and budget. Default 0.1.
|
|
453
|
+
*/
|
|
454
|
+
compressionSlackRatio?: number;
|
|
455
|
+
|
|
456
|
+
/**
|
|
457
|
+
* Enable bottom-up speculative pre-production of higher-level summaries.
|
|
458
|
+
* When a new L_k summary is produced, if N siblings exist that would share
|
|
459
|
+
* an L_{k+1} parent, the L_{k+1} is enqueued for production immediately
|
|
460
|
+
* (no picker request needed). Default true when adaptiveResolution is on.
|
|
461
|
+
*/
|
|
462
|
+
speculativeProduction?: boolean;
|
|
382
463
|
}
|
|
383
464
|
|
|
384
465
|
/**
|
|
385
466
|
* Compression level in the hierarchical pyramid.
|
|
467
|
+
*
|
|
468
|
+
* Historically constrained to 1 | 2 | 3. As of the adaptive-resolution design
|
|
469
|
+
* (`docs/adaptive-resolution-design.md`), levels are unbounded: the picker
|
|
470
|
+
* can recursively produce L4, L5, ... as needed. The narrower literal type
|
|
471
|
+
* is kept as `LegacySummaryLevel` for code that still assumes the old shape.
|
|
472
|
+
*/
|
|
473
|
+
export type SummaryLevel = number;
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* The narrow level type used by pre-adaptive-resolution code paths.
|
|
477
|
+
* Prefer `SummaryLevel` for new code.
|
|
386
478
|
*/
|
|
387
|
-
export type
|
|
479
|
+
export type LegacySummaryLevel = 1 | 2 | 3;
|
|
388
480
|
|
|
389
481
|
/**
|
|
390
482
|
* A summary entry in the hierarchical memory pyramid.
|
|
391
483
|
* L1: compressed from raw message chunks.
|
|
392
|
-
*
|
|
393
|
-
* L3: merged from mergeThreshold L2s.
|
|
484
|
+
* L_{k>1}: merged from mergeThreshold L_{k-1}s.
|
|
394
485
|
*/
|
|
395
486
|
export interface SummaryEntry {
|
|
396
487
|
/** Unique ID (e.g., "L1-0", "L2-3") */
|
|
397
488
|
id: string;
|
|
398
|
-
/** Compression level */
|
|
489
|
+
/** Compression level (1, 2, 3, ... — unbounded in the adaptive-resolution design) */
|
|
399
490
|
level: SummaryLevel;
|
|
400
491
|
/** The summary text */
|
|
401
492
|
content: string;
|
|
402
|
-
/** Estimated token count (content.length / 4) */
|
|
493
|
+
/** Estimated token count (content.length / 4 or tokenizer-cached) */
|
|
403
494
|
tokens: number;
|
|
404
|
-
/**
|
|
405
|
-
|
|
406
|
-
|
|
495
|
+
/**
|
|
496
|
+
* Level of the sources: 0 = raw messages, k = L_k summaries.
|
|
497
|
+
* Pre-adaptive code uses 0 | 1 | 2; new code may produce higher values.
|
|
498
|
+
*/
|
|
499
|
+
sourceLevel: number;
|
|
500
|
+
/** IDs of source items (message IDs for L1, summary IDs for L_{k>1}) */
|
|
407
501
|
sourceIds: string[];
|
|
408
502
|
/** Range of original message IDs covered */
|
|
409
503
|
sourceRange: { first: string; last: string };
|
|
410
|
-
/**
|
|
504
|
+
/**
|
|
505
|
+
* The L_{level+1} summary this one is a source for, if produced.
|
|
506
|
+
* Pure archive metadata in the adaptive-resolution design — display
|
|
507
|
+
* decisions live on per-chunk `currentResolution`, not here.
|
|
508
|
+
*/
|
|
509
|
+
parentId?: string;
|
|
510
|
+
/**
|
|
511
|
+
* @deprecated Renamed to `parentId` in the adaptive-resolution design.
|
|
512
|
+
* Kept for read compatibility with chronicles produced by the old
|
|
513
|
+
* threshold-driven path. New writes should set `parentId` only.
|
|
514
|
+
*/
|
|
411
515
|
mergedInto?: string;
|
|
412
516
|
/** Creation timestamp */
|
|
413
517
|
created: number;
|
|
@@ -415,6 +519,14 @@ export interface SummaryEntry {
|
|
|
415
519
|
phaseType?: string;
|
|
416
520
|
}
|
|
417
521
|
|
|
522
|
+
/**
|
|
523
|
+
* Helper: read the parent pointer from a summary, accepting either the
|
|
524
|
+
* new `parentId` field or the deprecated `mergedInto` alias.
|
|
525
|
+
*/
|
|
526
|
+
export function getSummaryParentId(s: SummaryEntry): string | undefined {
|
|
527
|
+
return s.parentId ?? s.mergedInto;
|
|
528
|
+
}
|
|
529
|
+
|
|
418
530
|
/**
|
|
419
531
|
* A range of messages protected from compression. Pins keep a span of raw
|
|
420
532
|
* messages visible at their original position in the rendered context.
|