agentic-qe 1.0.5 → 1.1.0
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/.claude/agents/qe-quality-analyzer.md +405 -0
- package/CHANGELOG.md +109 -0
- package/CONTRIBUTING.md +51 -0
- package/README.md +669 -162
- package/bin/aqe +90 -938
- package/dist/adapters/MemoryStoreAdapter.d.ts.map +1 -1
- package/dist/adapters/MemoryStoreAdapter.js +6 -0
- package/dist/adapters/MemoryStoreAdapter.js.map +1 -1
- package/dist/agents/CoverageAnalyzerAgent.d.ts +58 -3
- package/dist/agents/CoverageAnalyzerAgent.d.ts.map +1 -1
- package/dist/agents/CoverageAnalyzerAgent.js +316 -48
- package/dist/agents/CoverageAnalyzerAgent.js.map +1 -1
- package/dist/agents/FlakyTestHunterAgent.d.ts +48 -4
- package/dist/agents/FlakyTestHunterAgent.d.ts.map +1 -1
- package/dist/agents/FlakyTestHunterAgent.js +217 -10
- package/dist/agents/FlakyTestHunterAgent.js.map +1 -1
- package/dist/agents/LearningAgent.d.ts +75 -0
- package/dist/agents/LearningAgent.d.ts.map +1 -0
- package/dist/agents/LearningAgent.js +177 -0
- package/dist/agents/LearningAgent.js.map +1 -0
- package/dist/agents/TestGeneratorAgent.d.ts +42 -2
- package/dist/agents/TestGeneratorAgent.d.ts.map +1 -1
- package/dist/agents/TestGeneratorAgent.js +232 -13
- package/dist/agents/TestGeneratorAgent.js.map +1 -1
- package/dist/cli/commands/improve/index.d.ts +70 -0
- package/dist/cli/commands/improve/index.d.ts.map +1 -0
- package/dist/cli/commands/improve/index.js +530 -0
- package/dist/cli/commands/improve/index.js.map +1 -0
- package/dist/cli/commands/init.d.ts +33 -0
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +656 -39
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/learn/index.d.ts +68 -0
- package/dist/cli/commands/learn/index.d.ts.map +1 -0
- package/dist/cli/commands/learn/index.js +431 -0
- package/dist/cli/commands/learn/index.js.map +1 -0
- package/dist/cli/commands/patterns/index.d.ts +75 -0
- package/dist/cli/commands/patterns/index.d.ts.map +1 -0
- package/dist/cli/commands/patterns/index.js +502 -0
- package/dist/cli/commands/patterns/index.js.map +1 -0
- package/dist/cli/index.js +367 -8
- package/dist/cli/index.js.map +1 -1
- package/dist/core/memory/SwarmMemoryManager.d.ts +5 -0
- package/dist/core/memory/SwarmMemoryManager.d.ts.map +1 -1
- package/dist/core/memory/SwarmMemoryManager.js +7 -0
- package/dist/core/memory/SwarmMemoryManager.js.map +1 -1
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -1
- package/dist/learning/FlakyFixRecommendations.d.ts +40 -0
- package/dist/learning/FlakyFixRecommendations.d.ts.map +1 -0
- package/dist/learning/FlakyFixRecommendations.js +247 -0
- package/dist/learning/FlakyFixRecommendations.js.map +1 -0
- package/dist/learning/FlakyPredictionModel.d.ts +57 -0
- package/dist/learning/FlakyPredictionModel.d.ts.map +1 -0
- package/dist/learning/FlakyPredictionModel.js +289 -0
- package/dist/learning/FlakyPredictionModel.js.map +1 -0
- package/dist/learning/FlakyTestDetector.d.ts +46 -0
- package/dist/learning/FlakyTestDetector.d.ts.map +1 -0
- package/dist/learning/FlakyTestDetector.js +215 -0
- package/dist/learning/FlakyTestDetector.js.map +1 -0
- package/dist/learning/ImprovementLoop.d.ts +119 -0
- package/dist/learning/ImprovementLoop.d.ts.map +1 -0
- package/dist/learning/ImprovementLoop.js +353 -0
- package/dist/learning/ImprovementLoop.js.map +1 -0
- package/dist/learning/LearningEngine.d.ts +144 -0
- package/dist/learning/LearningEngine.d.ts.map +1 -0
- package/dist/learning/LearningEngine.js +531 -0
- package/dist/learning/LearningEngine.js.map +1 -0
- package/dist/learning/PerformanceTracker.d.ts +118 -0
- package/dist/learning/PerformanceTracker.d.ts.map +1 -0
- package/dist/learning/PerformanceTracker.js +376 -0
- package/dist/learning/PerformanceTracker.js.map +1 -0
- package/dist/learning/StatisticalAnalysis.d.ts +47 -0
- package/dist/learning/StatisticalAnalysis.d.ts.map +1 -0
- package/dist/learning/StatisticalAnalysis.js +170 -0
- package/dist/learning/StatisticalAnalysis.js.map +1 -0
- package/dist/learning/SwarmIntegration.d.ts +107 -0
- package/dist/learning/SwarmIntegration.d.ts.map +1 -0
- package/dist/learning/SwarmIntegration.js +191 -0
- package/dist/learning/SwarmIntegration.js.map +1 -0
- package/dist/learning/index.d.ts +10 -0
- package/dist/learning/index.d.ts.map +1 -0
- package/dist/learning/index.js +16 -0
- package/dist/learning/index.js.map +1 -0
- package/dist/learning/types.d.ts +288 -0
- package/dist/learning/types.d.ts.map +1 -0
- package/dist/learning/types.js +9 -0
- package/dist/learning/types.js.map +1 -0
- package/dist/mcp/handlers/phase2/Phase2Tools.d.ts +175 -0
- package/dist/mcp/handlers/phase2/Phase2Tools.d.ts.map +1 -0
- package/dist/mcp/handlers/phase2/Phase2Tools.js +693 -0
- package/dist/mcp/handlers/phase2/Phase2Tools.js.map +1 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +94 -0
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools.d.ts +15 -0
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +17 -1
- package/dist/mcp/tools.js.map +1 -1
- package/dist/reasoning/CodeSignatureGenerator.d.ts +98 -0
- package/dist/reasoning/CodeSignatureGenerator.d.ts.map +1 -0
- package/dist/reasoning/CodeSignatureGenerator.js +427 -0
- package/dist/reasoning/CodeSignatureGenerator.js.map +1 -0
- package/dist/reasoning/PatternClassifier.d.ts +98 -0
- package/dist/reasoning/PatternClassifier.d.ts.map +1 -0
- package/dist/reasoning/PatternClassifier.js +345 -0
- package/dist/reasoning/PatternClassifier.js.map +1 -0
- package/dist/reasoning/PatternExtractor.d.ts +131 -0
- package/dist/reasoning/PatternExtractor.d.ts.map +1 -0
- package/dist/reasoning/PatternExtractor.js +539 -0
- package/dist/reasoning/PatternExtractor.js.map +1 -0
- package/dist/reasoning/PatternMemoryIntegration.d.ts +102 -0
- package/dist/reasoning/PatternMemoryIntegration.d.ts.map +1 -0
- package/dist/reasoning/PatternMemoryIntegration.js +336 -0
- package/dist/reasoning/PatternMemoryIntegration.js.map +1 -0
- package/dist/reasoning/QEReasoningBank.d.ts +121 -0
- package/dist/reasoning/QEReasoningBank.d.ts.map +1 -0
- package/dist/reasoning/QEReasoningBank.js +235 -0
- package/dist/reasoning/QEReasoningBank.js.map +1 -0
- package/dist/reasoning/TestTemplateCreator.d.ts +95 -0
- package/dist/reasoning/TestTemplateCreator.d.ts.map +1 -0
- package/dist/reasoning/TestTemplateCreator.js +535 -0
- package/dist/reasoning/TestTemplateCreator.js.map +1 -0
- package/dist/reasoning/index.d.ts +10 -0
- package/dist/reasoning/index.d.ts.map +1 -0
- package/dist/reasoning/index.js +31 -0
- package/dist/reasoning/index.js.map +1 -0
- package/dist/reasoning/types.d.ts +717 -0
- package/dist/reasoning/types.d.ts.map +1 -0
- package/dist/reasoning/types.js +57 -0
- package/dist/reasoning/types.js.map +1 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/pattern.types.d.ts +364 -0
- package/dist/types/pattern.types.d.ts.map +1 -0
- package/dist/types/pattern.types.js +60 -0
- package/dist/types/pattern.types.js.map +1 -0
- package/package.json +25 -3
|
@@ -0,0 +1,693 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Phase2ToolsHandler - Management Tools for Phase 2 Features
|
|
4
|
+
*
|
|
5
|
+
* Implements 15 MCP tools for managing Phase 2 capabilities:
|
|
6
|
+
* - Learning Engine (5 tools)
|
|
7
|
+
* - Pattern Management (5 tools)
|
|
8
|
+
* - Improvement Loop (5 tools)
|
|
9
|
+
*
|
|
10
|
+
* @version 1.0.0
|
|
11
|
+
* @author Agentic QE Team
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.Phase2ToolsHandler = void 0;
|
|
15
|
+
const base_handler_1 = require("../base-handler");
|
|
16
|
+
const SwarmMemoryManager_1 = require("../../../core/memory/SwarmMemoryManager");
|
|
17
|
+
const LearningEngine_1 = require("../../../learning/LearningEngine");
|
|
18
|
+
const ImprovementLoop_1 = require("../../../learning/ImprovementLoop");
|
|
19
|
+
const PerformanceTracker_1 = require("../../../learning/PerformanceTracker");
|
|
20
|
+
const QEReasoningBank_1 = require("../../../reasoning/QEReasoningBank");
|
|
21
|
+
const PatternExtractor_1 = require("../../../reasoning/PatternExtractor");
|
|
22
|
+
/**
|
|
23
|
+
* Phase2ToolsHandler - Main handler for Phase 2 management tools
|
|
24
|
+
*/
|
|
25
|
+
class Phase2ToolsHandler extends base_handler_1.BaseHandler {
|
|
26
|
+
constructor(registry, hookExecutor, memoryStore) {
|
|
27
|
+
super();
|
|
28
|
+
this.registry = registry;
|
|
29
|
+
this.hookExecutor = hookExecutor;
|
|
30
|
+
this.learningEngines = new Map();
|
|
31
|
+
this.improvementLoops = new Map();
|
|
32
|
+
this.performanceTrackers = new Map();
|
|
33
|
+
this.reasoningBank = new QEReasoningBank_1.QEReasoningBank();
|
|
34
|
+
this.patternExtractor = new PatternExtractor_1.PatternExtractor();
|
|
35
|
+
this.memoryStore = memoryStore || new SwarmMemoryManager_1.SwarmMemoryManager();
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Main handle method - routes to specific tool handlers
|
|
39
|
+
*/
|
|
40
|
+
async handle(args) {
|
|
41
|
+
throw new Error('Use specific tool methods instead of generic handle()');
|
|
42
|
+
}
|
|
43
|
+
// =========================================================================
|
|
44
|
+
// LEARNING ENGINE TOOLS (5 tools)
|
|
45
|
+
// =========================================================================
|
|
46
|
+
/**
|
|
47
|
+
* Tool 1: learning_status
|
|
48
|
+
* Get learning engine status and performance metrics
|
|
49
|
+
*/
|
|
50
|
+
async handleLearningStatus(args) {
|
|
51
|
+
const requestId = this.generateRequestId();
|
|
52
|
+
try {
|
|
53
|
+
const { agentId, detailed = false } = args;
|
|
54
|
+
if (agentId) {
|
|
55
|
+
// Get specific agent learning status
|
|
56
|
+
const engine = this.learningEngines.get(agentId);
|
|
57
|
+
if (!engine) {
|
|
58
|
+
return this.createErrorResponse(`Learning engine not found for agent: ${agentId}`, requestId);
|
|
59
|
+
}
|
|
60
|
+
const status = {
|
|
61
|
+
agentId,
|
|
62
|
+
enabled: engine.isEnabled(),
|
|
63
|
+
totalExperiences: engine.getTotalExperiences(),
|
|
64
|
+
explorationRate: engine.getExplorationRate(),
|
|
65
|
+
patterns: detailed ? engine.getPatterns() : engine.getPatterns().slice(0, 5),
|
|
66
|
+
failurePatterns: detailed ? engine.getFailurePatterns() : engine.getFailurePatterns().slice(0, 3)
|
|
67
|
+
};
|
|
68
|
+
return this.createSuccessResponse(status, requestId);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
// Get all agents learning status
|
|
72
|
+
const allStatuses = [];
|
|
73
|
+
for (const [id, engine] of this.learningEngines.entries()) {
|
|
74
|
+
allStatuses.push({
|
|
75
|
+
agentId: id,
|
|
76
|
+
enabled: engine.isEnabled(),
|
|
77
|
+
totalExperiences: engine.getTotalExperiences(),
|
|
78
|
+
explorationRate: engine.getExplorationRate(),
|
|
79
|
+
patternsCount: engine.getPatterns().length,
|
|
80
|
+
failurePatternsCount: engine.getFailurePatterns().length
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
return this.createSuccessResponse({
|
|
84
|
+
totalAgents: this.learningEngines.size,
|
|
85
|
+
agents: allStatuses
|
|
86
|
+
}, requestId);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
this.log('error', 'Failed to get learning status', error);
|
|
91
|
+
return this.createErrorResponse(error instanceof Error ? error.message : 'Unknown error', requestId);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Tool 2: learning_train
|
|
96
|
+
* Trigger manual learning from task execution
|
|
97
|
+
*/
|
|
98
|
+
async handleLearningTrain(args) {
|
|
99
|
+
const requestId = this.generateRequestId();
|
|
100
|
+
try {
|
|
101
|
+
this.validateRequired(args, ['agentId', 'task', 'result']);
|
|
102
|
+
const { agentId, task, result, feedback } = args;
|
|
103
|
+
// Get or create learning engine
|
|
104
|
+
let engine = this.learningEngines.get(agentId);
|
|
105
|
+
if (!engine) {
|
|
106
|
+
engine = new LearningEngine_1.LearningEngine(agentId, this.memoryStore);
|
|
107
|
+
await engine.initialize();
|
|
108
|
+
this.learningEngines.set(agentId, engine);
|
|
109
|
+
}
|
|
110
|
+
// Learn from execution
|
|
111
|
+
const outcome = await engine.learnFromExecution(task, result, feedback);
|
|
112
|
+
this.log('info', `Learning completed for agent ${agentId}`, {
|
|
113
|
+
improved: outcome.improved,
|
|
114
|
+
improvementRate: outcome.improvementRate
|
|
115
|
+
});
|
|
116
|
+
return this.createSuccessResponse({
|
|
117
|
+
agentId,
|
|
118
|
+
learning: outcome,
|
|
119
|
+
totalExperiences: engine.getTotalExperiences()
|
|
120
|
+
}, requestId);
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
this.log('error', 'Failed to train learning engine', error);
|
|
124
|
+
return this.createErrorResponse(error instanceof Error ? error.message : 'Unknown error', requestId);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Tool 3: learning_history
|
|
129
|
+
* Get learning history and experience replay data
|
|
130
|
+
*/
|
|
131
|
+
async handleLearningHistory(args) {
|
|
132
|
+
const requestId = this.generateRequestId();
|
|
133
|
+
try {
|
|
134
|
+
this.validateRequired(args, ['agentId']);
|
|
135
|
+
const { agentId, limit = 20 } = args;
|
|
136
|
+
// Retrieve from memory store
|
|
137
|
+
const experiencesKey = `phase2/learning/${agentId}/state`;
|
|
138
|
+
const state = await this.memoryStore.retrieve(experiencesKey, { partition: 'learning' });
|
|
139
|
+
if (!state) {
|
|
140
|
+
return this.createErrorResponse(`No learning history found for agent: ${agentId}`, requestId);
|
|
141
|
+
}
|
|
142
|
+
const experiences = state.experiences || [];
|
|
143
|
+
const limitedExperiences = experiences.slice(-limit);
|
|
144
|
+
return this.createSuccessResponse({
|
|
145
|
+
agentId,
|
|
146
|
+
totalExperiences: experiences.length,
|
|
147
|
+
experiences: limitedExperiences,
|
|
148
|
+
patterns: state.patterns || [],
|
|
149
|
+
performance: state.performance || {}
|
|
150
|
+
}, requestId);
|
|
151
|
+
}
|
|
152
|
+
catch (error) {
|
|
153
|
+
this.log('error', 'Failed to get learning history', error);
|
|
154
|
+
return this.createErrorResponse(error instanceof Error ? error.message : 'Unknown error', requestId);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Tool 4: learning_reset
|
|
159
|
+
* Reset learning state for an agent
|
|
160
|
+
*/
|
|
161
|
+
async handleLearningReset(args) {
|
|
162
|
+
const requestId = this.generateRequestId();
|
|
163
|
+
try {
|
|
164
|
+
this.validateRequired(args, ['agentId', 'confirm']);
|
|
165
|
+
const { agentId, confirm } = args;
|
|
166
|
+
if (!confirm) {
|
|
167
|
+
return this.createErrorResponse('Confirmation required to reset learning state', requestId);
|
|
168
|
+
}
|
|
169
|
+
// Remove learning engine
|
|
170
|
+
this.learningEngines.delete(agentId);
|
|
171
|
+
// Clear memory state
|
|
172
|
+
const stateKey = `phase2/learning/${agentId}/state`;
|
|
173
|
+
const baselineKey = `phase2/learning/${agentId}/baseline`;
|
|
174
|
+
const configKey = `phase2/learning/${agentId}/config`;
|
|
175
|
+
// Note: SwarmMemoryManager doesn't have delete, so we'll store empty state
|
|
176
|
+
await this.memoryStore.store(stateKey, null, { partition: 'learning' });
|
|
177
|
+
await this.memoryStore.store(baselineKey, null, { partition: 'learning' });
|
|
178
|
+
await this.memoryStore.store(configKey, null, { partition: 'learning' });
|
|
179
|
+
this.log('info', `Learning state reset for agent ${agentId}`);
|
|
180
|
+
return this.createSuccessResponse({
|
|
181
|
+
agentId,
|
|
182
|
+
reset: true,
|
|
183
|
+
timestamp: new Date().toISOString()
|
|
184
|
+
}, requestId);
|
|
185
|
+
}
|
|
186
|
+
catch (error) {
|
|
187
|
+
this.log('error', 'Failed to reset learning state', error);
|
|
188
|
+
return this.createErrorResponse(error instanceof Error ? error.message : 'Unknown error', requestId);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Tool 5: learning_export
|
|
193
|
+
* Export learning data for backup or analysis
|
|
194
|
+
*/
|
|
195
|
+
async handleLearningExport(args) {
|
|
196
|
+
const requestId = this.generateRequestId();
|
|
197
|
+
try {
|
|
198
|
+
const { agentId, format = 'json' } = args;
|
|
199
|
+
if (agentId) {
|
|
200
|
+
// Export specific agent data
|
|
201
|
+
const stateKey = `phase2/learning/${agentId}/state`;
|
|
202
|
+
const state = await this.memoryStore.retrieve(stateKey, { partition: 'learning' });
|
|
203
|
+
if (!state) {
|
|
204
|
+
return this.createErrorResponse(`No learning data found for agent: ${agentId}`, requestId);
|
|
205
|
+
}
|
|
206
|
+
if (format === 'json') {
|
|
207
|
+
return this.createSuccessResponse({
|
|
208
|
+
format: 'json',
|
|
209
|
+
data: state
|
|
210
|
+
}, requestId);
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
// Convert to CSV
|
|
214
|
+
const csv = this.convertToCSV(state);
|
|
215
|
+
return this.createSuccessResponse({
|
|
216
|
+
format: 'csv',
|
|
217
|
+
data: csv
|
|
218
|
+
}, requestId);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
// Export all agents data
|
|
223
|
+
const allData = {};
|
|
224
|
+
for (const id of this.learningEngines.keys()) {
|
|
225
|
+
const stateKey = `phase2/learning/${id}/state`;
|
|
226
|
+
const state = await this.memoryStore.retrieve(stateKey, { partition: 'learning' });
|
|
227
|
+
if (state) {
|
|
228
|
+
allData[id] = state;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return this.createSuccessResponse({
|
|
232
|
+
format,
|
|
233
|
+
data: format === 'json' ? allData : this.convertToCSV(allData)
|
|
234
|
+
}, requestId);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
catch (error) {
|
|
238
|
+
this.log('error', 'Failed to export learning data', error);
|
|
239
|
+
return this.createErrorResponse(error instanceof Error ? error.message : 'Unknown error', requestId);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
// =========================================================================
|
|
243
|
+
// PATTERN MANAGEMENT TOOLS (5 tools)
|
|
244
|
+
// =========================================================================
|
|
245
|
+
/**
|
|
246
|
+
* Tool 6: pattern_store
|
|
247
|
+
* Store a new test pattern in the reasoning bank
|
|
248
|
+
*/
|
|
249
|
+
async handlePatternStore(args) {
|
|
250
|
+
const requestId = this.generateRequestId();
|
|
251
|
+
try {
|
|
252
|
+
this.validateRequired(args, ['pattern']);
|
|
253
|
+
const { pattern } = args;
|
|
254
|
+
// Validate pattern structure
|
|
255
|
+
if (!pattern.id || !pattern.name || !pattern.template) {
|
|
256
|
+
return this.createErrorResponse('Invalid pattern: id, name, and template are required', requestId);
|
|
257
|
+
}
|
|
258
|
+
// Store pattern
|
|
259
|
+
await this.reasoningBank.storePattern(pattern);
|
|
260
|
+
this.log('info', `Pattern stored: ${pattern.id} (${pattern.name})`);
|
|
261
|
+
return this.createSuccessResponse({
|
|
262
|
+
stored: true,
|
|
263
|
+
patternId: pattern.id,
|
|
264
|
+
name: pattern.name,
|
|
265
|
+
category: pattern.category,
|
|
266
|
+
framework: pattern.framework
|
|
267
|
+
}, requestId);
|
|
268
|
+
}
|
|
269
|
+
catch (error) {
|
|
270
|
+
this.log('error', 'Failed to store pattern', error);
|
|
271
|
+
return this.createErrorResponse(error instanceof Error ? error.message : 'Unknown error', requestId);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Tool 7: pattern_find
|
|
276
|
+
* Find matching patterns from reasoning bank
|
|
277
|
+
*/
|
|
278
|
+
async handlePatternFind(args) {
|
|
279
|
+
const requestId = this.generateRequestId();
|
|
280
|
+
try {
|
|
281
|
+
this.validateRequired(args, ['query']);
|
|
282
|
+
const { query, minConfidence = 0.85, limit = 10 } = args;
|
|
283
|
+
// Find matching patterns
|
|
284
|
+
const matches = await this.reasoningBank.findMatchingPatterns({
|
|
285
|
+
codeType: query.codeType || 'test',
|
|
286
|
+
framework: query.framework,
|
|
287
|
+
language: query.language,
|
|
288
|
+
keywords: query.keywords
|
|
289
|
+
}, limit);
|
|
290
|
+
// Filter by confidence
|
|
291
|
+
const filteredMatches = matches.filter(m => m.confidence >= minConfidence);
|
|
292
|
+
this.log('info', `Found ${filteredMatches.length} matching patterns`);
|
|
293
|
+
return this.createSuccessResponse({
|
|
294
|
+
query,
|
|
295
|
+
totalMatches: filteredMatches.length,
|
|
296
|
+
minConfidence,
|
|
297
|
+
patterns: filteredMatches.map(m => ({
|
|
298
|
+
pattern: m.pattern,
|
|
299
|
+
confidence: m.confidence,
|
|
300
|
+
reasoning: m.reasoning,
|
|
301
|
+
applicability: m.applicability
|
|
302
|
+
}))
|
|
303
|
+
}, requestId);
|
|
304
|
+
}
|
|
305
|
+
catch (error) {
|
|
306
|
+
this.log('error', 'Failed to find patterns', error);
|
|
307
|
+
return this.createErrorResponse(error instanceof Error ? error.message : 'Unknown error', requestId);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Tool 8: pattern_extract
|
|
312
|
+
* Extract patterns from existing test suite
|
|
313
|
+
*/
|
|
314
|
+
async handlePatternExtract(args) {
|
|
315
|
+
const requestId = this.generateRequestId();
|
|
316
|
+
try {
|
|
317
|
+
this.validateRequired(args, ['testFiles', 'projectId']);
|
|
318
|
+
const { testFiles, projectId } = args;
|
|
319
|
+
this.log('info', `Extracting patterns from ${testFiles.length} files`);
|
|
320
|
+
// Extract patterns
|
|
321
|
+
const result = await this.patternExtractor.extractFromFiles(testFiles);
|
|
322
|
+
// Store extracted patterns in reasoning bank
|
|
323
|
+
// Convert from pattern.types.TestPattern to reasoning.QEReasoningBank.TestPattern
|
|
324
|
+
for (const extractedPattern of result.patterns) {
|
|
325
|
+
try {
|
|
326
|
+
// Map the extracted pattern to the reasoning bank pattern format
|
|
327
|
+
const reasoningPattern = {
|
|
328
|
+
id: extractedPattern.id,
|
|
329
|
+
name: extractedPattern.name,
|
|
330
|
+
description: extractedPattern.template.description,
|
|
331
|
+
category: extractedPattern.category,
|
|
332
|
+
framework: extractedPattern.framework,
|
|
333
|
+
language: 'typescript', // Default, can be inferred from metadata
|
|
334
|
+
template: JSON.stringify(extractedPattern.template),
|
|
335
|
+
examples: extractedPattern.examples,
|
|
336
|
+
confidence: extractedPattern.confidence,
|
|
337
|
+
usageCount: extractedPattern.frequency || 0,
|
|
338
|
+
successRate: 0.5, // Default success rate for new patterns
|
|
339
|
+
metadata: {
|
|
340
|
+
createdAt: extractedPattern.createdAt,
|
|
341
|
+
updatedAt: extractedPattern.createdAt,
|
|
342
|
+
version: '1.0.0',
|
|
343
|
+
tags: extractedPattern.metadata?.tags || []
|
|
344
|
+
}
|
|
345
|
+
};
|
|
346
|
+
await this.reasoningBank.storePattern(reasoningPattern);
|
|
347
|
+
}
|
|
348
|
+
catch (error) {
|
|
349
|
+
this.log('warn', `Failed to store pattern ${extractedPattern.id}`, error);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
this.log('info', `Extracted ${result.patterns.length} patterns from ${testFiles.length} files`);
|
|
353
|
+
return this.createSuccessResponse({
|
|
354
|
+
projectId,
|
|
355
|
+
extraction: {
|
|
356
|
+
filesProcessed: result.statistics.filesProcessed,
|
|
357
|
+
patternsExtracted: result.patterns.length,
|
|
358
|
+
processingTime: result.statistics.processingTime,
|
|
359
|
+
patterns: result.patterns.map(p => ({
|
|
360
|
+
id: p.id,
|
|
361
|
+
name: p.name,
|
|
362
|
+
type: p.type,
|
|
363
|
+
confidence: p.confidence,
|
|
364
|
+
sourceFile: p.sourceFile
|
|
365
|
+
}))
|
|
366
|
+
},
|
|
367
|
+
errors: result.errors
|
|
368
|
+
}, requestId);
|
|
369
|
+
}
|
|
370
|
+
catch (error) {
|
|
371
|
+
this.log('error', 'Failed to extract patterns', error);
|
|
372
|
+
return this.createErrorResponse(error instanceof Error ? error.message : 'Unknown error', requestId);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Tool 9: pattern_share
|
|
377
|
+
* Share patterns across projects
|
|
378
|
+
*/
|
|
379
|
+
async handlePatternShare(args) {
|
|
380
|
+
const requestId = this.generateRequestId();
|
|
381
|
+
try {
|
|
382
|
+
this.validateRequired(args, ['patternId', 'projectIds']);
|
|
383
|
+
const { patternId, projectIds } = args;
|
|
384
|
+
// Get pattern
|
|
385
|
+
const pattern = await this.reasoningBank.getPattern(patternId);
|
|
386
|
+
if (!pattern) {
|
|
387
|
+
return this.createErrorResponse(`Pattern not found: ${patternId}`, requestId);
|
|
388
|
+
}
|
|
389
|
+
// Store pattern references in memory for each project
|
|
390
|
+
const sharedWith = [];
|
|
391
|
+
for (const projectId of projectIds) {
|
|
392
|
+
const key = `phase2/patterns/shared/${projectId}/${patternId}`;
|
|
393
|
+
await this.memoryStore.store(key, pattern, { partition: 'patterns' });
|
|
394
|
+
sharedWith.push(projectId);
|
|
395
|
+
}
|
|
396
|
+
this.log('info', `Pattern ${patternId} shared with ${projectIds.length} projects`);
|
|
397
|
+
return this.createSuccessResponse({
|
|
398
|
+
patternId,
|
|
399
|
+
pattern: pattern.name,
|
|
400
|
+
sharedWith,
|
|
401
|
+
timestamp: new Date().toISOString()
|
|
402
|
+
}, requestId);
|
|
403
|
+
}
|
|
404
|
+
catch (error) {
|
|
405
|
+
this.log('error', 'Failed to share pattern', error);
|
|
406
|
+
return this.createErrorResponse(error instanceof Error ? error.message : 'Unknown error', requestId);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* Tool 10: pattern_stats
|
|
411
|
+
* Get pattern bank statistics
|
|
412
|
+
*/
|
|
413
|
+
async handlePatternStats(args) {
|
|
414
|
+
const requestId = this.generateRequestId();
|
|
415
|
+
try {
|
|
416
|
+
const { framework } = args;
|
|
417
|
+
// Get overall statistics
|
|
418
|
+
const stats = await this.reasoningBank.getStatistics();
|
|
419
|
+
// Filter by framework if specified
|
|
420
|
+
let resultStats = stats;
|
|
421
|
+
if (framework) {
|
|
422
|
+
const frameworkCount = stats.byFramework[framework] || 0;
|
|
423
|
+
resultStats = {
|
|
424
|
+
...stats,
|
|
425
|
+
totalPatterns: frameworkCount,
|
|
426
|
+
filtered: true,
|
|
427
|
+
framework
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
return this.createSuccessResponse(resultStats, requestId);
|
|
431
|
+
}
|
|
432
|
+
catch (error) {
|
|
433
|
+
this.log('error', 'Failed to get pattern stats', error);
|
|
434
|
+
return this.createErrorResponse(error instanceof Error ? error.message : 'Unknown error', requestId);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
// =========================================================================
|
|
438
|
+
// IMPROVEMENT LOOP TOOLS (5 tools)
|
|
439
|
+
// =========================================================================
|
|
440
|
+
/**
|
|
441
|
+
* Tool 11: improvement_status
|
|
442
|
+
* Get improvement loop status
|
|
443
|
+
*/
|
|
444
|
+
async handleImprovementStatus(args) {
|
|
445
|
+
const requestId = this.generateRequestId();
|
|
446
|
+
try {
|
|
447
|
+
const { agentId } = args;
|
|
448
|
+
if (agentId) {
|
|
449
|
+
const loop = this.improvementLoops.get(agentId);
|
|
450
|
+
if (!loop) {
|
|
451
|
+
return this.createErrorResponse(`Improvement loop not found for agent: ${agentId}`, requestId);
|
|
452
|
+
}
|
|
453
|
+
return this.createSuccessResponse({
|
|
454
|
+
agentId,
|
|
455
|
+
active: loop.isActive(),
|
|
456
|
+
activeTests: loop.getActiveTests(),
|
|
457
|
+
strategies: loop.getStrategies()
|
|
458
|
+
}, requestId);
|
|
459
|
+
}
|
|
460
|
+
else {
|
|
461
|
+
// Get all improvement loops status
|
|
462
|
+
const statuses = [];
|
|
463
|
+
for (const [id, loop] of this.improvementLoops.entries()) {
|
|
464
|
+
statuses.push({
|
|
465
|
+
agentId: id,
|
|
466
|
+
active: loop.isActive(),
|
|
467
|
+
activeTestsCount: loop.getActiveTests().length,
|
|
468
|
+
strategiesCount: loop.getStrategies().length
|
|
469
|
+
});
|
|
470
|
+
}
|
|
471
|
+
return this.createSuccessResponse({
|
|
472
|
+
totalLoops: this.improvementLoops.size,
|
|
473
|
+
loops: statuses
|
|
474
|
+
}, requestId);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
catch (error) {
|
|
478
|
+
this.log('error', 'Failed to get improvement status', error);
|
|
479
|
+
return this.createErrorResponse(error instanceof Error ? error.message : 'Unknown error', requestId);
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* Tool 12: improvement_cycle
|
|
484
|
+
* Trigger improvement cycle
|
|
485
|
+
*/
|
|
486
|
+
async handleImprovementCycle(args) {
|
|
487
|
+
const requestId = this.generateRequestId();
|
|
488
|
+
try {
|
|
489
|
+
this.validateRequired(args, ['agentId']);
|
|
490
|
+
const { agentId, force = false } = args;
|
|
491
|
+
// Get or create improvement loop
|
|
492
|
+
let loop = this.improvementLoops.get(agentId);
|
|
493
|
+
if (!loop) {
|
|
494
|
+
// Create dependencies
|
|
495
|
+
const learningEngine = this.learningEngines.get(agentId) ||
|
|
496
|
+
new LearningEngine_1.LearningEngine(agentId, this.memoryStore);
|
|
497
|
+
const performanceTracker = this.performanceTrackers.get(agentId) ||
|
|
498
|
+
new PerformanceTracker_1.PerformanceTracker(agentId, this.memoryStore);
|
|
499
|
+
loop = new ImprovementLoop_1.ImprovementLoop(agentId, this.memoryStore, learningEngine, performanceTracker);
|
|
500
|
+
await loop.initialize();
|
|
501
|
+
this.improvementLoops.set(agentId, loop);
|
|
502
|
+
// Also store the dependencies
|
|
503
|
+
if (!this.learningEngines.has(agentId)) {
|
|
504
|
+
await learningEngine.initialize();
|
|
505
|
+
this.learningEngines.set(agentId, learningEngine);
|
|
506
|
+
}
|
|
507
|
+
if (!this.performanceTrackers.has(agentId)) {
|
|
508
|
+
await performanceTracker.initialize();
|
|
509
|
+
this.performanceTrackers.set(agentId, performanceTracker);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
// Run improvement cycle
|
|
513
|
+
await loop.runImprovementCycle();
|
|
514
|
+
this.log('info', `Improvement cycle completed for agent ${agentId}`);
|
|
515
|
+
return this.createSuccessResponse({
|
|
516
|
+
agentId,
|
|
517
|
+
cycleCompleted: true,
|
|
518
|
+
timestamp: new Date().toISOString(),
|
|
519
|
+
forced: force
|
|
520
|
+
}, requestId);
|
|
521
|
+
}
|
|
522
|
+
catch (error) {
|
|
523
|
+
this.log('error', 'Failed to run improvement cycle', error);
|
|
524
|
+
return this.createErrorResponse(error instanceof Error ? error.message : 'Unknown error', requestId);
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* Tool 13: improvement_ab_test
|
|
529
|
+
* Run A/B test between strategies
|
|
530
|
+
*/
|
|
531
|
+
async handleImprovementABTest(args) {
|
|
532
|
+
const requestId = this.generateRequestId();
|
|
533
|
+
try {
|
|
534
|
+
this.validateRequired(args, ['strategyA', 'strategyB']);
|
|
535
|
+
const { strategyA, strategyB, iterations = 100 } = args;
|
|
536
|
+
// Create A/B test in a default improvement loop
|
|
537
|
+
const testAgentId = 'ab-test-runner';
|
|
538
|
+
let loop = this.improvementLoops.get(testAgentId);
|
|
539
|
+
if (!loop) {
|
|
540
|
+
const learningEngine = new LearningEngine_1.LearningEngine(testAgentId, this.memoryStore);
|
|
541
|
+
const performanceTracker = new PerformanceTracker_1.PerformanceTracker(testAgentId, this.memoryStore);
|
|
542
|
+
await learningEngine.initialize();
|
|
543
|
+
await performanceTracker.initialize();
|
|
544
|
+
loop = new ImprovementLoop_1.ImprovementLoop(testAgentId, this.memoryStore, learningEngine, performanceTracker);
|
|
545
|
+
await loop.initialize();
|
|
546
|
+
this.improvementLoops.set(testAgentId, loop);
|
|
547
|
+
}
|
|
548
|
+
// Create A/B test
|
|
549
|
+
const testId = await loop.createABTest(`${strategyA} vs ${strategyB}`, [
|
|
550
|
+
{ name: strategyA, config: {} },
|
|
551
|
+
{ name: strategyB, config: {} }
|
|
552
|
+
], iterations);
|
|
553
|
+
this.log('info', `A/B test created: ${testId}`);
|
|
554
|
+
return this.createSuccessResponse({
|
|
555
|
+
testId,
|
|
556
|
+
strategyA,
|
|
557
|
+
strategyB,
|
|
558
|
+
iterations,
|
|
559
|
+
status: 'running',
|
|
560
|
+
message: 'A/B test created. Use improvement_status to monitor progress.'
|
|
561
|
+
}, requestId);
|
|
562
|
+
}
|
|
563
|
+
catch (error) {
|
|
564
|
+
this.log('error', 'Failed to create A/B test', error);
|
|
565
|
+
return this.createErrorResponse(error instanceof Error ? error.message : 'Unknown error', requestId);
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
569
|
+
* Tool 14: improvement_failures
|
|
570
|
+
* Get failure patterns and recommendations
|
|
571
|
+
*/
|
|
572
|
+
async handleImprovementFailures(args) {
|
|
573
|
+
const requestId = this.generateRequestId();
|
|
574
|
+
try {
|
|
575
|
+
const { limit = 10 } = args;
|
|
576
|
+
// Aggregate failure patterns from all learning engines
|
|
577
|
+
const allFailures = [];
|
|
578
|
+
for (const [agentId, engine] of this.learningEngines.entries()) {
|
|
579
|
+
const failures = engine.getFailurePatterns();
|
|
580
|
+
for (const failure of failures) {
|
|
581
|
+
allFailures.push({
|
|
582
|
+
agentId,
|
|
583
|
+
...failure
|
|
584
|
+
});
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
// Sort by frequency
|
|
588
|
+
allFailures.sort((a, b) => b.frequency - a.frequency);
|
|
589
|
+
// Take top N
|
|
590
|
+
const topFailures = allFailures.slice(0, limit);
|
|
591
|
+
// Generate recommendations
|
|
592
|
+
const recommendations = topFailures.map(failure => ({
|
|
593
|
+
pattern: failure.pattern,
|
|
594
|
+
frequency: failure.frequency,
|
|
595
|
+
confidence: failure.confidence,
|
|
596
|
+
agentId: failure.agentId,
|
|
597
|
+
mitigation: failure.mitigation || 'Add comprehensive error handling and fallback mechanisms',
|
|
598
|
+
priority: failure.frequency > 10 ? 'high' : failure.frequency > 5 ? 'medium' : 'low'
|
|
599
|
+
}));
|
|
600
|
+
return this.createSuccessResponse({
|
|
601
|
+
totalFailures: allFailures.length,
|
|
602
|
+
topFailures: recommendations
|
|
603
|
+
}, requestId);
|
|
604
|
+
}
|
|
605
|
+
catch (error) {
|
|
606
|
+
this.log('error', 'Failed to get failure patterns', error);
|
|
607
|
+
return this.createErrorResponse(error instanceof Error ? error.message : 'Unknown error', requestId);
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
/**
|
|
611
|
+
* Tool 15: performance_track
|
|
612
|
+
* Track performance metrics and improvement
|
|
613
|
+
*/
|
|
614
|
+
async handlePerformanceTrack(args) {
|
|
615
|
+
const requestId = this.generateRequestId();
|
|
616
|
+
try {
|
|
617
|
+
this.validateRequired(args, ['agentId', 'metrics']);
|
|
618
|
+
const { agentId, metrics } = args;
|
|
619
|
+
// Get or create performance tracker
|
|
620
|
+
let tracker = this.performanceTrackers.get(agentId);
|
|
621
|
+
if (!tracker) {
|
|
622
|
+
tracker = new PerformanceTracker_1.PerformanceTracker(agentId, this.memoryStore);
|
|
623
|
+
await tracker.initialize();
|
|
624
|
+
this.performanceTrackers.set(agentId, tracker);
|
|
625
|
+
}
|
|
626
|
+
// Record snapshot with proper structure
|
|
627
|
+
await tracker.recordSnapshot({
|
|
628
|
+
metrics,
|
|
629
|
+
trends: []
|
|
630
|
+
});
|
|
631
|
+
// Calculate improvement
|
|
632
|
+
const improvement = await tracker.calculateImprovement();
|
|
633
|
+
this.log('info', `Performance tracked for agent ${agentId}`, {
|
|
634
|
+
improvementRate: improvement.improvementRate
|
|
635
|
+
});
|
|
636
|
+
return this.createSuccessResponse({
|
|
637
|
+
agentId,
|
|
638
|
+
snapshot: metrics,
|
|
639
|
+
improvement,
|
|
640
|
+
baseline: tracker.getBaseline(),
|
|
641
|
+
snapshotCount: tracker.getSnapshotCount()
|
|
642
|
+
}, requestId);
|
|
643
|
+
}
|
|
644
|
+
catch (error) {
|
|
645
|
+
this.log('error', 'Failed to track performance', error);
|
|
646
|
+
return this.createErrorResponse(error instanceof Error ? error.message : 'Unknown error', requestId);
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
// =========================================================================
|
|
650
|
+
// HELPER METHODS
|
|
651
|
+
// =========================================================================
|
|
652
|
+
/**
|
|
653
|
+
* Convert data to CSV format
|
|
654
|
+
*/
|
|
655
|
+
convertToCSV(data) {
|
|
656
|
+
if (Array.isArray(data)) {
|
|
657
|
+
if (data.length === 0)
|
|
658
|
+
return '';
|
|
659
|
+
// Get headers from first object
|
|
660
|
+
const headers = Object.keys(data[0]);
|
|
661
|
+
const csv = [headers.join(',')];
|
|
662
|
+
// Add rows
|
|
663
|
+
for (const row of data) {
|
|
664
|
+
const values = headers.map(h => JSON.stringify(row[h] || ''));
|
|
665
|
+
csv.push(values.join(','));
|
|
666
|
+
}
|
|
667
|
+
return csv.join('\n');
|
|
668
|
+
}
|
|
669
|
+
else if (typeof data === 'object') {
|
|
670
|
+
// Convert object to CSV
|
|
671
|
+
const csv = ['key,value'];
|
|
672
|
+
for (const [key, value] of Object.entries(data)) {
|
|
673
|
+
csv.push(`${key},${JSON.stringify(value)}`);
|
|
674
|
+
}
|
|
675
|
+
return csv.join('\n');
|
|
676
|
+
}
|
|
677
|
+
return String(data);
|
|
678
|
+
}
|
|
679
|
+
/**
|
|
680
|
+
* Cleanup resources
|
|
681
|
+
*/
|
|
682
|
+
async cleanup() {
|
|
683
|
+
// Stop all improvement loops
|
|
684
|
+
for (const loop of this.improvementLoops.values()) {
|
|
685
|
+
await loop.stop();
|
|
686
|
+
}
|
|
687
|
+
this.learningEngines.clear();
|
|
688
|
+
this.improvementLoops.clear();
|
|
689
|
+
this.performanceTrackers.clear();
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
exports.Phase2ToolsHandler = Phase2ToolsHandler;
|
|
693
|
+
//# sourceMappingURL=Phase2Tools.js.map
|