autosnippet 3.3.7 → 3.3.8
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/README.md +1 -0
- package/dashboard/dist/assets/icons-BMNb0V6L.js +1 -0
- package/dashboard/dist/assets/index-DHJ1Dj7u.css +1 -0
- package/dashboard/dist/assets/index-DV8biUkH.js +112 -0
- package/dashboard/dist/index.html +3 -3
- package/dist/bin/cli.js +7 -4
- package/dist/lib/agent/core/ChatAgentPrompts.js +57 -21
- package/dist/lib/agent/core/LoopContext.d.ts +1 -0
- package/dist/lib/agent/core/ToolExecutionPipeline.js +13 -0
- package/dist/lib/agent/memory/ActiveContext.d.ts +0 -2
- package/dist/lib/agent/memory/ActiveContext.js +0 -2
- package/dist/lib/agent/memory/MemoryEmbeddingStore.d.ts +49 -0
- package/dist/lib/agent/memory/MemoryEmbeddingStore.js +159 -0
- package/dist/lib/agent/memory/MemoryRetriever.d.ts +2 -0
- package/dist/lib/agent/memory/MemoryRetriever.js +25 -11
- package/dist/lib/agent/memory/MemoryStore.d.ts +8 -41
- package/dist/lib/agent/memory/MemoryStore.js +196 -261
- package/dist/lib/agent/memory/PersistentMemory.d.ts +2 -0
- package/dist/lib/agent/memory/PersistentMemory.js +4 -5
- package/dist/lib/agent/memory/SessionStore.d.ts +0 -2
- package/dist/lib/agent/memory/SessionStore.js +0 -2
- package/dist/lib/agent/tools/ast-graph.js +21 -19
- package/dist/lib/agent/tools/infrastructure.js +3 -2
- package/dist/lib/agent/tools/project-access.d.ts +2 -2
- package/dist/lib/agent/tools/project-access.js +5 -4
- package/dist/lib/bootstrap.js +2 -1
- package/dist/lib/cli/AiScanService.js +4 -17
- package/dist/lib/cli/KnowledgeSyncService.d.ts +7 -37
- package/dist/lib/cli/KnowledgeSyncService.js +23 -51
- package/dist/lib/core/ast/ProjectGraph.js +5 -27
- package/dist/lib/core/discovery/CustomConfigDiscoverer.d.ts +0 -2
- package/dist/lib/core/discovery/CustomConfigDiscoverer.js +0 -2
- package/dist/lib/domain/dimension/DimensionRegistry.d.ts +0 -2
- package/dist/lib/domain/dimension/DimensionRegistry.js +0 -2
- package/dist/lib/domain/dimension/DimensionSop.js +44 -33
- package/dist/lib/domain/dimension/UnifiedDimension.d.ts +0 -2
- package/dist/lib/domain/dimension/UnifiedDimension.js +0 -2
- package/dist/lib/domain/knowledge/Lifecycle.d.ts +26 -0
- package/dist/lib/domain/knowledge/Lifecycle.js +42 -0
- package/dist/lib/domain/knowledge/index.d.ts +2 -1
- package/dist/lib/domain/knowledge/index.js +1 -1
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/BootstrapSnapshot.d.ts +2 -1
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/BootstrapSnapshot.js +102 -153
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js +33 -16
- package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.d.ts +1 -1
- package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.js +41 -37
- package/dist/lib/external/mcp/handlers/bootstrap-external.js +1 -1
- package/dist/lib/external/mcp/handlers/dimension-complete-external.js +7 -3
- package/dist/lib/external/mcp/handlers/evolve-external.d.ts +1 -0
- package/dist/lib/external/mcp/handlers/evolve-external.js +13 -16
- package/dist/lib/external/mcp/handlers/guard.js +15 -24
- package/dist/lib/external/mcp/handlers/panorama.js +9 -9
- package/dist/lib/external/mcp/handlers/rescan-external.js +7 -6
- package/dist/lib/external/mcp/handlers/rescan-internal.js +9 -5
- package/dist/lib/external/mcp/handlers/search.js +3 -1
- package/dist/lib/external/mcp/handlers/skill.js +4 -4
- package/dist/lib/external/mcp/handlers/structure.js +8 -12
- package/dist/lib/external/mcp/handlers/system.js +10 -34
- package/dist/lib/http/routes/ai.js +11 -13
- package/dist/lib/http/routes/guardReport.js +3 -5
- package/dist/lib/http/routes/panorama.js +12 -12
- package/dist/lib/http/routes/recipes.js +59 -8
- package/dist/lib/http/routes/remote.js +3 -13
- package/dist/lib/http/routes/search.js +11 -8
- package/dist/lib/infrastructure/audit/AuditLogger.d.ts +20 -3
- package/dist/lib/infrastructure/audit/AuditStore.d.ts +28 -29
- package/dist/lib/infrastructure/audit/AuditStore.js +81 -88
- package/dist/lib/infrastructure/database/drizzle/schema.d.ts +180 -2
- package/dist/lib/infrastructure/database/drizzle/schema.js +23 -3
- package/dist/lib/injection/ServiceContainer.js +7 -4
- package/dist/lib/injection/ServiceMap.d.ts +20 -0
- package/dist/lib/injection/modules/AppModule.js +2 -1
- package/dist/lib/injection/modules/GuardModule.js +5 -5
- package/dist/lib/injection/modules/InfraModule.js +60 -0
- package/dist/lib/injection/modules/KnowledgeModule.js +86 -51
- package/dist/lib/injection/modules/PanoramaModule.js +16 -10
- package/dist/lib/injection/modules/VectorModule.js +3 -0
- package/dist/lib/repository/audit/AuditRepository.d.ts +107 -0
- package/dist/lib/repository/audit/AuditRepository.js +272 -0
- package/dist/lib/repository/base/RepositoryBase.d.ts +46 -0
- package/dist/lib/repository/base/RepositoryBase.js +32 -0
- package/dist/lib/repository/bootstrap/BootstrapRepository.d.ts +94 -0
- package/dist/lib/repository/bootstrap/BootstrapRepository.js +246 -0
- package/dist/lib/repository/code/CodeEntityRepository.d.ts +91 -0
- package/dist/lib/repository/code/CodeEntityRepository.js +361 -0
- package/dist/lib/repository/delivery/DeliveryRepoAdapter.d.ts +39 -0
- package/dist/lib/repository/delivery/DeliveryRepoAdapter.js +23 -0
- package/dist/lib/repository/evolution/LifecycleEventRepository.d.ts +51 -0
- package/dist/lib/repository/evolution/LifecycleEventRepository.js +119 -0
- package/dist/lib/repository/evolution/ProposalRepository.d.ts +9 -12
- package/dist/lib/repository/evolution/ProposalRepository.js +114 -57
- package/dist/lib/repository/guard/GuardViolationRepository.d.ts +104 -0
- package/dist/lib/repository/guard/GuardViolationRepository.js +217 -0
- package/dist/lib/repository/knowledge/KnowledgeEdgeRepository.d.ts +129 -0
- package/dist/lib/repository/knowledge/KnowledgeEdgeRepository.js +475 -0
- package/dist/lib/repository/knowledge/KnowledgeFileStore.d.ts +39 -0
- package/dist/lib/repository/knowledge/KnowledgeFileStore.js +12 -0
- package/dist/lib/repository/knowledge/KnowledgeRepository.impl.d.ts +295 -11
- package/dist/lib/repository/knowledge/KnowledgeRepository.impl.js +608 -13
- package/dist/lib/repository/knowledge/KnowledgeUnitOfWork.d.ts +61 -0
- package/dist/lib/repository/knowledge/KnowledgeUnitOfWork.js +156 -0
- package/dist/lib/repository/memory/MemoryRepository.d.ts +90 -0
- package/dist/lib/repository/memory/MemoryRepository.js +260 -0
- package/dist/lib/repository/search/SearchRepoAdapter.d.ts +92 -0
- package/dist/lib/repository/search/SearchRepoAdapter.js +124 -0
- package/dist/lib/repository/session/SessionRepository.d.ts +46 -0
- package/dist/lib/repository/session/SessionRepository.js +110 -0
- package/dist/lib/repository/sourceref/RecipeSourceRefRepository.d.ts +66 -0
- package/dist/lib/repository/sourceref/RecipeSourceRefRepository.js +182 -0
- package/dist/lib/repository/sync/SyncRepoAdapter.d.ts +58 -0
- package/dist/lib/repository/sync/SyncRepoAdapter.js +58 -0
- package/dist/lib/service/bootstrap/UiStartupTasks.js +5 -6
- package/dist/lib/service/bootstrap/bootstrap-event-types.d.ts +0 -1
- package/dist/lib/service/bootstrap/bootstrap-event-types.js +0 -1
- package/dist/lib/service/cleanup/CleanupService.js +8 -4
- package/dist/lib/service/delivery/CursorDeliveryPipeline.js +6 -8
- package/dist/lib/service/evolution/ConsolidationAdvisor.d.ts +4 -9
- package/dist/lib/service/evolution/ConsolidationAdvisor.js +34 -70
- package/dist/lib/service/evolution/ContentPatcher.d.ts +4 -12
- package/dist/lib/service/evolution/ContentPatcher.js +48 -19
- package/dist/lib/service/evolution/ContradictionDetector.d.ts +3 -7
- package/dist/lib/service/evolution/ContradictionDetector.js +17 -24
- package/dist/lib/service/evolution/DecayDetector.d.ts +10 -9
- package/dist/lib/service/evolution/DecayDetector.js +63 -57
- package/dist/lib/service/evolution/EnhancementSuggester.d.ts +3 -9
- package/dist/lib/service/evolution/EnhancementSuggester.js +42 -86
- package/dist/lib/service/evolution/KnowledgeMetabolism.d.ts +4 -4
- package/dist/lib/service/evolution/KnowledgeMetabolism.js +102 -71
- package/dist/lib/service/evolution/ProposalExecutor.d.ts +5 -12
- package/dist/lib/service/evolution/ProposalExecutor.js +64 -69
- package/dist/lib/service/evolution/RecipeLifecycleSupervisor.d.ts +9 -14
- package/dist/lib/service/evolution/RecipeLifecycleSupervisor.js +94 -155
- package/dist/lib/service/evolution/RecipeRelevanceAuditor.d.ts +4 -1
- package/dist/lib/service/evolution/RecipeRelevanceAuditor.js +50 -49
- package/dist/lib/service/evolution/RedundancyAnalyzer.d.ts +3 -7
- package/dist/lib/service/evolution/RedundancyAnalyzer.js +15 -22
- package/dist/lib/service/evolution/StagingManager.d.ts +6 -15
- package/dist/lib/service/evolution/StagingManager.js +37 -95
- package/dist/lib/service/evolution/createSupersedeProposal.d.ts +1 -1
- package/dist/lib/service/evolution/createSupersedeProposal.js +7 -8
- package/dist/lib/service/guard/CoverageAnalyzer.d.ts +3 -7
- package/dist/lib/service/guard/CoverageAnalyzer.js +9 -11
- package/dist/lib/service/guard/GuardCheckEngine.d.ts +3 -0
- package/dist/lib/service/guard/GuardCheckEngine.js +14 -22
- package/dist/lib/service/guard/ReverseGuard.d.ts +4 -7
- package/dist/lib/service/guard/ReverseGuard.js +21 -31
- package/dist/lib/service/guard/ViolationsStore.d.ts +15 -21
- package/dist/lib/service/guard/ViolationsStore.js +75 -69
- package/dist/lib/service/knowledge/CodeEntityGraph.d.ts +39 -63
- package/dist/lib/service/knowledge/CodeEntityGraph.js +418 -512
- package/dist/lib/service/knowledge/ConfidenceRouter.js +18 -9
- package/dist/lib/service/knowledge/KnowledgeFileWriter.d.ts +2 -1
- package/dist/lib/service/knowledge/KnowledgeGraphService.d.ts +18 -60
- package/dist/lib/service/knowledge/KnowledgeGraphService.js +58 -109
- package/dist/lib/service/knowledge/KnowledgeService.d.ts +15 -1
- package/dist/lib/service/knowledge/KnowledgeService.js +76 -38
- package/dist/lib/service/knowledge/RecipeProductionGateway.d.ts +0 -2
- package/dist/lib/service/knowledge/RecipeProductionGateway.js +0 -2
- package/dist/lib/service/knowledge/SourceRefReconciler.d.ts +5 -13
- package/dist/lib/service/knowledge/SourceRefReconciler.js +58 -78
- package/dist/lib/service/panorama/CouplingAnalyzer.d.ts +5 -3
- package/dist/lib/service/panorama/CouplingAnalyzer.js +102 -39
- package/dist/lib/service/panorama/DimensionAnalyzer.d.ts +7 -4
- package/dist/lib/service/panorama/DimensionAnalyzer.js +72 -25
- package/dist/lib/service/panorama/LayerInferrer.js +1 -1
- package/dist/lib/service/panorama/ModuleDiscoverer.d.ts +7 -6
- package/dist/lib/service/panorama/ModuleDiscoverer.js +174 -82
- package/dist/lib/service/panorama/PanoramaAggregator.d.ts +10 -3
- package/dist/lib/service/panorama/PanoramaAggregator.js +67 -79
- package/dist/lib/service/panorama/PanoramaScanner.d.ts +5 -1
- package/dist/lib/service/panorama/PanoramaScanner.js +32 -31
- package/dist/lib/service/panorama/PanoramaService.d.ts +11 -8
- package/dist/lib/service/panorama/PanoramaService.js +41 -66
- package/dist/lib/service/panorama/PanoramaTypes.d.ts +3 -0
- package/dist/lib/service/panorama/RoleRefiner.d.ts +8 -5
- package/dist/lib/service/panorama/RoleRefiner.js +52 -283
- package/dist/lib/service/panorama/TechStackProfiler.js +7 -119
- package/dist/lib/service/quality/QualityScorer.d.ts +45 -26
- package/dist/lib/service/quality/QualityScorer.js +157 -83
- package/dist/lib/service/search/SearchEngine.d.ts +1 -0
- package/dist/lib/service/search/SearchEngine.js +32 -37
- package/dist/lib/service/signal/HitRecorder.js +5 -5
- package/dist/lib/service/skills/RuleRecallStrategy.js +7 -3
- package/dist/lib/service/skills/SignalCollector.d.ts +5 -8
- package/dist/lib/service/skills/SignalCollector.js +28 -55
- package/dist/lib/service/skills/SkillAdvisor.d.ts +7 -13
- package/dist/lib/service/skills/SkillAdvisor.js +30 -79
- package/dist/lib/service/vector/SyncCoordinator.d.ts +3 -1
- package/dist/lib/service/vector/SyncCoordinator.js +25 -3
- package/dist/lib/service/vector/VectorService.d.ts +2 -0
- package/dist/lib/service/vector/VectorService.js +3 -0
- package/dist/lib/service/wiki/WikiGenerator.js +1 -1
- package/dist/lib/shared/LanguageProfiles.d.ts +109 -0
- package/dist/lib/shared/LanguageProfiles.js +939 -0
- package/dist/lib/shared/LanguageService.d.ts +6 -0
- package/dist/lib/shared/LanguageService.js +16 -0
- package/dist/lib/shared/constants.d.ts +19 -19
- package/dist/lib/shared/constants.js +10 -10
- package/dist/lib/shared/schemas/mcp-tools.d.ts +1 -1
- package/dist/lib/types/project-snapshot-builder.d.ts +0 -1
- package/dist/lib/types/project-snapshot-builder.js +0 -1
- package/dist/lib/types/project-snapshot.d.ts +0 -1
- package/dist/lib/types/project-snapshot.js +0 -1
- package/dist/lib/types/snapshot-views.d.ts +0 -2
- package/dist/lib/types/snapshot-views.js +0 -1
- package/package.json +2 -1
- package/dashboard/dist/assets/icons-FHns2ypa.js +0 -1
- package/dashboard/dist/assets/index-BRJv5Y3r.js +0 -135
- package/dashboard/dist/assets/index-DzoB7kxK.css +0 -1
- package/dist/lib/repository/base/BaseRepository.d.ts +0 -53
- package/dist/lib/repository/base/BaseRepository.js +0 -226
|
@@ -25,6 +25,7 @@ import fs from 'node:fs';
|
|
|
25
25
|
import path from 'node:path';
|
|
26
26
|
import { CANDIDATES_DIR } from '#infra/config/Defaults.js';
|
|
27
27
|
import { getContextIndexPath, getProjectKnowledgePath, getProjectRecipesPath, getProjectSkillsPath, } from '#infra/config/Paths.js';
|
|
28
|
+
import { CONSUMABLE_LIFECYCLES, lifecycleInSql } from '../../domain/knowledge/Lifecycle.js';
|
|
28
29
|
// ── 常量 ────────────────────────────────────────────────────
|
|
29
30
|
/** 垃圾桶根目录(相对于 .autosnippet/) */
|
|
30
31
|
const TRASH_DIR = '.trash';
|
|
@@ -275,12 +276,15 @@ export class CleanupService {
|
|
|
275
276
|
return { count: 0, entries: [], coverageByDimension: {} };
|
|
276
277
|
}
|
|
277
278
|
try {
|
|
279
|
+
const { sql: lcFilter, params: lcParams } = lifecycleInSql(CONSUMABLE_LIFECYCLES);
|
|
278
280
|
const rows = this.#db
|
|
279
|
-
.prepare(
|
|
281
|
+
.prepare(
|
|
282
|
+
// @escape-hatch(permanent) — dynamic lifecycle filter + json_extract
|
|
283
|
+
`SELECT id, title, trigger, category, knowledgeType, doClause,
|
|
280
284
|
sourceFile, lifecycle, content, json_extract(reasoning, '$.sources') AS sourceRefsJson
|
|
281
285
|
FROM knowledge_entries
|
|
282
|
-
WHERE
|
|
283
|
-
.all();
|
|
286
|
+
WHERE ${lcFilter}`)
|
|
287
|
+
.all(...lcParams);
|
|
284
288
|
const entries = rows.map((r) => {
|
|
285
289
|
let parsedContent;
|
|
286
290
|
try {
|
|
@@ -430,7 +434,7 @@ export class CleanupService {
|
|
|
430
434
|
const lines = [];
|
|
431
435
|
for (const table of tablesToExport) {
|
|
432
436
|
try {
|
|
433
|
-
const rows = this.#db.prepare(`SELECT * FROM ${table}`).all();
|
|
437
|
+
const rows = this.#db.prepare(`SELECT * FROM ${table}`).all(); // @escape-hatch(permanent) — dynamic table name for backup export
|
|
434
438
|
for (const row of rows) {
|
|
435
439
|
lines.push(JSON.stringify({ _table: table, ...row }));
|
|
436
440
|
totalRows++;
|
|
@@ -18,6 +18,8 @@
|
|
|
18
18
|
*/
|
|
19
19
|
import fs from 'node:fs';
|
|
20
20
|
import path from 'node:path';
|
|
21
|
+
import { RawDbCallGraphAdapter, } from '../../repository/delivery/DeliveryRepoAdapter.js';
|
|
22
|
+
import { unwrapRawDb } from '../../repository/search/SearchRepoAdapter.js';
|
|
21
23
|
import { DELIVERY_RANK, KNOWLEDGE_CONFIDENCE } from '../../shared/constants.js';
|
|
22
24
|
import { DEFAULT_KNOWLEDGE_BASE_DIR } from '../../shared/ProjectMarkers.js';
|
|
23
25
|
import { AgentInstructionsGenerator } from './AgentInstructionsGenerator.js';
|
|
@@ -313,20 +315,16 @@ export class CursorDeliveryPipeline {
|
|
|
313
315
|
return null;
|
|
314
316
|
}
|
|
315
317
|
try {
|
|
316
|
-
const
|
|
318
|
+
const rawDb = unwrapRawDb(this.database);
|
|
319
|
+
const repo = new RawDbCallGraphAdapter(rawDb);
|
|
317
320
|
// 查询调用边中的跨目录调用模式
|
|
318
|
-
const callEdges =
|
|
319
|
-
.prepare(`SELECT from_id, to_id, metadata_json FROM knowledge_edges
|
|
320
|
-
WHERE relation = 'calls' AND metadata_json LIKE '%phase5%'`)
|
|
321
|
-
.all();
|
|
321
|
+
const callEdges = repo.findCallEdges();
|
|
322
322
|
if (!callEdges || callEdges.length < 5) {
|
|
323
323
|
return null;
|
|
324
324
|
}
|
|
325
325
|
// 提取 caller/callee 对应的文件路径
|
|
326
326
|
const entityFiles = new Map();
|
|
327
|
-
const entities =
|
|
328
|
-
.prepare(`SELECT entity_id, file_path FROM code_entities WHERE entity_type = 'method'`)
|
|
329
|
-
.all();
|
|
327
|
+
const entities = repo.findMethodEntities();
|
|
330
328
|
for (const e of entities) {
|
|
331
329
|
entityFiles.set(e.entity_id, e.file_path);
|
|
332
330
|
}
|
|
@@ -14,11 +14,7 @@
|
|
|
14
14
|
* 2. 语义域覆盖 — category + trigger 是否落在已有 Recipe 管辖范围
|
|
15
15
|
* 3. 独立价值 — 内容长度、具体性、是否有独立 coreCode
|
|
16
16
|
*/
|
|
17
|
-
|
|
18
|
-
prepare(sql: string): {
|
|
19
|
-
all(...params: unknown[]): Record<string, unknown>[];
|
|
20
|
-
};
|
|
21
|
-
}
|
|
17
|
+
import type KnowledgeRepositoryImpl from '../../repository/knowledge/KnowledgeRepository.impl.js';
|
|
22
18
|
/** 提交候选的必要字段 */
|
|
23
19
|
export interface CandidateForConsolidation {
|
|
24
20
|
title: string;
|
|
@@ -92,14 +88,14 @@ export interface BatchConsolidationResult {
|
|
|
92
88
|
}
|
|
93
89
|
export declare class ConsolidationAdvisor {
|
|
94
90
|
#private;
|
|
95
|
-
constructor(
|
|
91
|
+
constructor(knowledgeRepo: KnowledgeRepositoryImpl);
|
|
96
92
|
/**
|
|
97
93
|
* 分析候选知识与现有知识库的关系,返回融合建议。
|
|
98
94
|
*
|
|
99
95
|
* @param candidate - 待提交的候选数据
|
|
100
96
|
* @returns ConsolidationAdvice — 建议 + 理由 + 上下文
|
|
101
97
|
*/
|
|
102
|
-
analyze(candidate: CandidateForConsolidation): ConsolidationAdvice
|
|
98
|
+
analyze(candidate: CandidateForConsolidation): Promise<ConsolidationAdvice>;
|
|
103
99
|
/**
|
|
104
100
|
* 批量分析候选知识与现有知识库的关系。
|
|
105
101
|
*
|
|
@@ -109,6 +105,5 @@ export declare class ConsolidationAdvisor {
|
|
|
109
105
|
* @param candidates - 待提交的候选数组
|
|
110
106
|
* @returns BatchConsolidationResult — 每条分析 + 批次内重叠
|
|
111
107
|
*/
|
|
112
|
-
analyzeBatch(candidates: CandidateForConsolidation[]): BatchConsolidationResult
|
|
108
|
+
analyzeBatch(candidates: CandidateForConsolidation[]): Promise<BatchConsolidationResult>;
|
|
113
109
|
}
|
|
114
|
-
export {};
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
* 3. 独立价值 — 内容长度、具体性、是否有独立 coreCode
|
|
16
16
|
*/
|
|
17
17
|
var _a;
|
|
18
|
+
import { COUNTABLE_LIFECYCLES } from '../../domain/knowledge/Lifecycle.js';
|
|
18
19
|
import Logger from '../../infrastructure/logging/Logger.js';
|
|
19
20
|
import { ContradictionDetector } from './ContradictionDetector.js';
|
|
20
21
|
/* ────────────────────── Constants ────────────────────── */
|
|
@@ -29,10 +30,10 @@ const MAX_CANDIDATES_PER_ANALYSIS = 30;
|
|
|
29
30
|
const WEIGHTS = { title: 0.2, clause: 0.3, code: 0.3, guard: 0.2 };
|
|
30
31
|
/* ────────────────────── Class ────────────────────── */
|
|
31
32
|
export class ConsolidationAdvisor {
|
|
32
|
-
#
|
|
33
|
+
#knowledgeRepo;
|
|
33
34
|
#logger = Logger.getInstance();
|
|
34
|
-
constructor(
|
|
35
|
-
this.#
|
|
35
|
+
constructor(knowledgeRepo) {
|
|
36
|
+
this.#knowledgeRepo = knowledgeRepo;
|
|
36
37
|
}
|
|
37
38
|
/**
|
|
38
39
|
* 分析候选知识与现有知识库的关系,返回融合建议。
|
|
@@ -40,11 +41,11 @@ export class ConsolidationAdvisor {
|
|
|
40
41
|
* @param candidate - 待提交的候选数据
|
|
41
42
|
* @returns ConsolidationAdvice — 建议 + 理由 + 上下文
|
|
42
43
|
*/
|
|
43
|
-
analyze(candidate) {
|
|
44
|
+
async analyze(candidate) {
|
|
44
45
|
// ── Step 1: 独立价值评估 ──
|
|
45
46
|
const substanceScore = this.#assessSubstance(candidate);
|
|
46
47
|
// ── Step 2: 加载同域 / 相关 Recipe ──
|
|
47
|
-
const related = this.#loadRelatedRecipes(candidate);
|
|
48
|
+
const related = await this.#loadRelatedRecipes(candidate);
|
|
48
49
|
// ── Step 3: insufficient — 独立价值不足,交给 Agent 与开发者决定 ──
|
|
49
50
|
if (substanceScore < MIN_SUBSTANCE_SCORE) {
|
|
50
51
|
if (related.length > 0) {
|
|
@@ -188,12 +189,12 @@ export class ConsolidationAdvisor {
|
|
|
188
189
|
* @param candidates - 待提交的候选数组
|
|
189
190
|
* @returns BatchConsolidationResult — 每条分析 + 批次内重叠
|
|
190
191
|
*/
|
|
191
|
-
analyzeBatch(candidates) {
|
|
192
|
+
async analyzeBatch(candidates) {
|
|
192
193
|
// 对每个候选独立分析(vs DB)
|
|
193
|
-
const items =
|
|
194
|
-
|
|
195
|
-
advice: this.analyze(
|
|
196
|
-
}
|
|
194
|
+
const items = [];
|
|
195
|
+
for (let index = 0; index < candidates.length; index++) {
|
|
196
|
+
items.push({ index, advice: await this.analyze(candidates[index]) });
|
|
197
|
+
}
|
|
197
198
|
// 检测批次内候选之间的相互重叠
|
|
198
199
|
const internalOverlaps = [];
|
|
199
200
|
for (let i = 0; i < candidates.length; i++) {
|
|
@@ -288,78 +289,41 @@ export class ConsolidationAdvisor {
|
|
|
288
289
|
return msg;
|
|
289
290
|
}
|
|
290
291
|
/* ════════════════════ 相关 Recipe 加载 ════════════════════ */
|
|
291
|
-
#loadRelatedRecipes(candidate) {
|
|
292
|
+
async #loadRelatedRecipes(candidate) {
|
|
292
293
|
try {
|
|
293
|
-
// 先按 category 精确匹配 + trigger 前缀匹配
|
|
294
294
|
const category = candidate.category || '';
|
|
295
295
|
const trigger = candidate.trigger || '';
|
|
296
296
|
const triggerPrefix = trigger.startsWith('@')
|
|
297
297
|
? trigger.slice(0, Math.max(3, trigger.indexOf('-', 1) > 0 ? trigger.indexOf('-', 1) : trigger.length))
|
|
298
298
|
: '';
|
|
299
|
-
|
|
299
|
+
const toSummary = (e) => ({
|
|
300
|
+
id: e.id,
|
|
301
|
+
title: e.title,
|
|
302
|
+
doClause: e.doClause || null,
|
|
303
|
+
dontClause: e.dontClause || null,
|
|
304
|
+
coreCode: e.coreCode || null,
|
|
305
|
+
category: e.category || null,
|
|
306
|
+
trigger: e.trigger || null,
|
|
307
|
+
whenClause: e.whenClause || null,
|
|
308
|
+
guardPattern: e.content?.pattern || null,
|
|
309
|
+
});
|
|
300
310
|
if (category) {
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
json_extract(content, '$.coreCode') AS coreCode,
|
|
307
|
-
category, trigger, whenClause,
|
|
308
|
-
json_extract(content, '$.pattern') AS guardPattern
|
|
309
|
-
FROM knowledge_entries
|
|
310
|
-
WHERE lifecycle IN ('active', 'staging', 'evolving', 'pending')
|
|
311
|
-
AND category = ?
|
|
312
|
-
ORDER BY lifecycle DESC
|
|
313
|
-
LIMIT ?`)
|
|
314
|
-
.all(category, MAX_CANDIDATES_PER_ANALYSIS);
|
|
315
|
-
// 如果同 category 不够,再加载 trigger 相关的
|
|
316
|
-
if (rows.length < 5 && triggerPrefix.length >= 3) {
|
|
317
|
-
const extra = this.#db
|
|
318
|
-
.prepare(`SELECT id, title,
|
|
319
|
-
doClause,
|
|
320
|
-
dontClause,
|
|
321
|
-
json_extract(content, '$.coreCode') AS coreCode,
|
|
322
|
-
category, trigger, whenClause,
|
|
323
|
-
json_extract(content, '$.pattern') AS guardPattern
|
|
324
|
-
FROM knowledge_entries
|
|
325
|
-
WHERE lifecycle IN ('active', 'staging', 'evolving', 'pending')
|
|
326
|
-
AND category != ?
|
|
327
|
-
AND trigger LIKE ?
|
|
328
|
-
LIMIT ?`)
|
|
329
|
-
.all(category, `${triggerPrefix}%`, MAX_CANDIDATES_PER_ANALYSIS - rows.length);
|
|
330
|
-
const existingIds = new Set(rows.map((r) => r.id));
|
|
311
|
+
const entries = await this.#knowledgeRepo.findAllByLifecyclesAndCategory(COUNTABLE_LIFECYCLES, category, MAX_CANDIDATES_PER_ANALYSIS);
|
|
312
|
+
const results = entries.map(toSummary);
|
|
313
|
+
if (results.length < 5 && triggerPrefix.length >= 3) {
|
|
314
|
+
const extra = await this.#knowledgeRepo.findByLifecyclesAndTriggerPrefix(COUNTABLE_LIFECYCLES, category, triggerPrefix, MAX_CANDIDATES_PER_ANALYSIS - results.length);
|
|
315
|
+
const existingIds = new Set(results.map((r) => r.id));
|
|
331
316
|
for (const e of extra) {
|
|
332
|
-
|
|
333
|
-
|
|
317
|
+
const s = toSummary(e);
|
|
318
|
+
if (!existingIds.has(s.id)) {
|
|
319
|
+
results.push(s);
|
|
334
320
|
}
|
|
335
321
|
}
|
|
336
322
|
}
|
|
323
|
+
return results;
|
|
337
324
|
}
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
rows = this.#db
|
|
341
|
-
.prepare(`SELECT id, title,
|
|
342
|
-
doClause,
|
|
343
|
-
dontClause,
|
|
344
|
-
json_extract(content, '$.coreCode') AS coreCode,
|
|
345
|
-
category, trigger, whenClause,
|
|
346
|
-
json_extract(content, '$.pattern') AS guardPattern
|
|
347
|
-
FROM knowledge_entries
|
|
348
|
-
WHERE lifecycle IN ('active', 'staging', 'evolving', 'pending')
|
|
349
|
-
LIMIT ?`)
|
|
350
|
-
.all(MAX_CANDIDATES_PER_ANALYSIS);
|
|
351
|
-
}
|
|
352
|
-
return rows.map((r) => ({
|
|
353
|
-
id: r.id,
|
|
354
|
-
title: r.title,
|
|
355
|
-
doClause: r.doClause ?? null,
|
|
356
|
-
dontClause: r.dontClause ?? null,
|
|
357
|
-
coreCode: r.coreCode ?? null,
|
|
358
|
-
category: r.category ?? null,
|
|
359
|
-
trigger: r.trigger ?? null,
|
|
360
|
-
whenClause: r.whenClause ?? null,
|
|
361
|
-
guardPattern: r.guardPattern ?? null,
|
|
362
|
-
}));
|
|
325
|
+
const entries = await this.#knowledgeRepo.findAllByLifecycles(COUNTABLE_LIFECYCLES);
|
|
326
|
+
return entries.slice(0, MAX_CANDIDATES_PER_ANALYSIS).map(toSummary);
|
|
363
327
|
}
|
|
364
328
|
catch (err) {
|
|
365
329
|
this.#logger.warn(`ConsolidationAdvisor: failed to load recipes: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -16,19 +16,12 @@
|
|
|
16
16
|
*
|
|
17
17
|
* @module service/evolution/ContentPatcher
|
|
18
18
|
*/
|
|
19
|
+
import type KnowledgeRepositoryImpl from '../../repository/knowledge/KnowledgeRepository.impl.js';
|
|
20
|
+
import type { RecipeSourceRefRepositoryImpl } from '../../repository/sourceref/RecipeSourceRefRepository.js';
|
|
19
21
|
import type { ContentPatchResult } from '../../types/evolution.js';
|
|
20
|
-
interface DatabaseLike {
|
|
21
|
-
prepare(sql: string): {
|
|
22
|
-
all(...params: unknown[]): Record<string, unknown>[];
|
|
23
|
-
get(...params: unknown[]): Record<string, unknown> | undefined;
|
|
24
|
-
run(...params: unknown[]): {
|
|
25
|
-
changes: number;
|
|
26
|
-
};
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
22
|
export declare class ContentPatcher {
|
|
30
23
|
#private;
|
|
31
|
-
constructor(
|
|
24
|
+
constructor(knowledgeRepo: KnowledgeRepositoryImpl, sourceRefRepo: RecipeSourceRefRepositoryImpl);
|
|
32
25
|
/**
|
|
33
26
|
* 从 Proposal evidence 提取 suggestedChanges 并应用到 Recipe
|
|
34
27
|
*
|
|
@@ -39,6 +32,5 @@ export declare class ContentPatcher {
|
|
|
39
32
|
type: string;
|
|
40
33
|
targetRecipeId: string;
|
|
41
34
|
evidence: Record<string, unknown>[];
|
|
42
|
-
}, patchSource?: 'agent-suggestion' | 'correction' | 'merge'): ContentPatchResult
|
|
35
|
+
}, patchSource?: 'agent-suggestion' | 'correction' | 'merge'): Promise<ContentPatchResult>;
|
|
43
36
|
}
|
|
44
|
-
export {};
|
|
@@ -31,20 +31,22 @@ const PATCHABLE_FIELDS = new Set([
|
|
|
31
31
|
]);
|
|
32
32
|
/* ────────────────────── Class ────────────────────── */
|
|
33
33
|
export class ContentPatcher {
|
|
34
|
-
#
|
|
34
|
+
#knowledgeRepo;
|
|
35
|
+
#sourceRefRepo;
|
|
35
36
|
#logger = Logger.getInstance();
|
|
36
|
-
constructor(
|
|
37
|
-
this.#
|
|
37
|
+
constructor(knowledgeRepo, sourceRefRepo) {
|
|
38
|
+
this.#knowledgeRepo = knowledgeRepo;
|
|
39
|
+
this.#sourceRefRepo = sourceRefRepo;
|
|
38
40
|
}
|
|
39
41
|
/**
|
|
40
42
|
* 从 Proposal evidence 提取 suggestedChanges 并应用到 Recipe
|
|
41
43
|
*
|
|
42
44
|
* @returns ContentPatchResult — success: 是否成功应用了至少一个 patch
|
|
43
45
|
*/
|
|
44
|
-
applyProposal(proposal, patchSource = 'agent-suggestion') {
|
|
46
|
+
async applyProposal(proposal, patchSource = 'agent-suggestion') {
|
|
45
47
|
const recipeId = proposal.targetRecipeId;
|
|
46
48
|
// 1. 获取 Recipe 当前内容
|
|
47
|
-
const recipe = this.#getRecipe(recipeId);
|
|
49
|
+
const recipe = await this.#getRecipe(recipeId);
|
|
48
50
|
if (!recipe) {
|
|
49
51
|
return this.#skipResult(recipeId, patchSource, 'Recipe not found');
|
|
50
52
|
}
|
|
@@ -66,7 +68,7 @@ export class ContentPatcher {
|
|
|
66
68
|
return this.#skipResult(recipeId, patchSource, 'No valid fields to patch');
|
|
67
69
|
}
|
|
68
70
|
// 6. 持久化
|
|
69
|
-
this.#persistRecipe(recipe);
|
|
71
|
+
await this.#persistRecipe(recipe);
|
|
70
72
|
// 7. 创建 after 快照
|
|
71
73
|
const afterSnapshot = this.#createSnapshot(recipe);
|
|
72
74
|
this.#logger.info(`[ContentPatcher] Applied ${fieldsPatched.length} patches to recipe ${recipeId}: ${fieldsPatched.join(', ')}`);
|
|
@@ -257,20 +259,47 @@ export class ContentPatcher {
|
|
|
257
259
|
};
|
|
258
260
|
}
|
|
259
261
|
/* ═══════════════════ DB ═══════════════════ */
|
|
260
|
-
#getRecipe(recipeId) {
|
|
261
|
-
const
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
262
|
+
async #getRecipe(recipeId) {
|
|
263
|
+
const entry = await this.#knowledgeRepo.findById(recipeId);
|
|
264
|
+
if (!entry) {
|
|
265
|
+
return null;
|
|
266
|
+
}
|
|
267
|
+
// 从 recipe_source_refs 表读取关联的源引用路径
|
|
268
|
+
const refs = this.#sourceRefRepo.findByRecipeId(entry.id);
|
|
269
|
+
const sourcePaths = refs.map((r) => r.sourcePath);
|
|
270
|
+
return {
|
|
271
|
+
id: entry.id,
|
|
272
|
+
title: entry.title,
|
|
273
|
+
coreCode: entry.coreCode || '',
|
|
274
|
+
doClause: entry.doClause || '',
|
|
275
|
+
dontClause: entry.dontClause || '',
|
|
276
|
+
whenClause: entry.whenClause || '',
|
|
277
|
+
content: JSON.stringify(entry.content || {}),
|
|
278
|
+
sourceRefs: JSON.stringify(sourcePaths),
|
|
279
|
+
headers: JSON.stringify(entry.headers || []),
|
|
280
|
+
};
|
|
266
281
|
}
|
|
267
|
-
#persistRecipe(recipe) {
|
|
268
|
-
this.#
|
|
269
|
-
.
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
282
|
+
async #persistRecipe(recipe) {
|
|
283
|
+
await this.#knowledgeRepo.update(recipe.id, {
|
|
284
|
+
coreCode: recipe.coreCode,
|
|
285
|
+
doClause: recipe.doClause,
|
|
286
|
+
dontClause: recipe.dontClause,
|
|
287
|
+
whenClause: recipe.whenClause,
|
|
288
|
+
content: safeJsonParse(recipe.content, {}),
|
|
289
|
+
headers: safeJsonParse(recipe.headers, []),
|
|
290
|
+
});
|
|
291
|
+
// 同步 sourceRefs 到 recipe_source_refs 表
|
|
292
|
+
const newPaths = safeJsonParse(recipe.sourceRefs, []);
|
|
293
|
+
const now = Math.floor(Date.now() / 1000);
|
|
294
|
+
this.#sourceRefRepo.deleteByRecipeId(recipe.id);
|
|
295
|
+
for (const sourcePath of newPaths) {
|
|
296
|
+
this.#sourceRefRepo.upsert({
|
|
297
|
+
recipeId: recipe.id,
|
|
298
|
+
sourcePath,
|
|
299
|
+
status: 'active',
|
|
300
|
+
verifiedAt: now,
|
|
301
|
+
});
|
|
302
|
+
}
|
|
274
303
|
}
|
|
275
304
|
/* ═══════════════════ Helpers ═══════════════════ */
|
|
276
305
|
#skipResult(recipeId, patchSource, reason) {
|
|
@@ -13,11 +13,7 @@
|
|
|
13
13
|
* 结果:硬矛盾 (confidence ≥ 0.8) / 软矛盾 (0.4-0.8)
|
|
14
14
|
*/
|
|
15
15
|
import type { SignalBus } from '../../infrastructure/signal/SignalBus.js';
|
|
16
|
-
|
|
17
|
-
prepare(sql: string): {
|
|
18
|
-
all(...params: unknown[]): Record<string, unknown>[];
|
|
19
|
-
};
|
|
20
|
-
}
|
|
16
|
+
import type KnowledgeRepositoryImpl from '../../repository/knowledge/KnowledgeRepository.impl.js';
|
|
21
17
|
export interface ContradictionResult {
|
|
22
18
|
recipeA: string;
|
|
23
19
|
recipeB: string;
|
|
@@ -37,13 +33,13 @@ interface RecipeEntry {
|
|
|
37
33
|
}
|
|
38
34
|
export declare class ContradictionDetector {
|
|
39
35
|
#private;
|
|
40
|
-
constructor(
|
|
36
|
+
constructor(knowledgeRepo: KnowledgeRepositoryImpl, options?: {
|
|
41
37
|
signalBus?: SignalBus;
|
|
42
38
|
});
|
|
43
39
|
/**
|
|
44
40
|
* 检测所有 active/staging/evolving Recipe 之间的矛盾
|
|
45
41
|
*/
|
|
46
|
-
detectAll(): ContradictionResult[]
|
|
42
|
+
detectAll(): Promise<ContradictionResult[]>;
|
|
47
43
|
/**
|
|
48
44
|
* 检测两条 Recipe 是否矛盾
|
|
49
45
|
*/
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
* 结果:硬矛盾 (confidence ≥ 0.8) / 软矛盾 (0.4-0.8)
|
|
14
14
|
*/
|
|
15
15
|
var _a;
|
|
16
|
+
import { CONSUMABLE_LIFECYCLES } from '../../domain/knowledge/Lifecycle.js';
|
|
16
17
|
import Logger from '../../infrastructure/logging/Logger.js';
|
|
17
18
|
/* ────────────────────── Constants ────────────────────── */
|
|
18
19
|
const NEGATION_PATTERNS_ZH = /不(再)?使用|禁止|废弃|移除|取消|停止|不要|不采用|弃用|淘汰/;
|
|
@@ -71,18 +72,18 @@ const STOP_WORDS = new Set([
|
|
|
71
72
|
]);
|
|
72
73
|
/* ────────────────────── Class ────────────────────── */
|
|
73
74
|
export class ContradictionDetector {
|
|
74
|
-
#
|
|
75
|
+
#knowledgeRepo;
|
|
75
76
|
#signalBus;
|
|
76
77
|
#logger = Logger.getInstance();
|
|
77
|
-
constructor(
|
|
78
|
-
this.#
|
|
78
|
+
constructor(knowledgeRepo, options = {}) {
|
|
79
|
+
this.#knowledgeRepo = knowledgeRepo;
|
|
79
80
|
this.#signalBus = options.signalBus ?? null;
|
|
80
81
|
}
|
|
81
82
|
/**
|
|
82
83
|
* 检测所有 active/staging/evolving Recipe 之间的矛盾
|
|
83
84
|
*/
|
|
84
|
-
detectAll() {
|
|
85
|
-
const recipes = this.#loadRecipes();
|
|
85
|
+
async detectAll() {
|
|
86
|
+
const recipes = await this.#loadRecipes();
|
|
86
87
|
const results = [];
|
|
87
88
|
for (let i = 0; i < recipes.length; i++) {
|
|
88
89
|
for (let j = i + 1; j < recipes.length; j++) {
|
|
@@ -155,26 +156,18 @@ export class ContradictionDetector {
|
|
|
155
156
|
};
|
|
156
157
|
}
|
|
157
158
|
/* ── Internal ── */
|
|
158
|
-
#loadRecipes() {
|
|
159
|
+
async #loadRecipes() {
|
|
159
160
|
try {
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
.
|
|
169
|
-
|
|
170
|
-
id: r.id,
|
|
171
|
-
title: r.title,
|
|
172
|
-
lifecycle: r.lifecycle,
|
|
173
|
-
doClause: r.doClause ?? null,
|
|
174
|
-
dontClause: r.dontClause ?? null,
|
|
175
|
-
guardPattern: r.guardPattern ?? null,
|
|
176
|
-
description: r.description ?? null,
|
|
177
|
-
content_markdown: r.content_markdown ?? null,
|
|
161
|
+
const entries = await this.#knowledgeRepo.findAllByLifecycles(CONSUMABLE_LIFECYCLES);
|
|
162
|
+
return entries.map((e) => ({
|
|
163
|
+
id: e.id,
|
|
164
|
+
title: e.title,
|
|
165
|
+
lifecycle: e.lifecycle,
|
|
166
|
+
doClause: e.doClause || null,
|
|
167
|
+
dontClause: e.dontClause || null,
|
|
168
|
+
guardPattern: e.content?.pattern || null,
|
|
169
|
+
description: e.description || null,
|
|
170
|
+
content_markdown: e.content?.markdown || null,
|
|
178
171
|
}));
|
|
179
172
|
}
|
|
180
173
|
catch {
|
|
@@ -18,13 +18,11 @@
|
|
|
18
18
|
* 20-39: 严重 → Grace Period 缩短到 15d
|
|
19
19
|
* 0-19: 死亡 → 跳过确认直接 deprecated
|
|
20
20
|
*/
|
|
21
|
+
import type { DrizzleDB } from '../../infrastructure/database/drizzle/index.js';
|
|
21
22
|
import type { SignalBus } from '../../infrastructure/signal/SignalBus.js';
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
get(...params: unknown[]): Record<string, unknown> | undefined;
|
|
26
|
-
};
|
|
27
|
-
}
|
|
23
|
+
import type { KnowledgeEdgeRepositoryImpl } from '../../repository/knowledge/KnowledgeEdgeRepository.js';
|
|
24
|
+
import type KnowledgeRepositoryImpl from '../../repository/knowledge/KnowledgeRepository.impl.js';
|
|
25
|
+
import type { RecipeSourceRefRepositoryImpl } from '../../repository/sourceref/RecipeSourceRefRepository.js';
|
|
28
26
|
export interface DecaySignal {
|
|
29
27
|
recipeId: string;
|
|
30
28
|
strategy: DecayStrategy;
|
|
@@ -57,16 +55,19 @@ interface RecipeForDecay {
|
|
|
57
55
|
}
|
|
58
56
|
export declare class DecayDetector {
|
|
59
57
|
#private;
|
|
60
|
-
constructor(
|
|
58
|
+
constructor(knowledgeRepo: KnowledgeRepositoryImpl, options?: {
|
|
61
59
|
signalBus?: SignalBus;
|
|
60
|
+
knowledgeEdgeRepo?: KnowledgeEdgeRepositoryImpl;
|
|
61
|
+
sourceRefRepo?: RecipeSourceRefRepositoryImpl;
|
|
62
|
+
drizzle?: DrizzleDB;
|
|
62
63
|
});
|
|
63
64
|
/**
|
|
64
65
|
* 扫描所有 active 条目的衰退状态
|
|
65
66
|
*/
|
|
66
|
-
scanAll(): DecayScoreResult[]
|
|
67
|
+
scanAll(): Promise<DecayScoreResult[]>;
|
|
67
68
|
/**
|
|
68
69
|
* 评估单条 Recipe 的衰退状态
|
|
69
70
|
*/
|
|
70
|
-
evaluate(recipe: RecipeForDecay): DecayScoreResult
|
|
71
|
+
evaluate(recipe: RecipeForDecay): Promise<DecayScoreResult>;
|
|
71
72
|
}
|
|
72
73
|
export {};
|