@claude-flow/memory 3.0.0-alpha.2 → 3.0.0-alpha.21

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 (253) hide show
  1. package/README.md +651 -42
  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 +223 -0
  5. package/dist/agent-memory-scope.js.map +1 -0
  6. package/dist/agent-memory-scope.test.d.ts +8 -0
  7. package/dist/agent-memory-scope.test.d.ts.map +1 -0
  8. package/dist/agent-memory-scope.test.js +463 -0
  9. package/dist/agent-memory-scope.test.js.map +1 -0
  10. package/dist/agentdb-adapter.d.ts +82 -4
  11. package/dist/agentdb-adapter.d.ts.map +1 -1
  12. package/dist/agentdb-adapter.js +388 -17
  13. package/dist/agentdb-adapter.js.map +1 -1
  14. package/dist/agentdb-backend.d.ts +6 -0
  15. package/dist/agentdb-backend.d.ts.map +1 -1
  16. package/dist/agentdb-backend.js +89 -25
  17. package/dist/agentdb-backend.js.map +1 -1
  18. package/dist/auto-memory-bridge.d.ts +237 -0
  19. package/dist/auto-memory-bridge.d.ts.map +1 -0
  20. package/dist/auto-memory-bridge.js +758 -0
  21. package/dist/auto-memory-bridge.js.map +1 -0
  22. package/dist/auto-memory-bridge.test.d.ts +8 -0
  23. package/dist/auto-memory-bridge.test.d.ts.map +1 -0
  24. package/dist/auto-memory-bridge.test.js +849 -0
  25. package/dist/auto-memory-bridge.test.js.map +1 -0
  26. package/dist/benchmark.test.d.ts +2 -0
  27. package/dist/benchmark.test.d.ts.map +1 -0
  28. package/dist/benchmark.test.js +277 -0
  29. package/dist/benchmark.test.js.map +1 -0
  30. package/dist/consolidator.d.ts +96 -0
  31. package/dist/consolidator.d.ts.map +1 -0
  32. package/dist/consolidator.js +209 -0
  33. package/dist/consolidator.js.map +1 -0
  34. package/dist/consolidator.test.d.ts +17 -0
  35. package/dist/consolidator.test.d.ts.map +1 -0
  36. package/dist/consolidator.test.js +239 -0
  37. package/dist/consolidator.test.js.map +1 -0
  38. package/dist/controller-registry.d.ts +248 -0
  39. package/dist/controller-registry.d.ts.map +1 -0
  40. package/dist/controller-registry.js +1086 -0
  41. package/dist/controller-registry.js.map +1 -0
  42. package/dist/controller-registry.test.d.ts +14 -0
  43. package/dist/controller-registry.test.d.ts.map +1 -0
  44. package/dist/controller-registry.test.js +691 -0
  45. package/dist/controller-registry.test.js.map +1 -0
  46. package/dist/database-provider.d.ts +14 -2
  47. package/dist/database-provider.d.ts.map +1 -1
  48. package/dist/database-provider.js +63 -3
  49. package/dist/database-provider.js.map +1 -1
  50. package/dist/database-provider.test.js +56 -3
  51. package/dist/database-provider.test.js.map +1 -1
  52. package/dist/entity-tagger.d.ts +31 -0
  53. package/dist/entity-tagger.d.ts.map +1 -0
  54. package/dist/entity-tagger.js +80 -0
  55. package/dist/entity-tagger.js.map +1 -0
  56. package/dist/entity-tagger.test.d.ts +12 -0
  57. package/dist/entity-tagger.test.d.ts.map +1 -0
  58. package/dist/entity-tagger.test.js +70 -0
  59. package/dist/entity-tagger.test.js.map +1 -0
  60. package/dist/fts5.test.d.ts +13 -0
  61. package/dist/fts5.test.d.ts.map +1 -0
  62. package/dist/fts5.test.js +144 -0
  63. package/dist/fts5.test.js.map +1 -0
  64. package/dist/graceful-retrieval.test.d.ts +14 -0
  65. package/dist/graceful-retrieval.test.d.ts.map +1 -0
  66. package/dist/graceful-retrieval.test.js +192 -0
  67. package/dist/graceful-retrieval.test.js.map +1 -0
  68. package/dist/hnsw-index.d.ts +51 -0
  69. package/dist/hnsw-index.d.ts.map +1 -1
  70. package/dist/hnsw-index.js +396 -12
  71. package/dist/hnsw-index.js.map +1 -1
  72. package/dist/hnsw-persistence.test.d.ts +13 -0
  73. package/dist/hnsw-persistence.test.d.ts.map +1 -0
  74. package/dist/hnsw-persistence.test.js +208 -0
  75. package/dist/hnsw-persistence.test.js.map +1 -0
  76. package/dist/hybrid-backend.d.ts +28 -0
  77. package/dist/hybrid-backend.d.ts.map +1 -1
  78. package/dist/hybrid-backend.js +82 -4
  79. package/dist/hybrid-backend.js.map +1 -1
  80. package/dist/hybrid-backend.test.js +6 -5
  81. package/dist/hybrid-backend.test.js.map +1 -1
  82. package/dist/index.d.ts +167 -9
  83. package/dist/index.d.ts.map +1 -1
  84. package/dist/index.js +277 -30
  85. package/dist/index.js.map +1 -1
  86. package/dist/index.test.d.ts +10 -0
  87. package/dist/index.test.d.ts.map +1 -0
  88. package/dist/index.test.js +71 -0
  89. package/dist/index.test.js.map +1 -0
  90. package/dist/json-security.d.ts +12 -0
  91. package/dist/json-security.d.ts.map +1 -0
  92. package/dist/json-security.js +20 -0
  93. package/dist/json-security.js.map +1 -0
  94. package/dist/learning-bridge.d.ts +137 -0
  95. package/dist/learning-bridge.d.ts.map +1 -0
  96. package/dist/learning-bridge.js +335 -0
  97. package/dist/learning-bridge.js.map +1 -0
  98. package/dist/learning-bridge.test.d.ts +8 -0
  99. package/dist/learning-bridge.test.d.ts.map +1 -0
  100. package/dist/learning-bridge.test.js +578 -0
  101. package/dist/learning-bridge.test.js.map +1 -0
  102. package/dist/memory-graph.d.ts +100 -0
  103. package/dist/memory-graph.d.ts.map +1 -0
  104. package/dist/memory-graph.js +333 -0
  105. package/dist/memory-graph.js.map +1 -0
  106. package/dist/memory-graph.test.d.ts +8 -0
  107. package/dist/memory-graph.test.d.ts.map +1 -0
  108. package/dist/memory-graph.test.js +609 -0
  109. package/dist/memory-graph.test.js.map +1 -0
  110. package/dist/persistent-sona.d.ts +144 -0
  111. package/dist/persistent-sona.d.ts.map +1 -0
  112. package/dist/persistent-sona.js +332 -0
  113. package/dist/persistent-sona.js.map +1 -0
  114. package/dist/rvf-backend.d.ts +53 -0
  115. package/dist/rvf-backend.d.ts.map +1 -0
  116. package/dist/rvf-backend.js +643 -0
  117. package/dist/rvf-backend.js.map +1 -0
  118. package/dist/rvf-learning-store.d.ts +139 -0
  119. package/dist/rvf-learning-store.d.ts.map +1 -0
  120. package/dist/rvf-learning-store.js +295 -0
  121. package/dist/rvf-learning-store.js.map +1 -0
  122. package/dist/rvf-migration.d.ts +45 -0
  123. package/dist/rvf-migration.d.ts.map +1 -0
  124. package/dist/rvf-migration.js +254 -0
  125. package/dist/rvf-migration.js.map +1 -0
  126. package/dist/smart-retrieval.d.ts +118 -0
  127. package/dist/smart-retrieval.d.ts.map +1 -0
  128. package/dist/smart-retrieval.js +322 -0
  129. package/dist/smart-retrieval.js.map +1 -0
  130. package/dist/smart-retrieval.test.d.ts +2 -0
  131. package/dist/smart-retrieval.test.d.ts.map +1 -0
  132. package/dist/smart-retrieval.test.js +238 -0
  133. package/dist/smart-retrieval.test.js.map +1 -0
  134. package/dist/sqlite-backend.d.ts +10 -0
  135. package/dist/sqlite-backend.d.ts.map +1 -1
  136. package/dist/sqlite-backend.js +104 -8
  137. package/dist/sqlite-backend.js.map +1 -1
  138. package/dist/sqljs-backend.d.ts +9 -0
  139. package/dist/sqljs-backend.d.ts.map +1 -1
  140. package/dist/sqljs-backend.js +96 -5
  141. package/dist/sqljs-backend.js.map +1 -1
  142. package/dist/types.d.ts +3 -0
  143. package/dist/types.d.ts.map +1 -1
  144. package/package.json +21 -8
  145. package/.agentic-flow/intelligence.json +0 -16
  146. package/__tests__/coverage/base.css +0 -224
  147. package/__tests__/coverage/block-navigation.js +0 -87
  148. package/__tests__/coverage/coverage-final.json +0 -19
  149. package/__tests__/coverage/favicon.png +0 -0
  150. package/__tests__/coverage/index.html +0 -206
  151. package/__tests__/coverage/lcov-report/base.css +0 -224
  152. package/__tests__/coverage/lcov-report/block-navigation.js +0 -87
  153. package/__tests__/coverage/lcov-report/favicon.png +0 -0
  154. package/__tests__/coverage/lcov-report/index.html +0 -206
  155. package/__tests__/coverage/lcov-report/prettify.css +0 -1
  156. package/__tests__/coverage/lcov-report/prettify.js +0 -2
  157. package/__tests__/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  158. package/__tests__/coverage/lcov-report/sorter.js +0 -210
  159. package/__tests__/coverage/lcov-report/src/agentdb-adapter.ts.html +0 -2737
  160. package/__tests__/coverage/lcov-report/src/agentdb-backend.ts.html +0 -3130
  161. package/__tests__/coverage/lcov-report/src/application/commands/delete-memory.command.ts.html +0 -601
  162. package/__tests__/coverage/lcov-report/src/application/commands/index.html +0 -131
  163. package/__tests__/coverage/lcov-report/src/application/commands/store-memory.command.ts.html +0 -394
  164. package/__tests__/coverage/lcov-report/src/application/queries/index.html +0 -116
  165. package/__tests__/coverage/lcov-report/src/application/queries/search-memory.query.ts.html +0 -796
  166. package/__tests__/coverage/lcov-report/src/application/services/index.html +0 -116
  167. package/__tests__/coverage/lcov-report/src/application/services/memory-application-service.ts.html +0 -793
  168. package/__tests__/coverage/lcov-report/src/cache-manager.ts.html +0 -1633
  169. package/__tests__/coverage/lcov-report/src/database-provider.ts.html +0 -1618
  170. package/__tests__/coverage/lcov-report/src/domain/entities/index.html +0 -116
  171. package/__tests__/coverage/lcov-report/src/domain/entities/memory-entry.ts.html +0 -952
  172. package/__tests__/coverage/lcov-report/src/domain/services/index.html +0 -116
  173. package/__tests__/coverage/lcov-report/src/domain/services/memory-domain-service.ts.html +0 -1294
  174. package/__tests__/coverage/lcov-report/src/hnsw-index.ts.html +0 -3124
  175. package/__tests__/coverage/lcov-report/src/hybrid-backend.ts.html +0 -2167
  176. package/__tests__/coverage/lcov-report/src/index.html +0 -266
  177. package/__tests__/coverage/lcov-report/src/infrastructure/repositories/hybrid-memory-repository.ts.html +0 -1633
  178. package/__tests__/coverage/lcov-report/src/infrastructure/repositories/index.html +0 -116
  179. package/__tests__/coverage/lcov-report/src/migration.ts.html +0 -2092
  180. package/__tests__/coverage/lcov-report/src/query-builder.ts.html +0 -1711
  181. package/__tests__/coverage/lcov-report/src/sqlite-backend.ts.html +0 -2281
  182. package/__tests__/coverage/lcov-report/src/sqljs-backend.ts.html +0 -2374
  183. package/__tests__/coverage/lcov-report/src/types.ts.html +0 -2266
  184. package/__tests__/coverage/lcov.info +0 -10238
  185. package/__tests__/coverage/prettify.css +0 -1
  186. package/__tests__/coverage/prettify.js +0 -2
  187. package/__tests__/coverage/sort-arrow-sprite.png +0 -0
  188. package/__tests__/coverage/sorter.js +0 -210
  189. package/__tests__/coverage/src/agentdb-adapter.ts.html +0 -2737
  190. package/__tests__/coverage/src/agentdb-backend.ts.html +0 -3130
  191. package/__tests__/coverage/src/application/commands/delete-memory.command.ts.html +0 -601
  192. package/__tests__/coverage/src/application/commands/index.html +0 -131
  193. package/__tests__/coverage/src/application/commands/store-memory.command.ts.html +0 -394
  194. package/__tests__/coverage/src/application/queries/index.html +0 -116
  195. package/__tests__/coverage/src/application/queries/search-memory.query.ts.html +0 -796
  196. package/__tests__/coverage/src/application/services/index.html +0 -116
  197. package/__tests__/coverage/src/application/services/memory-application-service.ts.html +0 -793
  198. package/__tests__/coverage/src/cache-manager.ts.html +0 -1633
  199. package/__tests__/coverage/src/database-provider.ts.html +0 -1618
  200. package/__tests__/coverage/src/domain/entities/index.html +0 -116
  201. package/__tests__/coverage/src/domain/entities/memory-entry.ts.html +0 -952
  202. package/__tests__/coverage/src/domain/services/index.html +0 -116
  203. package/__tests__/coverage/src/domain/services/memory-domain-service.ts.html +0 -1294
  204. package/__tests__/coverage/src/hnsw-index.ts.html +0 -3124
  205. package/__tests__/coverage/src/hybrid-backend.ts.html +0 -2167
  206. package/__tests__/coverage/src/index.html +0 -266
  207. package/__tests__/coverage/src/infrastructure/repositories/hybrid-memory-repository.ts.html +0 -1633
  208. package/__tests__/coverage/src/infrastructure/repositories/index.html +0 -116
  209. package/__tests__/coverage/src/migration.ts.html +0 -2092
  210. package/__tests__/coverage/src/query-builder.ts.html +0 -1711
  211. package/__tests__/coverage/src/sqlite-backend.ts.html +0 -2281
  212. package/__tests__/coverage/src/sqljs-backend.ts.html +0 -2374
  213. package/__tests__/coverage/src/types.ts.html +0 -2266
  214. package/benchmarks/cache-hit-rate.bench.ts +0 -535
  215. package/benchmarks/hnsw-indexing.bench.ts +0 -552
  216. package/benchmarks/memory-write.bench.ts +0 -469
  217. package/benchmarks/vector-search.bench.ts +0 -449
  218. package/docs/AGENTDB-INTEGRATION.md +0 -388
  219. package/docs/CROSS_PLATFORM.md +0 -505
  220. package/docs/WINDOWS_SUPPORT.md +0 -422
  221. package/examples/agentdb-example.ts +0 -345
  222. package/examples/cross-platform-usage.ts +0 -326
  223. package/framework/benchmark.ts +0 -112
  224. package/src/agentdb-adapter.ts +0 -884
  225. package/src/agentdb-backend.test.ts +0 -339
  226. package/src/agentdb-backend.ts +0 -1016
  227. package/src/application/commands/delete-memory.command.ts +0 -172
  228. package/src/application/commands/store-memory.command.ts +0 -103
  229. package/src/application/index.ts +0 -36
  230. package/src/application/queries/search-memory.query.ts +0 -237
  231. package/src/application/services/memory-application-service.ts +0 -236
  232. package/src/cache-manager.ts +0 -516
  233. package/src/database-provider.test.ts +0 -364
  234. package/src/database-provider.ts +0 -511
  235. package/src/domain/entities/memory-entry.ts +0 -289
  236. package/src/domain/index.ts +0 -35
  237. package/src/domain/repositories/memory-repository.interface.ts +0 -120
  238. package/src/domain/services/memory-domain-service.ts +0 -403
  239. package/src/hnsw-index.ts +0 -1013
  240. package/src/hybrid-backend.test.ts +0 -399
  241. package/src/hybrid-backend.ts +0 -694
  242. package/src/index.ts +0 -515
  243. package/src/infrastructure/index.ts +0 -23
  244. package/src/infrastructure/repositories/hybrid-memory-repository.ts +0 -516
  245. package/src/migration.ts +0 -669
  246. package/src/query-builder.ts +0 -542
  247. package/src/sqlite-backend.ts +0 -732
  248. package/src/sqljs-backend.ts +0 -763
  249. package/src/types.ts +0 -727
  250. package/tmp.json +0 -0
  251. package/tsconfig.json +0 -9
  252. package/tsconfig.tsbuildinfo +0 -1
  253. package/verify-cross-platform.ts +0 -170
@@ -1,516 +0,0 @@
1
- /**
2
- * Hybrid Memory Repository - Infrastructure Layer
3
- *
4
- * Implements IMemoryRepository using SQLite + AgentDB hybrid backend.
5
- * Per ADR-009, this is the default memory backend.
6
- *
7
- * @module v3/memory/infrastructure/repositories
8
- */
9
-
10
- import { MemoryEntry, MemoryType, MemoryStatus } from '../../domain/entities/memory-entry.js';
11
- import {
12
- IMemoryRepository,
13
- MemoryQueryOptions,
14
- VectorSearchOptions,
15
- VectorSearchResult,
16
- BulkOperationResult,
17
- MemoryStatistics,
18
- } from '../../domain/repositories/memory-repository.interface.js';
19
-
20
- /**
21
- * Repository configuration
22
- */
23
- export interface HybridRepositoryConfig {
24
- sqlitePath: string;
25
- agentDbPath?: string;
26
- enableVectorSearch?: boolean;
27
- cacheSize?: number;
28
- verbose?: boolean;
29
- }
30
-
31
- /**
32
- * In-memory cache for hot entries
33
- */
34
- interface CacheEntry {
35
- entry: MemoryEntry;
36
- timestamp: number;
37
- }
38
-
39
- /**
40
- * Hybrid Memory Repository
41
- *
42
- * Uses SQLite for metadata and AgentDB for vectors.
43
- * Implements hot caching for frequently accessed entries.
44
- */
45
- export class HybridMemoryRepository implements IMemoryRepository {
46
- private entries: Map<string, MemoryEntry> = new Map();
47
- private namespaceIndex: Map<string, Set<string>> = new Map();
48
- private vectorIndex: Map<string, Float32Array> = new Map();
49
- private cache: Map<string, CacheEntry> = new Map();
50
- private initialized = false;
51
-
52
- constructor(private readonly config: HybridRepositoryConfig) {}
53
-
54
- // ============================================================================
55
- // Lifecycle
56
- // ============================================================================
57
-
58
- async initialize(): Promise<void> {
59
- if (this.initialized) return;
60
-
61
- // In production, would initialize SQLite and AgentDB connections
62
- // For now, using in-memory implementation
63
- this.entries = new Map();
64
- this.namespaceIndex = new Map();
65
- this.vectorIndex = new Map();
66
- this.cache = new Map();
67
-
68
- this.initialized = true;
69
- }
70
-
71
- async shutdown(): Promise<void> {
72
- // Clear all data
73
- this.cache.clear();
74
- this.initialized = false;
75
- }
76
-
77
- async clear(): Promise<void> {
78
- this.entries.clear();
79
- this.namespaceIndex.clear();
80
- this.vectorIndex.clear();
81
- this.cache.clear();
82
- }
83
-
84
- // ============================================================================
85
- // Basic CRUD
86
- // ============================================================================
87
-
88
- async save(entry: MemoryEntry): Promise<void> {
89
- this.ensureInitialized();
90
-
91
- // Store entry
92
- this.entries.set(entry.id, entry);
93
-
94
- // Update namespace index
95
- if (!this.namespaceIndex.has(entry.namespace)) {
96
- this.namespaceIndex.set(entry.namespace, new Set());
97
- }
98
- this.namespaceIndex.get(entry.namespace)!.add(entry.id);
99
-
100
- // Store vector if present
101
- if (entry.vector) {
102
- this.vectorIndex.set(entry.id, entry.vector);
103
- }
104
-
105
- // Update cache
106
- this.updateCache(entry);
107
- }
108
-
109
- async findById(id: string): Promise<MemoryEntry | null> {
110
- this.ensureInitialized();
111
-
112
- // Check cache first
113
- const cached = this.cache.get(id);
114
- if (cached) {
115
- return cached.entry;
116
- }
117
-
118
- return this.entries.get(id) ?? null;
119
- }
120
-
121
- async findByKey(namespace: string, key: string): Promise<MemoryEntry | null> {
122
- this.ensureInitialized();
123
-
124
- for (const entry of this.entries.values()) {
125
- if (entry.namespace === namespace && entry.key === key) {
126
- return entry;
127
- }
128
- }
129
- return null;
130
- }
131
-
132
- async findByCompositeKey(compositeKey: string): Promise<MemoryEntry | null> {
133
- const [namespace, key] = compositeKey.split(':');
134
- return this.findByKey(namespace, key);
135
- }
136
-
137
- async delete(id: string): Promise<boolean> {
138
- this.ensureInitialized();
139
-
140
- const entry = this.entries.get(id);
141
- if (!entry) return false;
142
-
143
- // Remove from all indexes
144
- this.entries.delete(id);
145
- this.namespaceIndex.get(entry.namespace)?.delete(id);
146
- this.vectorIndex.delete(id);
147
- this.cache.delete(id);
148
-
149
- return true;
150
- }
151
-
152
- async exists(id: string): Promise<boolean> {
153
- return this.entries.has(id);
154
- }
155
-
156
- // ============================================================================
157
- // Bulk Operations
158
- // ============================================================================
159
-
160
- async saveMany(entries: MemoryEntry[]): Promise<BulkOperationResult> {
161
- const errors: Array<{ id: string; error: string }> = [];
162
- let success = 0;
163
-
164
- for (const entry of entries) {
165
- try {
166
- await this.save(entry);
167
- success++;
168
- } catch (error) {
169
- errors.push({
170
- id: entry.id,
171
- error: error instanceof Error ? error.message : 'Unknown error',
172
- });
173
- }
174
- }
175
-
176
- return {
177
- success,
178
- failed: errors.length,
179
- errors,
180
- };
181
- }
182
-
183
- async findByIds(ids: string[]): Promise<MemoryEntry[]> {
184
- return ids
185
- .map((id) => this.entries.get(id))
186
- .filter((e): e is MemoryEntry => e !== undefined);
187
- }
188
-
189
- async deleteMany(ids: string[]): Promise<BulkOperationResult> {
190
- const errors: Array<{ id: string; error: string }> = [];
191
- let success = 0;
192
-
193
- for (const id of ids) {
194
- try {
195
- if (await this.delete(id)) {
196
- success++;
197
- } else {
198
- errors.push({ id, error: 'Entry not found' });
199
- }
200
- } catch (error) {
201
- errors.push({
202
- id,
203
- error: error instanceof Error ? error.message : 'Unknown error',
204
- });
205
- }
206
- }
207
-
208
- return {
209
- success,
210
- failed: errors.length,
211
- errors,
212
- };
213
- }
214
-
215
- // ============================================================================
216
- // Query Operations
217
- // ============================================================================
218
-
219
- async findAll(options?: MemoryQueryOptions): Promise<MemoryEntry[]> {
220
- this.ensureInitialized();
221
-
222
- let results = Array.from(this.entries.values());
223
-
224
- // Apply filters
225
- if (options?.namespace) {
226
- results = results.filter((e) => e.namespace === options.namespace);
227
- }
228
- if (options?.type) {
229
- results = results.filter((e) => e.type === options.type);
230
- }
231
- if (options?.status) {
232
- results = results.filter((e) => e.status === options.status);
233
- }
234
-
235
- // Apply sorting
236
- const orderBy = options?.orderBy ?? 'createdAt';
237
- const orderDir = options?.orderDirection ?? 'desc';
238
- results.sort((a, b) => {
239
- let aVal: number, bVal: number;
240
- switch (orderBy) {
241
- case 'accessCount':
242
- aVal = a.accessCount;
243
- bVal = b.accessCount;
244
- break;
245
- case 'lastAccessedAt':
246
- aVal = a.lastAccessedAt.getTime();
247
- bVal = b.lastAccessedAt.getTime();
248
- break;
249
- case 'updatedAt':
250
- aVal = a.updatedAt.getTime();
251
- bVal = b.updatedAt.getTime();
252
- break;
253
- default:
254
- aVal = a.createdAt.getTime();
255
- bVal = b.createdAt.getTime();
256
- }
257
- return orderDir === 'asc' ? aVal - bVal : bVal - aVal;
258
- });
259
-
260
- // Apply pagination
261
- if (options?.offset) {
262
- results = results.slice(options.offset);
263
- }
264
- if (options?.limit) {
265
- results = results.slice(0, options.limit);
266
- }
267
-
268
- return results;
269
- }
270
-
271
- async findByNamespace(
272
- namespace: string,
273
- options?: Omit<MemoryQueryOptions, 'namespace'>
274
- ): Promise<MemoryEntry[]> {
275
- return this.findAll({ ...options, namespace });
276
- }
277
-
278
- async findByType(
279
- type: MemoryType,
280
- options?: Omit<MemoryQueryOptions, 'type'>
281
- ): Promise<MemoryEntry[]> {
282
- return this.findAll({ ...options, type });
283
- }
284
-
285
- async findByStatus(
286
- status: MemoryStatus,
287
- options?: Omit<MemoryQueryOptions, 'status'>
288
- ): Promise<MemoryEntry[]> {
289
- return this.findAll({ ...options, status });
290
- }
291
-
292
- // ============================================================================
293
- // Vector Search
294
- // ============================================================================
295
-
296
- async searchByVector(options: VectorSearchOptions): Promise<VectorSearchResult[]> {
297
- this.ensureInitialized();
298
-
299
- const results: VectorSearchResult[] = [];
300
-
301
- for (const [id, vector] of this.vectorIndex) {
302
- const entry = this.entries.get(id);
303
- if (!entry) continue;
304
- if (options.namespace && entry.namespace !== options.namespace) continue;
305
- if (options.type && entry.type !== options.type) continue;
306
-
307
- const similarity = this.cosineSimilarity(options.vector, vector);
308
- const threshold = options.threshold ?? 0.5;
309
-
310
- if (similarity >= threshold) {
311
- results.push({
312
- entry,
313
- similarity,
314
- distance: 1 - similarity,
315
- });
316
- }
317
- }
318
-
319
- // Sort by similarity descending
320
- results.sort((a, b) => b.similarity - a.similarity);
321
-
322
- // Limit results
323
- return results.slice(0, options.limit ?? 10);
324
- }
325
-
326
- async findSimilar(entryId: string, limit = 10): Promise<VectorSearchResult[]> {
327
- const entry = this.entries.get(entryId);
328
- if (!entry || !entry.vector) return [];
329
-
330
- return this.searchByVector({
331
- vector: entry.vector,
332
- namespace: entry.namespace,
333
- limit: limit + 1, // Include self
334
- }).then((results) => results.filter((r) => r.entry.id !== entryId).slice(0, limit));
335
- }
336
-
337
- // ============================================================================
338
- // Maintenance Operations
339
- // ============================================================================
340
-
341
- async findExpired(): Promise<MemoryEntry[]> {
342
- return Array.from(this.entries.values()).filter((e) => e.isExpired());
343
- }
344
-
345
- async deleteExpired(): Promise<number> {
346
- const expired = await this.findExpired();
347
- for (const entry of expired) {
348
- await this.delete(entry.id);
349
- }
350
- return expired.length;
351
- }
352
-
353
- async findCold(milliseconds: number): Promise<MemoryEntry[]> {
354
- return Array.from(this.entries.values()).filter((e) => e.isCold(milliseconds));
355
- }
356
-
357
- async archiveCold(milliseconds: number): Promise<number> {
358
- const cold = await this.findCold(milliseconds);
359
- for (const entry of cold) {
360
- entry.archive();
361
- await this.save(entry);
362
- }
363
- return cold.length;
364
- }
365
-
366
- // ============================================================================
367
- // Statistics
368
- // ============================================================================
369
-
370
- async getStatistics(): Promise<MemoryStatistics> {
371
- const entries = Array.from(this.entries.values());
372
-
373
- const entriesByNamespace: Record<string, number> = {};
374
- const entriesByType: Record<MemoryType, number> = {
375
- semantic: 0,
376
- episodic: 0,
377
- procedural: 0,
378
- working: 0,
379
- };
380
-
381
- let totalAccessCount = 0;
382
- let totalSize = 0;
383
- let activeCount = 0;
384
- let archivedCount = 0;
385
- let deletedCount = 0;
386
-
387
- for (const entry of entries) {
388
- // Count by namespace
389
- entriesByNamespace[entry.namespace] = (entriesByNamespace[entry.namespace] ?? 0) + 1;
390
-
391
- // Count by type
392
- entriesByType[entry.type]++;
393
-
394
- // Accumulate stats
395
- totalAccessCount += entry.accessCount;
396
- totalSize += JSON.stringify(entry.value).length;
397
-
398
- // Count by status
399
- switch (entry.status) {
400
- case 'active':
401
- activeCount++;
402
- break;
403
- case 'archived':
404
- archivedCount++;
405
- break;
406
- case 'deleted':
407
- deletedCount++;
408
- break;
409
- }
410
- }
411
-
412
- // Find hottest and coldest
413
- const sorted = [...entries].sort((a, b) => b.accessCount - a.accessCount);
414
- const hottestEntries = sorted.slice(0, 5).map((e) => e.id);
415
- const coldestEntries = sorted.slice(-5).reverse().map((e) => e.id);
416
-
417
- return {
418
- totalEntries: entries.length,
419
- activeEntries: activeCount,
420
- archivedEntries: archivedCount,
421
- deletedEntries: deletedCount,
422
- totalSize,
423
- entriesByNamespace,
424
- entriesByType,
425
- averageAccessCount: entries.length > 0 ? totalAccessCount / entries.length : 0,
426
- hottestEntries,
427
- coldestEntries,
428
- };
429
- }
430
-
431
- async count(options?: MemoryQueryOptions): Promise<number> {
432
- const entries = await this.findAll(options);
433
- return entries.length;
434
- }
435
-
436
- // ============================================================================
437
- // Namespace Operations
438
- // ============================================================================
439
-
440
- async listNamespaces(): Promise<string[]> {
441
- return Array.from(this.namespaceIndex.keys());
442
- }
443
-
444
- async deleteNamespace(namespace: string): Promise<number> {
445
- const ids = this.namespaceIndex.get(namespace);
446
- if (!ids) return 0;
447
-
448
- const count = ids.size;
449
- for (const id of ids) {
450
- await this.delete(id);
451
- }
452
- this.namespaceIndex.delete(namespace);
453
- return count;
454
- }
455
-
456
- async getNamespaceSize(namespace: string): Promise<number> {
457
- const ids = this.namespaceIndex.get(namespace);
458
- if (!ids) return 0;
459
-
460
- let size = 0;
461
- for (const id of ids) {
462
- const entry = this.entries.get(id);
463
- if (entry) {
464
- size += JSON.stringify(entry.value).length;
465
- }
466
- }
467
- return size;
468
- }
469
-
470
- // ============================================================================
471
- // Private Methods
472
- // ============================================================================
473
-
474
- private ensureInitialized(): void {
475
- if (!this.initialized) {
476
- throw new Error('Repository not initialized. Call initialize() first.');
477
- }
478
- }
479
-
480
- private updateCache(entry: MemoryEntry): void {
481
- const maxCacheSize = this.config.cacheSize ?? 100;
482
-
483
- // Evict oldest entries if cache is full
484
- if (this.cache.size >= maxCacheSize) {
485
- const oldest = Array.from(this.cache.entries())
486
- .sort(([, a], [, b]) => a.timestamp - b.timestamp)
487
- .slice(0, Math.floor(maxCacheSize * 0.2));
488
-
489
- for (const [id] of oldest) {
490
- this.cache.delete(id);
491
- }
492
- }
493
-
494
- this.cache.set(entry.id, {
495
- entry,
496
- timestamp: Date.now(),
497
- });
498
- }
499
-
500
- private cosineSimilarity(a: Float32Array, b: Float32Array): number {
501
- if (a.length !== b.length) return 0;
502
-
503
- let dotProduct = 0;
504
- let normA = 0;
505
- let normB = 0;
506
-
507
- for (let i = 0; i < a.length; i++) {
508
- dotProduct += a[i] * b[i];
509
- normA += a[i] * a[i];
510
- normB += b[i] * b[i];
511
- }
512
-
513
- const denominator = Math.sqrt(normA) * Math.sqrt(normB);
514
- return denominator === 0 ? 0 : dotProduct / denominator;
515
- }
516
- }