@monoes/memory 1.0.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.
Files changed (178) hide show
  1. package/README.md +902 -0
  2. package/dist/agent-memory-scope.d.ts +131 -0
  3. package/dist/agent-memory-scope.d.ts.map +1 -0
  4. package/dist/agent-memory-scope.js +230 -0
  5. package/dist/agent-memory-scope.js.map +1 -0
  6. package/dist/agentdb-adapter.d.ts +165 -0
  7. package/dist/agentdb-adapter.d.ts.map +1 -0
  8. package/dist/agentdb-adapter.js +836 -0
  9. package/dist/agentdb-adapter.js.map +1 -0
  10. package/dist/agentdb-backend.d.ts +218 -0
  11. package/dist/agentdb-backend.d.ts.map +1 -0
  12. package/dist/agentdb-backend.js +879 -0
  13. package/dist/agentdb-backend.js.map +1 -0
  14. package/dist/auto-memory-bridge.d.ts +230 -0
  15. package/dist/auto-memory-bridge.d.ts.map +1 -0
  16. package/dist/auto-memory-bridge.js +730 -0
  17. package/dist/auto-memory-bridge.js.map +1 -0
  18. package/dist/cache-manager.d.ts +134 -0
  19. package/dist/cache-manager.d.ts.map +1 -0
  20. package/dist/cache-manager.js +410 -0
  21. package/dist/cache-manager.js.map +1 -0
  22. package/dist/checkpointer.d.ts +78 -0
  23. package/dist/checkpointer.d.ts.map +1 -0
  24. package/dist/checkpointer.js +174 -0
  25. package/dist/checkpointer.js.map +1 -0
  26. package/dist/controller-registry.d.ts +216 -0
  27. package/dist/controller-registry.d.ts.map +1 -0
  28. package/dist/controller-registry.js +897 -0
  29. package/dist/controller-registry.js.map +1 -0
  30. package/dist/database-provider.d.ts +87 -0
  31. package/dist/database-provider.d.ts.map +1 -0
  32. package/dist/database-provider.js +434 -0
  33. package/dist/database-provider.js.map +1 -0
  34. package/dist/diskann-backend.d.ts +126 -0
  35. package/dist/diskann-backend.d.ts.map +1 -0
  36. package/dist/diskann-backend.js +324 -0
  37. package/dist/diskann-backend.js.map +1 -0
  38. package/dist/episodic-store.d.ts +58 -0
  39. package/dist/episodic-store.d.ts.map +1 -0
  40. package/dist/episodic-store.js +160 -0
  41. package/dist/episodic-store.js.map +1 -0
  42. package/dist/hnsw-index.d.ts +111 -0
  43. package/dist/hnsw-index.d.ts.map +1 -0
  44. package/dist/hnsw-index.js +778 -0
  45. package/dist/hnsw-index.js.map +1 -0
  46. package/dist/hnsw-lite.d.ts +29 -0
  47. package/dist/hnsw-lite.d.ts.map +1 -0
  48. package/dist/hnsw-lite.js +236 -0
  49. package/dist/hnsw-lite.js.map +1 -0
  50. package/dist/hybrid-backend.d.ts +299 -0
  51. package/dist/hybrid-backend.d.ts.map +1 -0
  52. package/dist/hybrid-backend.js +804 -0
  53. package/dist/hybrid-backend.js.map +1 -0
  54. package/dist/index.d.ts +228 -0
  55. package/dist/index.d.ts.map +1 -0
  56. package/dist/index.js +379 -0
  57. package/dist/index.js.map +1 -0
  58. package/dist/knowledge/document-chunker.d.ts +22 -0
  59. package/dist/knowledge/document-chunker.d.ts.map +1 -0
  60. package/dist/knowledge/document-chunker.js +52 -0
  61. package/dist/knowledge/document-chunker.js.map +1 -0
  62. package/dist/knowledge/index.d.ts +12 -0
  63. package/dist/knowledge/index.d.ts.map +1 -0
  64. package/dist/knowledge/index.js +9 -0
  65. package/dist/knowledge/index.js.map +1 -0
  66. package/dist/knowledge/knowledge-retriever.d.ts +48 -0
  67. package/dist/knowledge/knowledge-retriever.d.ts.map +1 -0
  68. package/dist/knowledge/knowledge-retriever.js +80 -0
  69. package/dist/knowledge/knowledge-retriever.js.map +1 -0
  70. package/dist/knowledge/knowledge-store.d.ts +58 -0
  71. package/dist/knowledge/knowledge-store.d.ts.map +1 -0
  72. package/dist/knowledge/knowledge-store.js +121 -0
  73. package/dist/knowledge/knowledge-store.js.map +1 -0
  74. package/dist/learning-bridge.d.ts +162 -0
  75. package/dist/learning-bridge.d.ts.map +1 -0
  76. package/dist/learning-bridge.js +522 -0
  77. package/dist/learning-bridge.js.map +1 -0
  78. package/dist/memory-graph.d.ts +123 -0
  79. package/dist/memory-graph.d.ts.map +1 -0
  80. package/dist/memory-graph.js +412 -0
  81. package/dist/memory-graph.js.map +1 -0
  82. package/dist/migration.d.ts +68 -0
  83. package/dist/migration.d.ts.map +1 -0
  84. package/dist/migration.js +513 -0
  85. package/dist/migration.js.map +1 -0
  86. package/dist/partitioned-hnsw.d.ts +65 -0
  87. package/dist/partitioned-hnsw.d.ts.map +1 -0
  88. package/dist/partitioned-hnsw.js +209 -0
  89. package/dist/partitioned-hnsw.js.map +1 -0
  90. package/dist/persistent-sona.d.ts +144 -0
  91. package/dist/persistent-sona.d.ts.map +1 -0
  92. package/dist/persistent-sona.js +333 -0
  93. package/dist/persistent-sona.js.map +1 -0
  94. package/dist/procedural/action-record.d.ts +19 -0
  95. package/dist/procedural/action-record.d.ts.map +1 -0
  96. package/dist/procedural/action-record.js +51 -0
  97. package/dist/procedural/action-record.js.map +1 -0
  98. package/dist/procedural/action-sequence-extractor.d.ts +25 -0
  99. package/dist/procedural/action-sequence-extractor.d.ts.map +1 -0
  100. package/dist/procedural/action-sequence-extractor.js +91 -0
  101. package/dist/procedural/action-sequence-extractor.js.map +1 -0
  102. package/dist/procedural/index.d.ts +14 -0
  103. package/dist/procedural/index.d.ts.map +1 -0
  104. package/dist/procedural/index.js +13 -0
  105. package/dist/procedural/index.js.map +1 -0
  106. package/dist/procedural/learned-skill.d.ts +17 -0
  107. package/dist/procedural/learned-skill.d.ts.map +1 -0
  108. package/dist/procedural/learned-skill.js +73 -0
  109. package/dist/procedural/learned-skill.js.map +1 -0
  110. package/dist/procedural/procedure-extractor-worker.d.ts +27 -0
  111. package/dist/procedural/procedure-extractor-worker.d.ts.map +1 -0
  112. package/dist/procedural/procedure-extractor-worker.js +39 -0
  113. package/dist/procedural/procedure-extractor-worker.js.map +1 -0
  114. package/dist/procedural/skill-registry.d.ts +25 -0
  115. package/dist/procedural/skill-registry.d.ts.map +1 -0
  116. package/dist/procedural/skill-registry.js +56 -0
  117. package/dist/procedural/skill-registry.js.map +1 -0
  118. package/dist/procedural/types.d.ts +67 -0
  119. package/dist/procedural/types.d.ts.map +1 -0
  120. package/dist/procedural/types.js +15 -0
  121. package/dist/procedural/types.js.map +1 -0
  122. package/dist/prompt-version-store.d.ts +59 -0
  123. package/dist/prompt-version-store.d.ts.map +1 -0
  124. package/dist/prompt-version-store.js +175 -0
  125. package/dist/prompt-version-store.js.map +1 -0
  126. package/dist/query-builder.d.ts +52 -0
  127. package/dist/query-builder.d.ts.map +1 -0
  128. package/dist/query-builder.js +134 -0
  129. package/dist/query-builder.js.map +1 -0
  130. package/dist/rvf-backend.d.ts +51 -0
  131. package/dist/rvf-backend.d.ts.map +1 -0
  132. package/dist/rvf-backend.js +499 -0
  133. package/dist/rvf-backend.js.map +1 -0
  134. package/dist/rvf-learning-store.d.ts +141 -0
  135. package/dist/rvf-learning-store.d.ts.map +1 -0
  136. package/dist/rvf-learning-store.js +344 -0
  137. package/dist/rvf-learning-store.js.map +1 -0
  138. package/dist/rvf-migration.d.ts +45 -0
  139. package/dist/rvf-migration.d.ts.map +1 -0
  140. package/dist/rvf-migration.js +254 -0
  141. package/dist/rvf-migration.js.map +1 -0
  142. package/dist/sqlite-backend.d.ts +127 -0
  143. package/dist/sqlite-backend.d.ts.map +1 -0
  144. package/dist/sqlite-backend.js +618 -0
  145. package/dist/sqlite-backend.js.map +1 -0
  146. package/dist/sqljs-backend.d.ts +128 -0
  147. package/dist/sqljs-backend.d.ts.map +1 -0
  148. package/dist/sqljs-backend.js +611 -0
  149. package/dist/sqljs-backend.js.map +1 -0
  150. package/dist/tier-manager.d.ts +79 -0
  151. package/dist/tier-manager.d.ts.map +1 -0
  152. package/dist/tier-manager.js +169 -0
  153. package/dist/tier-manager.js.map +1 -0
  154. package/dist/tiers/contextual.d.ts +43 -0
  155. package/dist/tiers/contextual.d.ts.map +1 -0
  156. package/dist/tiers/contextual.js +102 -0
  157. package/dist/tiers/contextual.js.map +1 -0
  158. package/dist/tiers/entity.d.ts +46 -0
  159. package/dist/tiers/entity.d.ts.map +1 -0
  160. package/dist/tiers/entity.js +106 -0
  161. package/dist/tiers/entity.js.map +1 -0
  162. package/dist/tiers/index.d.ts +4 -0
  163. package/dist/tiers/index.d.ts.map +1 -0
  164. package/dist/tiers/index.js +4 -0
  165. package/dist/tiers/index.js.map +1 -0
  166. package/dist/tiers/short-term.d.ts +42 -0
  167. package/dist/tiers/short-term.d.ts.map +1 -0
  168. package/dist/tiers/short-term.js +89 -0
  169. package/dist/tiers/short-term.js.map +1 -0
  170. package/dist/types/checkpoint.d.ts +44 -0
  171. package/dist/types/checkpoint.d.ts.map +1 -0
  172. package/dist/types/checkpoint.js +8 -0
  173. package/dist/types/checkpoint.js.map +1 -0
  174. package/dist/types.d.ts +526 -0
  175. package/dist/types.d.ts.map +1 -0
  176. package/dist/types.js +58 -0
  177. package/dist/types.js.map +1 -0
  178. package/package.json +46 -0
@@ -0,0 +1,79 @@
1
+ /**
2
+ * TierManager — Routes memory operations to the correct tier (Task 09)
3
+ *
4
+ * Coordinates short-term (in-memory), long-term (persistent backend),
5
+ * entity (JSON-lines KV), and contextual (session summaries) tiers.
6
+ *
7
+ * @module v1/memory/tier-manager
8
+ */
9
+ import type { IMemoryBackend, MemoryEntry, MemoryEntryInput, MemoryTier, TierManagerConfig } from './types.js';
10
+ import { ShortTermMemory } from './tiers/short-term.js';
11
+ import { EntityMemory } from './tiers/entity.js';
12
+ import { ContextualMemory } from './tiers/contextual.js';
13
+ import { PartitionedHNSW, type PartitionedHNSWConfig } from './partitioned-hnsw.js';
14
+ import { DiskAnnBackend, type DiskAnnBackendConfig } from './diskann-backend.js';
15
+ export declare class TierManager {
16
+ readonly shortTerm: ShortTermMemory;
17
+ readonly entity: EntityMemory;
18
+ readonly contextual: ContextualMemory;
19
+ /** Timestamp-partitioned HNSW for temporally-local semantic search.
20
+ * Source: ICDE 2025 Timestamp-Partitioned HNSW */
21
+ readonly partitionedIndex: PartitionedHNSW;
22
+ /**
23
+ * Optional DiskANN backend for large-scale ANN search (Tier 4).
24
+ * Activated by passing `diskAnnConfig` to the constructor.
25
+ * Wraps the longTermBackend so all CRUD still flows through the delegate;
26
+ * `search()` uses the disk-resident graph + quantised beam search.
27
+ * Source: arXiv:2305.04359
28
+ */
29
+ readonly diskann?: DiskAnnBackend;
30
+ private readonly longTermBackend;
31
+ private readonly config;
32
+ constructor(longTermBackend: IMemoryBackend, config?: Partial<TierManagerConfig>, partitionedHNSWConfig?: PartitionedHNSWConfig, diskAnnConfig?: DiskAnnBackendConfig);
33
+ /**
34
+ * Store a memory entry, routing to the correct tier.
35
+ *
36
+ * - `short-term` goes to the in-memory buffer
37
+ * - `long-term` (or unspecified) goes to the persistent backend
38
+ *
39
+ * All entries are also indexed in the timestamp-partitioned HNSW for
40
+ * temporally-local search (ICDE 2025).
41
+ *
42
+ * Returns the generated entry ID.
43
+ */
44
+ store(input: MemoryEntryInput & {
45
+ tier?: MemoryTier;
46
+ }): Promise<string>;
47
+ /**
48
+ * Merged search across partitioned HNSW, short-term buffer, long-term backend,
49
+ * and (when configured) DiskANN beam search.
50
+ *
51
+ * Order of precedence:
52
+ * 1. Partitioned HNSW (newest buckets first — temporal locality)
53
+ * 2. Short-term in-memory buffer
54
+ * 3. Long-term persistent backend (metadata / hybrid query)
55
+ * 4. DiskANN ANN search — only when diskAnnConfig was supplied; uses a
56
+ * character-frequency proxy embedding as the query vector (approximation)
57
+ *
58
+ * Results are deduplicated by entry ID.
59
+ */
60
+ search(query: string, limit?: number): Promise<MemoryEntry[]>;
61
+ /**
62
+ * Derive a fixed-length Float32 proxy embedding from plain text.
63
+ *
64
+ * Maps character byte values into a 128-dimensional L2-normalised vector.
65
+ * This is NOT a semantic embedding — it is solely used to drive DiskANN
66
+ * beam traversal when no real embedding generator is available at this
67
+ * call site. Quality of DiskANN results improves dramatically when entries
68
+ * are stored with real semantic embeddings.
69
+ */
70
+ private static textToVec;
71
+ /**
72
+ * Flush the short-term buffer into the long-term backend.
73
+ * Promoted entries are also added to the partitioned HNSW index so they
74
+ * remain visible in partition-based searches after promotion.
75
+ * Returns the number of entries promoted.
76
+ */
77
+ flushShortTerm(): Promise<number>;
78
+ }
79
+ //# sourceMappingURL=tier-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tier-manager.d.ts","sourceRoot":"","sources":["../src/tier-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACV,cAAc,EACd,WAAW,EACX,gBAAgB,EAChB,UAAU,EACV,iBAAiB,EAClB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,KAAK,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACpF,OAAO,EAAE,cAAc,EAAE,KAAK,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAEjF,qBAAa,WAAW;IACtB,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAC;IAEtC;uDACmD;IACnD,QAAQ,CAAC,gBAAgB,EAAE,eAAe,CAAC;IAE3C;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,cAAc,CAAC;IAElC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAiB;IACjD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoB;gBAGzC,eAAe,EAAE,cAAc,EAC/B,MAAM,GAAE,OAAO,CAAC,iBAAiB,CAAM,EACvC,qBAAqB,GAAE,qBAA0B,EACjD,aAAa,CAAC,EAAE,oBAAoB;IA4BtC;;;;;;;;;;OAUG;IACG,KAAK,CAAC,KAAK,EAAE,gBAAgB,GAAG;QAAE,IAAI,CAAC,EAAE,UAAU,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAgB7E;;;;;;;;;;;;OAYG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IA+C/D;;;;;;;;OAQG;IACH,OAAO,CAAC,MAAM,CAAC,SAAS;IAYxB;;;;;OAKG;IACG,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;CAUxC"}
@@ -0,0 +1,169 @@
1
+ /**
2
+ * TierManager — Routes memory operations to the correct tier (Task 09)
3
+ *
4
+ * Coordinates short-term (in-memory), long-term (persistent backend),
5
+ * entity (JSON-lines KV), and contextual (session summaries) tiers.
6
+ *
7
+ * @module v1/memory/tier-manager
8
+ */
9
+ import { createDefaultEntry } from './types.js';
10
+ import { ShortTermMemory } from './tiers/short-term.js';
11
+ import { EntityMemory } from './tiers/entity.js';
12
+ import { ContextualMemory } from './tiers/contextual.js';
13
+ import { PartitionedHNSW } from './partitioned-hnsw.js';
14
+ import { DiskAnnBackend } from './diskann-backend.js';
15
+ export class TierManager {
16
+ shortTerm;
17
+ entity;
18
+ contextual;
19
+ /** Timestamp-partitioned HNSW for temporally-local semantic search.
20
+ * Source: ICDE 2025 Timestamp-Partitioned HNSW */
21
+ partitionedIndex;
22
+ /**
23
+ * Optional DiskANN backend for large-scale ANN search (Tier 4).
24
+ * Activated by passing `diskAnnConfig` to the constructor.
25
+ * Wraps the longTermBackend so all CRUD still flows through the delegate;
26
+ * `search()` uses the disk-resident graph + quantised beam search.
27
+ * Source: arXiv:2305.04359
28
+ */
29
+ diskann;
30
+ longTermBackend;
31
+ config;
32
+ constructor(longTermBackend, config = {}, partitionedHNSWConfig = {}, diskAnnConfig) {
33
+ this.config = {
34
+ shortTermCapacity: config.shortTermCapacity ?? 500,
35
+ entityStorePath: config.entityStorePath ?? './data/memory/entities.jsonl',
36
+ contextualNamespace: config.contextualNamespace ?? 'contextual-summaries',
37
+ autoFlushOnSessionEnd: config.autoFlushOnSessionEnd ?? true,
38
+ };
39
+ // If diskAnnConfig is supplied, wrap longTermBackend in a DiskAnnBackend.
40
+ // All CRUD still delegates to the original backend; search() uses DiskANN.
41
+ if (diskAnnConfig) {
42
+ const diskannBackend = new DiskAnnBackend(longTermBackend, diskAnnConfig);
43
+ this.diskann = diskannBackend;
44
+ this.longTermBackend = diskannBackend;
45
+ }
46
+ else {
47
+ this.longTermBackend = longTermBackend;
48
+ }
49
+ this.shortTerm = new ShortTermMemory(this.config.shortTermCapacity);
50
+ this.entity = new EntityMemory(this.config.entityStorePath);
51
+ this.contextual = new ContextualMemory(this.longTermBackend, this.config.contextualNamespace);
52
+ this.partitionedIndex = new PartitionedHNSW(partitionedHNSWConfig);
53
+ }
54
+ /**
55
+ * Store a memory entry, routing to the correct tier.
56
+ *
57
+ * - `short-term` goes to the in-memory buffer
58
+ * - `long-term` (or unspecified) goes to the persistent backend
59
+ *
60
+ * All entries are also indexed in the timestamp-partitioned HNSW for
61
+ * temporally-local search (ICDE 2025).
62
+ *
63
+ * Returns the generated entry ID.
64
+ */
65
+ async store(input) {
66
+ const entry = createDefaultEntry(input);
67
+ const tier = input.tier ?? 'long-term';
68
+ if (tier === 'short-term') {
69
+ this.shortTerm.store(entry);
70
+ }
71
+ else {
72
+ await this.longTermBackend.store(entry);
73
+ }
74
+ // Index in partitioned HNSW for temporal-locality search
75
+ this.partitionedIndex.add(entry);
76
+ return entry.id;
77
+ }
78
+ /**
79
+ * Merged search across partitioned HNSW, short-term buffer, long-term backend,
80
+ * and (when configured) DiskANN beam search.
81
+ *
82
+ * Order of precedence:
83
+ * 1. Partitioned HNSW (newest buckets first — temporal locality)
84
+ * 2. Short-term in-memory buffer
85
+ * 3. Long-term persistent backend (metadata / hybrid query)
86
+ * 4. DiskANN ANN search — only when diskAnnConfig was supplied; uses a
87
+ * character-frequency proxy embedding as the query vector (approximation)
88
+ *
89
+ * Results are deduplicated by entry ID.
90
+ */
91
+ async search(query, limit = 10) {
92
+ // 1. Partitioned HNSW — nearest neighbours in recent time buckets first
93
+ const partitionedResults = this.partitionedIndex.search(null, // no raw embedding at this call-site; uses text fallback
94
+ query, limit);
95
+ // 2. Short-term results (synchronous)
96
+ const shortResults = this.shortTerm.search(query, limit);
97
+ // 3. Long-term results via the backend query interface
98
+ const longResults = await this.longTermBackend.query({
99
+ type: 'hybrid',
100
+ content: query,
101
+ limit,
102
+ });
103
+ // 4. DiskANN ANN search (activated when diskann is configured)
104
+ // Uses a character-frequency proxy embedding to drive beam search.
105
+ // Re-ranking in DiskAnnBackend.search() uses the actual stored embeddings.
106
+ let annEntries = [];
107
+ if (this.diskann) {
108
+ try {
109
+ const proxyVec = TierManager.textToVec(query);
110
+ const annResults = await this.diskann.search(proxyVec, { k: limit });
111
+ annEntries = annResults.map(r => r.entry);
112
+ }
113
+ catch {
114
+ // Non-fatal; DiskANN is best-effort
115
+ }
116
+ }
117
+ // Deduplicate by id: partitioned > short-term > long-term > diskann
118
+ const seen = new Set();
119
+ const merged = [];
120
+ for (const entry of [...partitionedResults, ...shortResults, ...longResults, ...annEntries]) {
121
+ if (!seen.has(entry.id)) {
122
+ seen.add(entry.id);
123
+ merged.push(entry);
124
+ }
125
+ if (merged.length >= limit)
126
+ break;
127
+ }
128
+ return merged;
129
+ }
130
+ /**
131
+ * Derive a fixed-length Float32 proxy embedding from plain text.
132
+ *
133
+ * Maps character byte values into a 128-dimensional L2-normalised vector.
134
+ * This is NOT a semantic embedding — it is solely used to drive DiskANN
135
+ * beam traversal when no real embedding generator is available at this
136
+ * call site. Quality of DiskANN results improves dramatically when entries
137
+ * are stored with real semantic embeddings.
138
+ */
139
+ static textToVec(text, dims = 128) {
140
+ const vec = new Float32Array(dims);
141
+ for (let i = 0; i < text.length; i++) {
142
+ vec[i % dims] += text.charCodeAt(i) / 255;
143
+ }
144
+ let norm = 0;
145
+ for (const v of vec)
146
+ norm += v * v;
147
+ norm = Math.sqrt(norm) || 1;
148
+ for (let i = 0; i < dims; i++)
149
+ vec[i] /= norm;
150
+ return vec;
151
+ }
152
+ /**
153
+ * Flush the short-term buffer into the long-term backend.
154
+ * Promoted entries are also added to the partitioned HNSW index so they
155
+ * remain visible in partition-based searches after promotion.
156
+ * Returns the number of entries promoted.
157
+ */
158
+ async flushShortTerm() {
159
+ // Snapshot the entries before flush so we can index them afterwards.
160
+ // ShortTermMemory.flush() clears the buffer, so we must read first.
161
+ const toPromote = this.shortTerm.snapshot();
162
+ const count = await this.shortTerm.flush(this.longTermBackend);
163
+ for (const entry of toPromote) {
164
+ this.partitionedIndex.add(entry);
165
+ }
166
+ return count;
167
+ }
168
+ }
169
+ //# sourceMappingURL=tier-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tier-manager.js","sourceRoot":"","sources":["../src/tier-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * ContextualMemory — Compressed session summaries (Task 09)
3
+ *
4
+ * Wraps an IMemoryBackend to persist session summaries and
5
+ * provides token-budget-aware retrieval of relevant context.
6
+ *
7
+ * @module v1/memory/tiers/contextual
8
+ */
9
+ import type { IMemoryBackend } from '../types.js';
10
+ export interface SessionSummary {
11
+ sessionId: string;
12
+ agentSlugs: string[];
13
+ summary: string;
14
+ tokenCount: number;
15
+ createdAt: number;
16
+ }
17
+ export declare class ContextualMemory {
18
+ private readonly backend;
19
+ private summaries;
20
+ private readonly namespace;
21
+ private warmed;
22
+ constructor(backend: IMemoryBackend, namespace?: string);
23
+ /**
24
+ * Load persisted summaries from the backend into the in-memory cache.
25
+ * Called automatically before the first read so cross-session summaries
26
+ * are visible without an explicit initialization step.
27
+ */
28
+ warm(): Promise<void>;
29
+ /**
30
+ * Persist a session summary both in the local map and the
31
+ * backing memory store.
32
+ */
33
+ storeSummary(summary: SessionSummary): Promise<void>;
34
+ /**
35
+ * Retrieve summaries whose content matches the query (simple
36
+ * substring match over the local cache), respecting a maximum
37
+ * token budget. Summaries are returned newest-first.
38
+ */
39
+ retrieveContext(query: string, maxTokens?: number): Promise<string>;
40
+ /** Look up a summary by session ID (local cache only). */
41
+ getSummary(sessionId: string): SessionSummary | undefined;
42
+ }
43
+ //# sourceMappingURL=contextual.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contextual.d.ts","sourceRoot":"","sources":["../../src/tiers/contextual.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAoB,MAAM,aAAa,CAAC;AAGpE,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,gBAAgB;IAMzB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAL1B,OAAO,CAAC,SAAS,CAA0C;IAC3D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,MAAM,CAAS;gBAGJ,OAAO,EAAE,cAAc,EACxC,SAAS,SAAyB;IAKpC;;;;OAIG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA6B3B;;;OAGG;IACG,YAAY,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAqB1D;;;;OAIG;IACG,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,SAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAuBvE,0DAA0D;IAC1D,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;CAG1D"}
@@ -0,0 +1,102 @@
1
+ /**
2
+ * ContextualMemory — Compressed session summaries (Task 09)
3
+ *
4
+ * Wraps an IMemoryBackend to persist session summaries and
5
+ * provides token-budget-aware retrieval of relevant context.
6
+ *
7
+ * @module v1/memory/tiers/contextual
8
+ */
9
+ import { createDefaultEntry } from '../types.js';
10
+ export class ContextualMemory {
11
+ backend;
12
+ summaries = new Map();
13
+ namespace;
14
+ warmed = false;
15
+ constructor(backend, namespace = 'contextual-summaries') {
16
+ this.backend = backend;
17
+ this.namespace = namespace;
18
+ }
19
+ /**
20
+ * Load persisted summaries from the backend into the in-memory cache.
21
+ * Called automatically before the first read so cross-session summaries
22
+ * are visible without an explicit initialization step.
23
+ */
24
+ async warm() {
25
+ if (this.warmed)
26
+ return;
27
+ this.warmed = true;
28
+ try {
29
+ const entries = await this.backend.query({
30
+ type: 'hybrid',
31
+ namespace: this.namespace,
32
+ tags: ['session-summary'],
33
+ limit: 10000,
34
+ });
35
+ for (const entry of entries) {
36
+ const sessionId = entry.metadata?.sessionId;
37
+ if (!sessionId || this.summaries.has(sessionId))
38
+ continue;
39
+ this.summaries.set(sessionId, {
40
+ sessionId,
41
+ agentSlugs: entry.metadata?.agentSlugs ?? [],
42
+ summary: entry.content,
43
+ tokenCount: entry.metadata?.tokenCount ?? 0,
44
+ createdAt: entry.createdAt,
45
+ });
46
+ }
47
+ }
48
+ catch {
49
+ // Backend unavailable — proceed with empty cache
50
+ }
51
+ }
52
+ /**
53
+ * Persist a session summary both in the local map and the
54
+ * backing memory store.
55
+ */
56
+ async storeSummary(summary) {
57
+ this.summaries.set(summary.sessionId, summary);
58
+ const input = {
59
+ key: `ctx-summary:${summary.sessionId}`,
60
+ content: summary.summary,
61
+ namespace: this.namespace,
62
+ tags: ['session-summary', ...summary.agentSlugs],
63
+ metadata: {
64
+ sessionId: summary.sessionId,
65
+ agentSlugs: summary.agentSlugs,
66
+ tokenCount: summary.tokenCount,
67
+ },
68
+ };
69
+ const entry = createDefaultEntry(input);
70
+ entry.createdAt = summary.createdAt;
71
+ entry.updatedAt = summary.createdAt;
72
+ await this.backend.store(entry);
73
+ }
74
+ /**
75
+ * Retrieve summaries whose content matches the query (simple
76
+ * substring match over the local cache), respecting a maximum
77
+ * token budget. Summaries are returned newest-first.
78
+ */
79
+ async retrieveContext(query, maxTokens = 2000) {
80
+ await this.warm();
81
+ const lowerQuery = query.toLowerCase();
82
+ const sorted = Array.from(this.summaries.values()).sort((a, b) => b.createdAt - a.createdAt);
83
+ const parts = [];
84
+ let budget = maxTokens;
85
+ for (const s of sorted) {
86
+ if (budget <= 0)
87
+ break;
88
+ if (s.summary.toLowerCase().includes(lowerQuery) || lowerQuery === '') {
89
+ if (s.tokenCount <= budget) {
90
+ parts.push(s.summary);
91
+ budget -= s.tokenCount;
92
+ }
93
+ }
94
+ }
95
+ return parts.join('\n\n');
96
+ }
97
+ /** Look up a summary by session ID (local cache only). */
98
+ getSummary(sessionId) {
99
+ return this.summaries.get(sessionId);
100
+ }
101
+ }
102
+ //# sourceMappingURL=contextual.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contextual.js","sourceRoot":"","sources":["../../src/tiers/contextual.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * EntityMemory — Named-entity key-value facts stored as JSON-lines (Task 09)
3
+ *
4
+ * Uses a simple `.jsonl` file for persistence (no native dependencies).
5
+ * Each line is a JSON-serialised EntityFact. On mutation the full set is
6
+ * rewritten — acceptable for the expected cardinality of entity facts.
7
+ *
8
+ * @module v1/memory/tiers/entity
9
+ */
10
+ export interface EntityFact {
11
+ entity: string;
12
+ factType: string;
13
+ value: string;
14
+ confidence: number;
15
+ sourceRunId: string;
16
+ createdAt: number;
17
+ expiresAt?: number;
18
+ }
19
+ export declare class EntityMemory {
20
+ private readonly dbPath;
21
+ constructor(dbPath: string);
22
+ /**
23
+ * Store (or upsert) a fact. If a fact with the same (entity, factType)
24
+ * already exists it is replaced.
25
+ */
26
+ store(fact: EntityFact): void;
27
+ /**
28
+ * Delete facts for an entity, optionally scoped to a factType.
29
+ * Returns the number of facts removed.
30
+ */
31
+ delete(entity: string, factType?: string): number;
32
+ /** Remove all facts whose expiresAt is in the past. */
33
+ pruneExpired(): number;
34
+ /**
35
+ * Retrieve all non-expired facts for an entity,
36
+ * sorted by confidence descending.
37
+ */
38
+ retrieve(entity: string): EntityFact[];
39
+ /** Return all non-expired facts of a given type. */
40
+ findByFactType(factType: string): EntityFact[];
41
+ /** No-op for file-based storage. */
42
+ close(): void;
43
+ private readAll;
44
+ private writeAll;
45
+ }
46
+ //# sourceMappingURL=entity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity.d.ts","sourceRoot":"","sources":["../../src/tiers/entity.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAEpB,MAAM,EAAE,MAAM;IAW1B;;;OAGG;IACH,KAAK,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI;IAa7B;;;OAGG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM;IAYjD,uDAAuD;IACvD,YAAY,IAAI,MAAM;IAatB;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,EAAE;IAWtC,oDAAoD;IACpD,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,EAAE;IAW9C,oCAAoC;IACpC,KAAK,IAAI,IAAI;IAMb,OAAO,CAAC,OAAO;IAUf,OAAO,CAAC,QAAQ;CAIjB"}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * EntityMemory — Named-entity key-value facts stored as JSON-lines (Task 09)
3
+ *
4
+ * Uses a simple `.jsonl` file for persistence (no native dependencies).
5
+ * Each line is a JSON-serialised EntityFact. On mutation the full set is
6
+ * rewritten — acceptable for the expected cardinality of entity facts.
7
+ *
8
+ * @module v1/memory/tiers/entity
9
+ */
10
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
11
+ import { dirname } from 'node:path';
12
+ export class EntityMemory {
13
+ dbPath;
14
+ constructor(dbPath) {
15
+ this.dbPath = dbPath;
16
+ // Ensure parent directory exists
17
+ const dir = dirname(this.dbPath);
18
+ if (!existsSync(dir)) {
19
+ mkdirSync(dir, { recursive: true });
20
+ }
21
+ }
22
+ // ---- Mutation ----
23
+ /**
24
+ * Store (or upsert) a fact. If a fact with the same (entity, factType)
25
+ * already exists it is replaced.
26
+ */
27
+ store(fact) {
28
+ const all = this.readAll();
29
+ const idx = all.findIndex((f) => f.entity === fact.entity && f.factType === fact.factType);
30
+ if (idx >= 0) {
31
+ all[idx] = fact;
32
+ }
33
+ else {
34
+ all.push(fact);
35
+ }
36
+ this.writeAll(all);
37
+ }
38
+ /**
39
+ * Delete facts for an entity, optionally scoped to a factType.
40
+ * Returns the number of facts removed.
41
+ */
42
+ delete(entity, factType) {
43
+ const all = this.readAll();
44
+ const remaining = all.filter((f) => {
45
+ if (f.entity !== entity)
46
+ return true;
47
+ if (factType !== undefined && f.factType !== factType)
48
+ return true;
49
+ return false;
50
+ });
51
+ const removed = all.length - remaining.length;
52
+ if (removed > 0)
53
+ this.writeAll(remaining);
54
+ return removed;
55
+ }
56
+ /** Remove all facts whose expiresAt is in the past. */
57
+ pruneExpired() {
58
+ const now = Date.now();
59
+ const all = this.readAll();
60
+ const remaining = all.filter((f) => f.expiresAt === undefined || f.expiresAt > now);
61
+ const removed = all.length - remaining.length;
62
+ if (removed > 0)
63
+ this.writeAll(remaining);
64
+ return removed;
65
+ }
66
+ // ---- Retrieval ----
67
+ /**
68
+ * Retrieve all non-expired facts for an entity,
69
+ * sorted by confidence descending.
70
+ */
71
+ retrieve(entity) {
72
+ const now = Date.now();
73
+ return this.readAll()
74
+ .filter((f) => f.entity === entity &&
75
+ (f.expiresAt === undefined || f.expiresAt > now))
76
+ .sort((a, b) => b.confidence - a.confidence);
77
+ }
78
+ /** Return all non-expired facts of a given type. */
79
+ findByFactType(factType) {
80
+ const now = Date.now();
81
+ return this.readAll().filter((f) => f.factType === factType &&
82
+ (f.expiresAt === undefined || f.expiresAt > now));
83
+ }
84
+ // ---- Lifecycle ----
85
+ /** No-op for file-based storage. */
86
+ close() {
87
+ // intentionally empty
88
+ }
89
+ // ---- Private helpers ----
90
+ readAll() {
91
+ if (!existsSync(this.dbPath))
92
+ return [];
93
+ const raw = readFileSync(this.dbPath, 'utf-8').trim();
94
+ if (raw.length === 0)
95
+ return [];
96
+ return raw
97
+ .split('\n')
98
+ .filter(Boolean)
99
+ .map((line) => JSON.parse(line));
100
+ }
101
+ writeAll(facts) {
102
+ const data = facts.map((f) => JSON.stringify(f)).join('\n');
103
+ writeFileSync(this.dbPath, data.length > 0 ? data + '\n' : '', 'utf-8');
104
+ }
105
+ }
106
+ //# sourceMappingURL=entity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity.js","sourceRoot":"","sources":["../../src/tiers/entity.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export { ShortTermMemory } from './short-term.js';
2
+ export { EntityMemory, type EntityFact } from './entity.js';
3
+ export { ContextualMemory, type SessionSummary } from './contextual.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tiers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { ShortTermMemory } from './short-term.js';
2
+ export { EntityMemory } from './entity.js';
3
+ export { ContextualMemory } from './contextual.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tiers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAmB,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAuB,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * ShortTermMemory — In-memory Map-based buffer (Task 09)
3
+ *
4
+ * Holds entries for the current run only. Supports FIFO eviction
5
+ * when capacity is exceeded and bulk flush to a long-term backend.
6
+ *
7
+ * @module v1/memory/tiers/short-term
8
+ */
9
+ import type { MemoryEntry, IMemoryBackend } from '../types.js';
10
+ export declare class ShortTermMemory {
11
+ /** Insertion-ordered map for FIFO eviction */
12
+ private buffer;
13
+ private readonly capacity;
14
+ constructor(capacity?: number);
15
+ /**
16
+ * Store an entry. If the buffer exceeds capacity the oldest entry
17
+ * (first inserted) is evicted.
18
+ */
19
+ store(entry: MemoryEntry): void;
20
+ retrieve(id: string): MemoryEntry | undefined;
21
+ /**
22
+ * Simple substring search across entry content and key fields.
23
+ * Returns up to `limit` matches ordered by most-recent insertion.
24
+ */
25
+ search(query: string, limit?: number): MemoryEntry[];
26
+ /**
27
+ * Return a stable copy of all currently buffered entries without mutating
28
+ * the buffer. Used by callers (e.g. TierManager) that need to process
29
+ * entries alongside a flush operation.
30
+ */
31
+ snapshot(): MemoryEntry[];
32
+ /**
33
+ * Promote all buffered entries to the given long-term backend,
34
+ * then clear the buffer. Returns the number of flushed entries.
35
+ */
36
+ flush(longTermStore: IMemoryBackend): Promise<number>;
37
+ /** Remove all entries from the buffer. */
38
+ clear(): void;
39
+ /** Current number of entries in the buffer. */
40
+ get size(): number;
41
+ }
42
+ //# sourceMappingURL=short-term.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"short-term.d.ts","sourceRoot":"","sources":["../../src/tiers/short-term.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE/D,qBAAa,eAAe;IAC1B,8CAA8C;IAC9C,OAAO,CAAC,MAAM,CAAuC;IACrD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;gBAEtB,QAAQ,SAAM;IAM1B;;;OAGG;IACH,KAAK,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAmB/B,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAI7C;;;OAGG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,WAAW,EAAE;IAoBhD;;;;OAIG;IACH,QAAQ,IAAI,WAAW,EAAE;IAIzB;;;OAGG;IACG,KAAK,CAAC,aAAa,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC;IAU3D,0CAA0C;IAC1C,KAAK,IAAI,IAAI;IAIb,+CAA+C;IAC/C,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF"}