autosnippet 3.3.7 → 3.3.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (218) hide show
  1. package/README.md +1 -0
  2. package/dashboard/dist/assets/icons-BMNb0V6L.js +1 -0
  3. package/dashboard/dist/assets/index-DEU4tJtP.js +112 -0
  4. package/dashboard/dist/assets/index-DHJ1Dj7u.css +1 -0
  5. package/dashboard/dist/index.html +3 -3
  6. package/dist/bin/cli.js +7 -4
  7. package/dist/lib/agent/core/ChatAgentPrompts.js +57 -21
  8. package/dist/lib/agent/core/LoopContext.d.ts +1 -0
  9. package/dist/lib/agent/core/ToolExecutionPipeline.js +13 -0
  10. package/dist/lib/agent/memory/ActiveContext.d.ts +0 -2
  11. package/dist/lib/agent/memory/ActiveContext.js +0 -2
  12. package/dist/lib/agent/memory/MemoryEmbeddingStore.d.ts +49 -0
  13. package/dist/lib/agent/memory/MemoryEmbeddingStore.js +159 -0
  14. package/dist/lib/agent/memory/MemoryRetriever.d.ts +2 -0
  15. package/dist/lib/agent/memory/MemoryRetriever.js +25 -11
  16. package/dist/lib/agent/memory/MemoryStore.d.ts +8 -41
  17. package/dist/lib/agent/memory/MemoryStore.js +196 -261
  18. package/dist/lib/agent/memory/PersistentMemory.d.ts +2 -0
  19. package/dist/lib/agent/memory/PersistentMemory.js +4 -5
  20. package/dist/lib/agent/memory/SessionStore.d.ts +0 -2
  21. package/dist/lib/agent/memory/SessionStore.js +0 -2
  22. package/dist/lib/agent/tools/ast-graph.js +21 -19
  23. package/dist/lib/agent/tools/infrastructure.js +3 -2
  24. package/dist/lib/agent/tools/project-access.d.ts +2 -2
  25. package/dist/lib/agent/tools/project-access.js +5 -4
  26. package/dist/lib/bootstrap.js +8 -2
  27. package/dist/lib/cli/AiScanService.js +4 -17
  28. package/dist/lib/cli/KnowledgeSyncService.d.ts +7 -37
  29. package/dist/lib/cli/KnowledgeSyncService.js +23 -51
  30. package/dist/lib/cli/SetupService.js +5 -4
  31. package/dist/lib/core/ast/ProjectGraph.js +5 -27
  32. package/dist/lib/core/discovery/CustomConfigDiscoverer.d.ts +0 -2
  33. package/dist/lib/core/discovery/CustomConfigDiscoverer.js +0 -2
  34. package/dist/lib/domain/dimension/DimensionRegistry.d.ts +0 -2
  35. package/dist/lib/domain/dimension/DimensionRegistry.js +0 -2
  36. package/dist/lib/domain/dimension/DimensionSop.js +44 -33
  37. package/dist/lib/domain/dimension/UnifiedDimension.d.ts +0 -2
  38. package/dist/lib/domain/dimension/UnifiedDimension.js +0 -2
  39. package/dist/lib/domain/knowledge/Lifecycle.d.ts +26 -0
  40. package/dist/lib/domain/knowledge/Lifecycle.js +42 -0
  41. package/dist/lib/domain/knowledge/index.d.ts +2 -1
  42. package/dist/lib/domain/knowledge/index.js +1 -1
  43. package/dist/lib/external/mcp/McpServer.js +19 -2
  44. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/BootstrapSnapshot.d.ts +2 -1
  45. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/BootstrapSnapshot.js +102 -153
  46. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/mock-pipeline.js +10 -29
  47. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js +33 -16
  48. package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.d.ts +1 -1
  49. package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.js +41 -37
  50. package/dist/lib/external/mcp/handlers/bootstrap-external.js +1 -1
  51. package/dist/lib/external/mcp/handlers/dimension-complete-external.js +7 -3
  52. package/dist/lib/external/mcp/handlers/evolve-external.d.ts +1 -0
  53. package/dist/lib/external/mcp/handlers/evolve-external.js +13 -16
  54. package/dist/lib/external/mcp/handlers/guard.js +15 -24
  55. package/dist/lib/external/mcp/handlers/panorama.js +9 -9
  56. package/dist/lib/external/mcp/handlers/rescan-external.js +7 -6
  57. package/dist/lib/external/mcp/handlers/rescan-internal.js +9 -5
  58. package/dist/lib/external/mcp/handlers/search.js +3 -1
  59. package/dist/lib/external/mcp/handlers/skill.js +4 -4
  60. package/dist/lib/external/mcp/handlers/structure.js +8 -12
  61. package/dist/lib/external/mcp/handlers/system.js +10 -34
  62. package/dist/lib/http/routes/ai.js +11 -13
  63. package/dist/lib/http/routes/guardReport.js +3 -5
  64. package/dist/lib/http/routes/panorama.js +12 -12
  65. package/dist/lib/http/routes/recipes.js +59 -8
  66. package/dist/lib/http/routes/remote.js +3 -13
  67. package/dist/lib/http/routes/search.js +11 -8
  68. package/dist/lib/infrastructure/audit/AuditLogger.d.ts +20 -3
  69. package/dist/lib/infrastructure/audit/AuditStore.d.ts +28 -29
  70. package/dist/lib/infrastructure/audit/AuditStore.js +81 -88
  71. package/dist/lib/infrastructure/database/DatabaseConnection.js +7 -6
  72. package/dist/lib/infrastructure/database/drizzle/schema.d.ts +180 -2
  73. package/dist/lib/infrastructure/database/drizzle/schema.js +23 -3
  74. package/dist/lib/injection/ServiceContainer.js +7 -4
  75. package/dist/lib/injection/ServiceMap.d.ts +20 -0
  76. package/dist/lib/injection/modules/AppModule.js +2 -1
  77. package/dist/lib/injection/modules/GuardModule.js +5 -5
  78. package/dist/lib/injection/modules/InfraModule.js +60 -0
  79. package/dist/lib/injection/modules/KnowledgeModule.js +86 -51
  80. package/dist/lib/injection/modules/PanoramaModule.js +16 -10
  81. package/dist/lib/injection/modules/VectorModule.js +3 -0
  82. package/dist/lib/repository/audit/AuditRepository.d.ts +107 -0
  83. package/dist/lib/repository/audit/AuditRepository.js +272 -0
  84. package/dist/lib/repository/base/RepositoryBase.d.ts +46 -0
  85. package/dist/lib/repository/base/RepositoryBase.js +32 -0
  86. package/dist/lib/repository/bootstrap/BootstrapRepository.d.ts +94 -0
  87. package/dist/lib/repository/bootstrap/BootstrapRepository.js +246 -0
  88. package/dist/lib/repository/code/CodeEntityRepository.d.ts +91 -0
  89. package/dist/lib/repository/code/CodeEntityRepository.js +361 -0
  90. package/dist/lib/repository/delivery/DeliveryRepoAdapter.d.ts +39 -0
  91. package/dist/lib/repository/delivery/DeliveryRepoAdapter.js +23 -0
  92. package/dist/lib/repository/evolution/LifecycleEventRepository.d.ts +51 -0
  93. package/dist/lib/repository/evolution/LifecycleEventRepository.js +119 -0
  94. package/dist/lib/repository/evolution/ProposalRepository.d.ts +9 -12
  95. package/dist/lib/repository/evolution/ProposalRepository.js +114 -57
  96. package/dist/lib/repository/guard/GuardViolationRepository.d.ts +104 -0
  97. package/dist/lib/repository/guard/GuardViolationRepository.js +217 -0
  98. package/dist/lib/repository/knowledge/KnowledgeEdgeRepository.d.ts +129 -0
  99. package/dist/lib/repository/knowledge/KnowledgeEdgeRepository.js +475 -0
  100. package/dist/lib/repository/knowledge/KnowledgeFileStore.d.ts +39 -0
  101. package/dist/lib/repository/knowledge/KnowledgeFileStore.js +12 -0
  102. package/dist/lib/repository/knowledge/KnowledgeRepository.impl.d.ts +295 -11
  103. package/dist/lib/repository/knowledge/KnowledgeRepository.impl.js +608 -13
  104. package/dist/lib/repository/knowledge/KnowledgeUnitOfWork.d.ts +61 -0
  105. package/dist/lib/repository/knowledge/KnowledgeUnitOfWork.js +156 -0
  106. package/dist/lib/repository/memory/MemoryRepository.d.ts +90 -0
  107. package/dist/lib/repository/memory/MemoryRepository.js +260 -0
  108. package/dist/lib/repository/search/SearchRepoAdapter.d.ts +92 -0
  109. package/dist/lib/repository/search/SearchRepoAdapter.js +124 -0
  110. package/dist/lib/repository/session/SessionRepository.d.ts +46 -0
  111. package/dist/lib/repository/session/SessionRepository.js +110 -0
  112. package/dist/lib/repository/sourceref/RecipeSourceRefRepository.d.ts +66 -0
  113. package/dist/lib/repository/sourceref/RecipeSourceRefRepository.js +182 -0
  114. package/dist/lib/repository/sync/SyncRepoAdapter.d.ts +58 -0
  115. package/dist/lib/repository/sync/SyncRepoAdapter.js +58 -0
  116. package/dist/lib/service/bootstrap/UiStartupTasks.js +5 -6
  117. package/dist/lib/service/bootstrap/bootstrap-event-types.d.ts +0 -1
  118. package/dist/lib/service/bootstrap/bootstrap-event-types.js +0 -1
  119. package/dist/lib/service/cleanup/CleanupService.js +8 -4
  120. package/dist/lib/service/delivery/CursorDeliveryPipeline.js +21 -9
  121. package/dist/lib/service/evolution/ConsolidationAdvisor.d.ts +4 -9
  122. package/dist/lib/service/evolution/ConsolidationAdvisor.js +34 -70
  123. package/dist/lib/service/evolution/ContentPatcher.d.ts +4 -12
  124. package/dist/lib/service/evolution/ContentPatcher.js +48 -19
  125. package/dist/lib/service/evolution/ContradictionDetector.d.ts +3 -7
  126. package/dist/lib/service/evolution/ContradictionDetector.js +17 -24
  127. package/dist/lib/service/evolution/DecayDetector.d.ts +10 -9
  128. package/dist/lib/service/evolution/DecayDetector.js +63 -57
  129. package/dist/lib/service/evolution/EnhancementSuggester.d.ts +3 -9
  130. package/dist/lib/service/evolution/EnhancementSuggester.js +42 -86
  131. package/dist/lib/service/evolution/KnowledgeMetabolism.d.ts +4 -4
  132. package/dist/lib/service/evolution/KnowledgeMetabolism.js +102 -71
  133. package/dist/lib/service/evolution/ProposalExecutor.d.ts +5 -12
  134. package/dist/lib/service/evolution/ProposalExecutor.js +64 -69
  135. package/dist/lib/service/evolution/RecipeLifecycleSupervisor.d.ts +9 -14
  136. package/dist/lib/service/evolution/RecipeLifecycleSupervisor.js +94 -155
  137. package/dist/lib/service/evolution/RecipeRelevanceAuditor.d.ts +4 -1
  138. package/dist/lib/service/evolution/RecipeRelevanceAuditor.js +50 -49
  139. package/dist/lib/service/evolution/RedundancyAnalyzer.d.ts +3 -7
  140. package/dist/lib/service/evolution/RedundancyAnalyzer.js +15 -22
  141. package/dist/lib/service/evolution/StagingManager.d.ts +6 -15
  142. package/dist/lib/service/evolution/StagingManager.js +37 -95
  143. package/dist/lib/service/evolution/createSupersedeProposal.d.ts +1 -1
  144. package/dist/lib/service/evolution/createSupersedeProposal.js +7 -8
  145. package/dist/lib/service/guard/CoverageAnalyzer.d.ts +3 -7
  146. package/dist/lib/service/guard/CoverageAnalyzer.js +9 -11
  147. package/dist/lib/service/guard/GuardCheckEngine.d.ts +3 -0
  148. package/dist/lib/service/guard/GuardCheckEngine.js +14 -22
  149. package/dist/lib/service/guard/ReverseGuard.d.ts +4 -7
  150. package/dist/lib/service/guard/ReverseGuard.js +21 -31
  151. package/dist/lib/service/guard/ViolationsStore.d.ts +15 -21
  152. package/dist/lib/service/guard/ViolationsStore.js +75 -69
  153. package/dist/lib/service/knowledge/CodeEntityGraph.d.ts +39 -63
  154. package/dist/lib/service/knowledge/CodeEntityGraph.js +418 -512
  155. package/dist/lib/service/knowledge/ConfidenceRouter.js +18 -9
  156. package/dist/lib/service/knowledge/KnowledgeFileWriter.d.ts +2 -1
  157. package/dist/lib/service/knowledge/KnowledgeGraphService.d.ts +18 -60
  158. package/dist/lib/service/knowledge/KnowledgeGraphService.js +58 -109
  159. package/dist/lib/service/knowledge/KnowledgeService.d.ts +15 -1
  160. package/dist/lib/service/knowledge/KnowledgeService.js +76 -38
  161. package/dist/lib/service/knowledge/RecipeProductionGateway.d.ts +0 -2
  162. package/dist/lib/service/knowledge/RecipeProductionGateway.js +0 -2
  163. package/dist/lib/service/knowledge/SourceRefReconciler.d.ts +5 -13
  164. package/dist/lib/service/knowledge/SourceRefReconciler.js +58 -78
  165. package/dist/lib/service/panorama/CouplingAnalyzer.d.ts +5 -3
  166. package/dist/lib/service/panorama/CouplingAnalyzer.js +102 -39
  167. package/dist/lib/service/panorama/DimensionAnalyzer.d.ts +7 -4
  168. package/dist/lib/service/panorama/DimensionAnalyzer.js +72 -25
  169. package/dist/lib/service/panorama/LayerInferrer.js +1 -1
  170. package/dist/lib/service/panorama/ModuleDiscoverer.d.ts +7 -6
  171. package/dist/lib/service/panorama/ModuleDiscoverer.js +174 -82
  172. package/dist/lib/service/panorama/PanoramaAggregator.d.ts +10 -3
  173. package/dist/lib/service/panorama/PanoramaAggregator.js +67 -79
  174. package/dist/lib/service/panorama/PanoramaScanner.d.ts +5 -1
  175. package/dist/lib/service/panorama/PanoramaScanner.js +32 -31
  176. package/dist/lib/service/panorama/PanoramaService.d.ts +11 -8
  177. package/dist/lib/service/panorama/PanoramaService.js +41 -66
  178. package/dist/lib/service/panorama/PanoramaTypes.d.ts +3 -0
  179. package/dist/lib/service/panorama/RoleRefiner.d.ts +8 -5
  180. package/dist/lib/service/panorama/RoleRefiner.js +52 -283
  181. package/dist/lib/service/panorama/TechStackProfiler.js +7 -119
  182. package/dist/lib/service/quality/QualityScorer.d.ts +45 -26
  183. package/dist/lib/service/quality/QualityScorer.js +157 -83
  184. package/dist/lib/service/search/SearchEngine.d.ts +1 -0
  185. package/dist/lib/service/search/SearchEngine.js +32 -37
  186. package/dist/lib/service/signal/HitRecorder.js +5 -5
  187. package/dist/lib/service/skills/RuleRecallStrategy.js +7 -3
  188. package/dist/lib/service/skills/SignalCollector.d.ts +5 -8
  189. package/dist/lib/service/skills/SignalCollector.js +28 -55
  190. package/dist/lib/service/skills/SkillAdvisor.d.ts +7 -13
  191. package/dist/lib/service/skills/SkillAdvisor.js +30 -79
  192. package/dist/lib/service/vector/SyncCoordinator.d.ts +3 -1
  193. package/dist/lib/service/vector/SyncCoordinator.js +25 -3
  194. package/dist/lib/service/vector/VectorService.d.ts +2 -0
  195. package/dist/lib/service/vector/VectorService.js +3 -0
  196. package/dist/lib/service/wiki/WikiGenerator.js +1 -1
  197. package/dist/lib/shared/LanguageProfiles.d.ts +109 -0
  198. package/dist/lib/shared/LanguageProfiles.js +939 -0
  199. package/dist/lib/shared/LanguageService.d.ts +6 -0
  200. package/dist/lib/shared/LanguageService.js +16 -0
  201. package/dist/lib/shared/PathGuard.js +16 -10
  202. package/dist/lib/shared/constants.d.ts +19 -19
  203. package/dist/lib/shared/constants.js +10 -10
  204. package/dist/lib/shared/isOwnDevRepo.d.ts +29 -4
  205. package/dist/lib/shared/isOwnDevRepo.js +64 -4
  206. package/dist/lib/shared/schemas/mcp-tools.d.ts +1 -1
  207. package/dist/lib/types/project-snapshot-builder.d.ts +0 -1
  208. package/dist/lib/types/project-snapshot-builder.js +0 -1
  209. package/dist/lib/types/project-snapshot.d.ts +0 -1
  210. package/dist/lib/types/project-snapshot.js +0 -1
  211. package/dist/lib/types/snapshot-views.d.ts +0 -2
  212. package/dist/lib/types/snapshot-views.js +0 -1
  213. package/package.json +2 -1
  214. package/dashboard/dist/assets/icons-FHns2ypa.js +0 -1
  215. package/dashboard/dist/assets/index-BRJv5Y3r.js +0 -135
  216. package/dashboard/dist/assets/index-DzoB7kxK.css +0 -1
  217. package/dist/lib/repository/base/BaseRepository.d.ts +0 -53
  218. package/dist/lib/repository/base/BaseRepository.js +0 -226
@@ -0,0 +1,49 @@
1
+ /**
2
+ * MemoryEmbeddingStore — 向量嵌入的 JSON sidecar 存储
3
+ *
4
+ * 将 Agent Memory 的向量嵌入从 SQLite BLOB 迁移到独立 JSON 文件,
5
+ * 与 Knowledge 侧 HNSW `.asvec` 的设计理念对齐:
6
+ * **结构化数据存 SQLite,向量存独立文件。**
7
+ *
8
+ * 设计:
9
+ * - 内存 Map<id, number[]> 缓存,启动时一次性加载
10
+ * - 写入时更新内存 + debounced flush 到 JSON
11
+ * - 崩溃丢失可通过 embedAllMemories() backfill 恢复
12
+ *
13
+ * 文件位置: .autosnippet/context/memory_embeddings.json
14
+ *
15
+ * @module MemoryEmbeddingStore
16
+ */
17
+ export declare class MemoryEmbeddingStore {
18
+ #private;
19
+ /**
20
+ * @param projectRoot 项目根目录
21
+ * @param opts.filePath 覆盖默认文件路径 (测试用)
22
+ */
23
+ constructor(projectRoot: string, opts?: {
24
+ filePath?: string;
25
+ });
26
+ /** 获取单条 embedding */
27
+ get(id: string): number[] | null;
28
+ /** 设置单条 embedding */
29
+ set(id: string, embedding: number[]): void;
30
+ /** 批量设置 embeddings */
31
+ batchSet(entries: Array<{
32
+ id: string;
33
+ embedding: number[];
34
+ }>): number;
35
+ /** 删除单条 embedding */
36
+ delete(id: string): boolean;
37
+ /** 检查是否有 embedding */
38
+ has(id: string): boolean;
39
+ /** 返回所有缺少 embedding 的 ID (给定候选 ID 列表) */
40
+ getMissingIds(candidateIds: string[]): string[];
41
+ /** 缓存大小 */
42
+ get size(): number;
43
+ /** 清除所有 embeddings (用于重建) */
44
+ clear(): void;
45
+ /** 立即刷写到磁盘 (shutdown / 测试用) */
46
+ flushSync(): void;
47
+ /** GC: 移除不在给定 ID 集合中的 embeddings */
48
+ gc(activeIds: Set<string>): number;
49
+ }
@@ -0,0 +1,159 @@
1
+ /**
2
+ * MemoryEmbeddingStore — 向量嵌入的 JSON sidecar 存储
3
+ *
4
+ * 将 Agent Memory 的向量嵌入从 SQLite BLOB 迁移到独立 JSON 文件,
5
+ * 与 Knowledge 侧 HNSW `.asvec` 的设计理念对齐:
6
+ * **结构化数据存 SQLite,向量存独立文件。**
7
+ *
8
+ * 设计:
9
+ * - 内存 Map<id, number[]> 缓存,启动时一次性加载
10
+ * - 写入时更新内存 + debounced flush 到 JSON
11
+ * - 崩溃丢失可通过 embedAllMemories() backfill 恢复
12
+ *
13
+ * 文件位置: .autosnippet/context/memory_embeddings.json
14
+ *
15
+ * @module MemoryEmbeddingStore
16
+ */
17
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
18
+ import { dirname, join } from 'node:path';
19
+ /** debounce flush 延迟 (ms) */
20
+ const FLUSH_DELAY_MS = 2000;
21
+ export class MemoryEmbeddingStore {
22
+ /** 内存缓存: id → embedding vector */
23
+ #cache = new Map();
24
+ /** JSON 文件路径 */
25
+ #filePath;
26
+ /** debounce timer */
27
+ #flushTimer = null;
28
+ /** dirty flag */
29
+ #dirty = false;
30
+ /**
31
+ * @param projectRoot 项目根目录
32
+ * @param opts.filePath 覆盖默认文件路径 (测试用)
33
+ */
34
+ constructor(projectRoot, opts) {
35
+ this.#filePath =
36
+ opts?.filePath ?? join(projectRoot, '.autosnippet', 'context', 'memory_embeddings.json');
37
+ this.#load();
38
+ }
39
+ /** 获取单条 embedding */
40
+ get(id) {
41
+ return this.#cache.get(id) ?? null;
42
+ }
43
+ /** 设置单条 embedding */
44
+ set(id, embedding) {
45
+ this.#cache.set(id, embedding);
46
+ this.#scheduleDirtyFlush();
47
+ }
48
+ /** 批量设置 embeddings */
49
+ batchSet(entries) {
50
+ let count = 0;
51
+ for (const { id, embedding } of entries) {
52
+ this.#cache.set(id, embedding);
53
+ count++;
54
+ }
55
+ if (count > 0) {
56
+ this.#scheduleDirtyFlush();
57
+ }
58
+ return count;
59
+ }
60
+ /** 删除单条 embedding */
61
+ delete(id) {
62
+ const existed = this.#cache.delete(id);
63
+ if (existed) {
64
+ this.#scheduleDirtyFlush();
65
+ }
66
+ return existed;
67
+ }
68
+ /** 检查是否有 embedding */
69
+ has(id) {
70
+ return this.#cache.has(id);
71
+ }
72
+ /** 返回所有缺少 embedding 的 ID (给定候选 ID 列表) */
73
+ getMissingIds(candidateIds) {
74
+ return candidateIds.filter((id) => !this.#cache.has(id));
75
+ }
76
+ /** 缓存大小 */
77
+ get size() {
78
+ return this.#cache.size;
79
+ }
80
+ /** 清除所有 embeddings (用于重建) */
81
+ clear() {
82
+ this.#cache.clear();
83
+ this.#scheduleDirtyFlush();
84
+ }
85
+ /** 立即刷写到磁盘 (shutdown / 测试用) */
86
+ flushSync() {
87
+ if (this.#flushTimer) {
88
+ clearTimeout(this.#flushTimer);
89
+ this.#flushTimer = null;
90
+ }
91
+ if (!this.#dirty) {
92
+ return;
93
+ }
94
+ this.#writeFile();
95
+ this.#dirty = false;
96
+ }
97
+ /** GC: 移除不在给定 ID 集合中的 embeddings */
98
+ gc(activeIds) {
99
+ let removed = 0;
100
+ for (const id of this.#cache.keys()) {
101
+ if (!activeIds.has(id)) {
102
+ this.#cache.delete(id);
103
+ removed++;
104
+ }
105
+ }
106
+ if (removed > 0) {
107
+ this.#scheduleDirtyFlush();
108
+ }
109
+ return removed;
110
+ }
111
+ // ═══════════════════════════════════════════════════════════
112
+ // Private
113
+ // ═══════════════════════════════════════════════════════════
114
+ #load() {
115
+ try {
116
+ if (existsSync(this.#filePath)) {
117
+ const raw = readFileSync(this.#filePath, 'utf-8');
118
+ const data = JSON.parse(raw);
119
+ for (const [id, vec] of Object.entries(data)) {
120
+ if (Array.isArray(vec)) {
121
+ this.#cache.set(id, vec);
122
+ }
123
+ }
124
+ }
125
+ }
126
+ catch {
127
+ // 文件不存在或解析失败 → 空缓存,后续 backfill 会重建
128
+ }
129
+ }
130
+ #writeFile() {
131
+ try {
132
+ const dir = dirname(this.#filePath);
133
+ if (!existsSync(dir)) {
134
+ mkdirSync(dir, { recursive: true });
135
+ }
136
+ const obj = {};
137
+ for (const [id, vec] of this.#cache) {
138
+ obj[id] = vec;
139
+ }
140
+ writeFileSync(this.#filePath, JSON.stringify(obj), 'utf-8');
141
+ }
142
+ catch {
143
+ // 写入失败不阻塞运行时;下次 flush 或 backfill 会重试
144
+ }
145
+ }
146
+ #scheduleDirtyFlush() {
147
+ this.#dirty = true;
148
+ if (this.#flushTimer) {
149
+ return; // 已有 pending timer
150
+ }
151
+ this.#flushTimer = setTimeout(() => {
152
+ this.#flushTimer = null;
153
+ if (this.#dirty) {
154
+ this.#writeFile();
155
+ this.#dirty = false;
156
+ }
157
+ }, FLUSH_DELAY_MS);
158
+ }
159
+ }
@@ -10,6 +10,7 @@
10
10
  *
11
11
  * @module MemoryRetriever
12
12
  */
13
+ import type { MemoryEmbeddingStore } from './MemoryEmbeddingStore.js';
13
14
  import type { DeserializedMemory } from './MemoryStore.js';
14
15
  import { MemoryStore } from './MemoryStore.js';
15
16
  /** 带评分的记忆检索结果 */
@@ -49,6 +50,7 @@ export declare class MemoryRetriever {
49
50
  /** @param [opts.embeddingFn] 向量嵌入函数 (异步) */
50
51
  constructor(store: MemoryStore, opts?: {
51
52
  embeddingFn?: EmbeddingFn;
53
+ embeddingStore?: MemoryEmbeddingStore;
52
54
  });
53
55
  /**
54
56
  * 综合检索: recency × importance × relevance
@@ -25,10 +25,13 @@ export class MemoryRetriever {
25
25
  #store;
26
26
  /** 向量嵌入函数 */
27
27
  #embeddingFn;
28
+ /** 向量嵌入存储 (JSON sidecar) */
29
+ #embeddingStore;
28
30
  /** @param [opts.embeddingFn] 向量嵌入函数 (异步) */
29
31
  constructor(store, opts = {}) {
30
32
  this.#store = store;
31
33
  this.#embeddingFn = typeof opts.embeddingFn === 'function' ? opts.embeddingFn : null;
34
+ this.#embeddingStore = opts.embeddingStore ?? null;
32
35
  }
33
36
  // ═══════════════════════════════════════════════════════════
34
37
  // 综合检索
@@ -71,14 +74,15 @@ export class MemoryRetriever {
71
74
  const importance = (m.importance || 5) / 10;
72
75
  // Relevance: 词汇相关性 (lexical)
73
76
  const lexicalRelevance = MemoryRetriever.#computeRelevance(lowerQuery, queryTokens, m.content);
74
- // 向量相关性: 对有 embedding 的记忆计算余弦相似度
77
+ // 向量相关性: embeddingStore 查找 embedding 做余弦相似度
75
78
  const deserialized = MemoryStore.deserialize(m);
76
79
  let vectorRelevance = 0;
77
- if (queryVec && deserialized.embedding) {
78
- vectorRelevance = Math.max(0, cosineSimilarity(queryVec, deserialized.embedding));
80
+ const storedEmbedding = this.#embeddingStore?.get(m.id) ?? null;
81
+ if (queryVec && storedEmbedding) {
82
+ vectorRelevance = Math.max(0, cosineSimilarity(queryVec, storedEmbedding));
79
83
  }
80
84
  // 混合相关性: 有向量时 0.6 * vector + 0.4 * lexical,否则纯 lexical
81
- const relevance = queryVec && deserialized.embedding
85
+ const relevance = queryVec && storedEmbedding
82
86
  ? 0.6 * vectorRelevance + 0.4 * lexicalRelevance
83
87
  : lexicalRelevance;
84
88
  const score = WEIGHT_RECENCY * recency + WEIGHT_IMPORTANCE * importance + WEIGHT_RELEVANCE * relevance;
@@ -199,18 +203,28 @@ export class MemoryRetriever {
199
203
  * @returns 成功嵌入的记忆数
200
204
  */
201
205
  async embedAllMemories(batchSize = 20) {
202
- if (!this.#embeddingFn) {
206
+ if (!this.#embeddingFn || !this.#embeddingStore) {
203
207
  return 0;
204
208
  }
205
- const missing = this.#store.getWithoutEmbedding(batchSize);
206
- if (missing.length === 0) {
209
+ // MemoryStore 获取所有活跃记忆 ID,找出 embeddingStore 中缺失的
210
+ const allActive = this.#store.getAllActive();
211
+ const allIds = allActive.map((m) => m.id);
212
+ const missingIds = this.#embeddingStore.getMissingIds(allIds);
213
+ if (missingIds.length === 0) {
207
214
  return 0;
208
215
  }
216
+ // 取前 batchSize 条
217
+ const batch = missingIds.slice(0, batchSize);
218
+ const contentMap = new Map(allActive.map((m) => [m.id, m.content]));
209
219
  const entries = [];
210
- for (const item of missing) {
220
+ for (const id of batch) {
221
+ const content = contentMap.get(id);
222
+ if (!content) {
223
+ continue;
224
+ }
211
225
  try {
212
- const vec = await this.#embeddingFn(item.content);
213
- entries.push({ id: item.id, embedding: vec });
226
+ const vec = await this.#embeddingFn(content);
227
+ entries.push({ id, embedding: vec });
214
228
  }
215
229
  catch {
216
230
  // 单条失败不阻塞
@@ -219,7 +233,7 @@ export class MemoryRetriever {
219
233
  if (entries.length === 0) {
220
234
  return 0;
221
235
  }
222
- return this.#store.batchUpdateEmbeddings(entries);
236
+ return this.#embeddingStore.batchSet(entries);
223
237
  }
224
238
  /**
225
239
  * 使用嵌入函数计算语义相关性 (余弦相似度)
@@ -1,10 +1,8 @@
1
1
  /**
2
- * MemoryStore — 持久化记忆 SQLite 存储层
2
+ * MemoryStore — 持久化记忆 SQLite 存储层(Drizzle 类型安全版)
3
3
  *
4
4
  * 从 PersistentMemory.js 提取的 CRUD + SQL 基础设施。
5
5
  * 负责:
6
- * - 表结构确保 (#ensureTable)
7
- * - SQL 预编译 (#prepareStatements)
8
6
  * - 基本 CRUD: add, update, delete, get
9
7
  * - 批量查询: getAllActive, size, getStats
10
8
  * - 访问计数: touchAccess
@@ -13,8 +11,9 @@
13
11
  * - 统计: getStats, clearBootstrapMemories
14
12
  *
15
13
  * 设计原则:
16
- * - 拥有 #db #stmts,其他组件通过 MemoryStore 访问数据
17
- * - update() 使用动态 SQL 但通过 named parameters 防注入
14
+ * - 大部分操作通过 Drizzle 类型安全 API
15
+ * - update() 使用 Drizzle 类型安全 partial update
16
+ * - embedding 已迁移至 MemoryEmbeddingStore (JSON sidecar)
18
17
  * - 数据序列化/反序列化统一在此层处理
19
18
  *
20
19
  * @module MemoryStore
@@ -34,7 +33,7 @@ export interface SqliteStatement {
34
33
  get(...params: unknown[]): Record<string, unknown> | undefined;
35
34
  all(...params: unknown[]): Record<string, unknown>[];
36
35
  }
37
- /** 数据库行 (raw row from SQLite) */
36
+ /** 数据库行 (raw row from SQLite — 保持向后兼容) */
38
37
  export interface MemoryRow {
39
38
  id: string;
40
39
  type: string;
@@ -52,8 +51,6 @@ export interface MemoryRow {
52
51
  source_evidence: string | null;
53
52
  bootstrap_session: string | null;
54
53
  tags: string;
55
- /** 向量嵌入 (Float32Array BLOB) */
56
- embedding: Buffer | null;
57
54
  /** findSimilar 附加字段 */
58
55
  similarity?: number;
59
56
  related_memories_raw?: string;
@@ -76,8 +73,6 @@ export interface DeserializedMemory {
76
73
  sourceEvidence: string | null;
77
74
  bootstrapSession: string | null;
78
75
  tags: string[];
79
- /** 向量嵌入 (Float32Array) */
80
- embedding: number[] | null;
81
76
  }
82
77
  /** 添加记忆时的输入 */
83
78
  export interface MemoryInput {
@@ -91,8 +86,6 @@ export interface MemoryInput {
91
86
  sourceEvidence?: string | null;
92
87
  bootstrapSession?: string | null;
93
88
  tags?: string[];
94
- /** 向量嵌入 */
95
- embedding?: number[] | null;
96
89
  }
97
90
  /** 更新记忆时的字段 */
98
91
  export interface MemoryUpdates {
@@ -102,8 +95,6 @@ export interface MemoryUpdates {
102
95
  relatedEntities?: string[];
103
96
  relatedMemories?: string[];
104
97
  tags?: string[];
105
- /** 向量嵌入 */
106
- embedding?: number[] | null;
107
98
  }
108
99
  export declare class MemoryStore {
109
100
  #private;
@@ -119,7 +110,9 @@ export declare class MemoryStore {
119
110
  id: string;
120
111
  action: string;
121
112
  };
122
- /** 更新已有记忆 */
113
+ /**
114
+ * 更新已有记忆
115
+ */
123
116
  update(id: string, updates: MemoryUpdates): boolean;
124
117
  /** 删除一条记忆 */
125
118
  delete(id: string): boolean;
@@ -184,30 +177,4 @@ export declare class MemoryStore {
184
177
  /** 反序列化数据库行为域对象 */
185
178
  static deserialize(row: MemoryRow): DeserializedMemory;
186
179
  static safeParseJSON<T>(str: string | null | undefined, fallback: T): T;
187
- /**
188
- * 更新单条记忆的向量嵌入
189
- * @param id 记忆 ID
190
- * @param embedding 向量数组
191
- */
192
- updateEmbedding(id: string, embedding: number[]): boolean;
193
- /**
194
- * 批量更新向量嵌入
195
- * @param entries Array of { id, embedding }
196
- */
197
- batchUpdateEmbeddings(entries: Array<{
198
- id: string;
199
- embedding: number[];
200
- }>): number;
201
- /**
202
- * 获取缺少向量嵌入的记忆 ID 和内容
203
- * @param limit 最大返回数
204
- */
205
- getWithoutEmbedding(limit?: number): Array<{
206
- id: string;
207
- content: string;
208
- }>;
209
- /** 将 number[] 序列化为 Buffer (Float32Array → BLOB) */
210
- static serializeEmbedding(embedding: number[]): Buffer;
211
- /** 将 Buffer (BLOB) 反序列化为 number[] */
212
- static deserializeEmbedding(blob: Buffer): number[];
213
180
  }