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.
- package/config/constitution.yaml +19 -0
- package/config/default.json +6 -1
- package/dist/bin/cli.d.ts +2 -1
- package/dist/bin/cli.d.ts.map +1 -1
- package/dist/bin/cli.js +231 -22
- package/dist/bin/cli.js.map +1 -1
- package/dist/lib/cli/SetupService.d.ts +70 -6
- package/dist/lib/cli/SetupService.d.ts.map +1 -1
- package/dist/lib/cli/SetupService.js +238 -50
- package/dist/lib/cli/SetupService.js.map +1 -1
- package/dist/lib/cli/UpgradeService.d.ts.map +1 -1
- package/dist/lib/cli/UpgradeService.js +3 -2
- package/dist/lib/cli/UpgradeService.js.map +1 -1
- package/dist/lib/cli/deploy/FileDeployer.d.ts.map +1 -1
- package/dist/lib/cli/deploy/FileDeployer.js +6 -4
- package/dist/lib/cli/deploy/FileDeployer.js.map +1 -1
- package/dist/lib/cli/deploy/FileManifest.d.ts.map +1 -1
- package/dist/lib/cli/deploy/FileManifest.js +3 -2
- package/dist/lib/cli/deploy/FileManifest.js.map +1 -1
- package/dist/lib/core/capability/CapabilityProbe.d.ts +13 -0
- package/dist/lib/core/capability/CapabilityProbe.d.ts.map +1 -1
- package/dist/lib/core/capability/CapabilityProbe.js +36 -17
- package/dist/lib/core/capability/CapabilityProbe.js.map +1 -1
- package/dist/lib/external/mcp/McpServer.d.ts +13 -0
- package/dist/lib/external/mcp/McpServer.d.ts.map +1 -1
- package/dist/lib/external/mcp/McpServer.js +44 -3
- package/dist/lib/external/mcp/McpServer.js.map +1 -1
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.d.ts.map +1 -1
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js +16 -1
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js.map +1 -1
- package/dist/lib/external/mcp/handlers/bootstrap-external.js.map +1 -1
- package/dist/lib/external/mcp/handlers/consolidated.d.ts +22 -24
- package/dist/lib/external/mcp/handlers/consolidated.d.ts.map +1 -1
- package/dist/lib/external/mcp/handlers/dimension-complete-external.js.map +1 -1
- package/dist/lib/external/mcp/handlers/search.d.ts +115 -39
- package/dist/lib/external/mcp/handlers/search.d.ts.map +1 -1
- package/dist/lib/external/mcp/handlers/search.js +107 -190
- package/dist/lib/external/mcp/handlers/search.js.map +1 -1
- package/dist/lib/external/mcp/handlers/task.d.ts +3 -0
- package/dist/lib/external/mcp/handlers/task.d.ts.map +1 -1
- package/dist/lib/external/mcp/handlers/task.js +10 -1
- package/dist/lib/external/mcp/handlers/task.js.map +1 -1
- package/dist/lib/external/mcp/handlers/wiki-external.d.ts.map +1 -1
- package/dist/lib/external/mcp/handlers/wiki-external.js +4 -3
- package/dist/lib/external/mcp/handlers/wiki-external.js.map +1 -1
- package/dist/lib/http/HttpServer.js +2 -2
- package/dist/lib/http/HttpServer.js.map +1 -1
- package/dist/lib/http/middleware/gatewayMiddleware.js +2 -2
- package/dist/lib/http/middleware/gatewayMiddleware.js.map +1 -1
- package/dist/lib/http/routes/ai.js +3 -3
- package/dist/lib/http/routes/ai.js.map +1 -1
- package/dist/lib/http/routes/candidates.d.ts.map +1 -1
- package/dist/lib/http/routes/candidates.js +3 -1
- package/dist/lib/http/routes/candidates.js.map +1 -1
- package/dist/lib/http/routes/commands.d.ts.map +1 -1
- package/dist/lib/http/routes/commands.js +37 -9
- package/dist/lib/http/routes/commands.js.map +1 -1
- package/dist/lib/http/routes/guard.d.ts.map +1 -1
- package/dist/lib/http/routes/guard.js.map +1 -1
- package/dist/lib/http/routes/guardRules.d.ts.map +1 -1
- package/dist/lib/http/routes/guardRules.js +7 -7
- package/dist/lib/http/routes/guardRules.js.map +1 -1
- package/dist/lib/http/routes/knowledge.d.ts.map +1 -1
- package/dist/lib/http/routes/knowledge.js +62 -18
- package/dist/lib/http/routes/knowledge.js.map +1 -1
- package/dist/lib/http/routes/modules.d.ts.map +1 -1
- package/dist/lib/http/routes/modules.js +7 -5
- package/dist/lib/http/routes/modules.js.map +1 -1
- package/dist/lib/http/routes/recipes.js +1 -1
- package/dist/lib/http/routes/recipes.js.map +1 -1
- package/dist/lib/http/routes/remote.d.ts.map +1 -1
- package/dist/lib/http/routes/remote.js +1 -1
- package/dist/lib/http/routes/remote.js.map +1 -1
- package/dist/lib/http/routes/search.d.ts.map +1 -1
- package/dist/lib/http/routes/search.js +31 -23
- package/dist/lib/http/routes/search.js.map +1 -1
- package/dist/lib/http/routes/snippets.js +2 -2
- package/dist/lib/http/routes/snippets.js.map +1 -1
- package/dist/lib/http/routes/task.js.map +1 -1
- package/dist/lib/http/routes/violations.js +2 -2
- package/dist/lib/http/routes/violations.js.map +1 -1
- package/dist/lib/http/routes/wiki.d.ts.map +1 -1
- package/dist/lib/http/routes/wiki.js +3 -2
- package/dist/lib/http/routes/wiki.js.map +1 -1
- package/dist/lib/http/utils/routeHelpers.d.ts +2 -2
- package/dist/lib/http/utils/routeHelpers.js +2 -2
- package/dist/lib/http/utils/routeHelpers.js.map +1 -1
- package/dist/lib/infrastructure/config/Defaults.d.ts +3 -0
- package/dist/lib/infrastructure/config/Defaults.d.ts.map +1 -1
- package/dist/lib/infrastructure/config/Defaults.js +10 -6
- package/dist/lib/infrastructure/config/Defaults.js.map +1 -1
- package/dist/lib/infrastructure/config/Paths.d.ts +1 -1
- package/dist/lib/infrastructure/config/Paths.d.ts.map +1 -1
- package/dist/lib/infrastructure/config/Paths.js +4 -16
- package/dist/lib/infrastructure/config/Paths.js.map +1 -1
- package/dist/lib/infrastructure/vector/HnswVectorAdapter.d.ts +4 -1
- package/dist/lib/infrastructure/vector/HnswVectorAdapter.d.ts.map +1 -1
- package/dist/lib/infrastructure/vector/HnswVectorAdapter.js +26 -6
- package/dist/lib/infrastructure/vector/HnswVectorAdapter.js.map +1 -1
- package/dist/lib/infrastructure/vector/IndexingPipeline.d.ts +20 -0
- package/dist/lib/infrastructure/vector/IndexingPipeline.d.ts.map +1 -1
- package/dist/lib/infrastructure/vector/IndexingPipeline.js +65 -3
- package/dist/lib/infrastructure/vector/IndexingPipeline.js.map +1 -1
- package/dist/lib/infrastructure/vector/JsonVectorAdapter.d.ts +1 -1
- package/dist/lib/infrastructure/vector/JsonVectorAdapter.js +1 -1
- package/dist/lib/injection/ServiceContainer.d.ts +12 -2
- package/dist/lib/injection/ServiceContainer.d.ts.map +1 -1
- package/dist/lib/injection/ServiceContainer.js +10 -85
- package/dist/lib/injection/ServiceContainer.js.map +1 -1
- package/dist/lib/injection/ServiceMap.d.ts +124 -0
- package/dist/lib/injection/ServiceMap.d.ts.map +1 -0
- package/dist/lib/injection/ServiceMap.js +10 -0
- package/dist/lib/injection/ServiceMap.js.map +1 -0
- package/dist/lib/injection/modules/AiModule.d.ts +36 -0
- package/dist/lib/injection/modules/AiModule.d.ts.map +1 -0
- package/dist/lib/injection/modules/AiModule.js +99 -0
- package/dist/lib/injection/modules/AiModule.js.map +1 -0
- package/dist/lib/injection/modules/AppModule.js.map +1 -1
- package/dist/lib/injection/modules/GuardModule.js.map +1 -1
- package/dist/lib/injection/modules/KnowledgeModule.d.ts +1 -1
- package/dist/lib/injection/modules/KnowledgeModule.d.ts.map +1 -1
- package/dist/lib/injection/modules/KnowledgeModule.js +4 -10
- package/dist/lib/injection/modules/KnowledgeModule.js.map +1 -1
- package/dist/lib/injection/modules/VectorModule.d.ts +20 -0
- package/dist/lib/injection/modules/VectorModule.d.ts.map +1 -0
- package/dist/lib/injection/modules/VectorModule.js +74 -0
- package/dist/lib/injection/modules/VectorModule.js.map +1 -0
- package/dist/lib/platform/ios/routes/spm.d.ts.map +1 -1
- package/dist/lib/platform/ios/routes/spm.js +7 -5
- package/dist/lib/platform/ios/routes/spm.js.map +1 -1
- package/dist/lib/service/agent/AgentRuntime.d.ts +3 -73
- package/dist/lib/service/agent/AgentRuntime.d.ts.map +1 -1
- package/dist/lib/service/agent/AgentRuntime.js +2 -2
- package/dist/lib/service/agent/AgentRuntime.js.map +1 -1
- package/dist/lib/service/agent/AgentRuntimeTypes.d.ts +113 -0
- package/dist/lib/service/agent/AgentRuntimeTypes.d.ts.map +1 -0
- package/dist/lib/service/agent/AgentRuntimeTypes.js +11 -0
- package/dist/lib/service/agent/AgentRuntimeTypes.js.map +1 -0
- package/dist/lib/service/agent/PipelineStrategy.d.ts +1 -1
- package/dist/lib/service/agent/PipelineStrategy.d.ts.map +1 -1
- package/dist/lib/service/agent/PipelineStrategy.js +3 -3
- package/dist/lib/service/agent/PipelineStrategy.js.map +1 -1
- package/dist/lib/service/agent/core/ChatAgentPrompts.d.ts +2 -2
- package/dist/lib/service/agent/core/ChatAgentPrompts.d.ts.map +1 -1
- package/dist/lib/service/agent/core/ChatAgentPrompts.js +2 -2
- package/dist/lib/service/agent/core/ChatAgentPrompts.js.map +1 -1
- package/dist/lib/service/agent/domain/insight-analyst.d.ts +3 -3
- package/dist/lib/service/agent/domain/insight-analyst.d.ts.map +1 -1
- package/dist/lib/service/agent/domain/insight-analyst.js +3 -3
- package/dist/lib/service/agent/domain/insight-analyst.js.map +1 -1
- package/dist/lib/service/agent/memory/MemoryCoordinator.d.ts +3 -3
- package/dist/lib/service/agent/memory/MemoryCoordinator.d.ts.map +1 -1
- package/dist/lib/service/agent/memory/MemoryCoordinator.js +6 -6
- package/dist/lib/service/agent/memory/MemoryCoordinator.js.map +1 -1
- package/dist/lib/service/agent/memory/MemoryRetriever.d.ts +18 -12
- package/dist/lib/service/agent/memory/MemoryRetriever.d.ts.map +1 -1
- package/dist/lib/service/agent/memory/MemoryRetriever.js +70 -17
- package/dist/lib/service/agent/memory/MemoryRetriever.js.map +1 -1
- package/dist/lib/service/agent/memory/MemoryStore.d.ts +38 -0
- package/dist/lib/service/agent/memory/MemoryStore.d.ts.map +1 -1
- package/dist/lib/service/agent/memory/MemoryStore.js +70 -3
- package/dist/lib/service/agent/memory/MemoryStore.js.map +1 -1
- package/dist/lib/service/agent/memory/PersistentMemory.d.ts +18 -4
- package/dist/lib/service/agent/memory/PersistentMemory.d.ts.map +1 -1
- package/dist/lib/service/agent/memory/PersistentMemory.js +24 -4
- package/dist/lib/service/agent/memory/PersistentMemory.js.map +1 -1
- package/dist/lib/service/agent/presets.d.ts +2 -2
- package/dist/lib/service/agent/tools/index.d.ts +0 -5
- package/dist/lib/service/agent/tools/index.d.ts.map +1 -1
- package/dist/lib/service/agent/tools/query.d.ts +0 -5
- package/dist/lib/service/agent/tools/query.d.ts.map +1 -1
- package/dist/lib/service/agent/tools/query.js +41 -32
- package/dist/lib/service/agent/tools/query.js.map +1 -1
- package/dist/lib/service/automation/FileWatcher.js +9 -9
- package/dist/lib/service/automation/FileWatcher.js.map +1 -1
- package/dist/lib/service/automation/handlers/AlinkHandler.d.ts.map +1 -1
- package/dist/lib/service/automation/handlers/AlinkHandler.js +1 -1
- package/dist/lib/service/automation/handlers/AlinkHandler.js.map +1 -1
- package/dist/lib/service/automation/handlers/GuardHandler.js +1 -1
- package/dist/lib/service/automation/handlers/GuardHandler.js.map +1 -1
- package/dist/lib/service/automation/handlers/SearchHandler.d.ts.map +1 -1
- package/dist/lib/service/automation/handlers/SearchHandler.js +10 -10
- package/dist/lib/service/automation/handlers/SearchHandler.js.map +1 -1
- package/dist/lib/service/cursor/CursorDeliveryPipeline.d.ts.map +1 -1
- package/dist/lib/service/cursor/CursorDeliveryPipeline.js +2 -1
- package/dist/lib/service/cursor/CursorDeliveryPipeline.js.map +1 -1
- package/dist/lib/service/cursor/SkillsSyncer.d.ts.map +1 -1
- package/dist/lib/service/cursor/SkillsSyncer.js +2 -1
- package/dist/lib/service/cursor/SkillsSyncer.js.map +1 -1
- package/dist/lib/service/guard/ExclusionManager.d.ts.map +1 -1
- package/dist/lib/service/guard/ExclusionManager.js +2 -1
- package/dist/lib/service/guard/ExclusionManager.js.map +1 -1
- package/dist/lib/service/guard/RuleLearner.d.ts.map +1 -1
- package/dist/lib/service/guard/RuleLearner.js +2 -1
- package/dist/lib/service/guard/RuleLearner.js.map +1 -1
- package/dist/lib/service/knowledge/KnowledgeService.d.ts +5 -0
- package/dist/lib/service/knowledge/KnowledgeService.d.ts.map +1 -1
- package/dist/lib/service/knowledge/KnowledgeService.js +27 -0
- package/dist/lib/service/knowledge/KnowledgeService.js.map +1 -1
- package/dist/lib/service/module/ModuleService.d.ts.map +1 -1
- package/dist/lib/service/module/ModuleService.js +1 -0
- package/dist/lib/service/module/ModuleService.js.map +1 -1
- package/dist/lib/service/quality/FeedbackCollector.d.ts.map +1 -1
- package/dist/lib/service/quality/FeedbackCollector.js +2 -1
- package/dist/lib/service/quality/FeedbackCollector.js.map +1 -1
- package/dist/lib/service/search/BM25Scorer.d.ts +52 -0
- package/dist/lib/service/search/BM25Scorer.d.ts.map +1 -0
- package/dist/lib/service/search/BM25Scorer.js +155 -0
- package/dist/lib/service/search/BM25Scorer.js.map +1 -0
- package/dist/lib/service/search/CrossEncoderReranker.js +1 -1
- package/dist/lib/service/search/CrossEncoderReranker.js.map +1 -1
- package/dist/lib/service/search/MultiSignalRanker.d.ts +7 -0
- package/dist/lib/service/search/MultiSignalRanker.d.ts.map +1 -1
- package/dist/lib/service/search/MultiSignalRanker.js +37 -18
- package/dist/lib/service/search/MultiSignalRanker.js.map +1 -1
- package/dist/lib/service/search/SearchEngine.d.ts +15 -215
- package/dist/lib/service/search/SearchEngine.d.ts.map +1 -1
- package/dist/lib/service/search/SearchEngine.js +127 -270
- package/dist/lib/service/search/SearchEngine.js.map +1 -1
- package/dist/lib/service/search/SearchTypes.d.ts +258 -0
- package/dist/lib/service/search/SearchTypes.d.ts.map +1 -0
- package/dist/lib/service/search/SearchTypes.js +50 -0
- package/dist/lib/service/search/SearchTypes.js.map +1 -0
- package/dist/lib/service/search/contextBoost.d.ts +1 -1
- package/dist/lib/service/search/contextBoost.js +2 -2
- package/dist/lib/service/search/contextBoost.js.map +1 -1
- package/dist/lib/service/search/tokenizer.d.ts +18 -0
- package/dist/lib/service/search/tokenizer.d.ts.map +1 -0
- package/dist/lib/service/search/tokenizer.js +215 -0
- package/dist/lib/service/search/tokenizer.js.map +1 -0
- package/dist/lib/service/task/TaskGraphService.d.ts +15 -6
- package/dist/lib/service/task/TaskGraphService.d.ts.map +1 -1
- package/dist/lib/service/task/TaskGraphService.js +55 -5
- package/dist/lib/service/task/TaskGraphService.js.map +1 -1
- package/dist/lib/service/task/TaskKnowledgeBridge.d.ts +90 -25
- package/dist/lib/service/task/TaskKnowledgeBridge.d.ts.map +1 -1
- package/dist/lib/service/task/TaskKnowledgeBridge.js +253 -35
- package/dist/lib/service/task/TaskKnowledgeBridge.js.map +1 -1
- package/dist/lib/service/vector/ContextualEnricher.d.ts +62 -0
- package/dist/lib/service/vector/ContextualEnricher.d.ts.map +1 -0
- package/dist/lib/service/vector/ContextualEnricher.js +150 -0
- package/dist/lib/service/vector/ContextualEnricher.js.map +1 -0
- package/dist/lib/service/vector/SyncCoordinator.d.ts +63 -0
- package/dist/lib/service/vector/SyncCoordinator.d.ts.map +1 -0
- package/dist/lib/service/vector/SyncCoordinator.js +290 -0
- package/dist/lib/service/vector/SyncCoordinator.js.map +1 -0
- package/dist/lib/service/vector/VectorService.d.ts +176 -0
- package/dist/lib/service/vector/VectorService.d.ts.map +1 -0
- package/dist/lib/service/vector/VectorService.js +456 -0
- package/dist/lib/service/vector/VectorService.js.map +1 -0
- package/dist/lib/service/wiki/WikiGenerator.d.ts.map +1 -1
- package/dist/lib/service/wiki/WikiGenerator.js +2 -1
- package/dist/lib/service/wiki/WikiGenerator.js.map +1 -1
- package/dist/lib/service/wiki/WikiRenderers.d.ts +4 -128
- package/dist/lib/service/wiki/WikiRenderers.d.ts.map +1 -1
- package/dist/lib/service/wiki/WikiRenderers.js +2 -0
- package/dist/lib/service/wiki/WikiRenderers.js.map +1 -1
- package/dist/lib/service/wiki/WikiTypes.d.ts +146 -0
- package/dist/lib/service/wiki/WikiTypes.d.ts.map +1 -0
- package/dist/lib/service/wiki/WikiTypes.js +10 -0
- package/dist/lib/service/wiki/WikiTypes.js.map +1 -0
- package/dist/lib/service/wiki/WikiUtils.d.ts.map +1 -1
- package/dist/lib/service/wiki/WikiUtils.js +2 -1
- package/dist/lib/service/wiki/WikiUtils.js.map +1 -1
- package/dist/lib/shared/PathGuard.d.ts.map +1 -1
- package/dist/lib/shared/PathGuard.js +8 -17
- package/dist/lib/shared/PathGuard.js.map +1 -1
- package/dist/lib/shared/ProjectMarkers.d.ts +67 -0
- package/dist/lib/shared/ProjectMarkers.d.ts.map +1 -0
- package/dist/lib/shared/ProjectMarkers.js +142 -0
- package/dist/lib/shared/ProjectMarkers.js.map +1 -0
- package/dist/lib/shared/schemas/mcp-tools.d.ts +3 -0
- package/dist/lib/shared/schemas/mcp-tools.d.ts.map +1 -1
- package/dist/lib/shared/schemas/mcp-tools.js +6 -0
- package/dist/lib/shared/schemas/mcp-tools.js.map +1 -1
- package/package.json +1 -1
- package/templates/constitution.yaml +23 -2
- package/dist/lib/service/search/InvertedIndex.d.ts +0 -34
- package/dist/lib/service/search/InvertedIndex.d.ts.map +0 -1
- package/dist/lib/service/search/InvertedIndex.js +0 -83
- package/dist/lib/service/search/InvertedIndex.js.map +0 -1
- package/dist/lib/service/search/RetrievalFunnel.d.ts +0 -26
- package/dist/lib/service/search/RetrievalFunnel.d.ts.map +0 -1
- package/dist/lib/service/search/RetrievalFunnel.js +0 -77
- 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. 任务标题/描述
|
|
10
|
-
* 2.
|
|
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
|
|
27
|
-
* @
|
|
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
|
-
*
|
|
75
|
+
* 独立搜索 — 仅基于 userQuery 搜索知识(不依赖任何 Task)
|
|
76
|
+
*
|
|
77
|
+
* 场景: prime() 时没有 ready tasks 但有用户输入,直接搜索知识库。
|
|
78
|
+
*
|
|
79
|
+
* @param userQuery 用户输入的原始文本
|
|
80
|
+
* @param options 可选的 language
|
|
47
81
|
*/
|
|
48
|
-
async
|
|
49
|
-
|
|
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(
|
|
87
|
+
const searchResult = await this._search.search(userQuery.trim(), {
|
|
55
88
|
mode: 'auto',
|
|
56
|
-
limit:
|
|
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
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
const
|
|
63
|
-
|
|
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
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAEjD,OAAO,MAAM,MAAM,wCAAwC,CAAC;
|
|
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, '&')
|
|
145
|
+
.replace(/</g, '<')
|
|
146
|
+
.replace(/>/g, '>')
|
|
147
|
+
.replace(/"/g, '"');
|
|
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"}
|