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
|
@@ -24,6 +24,7 @@ export class KnowledgeMetabolism {
|
|
|
24
24
|
#logger = Logger.getInstance();
|
|
25
25
|
#pendingTriggers = [];
|
|
26
26
|
#debounceTimer = null;
|
|
27
|
+
#running = false;
|
|
27
28
|
constructor(options) {
|
|
28
29
|
this.#contradictionDetector = options.contradictionDetector;
|
|
29
30
|
this.#redundancyAnalyzer = options.redundancyAnalyzer;
|
|
@@ -40,13 +41,17 @@ export class KnowledgeMetabolism {
|
|
|
40
41
|
}
|
|
41
42
|
}
|
|
42
43
|
#scheduleMetabolism() {
|
|
44
|
+
// 当前正在执行周期时,忽略信号(防止自身产出的信号导致无限循环)
|
|
45
|
+
if (this.#running) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
43
48
|
if (this.#debounceTimer) {
|
|
44
49
|
return;
|
|
45
50
|
}
|
|
46
51
|
this.#debounceTimer = setTimeout(() => {
|
|
47
52
|
this.#debounceTimer = null;
|
|
48
|
-
if (this.#pendingTriggers.length > 0) {
|
|
49
|
-
this.runFullCycle();
|
|
53
|
+
if (this.#pendingTriggers.length > 0 && !this.#running) {
|
|
54
|
+
void this.runFullCycle();
|
|
50
55
|
this.#pendingTriggers = [];
|
|
51
56
|
}
|
|
52
57
|
}, 30_000);
|
|
@@ -54,95 +59,121 @@ export class KnowledgeMetabolism {
|
|
|
54
59
|
/**
|
|
55
60
|
* 执行完整治理周期
|
|
56
61
|
*/
|
|
57
|
-
runFullCycle() {
|
|
58
|
-
this.#
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
62
|
+
async runFullCycle() {
|
|
63
|
+
if (this.#running) {
|
|
64
|
+
this.#logger.warn('KnowledgeMetabolism: cycle already in progress, skipping');
|
|
65
|
+
return {
|
|
66
|
+
contradictions: [],
|
|
67
|
+
redundancies: [],
|
|
68
|
+
decayResults: [],
|
|
69
|
+
proposals: [],
|
|
70
|
+
summary: {
|
|
71
|
+
totalScanned: 0,
|
|
72
|
+
contradictionCount: 0,
|
|
73
|
+
redundancyCount: 0,
|
|
74
|
+
decayingCount: 0,
|
|
75
|
+
proposalCount: 0,
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
this.#running = true;
|
|
80
|
+
// 清除执行期间积累的信号,避免周期结束后立刻再次触发
|
|
81
|
+
this.#pendingTriggers = [];
|
|
82
|
+
try {
|
|
83
|
+
this.#logger.info('KnowledgeMetabolism: starting full governance cycle');
|
|
84
|
+
// 1. 衰退检测
|
|
85
|
+
const decayResults = await this.#decayDetector.scanAll();
|
|
86
|
+
// 2. 矛盾检测
|
|
87
|
+
const contradictions = await this.#contradictionDetector.detectAll();
|
|
88
|
+
// 3. 冗余分析
|
|
89
|
+
const redundancies = await this.#redundancyAnalyzer.analyzeAll();
|
|
90
|
+
// 4. 生成进化提案
|
|
91
|
+
const proposals = [
|
|
92
|
+
...this.#proposalsFromContradictions(contradictions),
|
|
93
|
+
...this.#proposalsFromRedundancies(redundancies),
|
|
94
|
+
...this.#proposalsFromDecay(decayResults),
|
|
95
|
+
];
|
|
96
|
+
// 5. 持久化提案到 evolution_proposals 表
|
|
97
|
+
let persistedCount = 0;
|
|
98
|
+
if (this.#proposalRepo && proposals.length > 0) {
|
|
99
|
+
for (const p of proposals) {
|
|
100
|
+
const sourceMap = {
|
|
101
|
+
contradiction: 'metabolism',
|
|
102
|
+
redundancy: 'metabolism',
|
|
103
|
+
decay: 'decay-scan',
|
|
104
|
+
enhancement: 'metabolism',
|
|
105
|
+
};
|
|
106
|
+
const record = this.#proposalRepo.create({
|
|
107
|
+
type: p.type,
|
|
108
|
+
targetRecipeId: p.targetRecipeId,
|
|
109
|
+
relatedRecipeIds: p.relatedRecipeIds,
|
|
110
|
+
confidence: p.confidence,
|
|
111
|
+
source: sourceMap[p.source] ?? 'metabolism',
|
|
112
|
+
description: p.description,
|
|
113
|
+
evidence: p.evidence.map((e) => ({ detail: e })),
|
|
114
|
+
});
|
|
115
|
+
if (record) {
|
|
116
|
+
persistedCount++;
|
|
117
|
+
}
|
|
92
118
|
}
|
|
93
119
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
120
|
+
// 6. 写入治理报告(降级:同时写 ReportStore)
|
|
121
|
+
if (this.#reportStore && proposals.length > 0) {
|
|
122
|
+
void this.#reportStore.write({
|
|
123
|
+
category: 'governance',
|
|
124
|
+
type: 'metabolism_cycle',
|
|
125
|
+
producer: 'KnowledgeMetabolism',
|
|
126
|
+
data: {
|
|
127
|
+
proposalCount: proposals.length,
|
|
128
|
+
persistedCount,
|
|
129
|
+
contradictionCount: contradictions.length,
|
|
130
|
+
redundancyCount: redundancies.length,
|
|
131
|
+
decayingCount: decayResults.filter((d) => d.level !== 'healthy' && d.level !== 'watch')
|
|
132
|
+
.length,
|
|
133
|
+
},
|
|
134
|
+
timestamp: Date.now(),
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
const report = {
|
|
138
|
+
contradictions,
|
|
139
|
+
redundancies,
|
|
140
|
+
decayResults,
|
|
141
|
+
proposals,
|
|
142
|
+
summary: {
|
|
143
|
+
totalScanned: decayResults.length,
|
|
104
144
|
contradictionCount: contradictions.length,
|
|
105
145
|
redundancyCount: redundancies.length,
|
|
106
146
|
decayingCount: decayResults.filter((d) => d.level !== 'healthy' && d.level !== 'watch')
|
|
107
147
|
.length,
|
|
148
|
+
proposalCount: proposals.length,
|
|
108
149
|
},
|
|
109
|
-
|
|
110
|
-
});
|
|
150
|
+
};
|
|
151
|
+
this.#logger.info(`KnowledgeMetabolism: cycle complete — ${report.summary.proposalCount} proposals generated`);
|
|
152
|
+
return report;
|
|
153
|
+
}
|
|
154
|
+
finally {
|
|
155
|
+
this.#running = false;
|
|
156
|
+
// 清除周期期间积累的信号,防止自身产出的信号立即触发下一轮
|
|
157
|
+
this.#pendingTriggers = [];
|
|
111
158
|
}
|
|
112
|
-
const report = {
|
|
113
|
-
contradictions,
|
|
114
|
-
redundancies,
|
|
115
|
-
decayResults,
|
|
116
|
-
proposals,
|
|
117
|
-
summary: {
|
|
118
|
-
totalScanned: decayResults.length,
|
|
119
|
-
contradictionCount: contradictions.length,
|
|
120
|
-
redundancyCount: redundancies.length,
|
|
121
|
-
decayingCount: decayResults.filter((d) => d.level !== 'healthy' && d.level !== 'watch')
|
|
122
|
-
.length,
|
|
123
|
-
proposalCount: proposals.length,
|
|
124
|
-
},
|
|
125
|
-
};
|
|
126
|
-
this.#logger.info(`KnowledgeMetabolism: cycle complete — ${report.summary.proposalCount} proposals generated`);
|
|
127
|
-
return report;
|
|
128
159
|
}
|
|
129
160
|
/**
|
|
130
161
|
* 只执行衰退扫描
|
|
131
162
|
*/
|
|
132
|
-
checkDecay() {
|
|
133
|
-
return this.#decayDetector.scanAll();
|
|
163
|
+
async checkDecay() {
|
|
164
|
+
return await this.#decayDetector.scanAll();
|
|
134
165
|
}
|
|
135
166
|
/**
|
|
136
167
|
* 只执行矛盾检测
|
|
137
168
|
*/
|
|
138
|
-
checkContradictions() {
|
|
139
|
-
return this.#contradictionDetector.detectAll();
|
|
169
|
+
async checkContradictions() {
|
|
170
|
+
return await this.#contradictionDetector.detectAll();
|
|
140
171
|
}
|
|
141
172
|
/**
|
|
142
173
|
* 只执行冗余分析
|
|
143
174
|
*/
|
|
144
|
-
checkRedundancy() {
|
|
145
|
-
return this.#redundancyAnalyzer.analyzeAll();
|
|
175
|
+
async checkRedundancy() {
|
|
176
|
+
return await this.#redundancyAnalyzer.analyzeAll();
|
|
146
177
|
}
|
|
147
178
|
/* ── Proposal Generation ── */
|
|
148
179
|
#proposalsFromContradictions(results) {
|
|
@@ -17,17 +17,10 @@
|
|
|
17
17
|
*/
|
|
18
18
|
import type { SignalBus } from '../../infrastructure/signal/SignalBus.js';
|
|
19
19
|
import type { ProposalRepository, ProposalType } from '../../repository/evolution/ProposalRepository.js';
|
|
20
|
+
import type { KnowledgeEdgeRepositoryImpl } from '../../repository/knowledge/KnowledgeEdgeRepository.js';
|
|
21
|
+
import type KnowledgeRepositoryImpl from '../../repository/knowledge/KnowledgeRepository.impl.js';
|
|
20
22
|
import type { ContentPatcher } from './ContentPatcher.js';
|
|
21
23
|
import type { RecipeLifecycleSupervisor } from './RecipeLifecycleSupervisor.js';
|
|
22
|
-
interface DatabaseLike {
|
|
23
|
-
prepare(sql: string): {
|
|
24
|
-
all(...params: unknown[]): Record<string, unknown>[];
|
|
25
|
-
get(...params: unknown[]): Record<string, unknown> | undefined;
|
|
26
|
-
run(...params: unknown[]): {
|
|
27
|
-
changes: number;
|
|
28
|
-
};
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
24
|
export interface ProposalExecutionResult {
|
|
32
25
|
executed: {
|
|
33
26
|
id: string;
|
|
@@ -51,16 +44,16 @@ export interface ProposalExecutionResult {
|
|
|
51
44
|
}
|
|
52
45
|
export declare class ProposalExecutor {
|
|
53
46
|
#private;
|
|
54
|
-
constructor(
|
|
47
|
+
constructor(knowledgeRepo: KnowledgeRepositoryImpl, repo: ProposalRepository, options?: {
|
|
55
48
|
signalBus?: SignalBus;
|
|
56
49
|
contentPatcher?: ContentPatcher;
|
|
57
50
|
supervisor?: RecipeLifecycleSupervisor;
|
|
51
|
+
knowledgeEdgeRepo?: KnowledgeEdgeRepositoryImpl;
|
|
58
52
|
});
|
|
59
53
|
/**
|
|
60
54
|
* 定期调用(UiStartupTasks Stage 5)
|
|
61
55
|
*
|
|
62
56
|
* 扫描所有到期 Proposal → 评估 → 执行/拒绝/过期
|
|
63
57
|
*/
|
|
64
|
-
checkAndExecute(): ProposalExecutionResult
|
|
58
|
+
checkAndExecute(): Promise<ProposalExecutionResult>;
|
|
65
59
|
}
|
|
66
|
-
export {};
|
|
@@ -23,15 +23,17 @@ const HIGH_RISK_TYPES = new Set(['contradiction', 'reorganize']);
|
|
|
23
23
|
const PENDING_EXPIRY_DAYS = 14;
|
|
24
24
|
/* ────────────────────── Class ────────────────────── */
|
|
25
25
|
export class ProposalExecutor {
|
|
26
|
-
#
|
|
26
|
+
#knowledgeRepo;
|
|
27
|
+
#edgeRepo;
|
|
27
28
|
#repo;
|
|
28
29
|
#signalBus;
|
|
29
30
|
#contentPatcher;
|
|
30
31
|
#supervisor;
|
|
31
32
|
#logger = Logger.getInstance();
|
|
32
|
-
constructor(
|
|
33
|
-
this.#
|
|
33
|
+
constructor(knowledgeRepo, repo, options = {}) {
|
|
34
|
+
this.#knowledgeRepo = knowledgeRepo;
|
|
34
35
|
this.#repo = repo;
|
|
36
|
+
this.#edgeRepo = options.knowledgeEdgeRepo ?? null;
|
|
35
37
|
this.#signalBus = options.signalBus ?? null;
|
|
36
38
|
this.#contentPatcher = options.contentPatcher ?? null;
|
|
37
39
|
this.#supervisor = options.supervisor ?? null;
|
|
@@ -41,7 +43,7 @@ export class ProposalExecutor {
|
|
|
41
43
|
*
|
|
42
44
|
* 扫描所有到期 Proposal → 评估 → 执行/拒绝/过期
|
|
43
45
|
*/
|
|
44
|
-
checkAndExecute() {
|
|
46
|
+
async checkAndExecute() {
|
|
45
47
|
const result = {
|
|
46
48
|
executed: [],
|
|
47
49
|
rejected: [],
|
|
@@ -60,7 +62,7 @@ export class ProposalExecutor {
|
|
|
60
62
|
});
|
|
61
63
|
continue;
|
|
62
64
|
}
|
|
63
|
-
this.#processExpiredProposal(proposal, result);
|
|
65
|
+
await this.#processExpiredProposal(proposal, result);
|
|
64
66
|
}
|
|
65
67
|
// 2. 清理超期未操作的 pending Proposal
|
|
66
68
|
this.#expireOldPending(result);
|
|
@@ -71,22 +73,22 @@ export class ProposalExecutor {
|
|
|
71
73
|
return result;
|
|
72
74
|
}
|
|
73
75
|
/* ═══════════════════ Internal ═══════════════════ */
|
|
74
|
-
#processExpiredProposal(proposal, result) {
|
|
75
|
-
const metrics = this.#collectRecipeMetrics(proposal.targetRecipeId);
|
|
76
|
+
async #processExpiredProposal(proposal, result) {
|
|
77
|
+
const metrics = await this.#collectRecipeMetrics(proposal.targetRecipeId);
|
|
76
78
|
const snapshot = this.#extractSnapshot(proposal);
|
|
77
79
|
switch (proposal.type) {
|
|
78
80
|
case 'merge':
|
|
79
81
|
case 'enhance':
|
|
80
|
-
this.#executeMergeOrEnhance(proposal, metrics, snapshot, result);
|
|
82
|
+
await this.#executeMergeOrEnhance(proposal, metrics, snapshot, result);
|
|
81
83
|
break;
|
|
82
84
|
case 'supersede':
|
|
83
|
-
this.#executeSupersede(proposal, metrics, snapshot, result);
|
|
85
|
+
await this.#executeSupersede(proposal, metrics, snapshot, result);
|
|
84
86
|
break;
|
|
85
87
|
case 'deprecate':
|
|
86
|
-
this.#executeDeprecate(proposal, metrics, snapshot, result);
|
|
88
|
+
await this.#executeDeprecate(proposal, metrics, snapshot, result);
|
|
87
89
|
break;
|
|
88
90
|
case 'correction':
|
|
89
|
-
this.#executeCorrection(proposal, metrics, result);
|
|
91
|
+
await this.#executeCorrection(proposal, metrics, result);
|
|
90
92
|
break;
|
|
91
93
|
default:
|
|
92
94
|
result.skipped.push({
|
|
@@ -97,7 +99,7 @@ export class ProposalExecutor {
|
|
|
97
99
|
}
|
|
98
100
|
}
|
|
99
101
|
/* ── merge / enhance ── */
|
|
100
|
-
#executeMergeOrEnhance(proposal, metrics, snapshot, result) {
|
|
102
|
+
async #executeMergeOrEnhance(proposal, metrics, snapshot, result) {
|
|
101
103
|
// 执行判据:
|
|
102
104
|
// - 目标 Recipe 在观察期内无 FP rate 异常飙升
|
|
103
105
|
// - 目标 Recipe 在观察期内仍有使用
|
|
@@ -105,16 +107,15 @@ export class ProposalExecutor {
|
|
|
105
107
|
const hasUsage = metrics.guardHits > 0 || metrics.searchHits > 0;
|
|
106
108
|
if (fpOk && hasUsage) {
|
|
107
109
|
// 通过 → evolving → ContentPatcher → staging(重走 Grace Period)
|
|
108
|
-
this.#transitionRecipe(proposal.targetRecipeId, 'evolving', 'proposal-attach', proposal.id);
|
|
109
|
-
const patchResult = this.#tryApplyPatch(proposal, 'agent-suggestion');
|
|
110
|
+
await this.#transitionRecipe(proposal.targetRecipeId, 'evolving', 'proposal-attach', proposal.id);
|
|
111
|
+
const patchResult = await this.#tryApplyPatch(proposal, 'agent-suggestion');
|
|
110
112
|
if (patchResult?.skipped || (!patchResult?.success && patchResult !== null)) {
|
|
111
|
-
|
|
112
|
-
this.#transitionRecipe(proposal.targetRecipeId, 'active', 'content-patch-complete', proposal.id);
|
|
113
|
+
await this.#transitionRecipe(proposal.targetRecipeId, 'active', 'content-patch-complete', proposal.id);
|
|
113
114
|
const skipInfo = patchResult?.skipReason ? `: ${patchResult.skipReason}` : '';
|
|
114
115
|
this.#repo.markExecuted(proposal.id, `观察期合格但 patch 未生效${skipInfo}, 回退 active`);
|
|
115
116
|
}
|
|
116
117
|
else {
|
|
117
|
-
this.#transitionRecipe(proposal.targetRecipeId, 'staging', 'content-patch-complete', proposal.id);
|
|
118
|
+
await this.#transitionRecipe(proposal.targetRecipeId, 'staging', 'content-patch-complete', proposal.id);
|
|
118
119
|
const patchInfo = patchResult?.success
|
|
119
120
|
? `, patched=[${patchResult.fieldsPatched.join(',')}]`
|
|
120
121
|
: '';
|
|
@@ -129,7 +130,7 @@ export class ProposalExecutor {
|
|
|
129
130
|
}
|
|
130
131
|
else {
|
|
131
132
|
// 不通过 → Recipe 恢复原状态
|
|
132
|
-
this.#restoreRecipe(proposal.targetRecipeId);
|
|
133
|
+
await this.#restoreRecipe(proposal.targetRecipeId);
|
|
133
134
|
this.#repo.markRejected(proposal.id, `观察期表现不达标: FP=${(metrics.ruleFalsePositiveRate * 100).toFixed(0)}%, hasUsage=${hasUsage}`);
|
|
134
135
|
result.rejected.push({
|
|
135
136
|
id: proposal.id,
|
|
@@ -140,7 +141,7 @@ export class ProposalExecutor {
|
|
|
140
141
|
}
|
|
141
142
|
}
|
|
142
143
|
/* ── supersede ── */
|
|
143
|
-
#executeSupersede(proposal, metrics, snapshot, result) {
|
|
144
|
+
async #executeSupersede(proposal, metrics, snapshot, result) {
|
|
144
145
|
// 新 Recipe 必须已到达 active
|
|
145
146
|
const newRecipeId = proposal.relatedRecipeIds[0];
|
|
146
147
|
if (!newRecipeId) {
|
|
@@ -152,7 +153,7 @@ export class ProposalExecutor {
|
|
|
152
153
|
});
|
|
153
154
|
return;
|
|
154
155
|
}
|
|
155
|
-
const newRecipe = this.#getRecipeLifecycle(newRecipeId);
|
|
156
|
+
const newRecipe = await this.#getRecipeLifecycle(newRecipeId);
|
|
156
157
|
if (newRecipe?.lifecycle !== 'active') {
|
|
157
158
|
// 新 Recipe 尚未 active → 跳过,等下次检查
|
|
158
159
|
result.skipped.push({
|
|
@@ -163,13 +164,13 @@ export class ProposalExecutor {
|
|
|
163
164
|
return;
|
|
164
165
|
}
|
|
165
166
|
// 对比新旧 Recipe 的使用数据
|
|
166
|
-
const newMetrics = this.#collectRecipeMetrics(newRecipeId);
|
|
167
|
+
const newMetrics = await this.#collectRecipeMetrics(newRecipeId);
|
|
167
168
|
const oldUsage = metrics.guardHits + metrics.searchHits;
|
|
168
169
|
const newUsage = newMetrics.guardHits + newMetrics.searchHits;
|
|
169
170
|
if (newUsage >= oldUsage * 0.5 || oldUsage === 0) {
|
|
170
171
|
// 新 Recipe 表现足够 → 旧 Recipe → decaying,建立 deprecated_by
|
|
171
|
-
this.#transitionRecipe(proposal.targetRecipeId, 'decaying', 'proposal-execution', proposal.id);
|
|
172
|
-
this.#createDeprecatedByEdge(newRecipeId, proposal.targetRecipeId);
|
|
172
|
+
await this.#transitionRecipe(proposal.targetRecipeId, 'decaying', 'proposal-execution', proposal.id);
|
|
173
|
+
await this.#createDeprecatedByEdge(newRecipeId, proposal.targetRecipeId);
|
|
173
174
|
this.#repo.markExecuted(proposal.id, `supersede executed: new usage=${newUsage}, old usage=${oldUsage}`);
|
|
174
175
|
result.executed.push({
|
|
175
176
|
id: proposal.id,
|
|
@@ -180,7 +181,7 @@ export class ProposalExecutor {
|
|
|
180
181
|
}
|
|
181
182
|
else {
|
|
182
183
|
// 新 Recipe 表现不足 → 拒绝
|
|
183
|
-
this.#restoreRecipe(proposal.targetRecipeId);
|
|
184
|
+
await this.#restoreRecipe(proposal.targetRecipeId);
|
|
184
185
|
this.#repo.markRejected(proposal.id, `new recipe usage (${newUsage}) < 50% of old (${oldUsage})`);
|
|
185
186
|
result.rejected.push({
|
|
186
187
|
id: proposal.id,
|
|
@@ -191,12 +192,12 @@ export class ProposalExecutor {
|
|
|
191
192
|
}
|
|
192
193
|
}
|
|
193
194
|
/* ── deprecate ── */
|
|
194
|
-
#executeDeprecate(proposal, metrics, snapshot, result) {
|
|
195
|
+
async #executeDeprecate(proposal, metrics, snapshot, result) {
|
|
195
196
|
const currentDecay = metrics.decayScore;
|
|
196
197
|
const snapshotDecay = snapshot?.decayScore ?? currentDecay;
|
|
197
198
|
// 观察期内 decayScore 有回升 → 拒绝
|
|
198
199
|
if (currentDecay > snapshotDecay + 10) {
|
|
199
|
-
this.#restoreRecipe(proposal.targetRecipeId);
|
|
200
|
+
await this.#restoreRecipe(proposal.targetRecipeId);
|
|
200
201
|
this.#repo.markRejected(proposal.id, `decayScore recovered: ${snapshotDecay} → ${currentDecay}`);
|
|
201
202
|
result.rejected.push({
|
|
202
203
|
id: proposal.id,
|
|
@@ -209,17 +210,17 @@ export class ProposalExecutor {
|
|
|
209
210
|
// 无回升 → 根据 decayScore 决定操作
|
|
210
211
|
if (currentDecay <= 19) {
|
|
211
212
|
// 死亡 → 直接 deprecated
|
|
212
|
-
this.#transitionRecipe(proposal.targetRecipeId, 'deprecated', 'proposal-execution', proposal.id);
|
|
213
|
+
await this.#transitionRecipe(proposal.targetRecipeId, 'deprecated', 'proposal-execution', proposal.id);
|
|
213
214
|
this.#repo.markExecuted(proposal.id, `deprecated (dead): decayScore=${currentDecay}`);
|
|
214
215
|
}
|
|
215
216
|
else if (currentDecay <= 40) {
|
|
216
217
|
// 严重 → decaying
|
|
217
|
-
this.#transitionRecipe(proposal.targetRecipeId, 'decaying', 'proposal-execution', proposal.id);
|
|
218
|
+
await this.#transitionRecipe(proposal.targetRecipeId, 'decaying', 'proposal-execution', proposal.id);
|
|
218
219
|
this.#repo.markExecuted(proposal.id, `decaying (severe): decayScore=${currentDecay}`);
|
|
219
220
|
}
|
|
220
221
|
else {
|
|
221
222
|
// 衰退减缓 → 拒绝
|
|
222
|
-
this.#restoreRecipe(proposal.targetRecipeId);
|
|
223
|
+
await this.#restoreRecipe(proposal.targetRecipeId);
|
|
223
224
|
this.#repo.markRejected(proposal.id, `decayScore above threshold (${currentDecay}), not critical enough`);
|
|
224
225
|
result.rejected.push({
|
|
225
226
|
id: proposal.id,
|
|
@@ -237,20 +238,19 @@ export class ProposalExecutor {
|
|
|
237
238
|
this.#emitSignal(proposal, 'executed');
|
|
238
239
|
}
|
|
239
240
|
/* ── correction ── */
|
|
240
|
-
#executeCorrection(proposal, metrics, result) {
|
|
241
|
+
async #executeCorrection(proposal, metrics, result) {
|
|
241
242
|
// correction 低风险,到期直接执行(Recipe → evolving → patch → staging 重新审核)
|
|
242
243
|
const hasUsage = metrics.guardHits > 0 || metrics.searchHits > 0;
|
|
243
244
|
if (hasUsage) {
|
|
244
|
-
this.#transitionRecipe(proposal.targetRecipeId, 'evolving', 'proposal-attach', proposal.id);
|
|
245
|
-
const patchResult = this.#tryApplyPatch(proposal, 'correction');
|
|
245
|
+
await this.#transitionRecipe(proposal.targetRecipeId, 'evolving', 'proposal-attach', proposal.id);
|
|
246
|
+
const patchResult = await this.#tryApplyPatch(proposal, 'correction');
|
|
246
247
|
if (patchResult?.skipped || (!patchResult?.success && patchResult !== null)) {
|
|
247
|
-
|
|
248
|
-
this.#transitionRecipe(proposal.targetRecipeId, 'active', 'content-patch-complete', proposal.id);
|
|
248
|
+
await this.#transitionRecipe(proposal.targetRecipeId, 'active', 'content-patch-complete', proposal.id);
|
|
249
249
|
const skipInfo = patchResult?.skipReason ? `: ${patchResult.skipReason}` : '';
|
|
250
250
|
this.#repo.markExecuted(proposal.id, `correction patch 未生效${skipInfo}, 回退 active`);
|
|
251
251
|
}
|
|
252
252
|
else {
|
|
253
|
-
this.#transitionRecipe(proposal.targetRecipeId, 'staging', 'content-patch-complete', proposal.id);
|
|
253
|
+
await this.#transitionRecipe(proposal.targetRecipeId, 'staging', 'content-patch-complete', proposal.id);
|
|
254
254
|
const patchInfo = patchResult?.success
|
|
255
255
|
? `, patched=[${patchResult.fieldsPatched.join(',')}]`
|
|
256
256
|
: '';
|
|
@@ -289,11 +289,9 @@ export class ProposalExecutor {
|
|
|
289
289
|
}
|
|
290
290
|
}
|
|
291
291
|
/* ═══════════════════ DB Helpers ═══════════════════ */
|
|
292
|
-
#collectRecipeMetrics(recipeId) {
|
|
293
|
-
const
|
|
294
|
-
|
|
295
|
-
.get(recipeId);
|
|
296
|
-
if (!row) {
|
|
292
|
+
async #collectRecipeMetrics(recipeId) {
|
|
293
|
+
const entry = await this.#knowledgeRepo.findById(recipeId);
|
|
294
|
+
if (!entry) {
|
|
297
295
|
return {
|
|
298
296
|
guardHits: 0,
|
|
299
297
|
searchHits: 0,
|
|
@@ -303,8 +301,8 @@ export class ProposalExecutor {
|
|
|
303
301
|
quality: 0,
|
|
304
302
|
};
|
|
305
303
|
}
|
|
306
|
-
const stats =
|
|
307
|
-
const quality =
|
|
304
|
+
const stats = (entry.stats ?? {});
|
|
305
|
+
const quality = (entry.quality ?? {});
|
|
308
306
|
return {
|
|
309
307
|
guardHits: stats.guardHits ?? 0,
|
|
310
308
|
searchHits: stats.searchHits ?? 0,
|
|
@@ -330,15 +328,13 @@ export class ProposalExecutor {
|
|
|
330
328
|
}
|
|
331
329
|
return null;
|
|
332
330
|
}
|
|
333
|
-
#getRecipeLifecycle(recipeId) {
|
|
334
|
-
const
|
|
335
|
-
|
|
336
|
-
.get(recipeId);
|
|
337
|
-
return row ?? null;
|
|
331
|
+
async #getRecipeLifecycle(recipeId) {
|
|
332
|
+
const entry = await this.#knowledgeRepo.findById(recipeId);
|
|
333
|
+
return entry ? { lifecycle: entry.lifecycle } : null;
|
|
338
334
|
}
|
|
339
|
-
#transitionRecipe(recipeId, newLifecycle, trigger = 'proposal-execution', proposalId) {
|
|
335
|
+
async #transitionRecipe(recipeId, newLifecycle, trigger = 'proposal-execution', proposalId) {
|
|
340
336
|
if (this.#supervisor) {
|
|
341
|
-
const result = this.#supervisor.transition({
|
|
337
|
+
const result = await this.#supervisor.transition({
|
|
342
338
|
recipeId,
|
|
343
339
|
targetState: newLifecycle,
|
|
344
340
|
trigger,
|
|
@@ -347,48 +343,47 @@ export class ProposalExecutor {
|
|
|
347
343
|
});
|
|
348
344
|
if (!result.success) {
|
|
349
345
|
this.#logger.warn(`[ProposalExecutor] Supervisor rejected transition ${recipeId} → ${newLifecycle}: ${result.error}`);
|
|
350
|
-
|
|
351
|
-
this.#db
|
|
352
|
-
.prepare(`UPDATE knowledge_entries SET lifecycle = ?, updatedAt = ? WHERE id = ?`)
|
|
353
|
-
.run(newLifecycle, Date.now(), recipeId);
|
|
346
|
+
await this.#knowledgeRepo.updateLifecycle(recipeId, newLifecycle);
|
|
354
347
|
}
|
|
355
348
|
}
|
|
356
349
|
else {
|
|
357
|
-
this.#
|
|
358
|
-
.prepare(`UPDATE knowledge_entries SET lifecycle = ?, updatedAt = ? WHERE id = ?`)
|
|
359
|
-
.run(newLifecycle, Date.now(), recipeId);
|
|
350
|
+
await this.#knowledgeRepo.updateLifecycle(recipeId, newLifecycle);
|
|
360
351
|
}
|
|
361
352
|
}
|
|
362
|
-
#restoreRecipe(recipeId) {
|
|
363
|
-
|
|
364
|
-
const current = this.#getRecipeLifecycle(recipeId);
|
|
353
|
+
async #restoreRecipe(recipeId) {
|
|
354
|
+
const current = await this.#getRecipeLifecycle(recipeId);
|
|
365
355
|
if (current && (current.lifecycle === 'evolving' || current.lifecycle === 'decaying')) {
|
|
366
|
-
this.#transitionRecipe(recipeId, 'active');
|
|
356
|
+
await this.#transitionRecipe(recipeId, 'active');
|
|
367
357
|
}
|
|
368
358
|
}
|
|
369
359
|
/**
|
|
370
360
|
* 尝试通过 ContentPatcher 应用 Proposal 中的 suggestedChanges
|
|
371
361
|
* 降级容忍:无 ContentPatcher 或 patch 失败时返回 null/skipped,不阻塞状态转移
|
|
372
362
|
*/
|
|
373
|
-
#tryApplyPatch(proposal, patchSource) {
|
|
363
|
+
async #tryApplyPatch(proposal, patchSource) {
|
|
374
364
|
if (!this.#contentPatcher) {
|
|
375
365
|
return null;
|
|
376
366
|
}
|
|
377
367
|
try {
|
|
378
|
-
return this.#contentPatcher.applyProposal(proposal, patchSource);
|
|
368
|
+
return await this.#contentPatcher.applyProposal(proposal, patchSource);
|
|
379
369
|
}
|
|
380
370
|
catch (err) {
|
|
381
371
|
this.#logger.warn(`[ProposalExecutor] ContentPatcher failed for proposal ${proposal.id}: ${err instanceof Error ? err.message : String(err)}`);
|
|
382
372
|
return null;
|
|
383
373
|
}
|
|
384
374
|
}
|
|
385
|
-
#createDeprecatedByEdge(newRecipeId, oldRecipeId) {
|
|
386
|
-
const now = Date.now();
|
|
375
|
+
async #createDeprecatedByEdge(newRecipeId, oldRecipeId) {
|
|
387
376
|
try {
|
|
388
|
-
this.#
|
|
389
|
-
.
|
|
390
|
-
|
|
391
|
-
|
|
377
|
+
if (this.#edgeRepo) {
|
|
378
|
+
await this.#edgeRepo.upsertEdge({
|
|
379
|
+
fromId: newRecipeId,
|
|
380
|
+
fromType: 'recipe',
|
|
381
|
+
toId: oldRecipeId,
|
|
382
|
+
toType: 'recipe',
|
|
383
|
+
relation: 'deprecated_by',
|
|
384
|
+
weight: 1.0,
|
|
385
|
+
});
|
|
386
|
+
}
|
|
392
387
|
}
|
|
393
388
|
catch {
|
|
394
389
|
// knowledge_edges 表可能不存在(降级容忍)
|
|
@@ -411,7 +406,7 @@ export class ProposalExecutor {
|
|
|
411
406
|
}
|
|
412
407
|
}
|
|
413
408
|
/* ────────────────────── Util ────────────────────── */
|
|
414
|
-
function
|
|
409
|
+
function _safeJsonParse(json, fallback) {
|
|
415
410
|
if (!json) {
|
|
416
411
|
return fallback;
|
|
417
412
|
}
|
|
@@ -17,20 +17,16 @@
|
|
|
17
17
|
* @module service/evolution/RecipeLifecycleSupervisor
|
|
18
18
|
*/
|
|
19
19
|
import type { SignalBus } from '../../infrastructure/signal/SignalBus.js';
|
|
20
|
+
import type { LifecycleEventRepository } from '../../repository/evolution/LifecycleEventRepository.js';
|
|
21
|
+
import type { ProposalRepository } from '../../repository/evolution/ProposalRepository.js';
|
|
22
|
+
import type KnowledgeRepositoryImpl from '../../repository/knowledge/KnowledgeRepository.impl.js';
|
|
20
23
|
import type { LifecycleHealthSummary, TimeoutCheckResult, TransitionEvent, TransitionRequest, TransitionResult } from '../../types/evolution.js';
|
|
21
|
-
interface DatabaseLike {
|
|
22
|
-
prepare(sql: string): {
|
|
23
|
-
all(...params: unknown[]): Record<string, unknown>[];
|
|
24
|
-
get(...params: unknown[]): Record<string, unknown> | undefined;
|
|
25
|
-
run(...params: unknown[]): {
|
|
26
|
-
changes: number;
|
|
27
|
-
};
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
24
|
export declare class RecipeLifecycleSupervisor {
|
|
31
25
|
#private;
|
|
32
|
-
constructor(
|
|
26
|
+
constructor(knowledgeRepo: KnowledgeRepositoryImpl, options?: {
|
|
33
27
|
signalBus?: SignalBus;
|
|
28
|
+
lifecycleEventRepo?: LifecycleEventRepository;
|
|
29
|
+
proposalRepo?: ProposalRepository;
|
|
34
30
|
});
|
|
35
31
|
/**
|
|
36
32
|
* 执行状态转移 — 统一入口
|
|
@@ -43,7 +39,7 @@ export declare class RecipeLifecycleSupervisor {
|
|
|
43
39
|
* 6. 记录 TransitionEvent
|
|
44
40
|
* 7. 发射信号
|
|
45
41
|
*/
|
|
46
|
-
transition(request: TransitionRequest): TransitionResult
|
|
42
|
+
transition(request: TransitionRequest): Promise<TransitionResult>;
|
|
47
43
|
/**
|
|
48
44
|
* 检查中间态超时 + 自动处理
|
|
49
45
|
*
|
|
@@ -51,7 +47,7 @@ export declare class RecipeLifecycleSupervisor {
|
|
|
51
47
|
* - evolving > 7d → active(回退)
|
|
52
48
|
* - decaying > 30d → deprecated
|
|
53
49
|
*/
|
|
54
|
-
checkTimeouts(): TimeoutCheckResult
|
|
50
|
+
checkTimeouts(): Promise<TimeoutCheckResult>;
|
|
55
51
|
/**
|
|
56
52
|
* 查询 Recipe 的转移历史
|
|
57
53
|
*/
|
|
@@ -59,6 +55,5 @@ export declare class RecipeLifecycleSupervisor {
|
|
|
59
55
|
/**
|
|
60
56
|
* 获取全局状态健康摘要
|
|
61
57
|
*/
|
|
62
|
-
getHealthSummary(): LifecycleHealthSummary
|
|
58
|
+
getHealthSummary(): Promise<LifecycleHealthSummary>;
|
|
63
59
|
}
|
|
64
|
-
export {};
|