autosnippet 3.2.13 → 3.2.15

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 (285) hide show
  1. package/config/constitution.yaml +19 -0
  2. package/config/default.json +6 -1
  3. package/dist/bin/cli.d.ts +2 -1
  4. package/dist/bin/cli.d.ts.map +1 -1
  5. package/dist/bin/cli.js +231 -22
  6. package/dist/bin/cli.js.map +1 -1
  7. package/dist/lib/cli/SetupService.d.ts +70 -6
  8. package/dist/lib/cli/SetupService.d.ts.map +1 -1
  9. package/dist/lib/cli/SetupService.js +238 -50
  10. package/dist/lib/cli/SetupService.js.map +1 -1
  11. package/dist/lib/cli/UpgradeService.d.ts.map +1 -1
  12. package/dist/lib/cli/UpgradeService.js +3 -2
  13. package/dist/lib/cli/UpgradeService.js.map +1 -1
  14. package/dist/lib/cli/deploy/FileDeployer.d.ts.map +1 -1
  15. package/dist/lib/cli/deploy/FileDeployer.js +6 -4
  16. package/dist/lib/cli/deploy/FileDeployer.js.map +1 -1
  17. package/dist/lib/cli/deploy/FileManifest.d.ts.map +1 -1
  18. package/dist/lib/cli/deploy/FileManifest.js +3 -2
  19. package/dist/lib/cli/deploy/FileManifest.js.map +1 -1
  20. package/dist/lib/core/capability/CapabilityProbe.d.ts +13 -0
  21. package/dist/lib/core/capability/CapabilityProbe.d.ts.map +1 -1
  22. package/dist/lib/core/capability/CapabilityProbe.js +36 -17
  23. package/dist/lib/core/capability/CapabilityProbe.js.map +1 -1
  24. package/dist/lib/external/mcp/McpServer.d.ts +13 -0
  25. package/dist/lib/external/mcp/McpServer.d.ts.map +1 -1
  26. package/dist/lib/external/mcp/McpServer.js +44 -3
  27. package/dist/lib/external/mcp/McpServer.js.map +1 -1
  28. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.d.ts.map +1 -1
  29. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js +16 -1
  30. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js.map +1 -1
  31. package/dist/lib/external/mcp/handlers/bootstrap-external.js.map +1 -1
  32. package/dist/lib/external/mcp/handlers/consolidated.d.ts +22 -24
  33. package/dist/lib/external/mcp/handlers/consolidated.d.ts.map +1 -1
  34. package/dist/lib/external/mcp/handlers/dimension-complete-external.js.map +1 -1
  35. package/dist/lib/external/mcp/handlers/search.d.ts +115 -39
  36. package/dist/lib/external/mcp/handlers/search.d.ts.map +1 -1
  37. package/dist/lib/external/mcp/handlers/search.js +107 -190
  38. package/dist/lib/external/mcp/handlers/search.js.map +1 -1
  39. package/dist/lib/external/mcp/handlers/task.d.ts +3 -0
  40. package/dist/lib/external/mcp/handlers/task.d.ts.map +1 -1
  41. package/dist/lib/external/mcp/handlers/task.js +10 -1
  42. package/dist/lib/external/mcp/handlers/task.js.map +1 -1
  43. package/dist/lib/external/mcp/handlers/wiki-external.d.ts.map +1 -1
  44. package/dist/lib/external/mcp/handlers/wiki-external.js +4 -3
  45. package/dist/lib/external/mcp/handlers/wiki-external.js.map +1 -1
  46. package/dist/lib/http/HttpServer.js +2 -2
  47. package/dist/lib/http/HttpServer.js.map +1 -1
  48. package/dist/lib/http/middleware/gatewayMiddleware.js +2 -2
  49. package/dist/lib/http/middleware/gatewayMiddleware.js.map +1 -1
  50. package/dist/lib/http/routes/ai.js +3 -3
  51. package/dist/lib/http/routes/ai.js.map +1 -1
  52. package/dist/lib/http/routes/candidates.d.ts.map +1 -1
  53. package/dist/lib/http/routes/candidates.js +3 -1
  54. package/dist/lib/http/routes/candidates.js.map +1 -1
  55. package/dist/lib/http/routes/commands.d.ts.map +1 -1
  56. package/dist/lib/http/routes/commands.js +37 -9
  57. package/dist/lib/http/routes/commands.js.map +1 -1
  58. package/dist/lib/http/routes/guard.d.ts.map +1 -1
  59. package/dist/lib/http/routes/guard.js.map +1 -1
  60. package/dist/lib/http/routes/guardRules.d.ts.map +1 -1
  61. package/dist/lib/http/routes/guardRules.js +7 -7
  62. package/dist/lib/http/routes/guardRules.js.map +1 -1
  63. package/dist/lib/http/routes/knowledge.d.ts.map +1 -1
  64. package/dist/lib/http/routes/knowledge.js +62 -18
  65. package/dist/lib/http/routes/knowledge.js.map +1 -1
  66. package/dist/lib/http/routes/modules.d.ts.map +1 -1
  67. package/dist/lib/http/routes/modules.js +7 -5
  68. package/dist/lib/http/routes/modules.js.map +1 -1
  69. package/dist/lib/http/routes/recipes.js +1 -1
  70. package/dist/lib/http/routes/recipes.js.map +1 -1
  71. package/dist/lib/http/routes/remote.d.ts.map +1 -1
  72. package/dist/lib/http/routes/remote.js +1 -1
  73. package/dist/lib/http/routes/remote.js.map +1 -1
  74. package/dist/lib/http/routes/search.d.ts.map +1 -1
  75. package/dist/lib/http/routes/search.js +31 -23
  76. package/dist/lib/http/routes/search.js.map +1 -1
  77. package/dist/lib/http/routes/snippets.js +2 -2
  78. package/dist/lib/http/routes/snippets.js.map +1 -1
  79. package/dist/lib/http/routes/task.js.map +1 -1
  80. package/dist/lib/http/routes/violations.js +2 -2
  81. package/dist/lib/http/routes/violations.js.map +1 -1
  82. package/dist/lib/http/routes/wiki.d.ts.map +1 -1
  83. package/dist/lib/http/routes/wiki.js +3 -2
  84. package/dist/lib/http/routes/wiki.js.map +1 -1
  85. package/dist/lib/http/utils/routeHelpers.d.ts +2 -2
  86. package/dist/lib/http/utils/routeHelpers.js +2 -2
  87. package/dist/lib/http/utils/routeHelpers.js.map +1 -1
  88. package/dist/lib/infrastructure/config/Defaults.d.ts +3 -0
  89. package/dist/lib/infrastructure/config/Defaults.d.ts.map +1 -1
  90. package/dist/lib/infrastructure/config/Defaults.js +10 -6
  91. package/dist/lib/infrastructure/config/Defaults.js.map +1 -1
  92. package/dist/lib/infrastructure/config/Paths.d.ts +1 -1
  93. package/dist/lib/infrastructure/config/Paths.d.ts.map +1 -1
  94. package/dist/lib/infrastructure/config/Paths.js +4 -16
  95. package/dist/lib/infrastructure/config/Paths.js.map +1 -1
  96. package/dist/lib/infrastructure/vector/HnswVectorAdapter.d.ts +4 -1
  97. package/dist/lib/infrastructure/vector/HnswVectorAdapter.d.ts.map +1 -1
  98. package/dist/lib/infrastructure/vector/HnswVectorAdapter.js +26 -6
  99. package/dist/lib/infrastructure/vector/HnswVectorAdapter.js.map +1 -1
  100. package/dist/lib/infrastructure/vector/IndexingPipeline.d.ts +20 -0
  101. package/dist/lib/infrastructure/vector/IndexingPipeline.d.ts.map +1 -1
  102. package/dist/lib/infrastructure/vector/IndexingPipeline.js +65 -3
  103. package/dist/lib/infrastructure/vector/IndexingPipeline.js.map +1 -1
  104. package/dist/lib/infrastructure/vector/JsonVectorAdapter.d.ts +1 -1
  105. package/dist/lib/infrastructure/vector/JsonVectorAdapter.js +1 -1
  106. package/dist/lib/injection/ServiceContainer.d.ts +12 -2
  107. package/dist/lib/injection/ServiceContainer.d.ts.map +1 -1
  108. package/dist/lib/injection/ServiceContainer.js +10 -85
  109. package/dist/lib/injection/ServiceContainer.js.map +1 -1
  110. package/dist/lib/injection/ServiceMap.d.ts +124 -0
  111. package/dist/lib/injection/ServiceMap.d.ts.map +1 -0
  112. package/dist/lib/injection/ServiceMap.js +10 -0
  113. package/dist/lib/injection/ServiceMap.js.map +1 -0
  114. package/dist/lib/injection/modules/AiModule.d.ts +36 -0
  115. package/dist/lib/injection/modules/AiModule.d.ts.map +1 -0
  116. package/dist/lib/injection/modules/AiModule.js +99 -0
  117. package/dist/lib/injection/modules/AiModule.js.map +1 -0
  118. package/dist/lib/injection/modules/AppModule.js.map +1 -1
  119. package/dist/lib/injection/modules/GuardModule.js.map +1 -1
  120. package/dist/lib/injection/modules/KnowledgeModule.d.ts +1 -1
  121. package/dist/lib/injection/modules/KnowledgeModule.d.ts.map +1 -1
  122. package/dist/lib/injection/modules/KnowledgeModule.js +4 -10
  123. package/dist/lib/injection/modules/KnowledgeModule.js.map +1 -1
  124. package/dist/lib/injection/modules/VectorModule.d.ts +20 -0
  125. package/dist/lib/injection/modules/VectorModule.d.ts.map +1 -0
  126. package/dist/lib/injection/modules/VectorModule.js +74 -0
  127. package/dist/lib/injection/modules/VectorModule.js.map +1 -0
  128. package/dist/lib/platform/ios/routes/spm.d.ts.map +1 -1
  129. package/dist/lib/platform/ios/routes/spm.js +7 -5
  130. package/dist/lib/platform/ios/routes/spm.js.map +1 -1
  131. package/dist/lib/service/agent/AgentRuntime.d.ts +3 -73
  132. package/dist/lib/service/agent/AgentRuntime.d.ts.map +1 -1
  133. package/dist/lib/service/agent/AgentRuntime.js +2 -2
  134. package/dist/lib/service/agent/AgentRuntime.js.map +1 -1
  135. package/dist/lib/service/agent/AgentRuntimeTypes.d.ts +113 -0
  136. package/dist/lib/service/agent/AgentRuntimeTypes.d.ts.map +1 -0
  137. package/dist/lib/service/agent/AgentRuntimeTypes.js +11 -0
  138. package/dist/lib/service/agent/AgentRuntimeTypes.js.map +1 -0
  139. package/dist/lib/service/agent/PipelineStrategy.d.ts +1 -1
  140. package/dist/lib/service/agent/PipelineStrategy.d.ts.map +1 -1
  141. package/dist/lib/service/agent/PipelineStrategy.js +3 -3
  142. package/dist/lib/service/agent/PipelineStrategy.js.map +1 -1
  143. package/dist/lib/service/agent/core/ChatAgentPrompts.d.ts +2 -2
  144. package/dist/lib/service/agent/core/ChatAgentPrompts.d.ts.map +1 -1
  145. package/dist/lib/service/agent/core/ChatAgentPrompts.js +2 -2
  146. package/dist/lib/service/agent/core/ChatAgentPrompts.js.map +1 -1
  147. package/dist/lib/service/agent/domain/insight-analyst.d.ts +3 -3
  148. package/dist/lib/service/agent/domain/insight-analyst.d.ts.map +1 -1
  149. package/dist/lib/service/agent/domain/insight-analyst.js +3 -3
  150. package/dist/lib/service/agent/domain/insight-analyst.js.map +1 -1
  151. package/dist/lib/service/agent/memory/MemoryCoordinator.d.ts +3 -3
  152. package/dist/lib/service/agent/memory/MemoryCoordinator.d.ts.map +1 -1
  153. package/dist/lib/service/agent/memory/MemoryCoordinator.js +6 -6
  154. package/dist/lib/service/agent/memory/MemoryCoordinator.js.map +1 -1
  155. package/dist/lib/service/agent/memory/MemoryRetriever.d.ts +18 -12
  156. package/dist/lib/service/agent/memory/MemoryRetriever.d.ts.map +1 -1
  157. package/dist/lib/service/agent/memory/MemoryRetriever.js +70 -17
  158. package/dist/lib/service/agent/memory/MemoryRetriever.js.map +1 -1
  159. package/dist/lib/service/agent/memory/MemoryStore.d.ts +38 -0
  160. package/dist/lib/service/agent/memory/MemoryStore.d.ts.map +1 -1
  161. package/dist/lib/service/agent/memory/MemoryStore.js +70 -3
  162. package/dist/lib/service/agent/memory/MemoryStore.js.map +1 -1
  163. package/dist/lib/service/agent/memory/PersistentMemory.d.ts +18 -4
  164. package/dist/lib/service/agent/memory/PersistentMemory.d.ts.map +1 -1
  165. package/dist/lib/service/agent/memory/PersistentMemory.js +24 -4
  166. package/dist/lib/service/agent/memory/PersistentMemory.js.map +1 -1
  167. package/dist/lib/service/agent/presets.d.ts +2 -2
  168. package/dist/lib/service/agent/tools/index.d.ts +0 -5
  169. package/dist/lib/service/agent/tools/index.d.ts.map +1 -1
  170. package/dist/lib/service/agent/tools/query.d.ts +0 -5
  171. package/dist/lib/service/agent/tools/query.d.ts.map +1 -1
  172. package/dist/lib/service/agent/tools/query.js +41 -32
  173. package/dist/lib/service/agent/tools/query.js.map +1 -1
  174. package/dist/lib/service/automation/FileWatcher.js +9 -9
  175. package/dist/lib/service/automation/FileWatcher.js.map +1 -1
  176. package/dist/lib/service/automation/handlers/AlinkHandler.d.ts.map +1 -1
  177. package/dist/lib/service/automation/handlers/AlinkHandler.js +1 -1
  178. package/dist/lib/service/automation/handlers/AlinkHandler.js.map +1 -1
  179. package/dist/lib/service/automation/handlers/GuardHandler.js +1 -1
  180. package/dist/lib/service/automation/handlers/GuardHandler.js.map +1 -1
  181. package/dist/lib/service/automation/handlers/SearchHandler.d.ts.map +1 -1
  182. package/dist/lib/service/automation/handlers/SearchHandler.js +10 -10
  183. package/dist/lib/service/automation/handlers/SearchHandler.js.map +1 -1
  184. package/dist/lib/service/cursor/CursorDeliveryPipeline.d.ts.map +1 -1
  185. package/dist/lib/service/cursor/CursorDeliveryPipeline.js +2 -1
  186. package/dist/lib/service/cursor/CursorDeliveryPipeline.js.map +1 -1
  187. package/dist/lib/service/cursor/SkillsSyncer.d.ts.map +1 -1
  188. package/dist/lib/service/cursor/SkillsSyncer.js +2 -1
  189. package/dist/lib/service/cursor/SkillsSyncer.js.map +1 -1
  190. package/dist/lib/service/guard/ExclusionManager.d.ts.map +1 -1
  191. package/dist/lib/service/guard/ExclusionManager.js +2 -1
  192. package/dist/lib/service/guard/ExclusionManager.js.map +1 -1
  193. package/dist/lib/service/guard/RuleLearner.d.ts.map +1 -1
  194. package/dist/lib/service/guard/RuleLearner.js +2 -1
  195. package/dist/lib/service/guard/RuleLearner.js.map +1 -1
  196. package/dist/lib/service/knowledge/KnowledgeService.d.ts +5 -0
  197. package/dist/lib/service/knowledge/KnowledgeService.d.ts.map +1 -1
  198. package/dist/lib/service/knowledge/KnowledgeService.js +27 -0
  199. package/dist/lib/service/knowledge/KnowledgeService.js.map +1 -1
  200. package/dist/lib/service/module/ModuleService.d.ts.map +1 -1
  201. package/dist/lib/service/module/ModuleService.js +1 -0
  202. package/dist/lib/service/module/ModuleService.js.map +1 -1
  203. package/dist/lib/service/quality/FeedbackCollector.d.ts.map +1 -1
  204. package/dist/lib/service/quality/FeedbackCollector.js +2 -1
  205. package/dist/lib/service/quality/FeedbackCollector.js.map +1 -1
  206. package/dist/lib/service/search/BM25Scorer.d.ts +52 -0
  207. package/dist/lib/service/search/BM25Scorer.d.ts.map +1 -0
  208. package/dist/lib/service/search/BM25Scorer.js +155 -0
  209. package/dist/lib/service/search/BM25Scorer.js.map +1 -0
  210. package/dist/lib/service/search/CrossEncoderReranker.js +1 -1
  211. package/dist/lib/service/search/CrossEncoderReranker.js.map +1 -1
  212. package/dist/lib/service/search/MultiSignalRanker.d.ts +7 -0
  213. package/dist/lib/service/search/MultiSignalRanker.d.ts.map +1 -1
  214. package/dist/lib/service/search/MultiSignalRanker.js +37 -18
  215. package/dist/lib/service/search/MultiSignalRanker.js.map +1 -1
  216. package/dist/lib/service/search/SearchEngine.d.ts +15 -215
  217. package/dist/lib/service/search/SearchEngine.d.ts.map +1 -1
  218. package/dist/lib/service/search/SearchEngine.js +127 -270
  219. package/dist/lib/service/search/SearchEngine.js.map +1 -1
  220. package/dist/lib/service/search/SearchTypes.d.ts +258 -0
  221. package/dist/lib/service/search/SearchTypes.d.ts.map +1 -0
  222. package/dist/lib/service/search/SearchTypes.js +50 -0
  223. package/dist/lib/service/search/SearchTypes.js.map +1 -0
  224. package/dist/lib/service/search/contextBoost.d.ts +1 -1
  225. package/dist/lib/service/search/contextBoost.js +2 -2
  226. package/dist/lib/service/search/contextBoost.js.map +1 -1
  227. package/dist/lib/service/search/tokenizer.d.ts +18 -0
  228. package/dist/lib/service/search/tokenizer.d.ts.map +1 -0
  229. package/dist/lib/service/search/tokenizer.js +215 -0
  230. package/dist/lib/service/search/tokenizer.js.map +1 -0
  231. package/dist/lib/service/task/TaskGraphService.d.ts +15 -6
  232. package/dist/lib/service/task/TaskGraphService.d.ts.map +1 -1
  233. package/dist/lib/service/task/TaskGraphService.js +55 -5
  234. package/dist/lib/service/task/TaskGraphService.js.map +1 -1
  235. package/dist/lib/service/task/TaskKnowledgeBridge.d.ts +90 -25
  236. package/dist/lib/service/task/TaskKnowledgeBridge.d.ts.map +1 -1
  237. package/dist/lib/service/task/TaskKnowledgeBridge.js +253 -35
  238. package/dist/lib/service/task/TaskKnowledgeBridge.js.map +1 -1
  239. package/dist/lib/service/vector/ContextualEnricher.d.ts +62 -0
  240. package/dist/lib/service/vector/ContextualEnricher.d.ts.map +1 -0
  241. package/dist/lib/service/vector/ContextualEnricher.js +150 -0
  242. package/dist/lib/service/vector/ContextualEnricher.js.map +1 -0
  243. package/dist/lib/service/vector/SyncCoordinator.d.ts +63 -0
  244. package/dist/lib/service/vector/SyncCoordinator.d.ts.map +1 -0
  245. package/dist/lib/service/vector/SyncCoordinator.js +290 -0
  246. package/dist/lib/service/vector/SyncCoordinator.js.map +1 -0
  247. package/dist/lib/service/vector/VectorService.d.ts +176 -0
  248. package/dist/lib/service/vector/VectorService.d.ts.map +1 -0
  249. package/dist/lib/service/vector/VectorService.js +456 -0
  250. package/dist/lib/service/vector/VectorService.js.map +1 -0
  251. package/dist/lib/service/wiki/WikiGenerator.d.ts.map +1 -1
  252. package/dist/lib/service/wiki/WikiGenerator.js +2 -1
  253. package/dist/lib/service/wiki/WikiGenerator.js.map +1 -1
  254. package/dist/lib/service/wiki/WikiRenderers.d.ts +4 -128
  255. package/dist/lib/service/wiki/WikiRenderers.d.ts.map +1 -1
  256. package/dist/lib/service/wiki/WikiRenderers.js +2 -0
  257. package/dist/lib/service/wiki/WikiRenderers.js.map +1 -1
  258. package/dist/lib/service/wiki/WikiTypes.d.ts +146 -0
  259. package/dist/lib/service/wiki/WikiTypes.d.ts.map +1 -0
  260. package/dist/lib/service/wiki/WikiTypes.js +10 -0
  261. package/dist/lib/service/wiki/WikiTypes.js.map +1 -0
  262. package/dist/lib/service/wiki/WikiUtils.d.ts.map +1 -1
  263. package/dist/lib/service/wiki/WikiUtils.js +2 -1
  264. package/dist/lib/service/wiki/WikiUtils.js.map +1 -1
  265. package/dist/lib/shared/PathGuard.d.ts.map +1 -1
  266. package/dist/lib/shared/PathGuard.js +8 -17
  267. package/dist/lib/shared/PathGuard.js.map +1 -1
  268. package/dist/lib/shared/ProjectMarkers.d.ts +67 -0
  269. package/dist/lib/shared/ProjectMarkers.d.ts.map +1 -0
  270. package/dist/lib/shared/ProjectMarkers.js +142 -0
  271. package/dist/lib/shared/ProjectMarkers.js.map +1 -0
  272. package/dist/lib/shared/schemas/mcp-tools.d.ts +3 -0
  273. package/dist/lib/shared/schemas/mcp-tools.d.ts.map +1 -1
  274. package/dist/lib/shared/schemas/mcp-tools.js +6 -0
  275. package/dist/lib/shared/schemas/mcp-tools.js.map +1 -1
  276. package/package.json +1 -1
  277. package/templates/constitution.yaml +23 -2
  278. package/dist/lib/service/search/InvertedIndex.d.ts +0 -34
  279. package/dist/lib/service/search/InvertedIndex.d.ts.map +0 -1
  280. package/dist/lib/service/search/InvertedIndex.js +0 -83
  281. package/dist/lib/service/search/InvertedIndex.js.map +0 -1
  282. package/dist/lib/service/search/RetrievalFunnel.d.ts +0 -26
  283. package/dist/lib/service/search/RetrievalFunnel.d.ts.map +0 -1
  284. package/dist/lib/service/search/RetrievalFunnel.js +0 -77
  285. package/dist/lib/service/search/RetrievalFunnel.js.map +0 -1
@@ -1,17 +1,47 @@
1
+ import { slimSearchResult } from '#service/search/SearchTypes.js';
1
2
  import { ioLimit } from '#shared/concurrency.js';
2
3
  import Logger from '../../infrastructure/logging/Logger.js';
4
+ // ─── Constants ──────────────────────────────────────────
5
+ /**
6
+ * 搜索结果相关性阈值 — 低于此分数的结果不注入
7
+ *
8
+ * 真实分数分布 (BiliDemo, auto 模式 RRF+Ranking):
9
+ * min=0.434 P10=0.453 P25=0.460 median=0.479 P75=0.495 P90=0.505 max=0.534
10
+ * 所有结果集中在 [0.43, 0.54],0.15 无法过滤任何噪声。
11
+ *
12
+ * 阈值设定依据:
13
+ * 0.44 — 过滤掉最边缘的低质量尾部结果(约过滤 P5 以下)
14
+ */
15
+ const RELEVANCE_THRESHOLD = 0.44;
16
+ /** 缓存 TTL (ms) — 5 分钟 */
17
+ const CACHE_TTL_MS = 300_000;
18
+ /** 技术术语提取正则 */
19
+ const TECH_TERM_PATTERNS = [
20
+ // CamelCase 类名 — 含常见 iOS/Android/Web 后缀
21
+ /\b[A-Z][a-zA-Z]+(?:Controller|ViewController|Service|Manager|Handler|View|Model|Request|Response|Provider|Repository|Factory|Builder|Delegate|Protocol|Router|Coordinator|Cell|Layout|Adapter|Module|Plugin|Monitor|Loader|Store|Cache|Config|Helper|Util|Extension|Category)\b/g,
22
+ // BD / UI / NS 前缀类名 (常见 iOS 项目)
23
+ /\b(?:BD|UI|NS|CG|CA|MK|AV|WK|SK|CL)[A-Z][a-zA-Z]{2,}\b/g,
24
+ // 反引号包裹的代码引用
25
+ /`([^`]+)`/g,
26
+ // 文件名引用 (xxx.swift / xxx.ts / xxx.json 等)
27
+ /\b[\w.-]+\.(?:swift|ts|tsx|js|jsx|py|java|kt|go|rs|rb|cpp|h|m|mm|json|yaml|yml|xml|gradle|plist|xib|storyboard)\b/g,
28
+ ];
3
29
  /**
4
30
  * TaskKnowledgeBridge — 任务 ↔ 知识桥接服务
5
31
  *
6
32
  * AutoSnippet 独有能力:返回「带知识上下文的任务」,而非裸任务。
7
33
  *
8
- * 桥接策略:
9
- * 1. 任务标题/描述 搜索知识库关联 pattern/rule/fact
10
- * 2. 关联的 Guard 规则嵌入任务上下文
34
+ * 桥接策略(v2 — 用户输入感知 + Multi-Query + 上下文透传 + 缓存):
35
+ * 1. 任务标题/描述 + 用户输入(userQuery)Multi-Query 搜索知识库
36
+ * 2. 传递 language / intent 上下文信号 SearchEngine ContextBoost 生效
37
+ * 3. 关联的 Guard 规则 → 优先嵌入任务上下文
38
+ * 4. 任务级缓存 → 避免重复搜索
11
39
  */
12
40
  export class TaskKnowledgeBridge {
13
41
  _search;
14
42
  logger;
43
+ /** 任务级知识缓存 (taskId → CacheEntry) */
44
+ _cache = new Map();
15
45
  /**
16
46
  * @param {import('../../service/search/SearchEngine.js').SearchEngine} searchEngine
17
47
  */
@@ -23,17 +53,17 @@ export class TaskKnowledgeBridge {
23
53
  * 为就绪任务附加知识上下文
24
54
  * 并行搜索,不阻塞主流程
25
55
  *
26
- * @param {import('../../domain/task/Task.js').Task[]} tasks
27
- * @returns {Promise<import('../../domain/task/Task.js').Task[]>}
56
+ * @param tasks 需要注入知识的任务列表
57
+ * @param options 上下文选项(userQuery / activeFile / language)
28
58
  */
29
- async enrichWithKnowledge(tasks) {
59
+ async enrichWithKnowledge(tasks, options) {
30
60
  if (!tasks || tasks.length === 0) {
31
61
  return tasks;
32
62
  }
33
63
  if (!this._search) {
34
64
  return tasks;
35
65
  }
36
- const results = await Promise.allSettled(tasks.map((task) => ioLimit(() => this._buildContext(task))));
66
+ const results = await Promise.allSettled(tasks.map((task) => ioLimit(() => this._buildContext(task, options))));
37
67
  return tasks.map((task, i) => {
38
68
  if (results[i].status === 'fulfilled' && results[i].value) {
39
69
  task.knowledgeContext = results[i].value;
@@ -42,42 +72,94 @@ export class TaskKnowledgeBridge {
42
72
  });
43
73
  }
44
74
  /**
45
- * 为单个任务构建知识上下文
46
- * @private
75
+ * 独立搜索 — 仅基于 userQuery 搜索知识(不依赖任何 Task)
76
+ *
77
+ * 场景: prime() 时没有 ready tasks 但有用户输入,直接搜索知识库。
78
+ *
79
+ * @param userQuery 用户输入的原始文本
80
+ * @param options 可选的 language
47
81
  */
48
- async _buildContext(task) {
49
- const query = `${task.title} ${task.description}`.trim();
50
- if (!query) {
82
+ async searchForQuery(userQuery, options) {
83
+ if (!this._search || !userQuery?.trim()) {
51
84
  return null;
52
85
  }
53
86
  try {
54
- const searchResult = await this._search.search(query, {
87
+ const searchResult = await this._search.search(userQuery.trim(), {
55
88
  mode: 'auto',
56
- limit: 5,
89
+ limit: 8,
90
+ rank: true,
91
+ context: {
92
+ language: options?.language,
93
+ intent: 'user-query-knowledge',
94
+ },
57
95
  });
58
- const allResults = (searchResult?.items || searchResult?.results || []);
59
- const knowledge = allResults
60
- .filter((r) => r.kind !== 'rule')
61
- .slice(0, 3);
62
- const guardRules = allResults
63
- .filter((r) => r.kind === 'rule')
64
- .slice(0, 5);
96
+ const allResults = (searchResult?.items || searchResult?.results || []).filter((r) => this._aboveThreshold(r));
97
+ if (allResults.length === 0) {
98
+ return null;
99
+ }
100
+ const knowledge = allResults.filter((r) => r.kind !== 'rule').slice(0, 5);
101
+ const guardRules = allResults.filter((r) => r.kind === 'rule').slice(0, 3);
65
102
  return {
66
- relatedKnowledge: knowledge.map((k) => ({
67
- id: k.id,
68
- title: k.title,
69
- kind: k.kind,
70
- trigger: k.trigger,
71
- actionHint: k.actionHint || k.doClause || '',
72
- })),
73
- guardRules: guardRules.map((r) => ({
74
- id: r.id,
75
- title: r.title,
76
- trigger: r.trigger,
77
- actionHint: r.actionHint || r.doClause || '',
78
- })),
79
- searchQuery: query,
103
+ relatedKnowledge: knowledge.map((k) => this._projectItem(k)),
104
+ guardRules: guardRules.map((r) => this._projectItem(r)),
105
+ searchQuery: userQuery.trim(),
106
+ };
107
+ }
108
+ catch (err) {
109
+ this.logger.debug('TaskKnowledgeBridge.searchForQuery error', {
110
+ error: err.message,
111
+ });
112
+ return null;
113
+ }
114
+ }
115
+ // ═══ 私有方法 ═══════════════════════════════════════
116
+ /**
117
+ * 为单个任务构建知识上下文(v2 — multi-query + 上下文 + 缓存)
118
+ * @private
119
+ */
120
+ async _buildContext(task, options) {
121
+ const taskQuery = `${task.title} ${task.description}`.trim();
122
+ if (!taskQuery && !options?.userQuery) {
123
+ return null;
124
+ }
125
+ // ── P6: 缓存检查 ──
126
+ const contentKey = this._contentKey(taskQuery, options?.userQuery);
127
+ if (task.id) {
128
+ const cached = this._cache.get(task.id);
129
+ if (cached &&
130
+ cached.contentKey === contentKey &&
131
+ Date.now() - cached.timestamp < CACHE_TTL_MS) {
132
+ return cached.context;
133
+ }
134
+ }
135
+ try {
136
+ // ── P2: Multi-Query 策略 ──
137
+ const queries = this._buildSearchQueries(task, options?.userQuery);
138
+ const allResults = await this._multiQuerySearch(queries, {
139
+ language: options?.language,
140
+ });
141
+ // ── P4: 相关性阈值过滤 ──
142
+ const filtered = allResults.filter((r) => this._aboveThreshold(r));
143
+ // ── P4: 分类 & 增强投影 ──
144
+ const knowledge = filtered.filter((r) => r.kind !== 'rule').slice(0, 5);
145
+ const guardRules = filtered.filter((r) => r.kind === 'rule').slice(0, 3);
146
+ const context = {
147
+ relatedKnowledge: knowledge.map((k) => this._projectItem(k)),
148
+ guardRules: guardRules.map((r) => this._projectItem(r)),
149
+ searchQuery: queries.join(' | '),
80
150
  };
151
+ // ── P6: 写入缓存 ──
152
+ if (task.id) {
153
+ this._cache.set(task.id, { context, contentKey, timestamp: Date.now() });
154
+ // 限制缓存大小 — 超出 100 条时淘汰最旧的
155
+ if (this._cache.size > 100) {
156
+ const firstKey = this._cache.keys().next().value;
157
+ if (firstKey !== undefined) {
158
+ this._cache.delete(firstKey);
159
+ }
160
+ }
161
+ }
162
+ return context;
81
163
  }
82
164
  catch (err) {
83
165
  this.logger.debug('TaskKnowledgeBridge._buildContext error', {
@@ -87,6 +169,142 @@ export class TaskKnowledgeBridge {
87
169
  return null;
88
170
  }
89
171
  }
172
+ /**
173
+ * P2: 构建多条互补搜索查询
174
+ *
175
+ * 策略:
176
+ * Q1 (精确): 任务标题 — 通常最精练
177
+ * Q2 (语义): 用户输入 — 包含更丰富的自然语义
178
+ * Q3 (关键词): 从描述/用户输入提取技术术语
179
+ *
180
+ * @private
181
+ */
182
+ _buildSearchQueries(task, userQuery) {
183
+ const queries = [];
184
+ // Q1: 任务标题(最精练)
185
+ const title = task.title?.trim();
186
+ if (title) {
187
+ queries.push(title);
188
+ }
189
+ // Q2: 用户原始输入(与标题不同才添加)
190
+ const uq = userQuery?.trim();
191
+ if (uq && uq !== title) {
192
+ queries.push(uq);
193
+ }
194
+ // Q3: 技术术语提取 — 从描述 + 用户输入中提取
195
+ const corpus = [task.description, userQuery].filter(Boolean).join(' ');
196
+ const techTerms = this._extractTechTerms(corpus);
197
+ if (techTerms.length > 0) {
198
+ const termQuery = techTerms.join(' ');
199
+ // 避免与已有查询重复
200
+ if (!queries.includes(termQuery)) {
201
+ queries.push(termQuery);
202
+ }
203
+ }
204
+ // 兜底: 若上述都为空,用 title + description
205
+ if (queries.length === 0) {
206
+ const fallback = `${task.title} ${task.description}`.trim();
207
+ if (fallback) {
208
+ queries.push(fallback);
209
+ }
210
+ }
211
+ return queries;
212
+ }
213
+ /**
214
+ * P2: 从文本中提取技术术语(类名、文件名、API 名等)
215
+ * @private
216
+ */
217
+ _extractTechTerms(text) {
218
+ if (!text) {
219
+ return [];
220
+ }
221
+ const terms = new Set();
222
+ for (const pattern of TECH_TERM_PATTERNS) {
223
+ // 重置 lastIndex(全局正则复用安全)
224
+ pattern.lastIndex = 0;
225
+ let match;
226
+ while ((match = pattern.exec(text)) !== null) {
227
+ // 优先取捕获组(反引号中的内容),否则取整个匹配
228
+ const term = (match[1] || match[0]).trim();
229
+ if (term.length >= 2) {
230
+ terms.add(term);
231
+ }
232
+ }
233
+ }
234
+ return [...terms].slice(0, 8); // 最多 8 个术语
235
+ }
236
+ /**
237
+ * P2 + P3: Multi-Query 搜索 + 合并去重
238
+ *
239
+ * 对每个 query 执行搜索(并行),合并结果并按 score 去重保留最高分。
240
+ * @private
241
+ */
242
+ async _multiQuerySearch(queries, options) {
243
+ if (queries.length === 0) {
244
+ return [];
245
+ }
246
+ // 单 query 直接搜索(优化常见情况)
247
+ if (queries.length === 1) {
248
+ return this._singleSearch(queries[0], options);
249
+ }
250
+ // 多 query 并行搜索
251
+ const searchPromises = queries.map((q) => this._singleSearch(q, options).catch(() => []));
252
+ const resultSets = await Promise.all(searchPromises);
253
+ // 合并去重 — 按 id 保留最高 score
254
+ const merged = new Map();
255
+ for (const results of resultSets) {
256
+ for (const item of results) {
257
+ const existing = merged.get(item.id);
258
+ if (!existing || item.score > existing.score) {
259
+ merged.set(item.id, item);
260
+ }
261
+ }
262
+ }
263
+ // 按 score 降序排序
264
+ return [...merged.values()].sort((a, b) => (b.score || 0) - (a.score || 0));
265
+ }
266
+ /**
267
+ * 执行单次搜索(含 P3 上下文透传)
268
+ * @private
269
+ */
270
+ async _singleSearch(query, options) {
271
+ const searchResult = await this._search.search(query, {
272
+ mode: 'auto',
273
+ limit: 8,
274
+ rank: true,
275
+ context: {
276
+ language: options.language,
277
+ intent: 'task-knowledge',
278
+ },
279
+ });
280
+ return (searchResult?.items || searchResult?.results || []).slice(0, 8);
281
+ }
282
+ /**
283
+ * P4: 相关性阈值判断
284
+ * @private
285
+ */
286
+ _aboveThreshold(item) {
287
+ const score = item.score || 0;
288
+ return score >= RELEVANCE_THRESHOLD;
289
+ }
290
+ /**
291
+ * P4: 增强投影 — 使用统一 slimSearchResult() 投影函数
292
+ * @private
293
+ */
294
+ _projectItem(item) {
295
+ return slimSearchResult(item);
296
+ }
297
+ /**
298
+ * P6: 缓存键 — 基于 taskQuery + userQuery 的内容指纹
299
+ * @private
300
+ */
301
+ _contentKey(taskQuery, userQuery) {
302
+ return `${taskQuery}||${userQuery || ''}`;
303
+ }
304
+ /** 清除全部缓存(测试 / 索引重建后使用) */
305
+ clearCache() {
306
+ this._cache.clear();
307
+ }
90
308
  }
91
309
  export default TaskKnowledgeBridge;
92
310
  //# sourceMappingURL=TaskKnowledgeBridge.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TaskKnowledgeBridge.js","sourceRoot":"","sources":["../../../../lib/service/task/TaskKnowledgeBridge.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TaskKnowledgeBridge.js","sourceRoot":"","sources":["../../../../lib/service/task/TaskKnowledgeBridge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * ContextualEnricher — 上下文增强管线
3
+ *
4
+ * 基于 Anthropic Contextual Retrieval 论文 (2024-09) 的实现。
5
+ * 对每个 chunk 生成 50-100 token 的上下文前缀,使其嵌入时保留文档层面的语义。
6
+ *
7
+ * 效果: retrieval failure rate 降低 35-67% (with reranking)
8
+ *
9
+ * 成本控制:
10
+ * - 使用轻量模型 (Haiku/Gemini Flash)
11
+ * - Prompt Caching: 同一文档不同 chunk 共享 system prompt 缓存
12
+ * - 增量模式: 只对新增/变更 chunk 做 enrichment
13
+ * - 配置开关: contextualEnrich = false 时完全跳过
14
+ *
15
+ * @module service/vector/ContextualEnricher
16
+ */
17
+ export interface AiProviderLike {
18
+ chat(prompt: string, options?: {
19
+ system?: string;
20
+ maxTokens?: number;
21
+ temperature?: number;
22
+ }): Promise<string>;
23
+ }
24
+ export interface ChunkData {
25
+ content: string;
26
+ metadata: Record<string, unknown>;
27
+ }
28
+ export interface DocumentInfo {
29
+ title: string;
30
+ content: string;
31
+ kind: string;
32
+ sourcePath?: string;
33
+ }
34
+ export interface EnricherConfig {
35
+ aiProvider: AiProviderLike;
36
+ /** 缓存 enrichment 结果防止重复调用 */
37
+ cacheEnabled?: boolean;
38
+ }
39
+ export declare class ContextualEnricher {
40
+ #private;
41
+ constructor(config: EnricherConfig);
42
+ /**
43
+ * 为多个 chunks 生成上下文前缀
44
+ *
45
+ * 策略: 将整篇文档作为 system prompt,逐 chunk 请求上下文描述。
46
+ * 利用 Prompt Caching: 文档只需编码一次,后续 chunk 查询只需增量 tokens。
47
+ *
48
+ * @param document - 文档整体信息
49
+ * @param chunks - 分块后的内容数组
50
+ * @returns 带上下文前缀的 chunks
51
+ */
52
+ enrichChunks(document: DocumentInfo, chunks: ChunkData[]): Promise<ChunkData[]>;
53
+ /**
54
+ * 清除缓存
55
+ */
56
+ clearCache(): void;
57
+ /**
58
+ * 当前缓存大小
59
+ */
60
+ get cacheSize(): number;
61
+ }
62
+ //# sourceMappingURL=ContextualEnricher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ContextualEnricher.d.ts","sourceRoot":"","sources":["../../../../lib/service/vector/ContextualEnricher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,MAAM,WAAW,cAAc;IAC7B,IAAI,CACF,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GACtE,OAAO,CAAC,MAAM,CAAC,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,cAAc,CAAC;IAC3B,6BAA6B;IAC7B,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAID,qBAAa,kBAAkB;;gBAMjB,MAAM,EAAE,cAAc;IAMlC;;;;;;;;;OASG;IACG,YAAY,CAAC,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAiDrF;;OAEG;IACH,UAAU,IAAI,IAAI;IAIlB;;OAEG;IACH,IAAI,SAAS,IAAI,MAAM,CAEtB;CAgEF"}
@@ -0,0 +1,150 @@
1
+ /**
2
+ * ContextualEnricher — 上下文增强管线
3
+ *
4
+ * 基于 Anthropic Contextual Retrieval 论文 (2024-09) 的实现。
5
+ * 对每个 chunk 生成 50-100 token 的上下文前缀,使其嵌入时保留文档层面的语义。
6
+ *
7
+ * 效果: retrieval failure rate 降低 35-67% (with reranking)
8
+ *
9
+ * 成本控制:
10
+ * - 使用轻量模型 (Haiku/Gemini Flash)
11
+ * - Prompt Caching: 同一文档不同 chunk 共享 system prompt 缓存
12
+ * - 增量模式: 只对新增/变更 chunk 做 enrichment
13
+ * - 配置开关: contextualEnrich = false 时完全跳过
14
+ *
15
+ * @module service/vector/ContextualEnricher
16
+ */
17
+ import Logger from '../../infrastructure/logging/Logger.js';
18
+ // ── Enricher ──
19
+ export class ContextualEnricher {
20
+ #aiProvider;
21
+ #cache;
22
+ #cacheEnabled;
23
+ #logger = Logger.getInstance();
24
+ constructor(config) {
25
+ this.#aiProvider = config.aiProvider;
26
+ this.#cacheEnabled = config.cacheEnabled !== false;
27
+ this.#cache = new Map();
28
+ }
29
+ /**
30
+ * 为多个 chunks 生成上下文前缀
31
+ *
32
+ * 策略: 将整篇文档作为 system prompt,逐 chunk 请求上下文描述。
33
+ * 利用 Prompt Caching: 文档只需编码一次,后续 chunk 查询只需增量 tokens。
34
+ *
35
+ * @param document - 文档整体信息
36
+ * @param chunks - 分块后的内容数组
37
+ * @returns 带上下文前缀的 chunks
38
+ */
39
+ async enrichChunks(document, chunks) {
40
+ if (chunks.length === 0) {
41
+ return [];
42
+ }
43
+ const systemPrompt = this.#buildSystemPrompt(document);
44
+ const enriched = [];
45
+ for (const chunk of chunks) {
46
+ try {
47
+ // 检查缓存
48
+ const cacheKey = this.#cacheEnabled
49
+ ? this.#computeCacheKey(document.sourcePath || document.title, chunk.content)
50
+ : '';
51
+ let context;
52
+ if (this.#cacheEnabled && this.#cache.has(cacheKey)) {
53
+ context = this.#cache.get(cacheKey);
54
+ }
55
+ else {
56
+ context = await this.#generateContext(systemPrompt, chunk.content);
57
+ if (this.#cacheEnabled && context) {
58
+ this.#cache.set(cacheKey, context);
59
+ }
60
+ }
61
+ if (context) {
62
+ enriched.push({
63
+ content: `[${context.trim()}]\n\n${chunk.content}`,
64
+ metadata: {
65
+ ...chunk.metadata,
66
+ contextEnriched: true,
67
+ contextLength: context.length,
68
+ },
69
+ });
70
+ }
71
+ else {
72
+ enriched.push(chunk);
73
+ }
74
+ }
75
+ catch (err) {
76
+ // 单个 chunk enrichment 失败不阻塞整个流程
77
+ this.#logger.warn('[ContextualEnricher] Failed to enrich chunk', {
78
+ error: err instanceof Error ? err.message : String(err),
79
+ });
80
+ enriched.push(chunk);
81
+ }
82
+ }
83
+ return enriched;
84
+ }
85
+ /**
86
+ * 清除缓存
87
+ */
88
+ clearCache() {
89
+ this.#cache.clear();
90
+ }
91
+ /**
92
+ * 当前缓存大小
93
+ */
94
+ get cacheSize() {
95
+ return this.#cache.size;
96
+ }
97
+ // ═══ Private ═══
98
+ #buildSystemPrompt(document) {
99
+ // 截断过长文档(避免超出模型 context window)
100
+ const maxDocLen = 8000;
101
+ const docContent = document.content.length > maxDocLen
102
+ ? `${document.content.slice(0, maxDocLen)}\n\n[... document truncated ...]`
103
+ : document.content;
104
+ return [
105
+ `<document title="${this.#escapeXml(document.title)}" kind="${document.kind}">`,
106
+ docContent,
107
+ '</document>',
108
+ '',
109
+ 'Given the above document, provide 1-2 sentences of context that situate the following chunk within the document.',
110
+ 'Focus on: what topic/function/section this chunk belongs to, and any key entities or concepts referenced.',
111
+ 'Answer ONLY with the context sentences, nothing else.',
112
+ ].join('\n');
113
+ }
114
+ async #generateContext(systemPrompt, chunkContent) {
115
+ const userPrompt = `<chunk>\n${chunkContent}\n</chunk>`;
116
+ const response = await this.#aiProvider.chat(userPrompt, {
117
+ system: systemPrompt,
118
+ maxTokens: 120,
119
+ temperature: 0,
120
+ });
121
+ // 清理响应 — 移除可能的 XML tag 或多余引号
122
+ let cleaned = response.trim();
123
+ if (cleaned.startsWith('"') && cleaned.endsWith('"')) {
124
+ cleaned = cleaned.slice(1, -1);
125
+ }
126
+ // 限制长度
127
+ if (cleaned.length > 500) {
128
+ cleaned = cleaned.slice(0, 500);
129
+ }
130
+ return cleaned;
131
+ }
132
+ #computeCacheKey(sourcePath, content) {
133
+ // 简单的字符串 hash(不需要加密级别)
134
+ let hash = 0;
135
+ const str = `${sourcePath}::${content.slice(0, 200)}`;
136
+ for (let i = 0; i < str.length; i++) {
137
+ const char = str.charCodeAt(i);
138
+ hash = ((hash << 5) - hash + char) | 0;
139
+ }
140
+ return `ctx_${hash.toString(36)}`;
141
+ }
142
+ #escapeXml(str) {
143
+ return str
144
+ .replace(/&/g, '&amp;')
145
+ .replace(/</g, '&lt;')
146
+ .replace(/>/g, '&gt;')
147
+ .replace(/"/g, '&quot;');
148
+ }
149
+ }
150
+ //# sourceMappingURL=ContextualEnricher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ContextualEnricher.js","sourceRoot":"","sources":["../../../../lib/service/vector/ContextualEnricher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * SyncCoordinator — 知识 CRUD → 向量索引事件驱动同步
3
+ *
4
+ * 监听 EventBus 的 `knowledge:changed` 事件,
5
+ * debounce 合并后批量执行 chunk → embed → upsert/remove。
6
+ *
7
+ * 设计:
8
+ * - 2s debounce 窗口内合并多个 CRUD 事件
9
+ * - maxBatchSize(20) 达到时立即触发
10
+ * - 启动时可执行一次 DB↔Vector 对账
11
+ *
12
+ * @module service/vector/SyncCoordinator
13
+ */
14
+ import type { EventBus } from '../../infrastructure/event/EventBus.js';
15
+ import type { VectorStore } from '../../infrastructure/vector/VectorStore.js';
16
+ import type { ContextualEnricher } from './ContextualEnricher.js';
17
+ import type { EmbedProvider } from './VectorService.js';
18
+ export interface SyncCoordinatorConfig {
19
+ vectorStore: VectorStore;
20
+ embedProvider: EmbedProvider;
21
+ contextualEnricher: ContextualEnricher | null;
22
+ debounceMs: number;
23
+ maxBatchSize?: number;
24
+ }
25
+ export declare class SyncCoordinator {
26
+ #private;
27
+ constructor(config: SyncCoordinatorConfig);
28
+ /**
29
+ * 绑定 EventBus,开始监听知识变更事件
30
+ */
31
+ bindEventBus(eventBus: EventBus): void;
32
+ /**
33
+ * 手动触发立即刷入(用于测试或 shutdown 前确保数据落盘)
34
+ */
35
+ flush(): Promise<void>;
36
+ /**
37
+ * 启动对账: 比较 DB knowledge_entries 与向量索引,修复不一致
38
+ * - 孤儿向量 (在索引中但 DB 无对应) → 删除
39
+ * - 缺失向量 (在 DB 中但索引无对应) → 加入待同步队列
40
+ *
41
+ * @param db - 数据库连接 (better-sqlite3 style)
42
+ * @returns 对账结果
43
+ */
44
+ reconcile(db: {
45
+ prepare(sql: string): {
46
+ all(...args: unknown[]): Array<{
47
+ id: string;
48
+ title?: string;
49
+ content?: string;
50
+ kind?: string;
51
+ }>;
52
+ };
53
+ }): Promise<{
54
+ orphansRemoved: number;
55
+ missingSynced: number;
56
+ errors: string[];
57
+ }>;
58
+ /**
59
+ * 销毁: 清理定时器和事件监听
60
+ */
61
+ destroy(): void;
62
+ }
63
+ //# sourceMappingURL=SyncCoordinator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SyncCoordinator.d.ts","sourceRoot":"","sources":["../../../../lib/service/vector/SyncCoordinator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wCAAwC,CAAC;AAEvE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4CAA4C,CAAC;AAC9E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAIxD,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,WAAW,CAAC;IACzB,aAAa,EAAE,aAAa,CAAC;IAC7B,kBAAkB,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAC9C,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAaD,qBAAa,eAAe;;gBAad,MAAM,EAAE,qBAAqB;IAQzC;;OAEG;IACH,YAAY,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAuBtC;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ5B;;;;;;;OAOG;IACG,SAAS,CAAC,EAAE,EAAE;QAClB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG;YACpB,GAAG,CACD,GAAG,IAAI,EAAE,OAAO,EAAE,GACjB,KAAK,CAAC;gBAAE,EAAE,EAAE,MAAM,CAAC;gBAAC,KAAK,CAAC,EAAE,MAAM,CAAC;gBAAC,OAAO,CAAC,EAAE,MAAM,CAAC;gBAAC,IAAI,CAAC,EAAE,MAAM,CAAA;aAAE,CAAC,CAAC;SAC3E,CAAC;KACH,GAAG,OAAO,CAAC;QAAE,cAAc,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAkEhF;;OAEG;IACH,OAAO,IAAI,IAAI;CA6KhB"}