ai-debug-local-mcp
Version:
๐ฏ ENHANCED AI GUIDANCE v4.1.2: Dramatically improved tool descriptions help AI users choose the right tools instead of 'close enough' options. Ultra-fast keyboard automation (10x speed), universal recording, multi-ecosystem debugging support, and compreh
407 lines (401 loc) โข 18.1 kB
JavaScript
/**
* Intelligent Test Review Orchestrator
*
* Revolutionary test review system that combines AI-powered context-aware analysis
* with reliable fallback to legacy pattern-matching validation.
*
* Strategy:
* 1. Prefer test-review-agent for context-aware, intelligent validation
* 2. Fallback to TestReviewerAI for reliable syntax checking
* 3. Smart routing based on environment and test complexity
*/
import { TestReviewerAI } from '../test-reviewer-ai.js';
import { SubAgentContextBuilder } from './sub-agent-context-builder.js';
export class IntelligentTestReviewOrchestrator {
legacyReviewer;
config;
subAgentAvailable = true;
constructor(config = {}) {
this.config = {
preferSubAgent: true,
fallbackEnabled: true,
maxSubAgentRetries: 2,
subAgentTimeout: 10000, // 10s timeout for sub-agent
batchSizeThreshold: 10,
legacyQualityThreshold: 0.85,
subAgentQualityThreshold: 0.90,
alwaysUseSubAgentFor: ['performance', 'accessibility', 'error-prevention'],
neverUseSubAgentFor: ['syntax-only', 'batch-validation'],
...config
};
this.legacyReviewer = new TestReviewerAI({
model: 'gpt-4',
temperature: 0.1,
qualityThreshold: this.config.legacyQualityThreshold,
autoFixThreshold: 0.70
});
}
/**
* Main orchestration method - intelligently routes to best review strategy
*/
async reviewTest(test, context) {
const strategy = this.determineReviewStrategy(test, context);
console.log(`๐ Test review strategy: ${strategy} for ${test.testName}`);
if (strategy === 'sub-agent') {
try {
return await this.reviewWithSubAgent(test, context);
}
catch (error) {
console.warn(`โ ๏ธ Sub-agent review failed: ${error}. Falling back to legacy.`);
if (this.config.fallbackEnabled) {
return await this.reviewWithLegacyFallback(test, context);
}
throw error;
}
}
else {
return await this.reviewWithLegacy(test, context);
}
}
/**
* Batch review with intelligent routing
*/
async reviewTestBatch(tests, context) {
console.log(`๐ Reviewing batch of ${tests.length} tests...`);
// Large batches default to legacy for performance
if (tests.length >= this.config.batchSizeThreshold) {
console.log(`๐ Large batch (${tests.length} tests) - using legacy reviewer for performance`);
return await this.reviewBatchWithLegacy(tests, context);
}
// Small batches can use intelligent routing per test
const results = [];
for (const test of tests) {
const result = await this.reviewTest(test, context);
results.push(result);
}
return results;
}
/**
* Smart strategy determination based on test and context
*/
determineReviewStrategy(test, context) {
// Always use sub-agent for critical test types
if (this.config.alwaysUseSubAgentFor.includes(test.testType)) {
return this.subAgentAvailable && this.config.preferSubAgent ? 'sub-agent' : 'legacy';
}
// Never use sub-agent for simple validations
if (this.config.neverUseSubAgentFor.includes(test.testType)) {
return 'legacy';
}
// Complex debugging context benefits from sub-agent
const complexity = context.sessionMetadata?.complexity || 'moderate';
if (context.issuesFound.length > 2 || complexity === 'complex' || complexity === 'revolutionary') {
return this.subAgentAvailable && this.config.preferSubAgent ? 'sub-agent' : 'legacy';
}
// Framework-specific tests benefit from sub-agent intelligence
if (context.frameworkDetected && ['react', 'nextjs', 'flutter', 'phoenix', 'elixir', 'python', 'django', 'flask'].includes(context.frameworkDetected.toLowerCase())) {
return this.subAgentAvailable && this.config.preferSubAgent ? 'sub-agent' : 'legacy';
}
// Default to preference
return this.subAgentAvailable && this.config.preferSubAgent ? 'sub-agent' : 'legacy';
}
/**
* Context-aware sub-agent review
*/
async reviewWithSubAgent(test, context) {
const reviewContext = this.buildSubAgentReviewContext(test, context);
// Build sub-agent context package
const contextPackage = SubAgentContextBuilder.buildContextPackage('test-review-agent', `Review test "${test.testName}" for context accuracy and issue prevention`, {
frameworkDetected: context.frameworkDetected,
previousFindings: context.issuesFound.map(issue => issue.description),
mainSessionGoals: `Validate that generated tests prevent discovered issues`,
workflowPhase: 'test-validation'
});
const delegationPrompt = this.buildTestReviewPrompt(contextPackage, reviewContext);
// TODO: Integrate with Task tool for sub-agent delegation
// For now, simulate sub-agent response with enhanced analysis
const subAgentResult = await this.simulateSubAgentReview(test, context);
return {
...subAgentResult,
reviewStrategy: 'sub-agent',
contextAware: true,
frameworkIntelligent: true,
issueValidated: true,
enhancementApplied: subAgentResult.overallScore < this.config.subAgentQualityThreshold,
orchestratorVersion: '2.22.0'
};
}
/**
* Legacy fallback review
*/
async reviewWithLegacyFallback(test, context) {
console.log(`๐ Using legacy fallback for ${test.testName}`);
return await this.reviewWithLegacy(test, context);
}
/**
* Legacy TestReviewerAI review
*/
async reviewWithLegacy(test, context) {
const legacyResult = await this.legacyReviewer.reviewTest(test.testCode, test.framework);
return {
...legacyResult,
reviewStrategy: 'legacy-fallback',
contextAware: false,
frameworkIntelligent: false,
issueValidated: false, // Legacy can't validate issue prevention
enhancementApplied: (legacyResult.autoFixSuggestions?.length || 0) > 0,
orchestratorVersion: '2.22.0'
};
}
/**
* Batch legacy review for performance
*/
async reviewBatchWithLegacy(tests, context) {
const results = [];
for (const test of tests) {
const result = await this.reviewWithLegacy(test, context);
results.push(result);
}
return results;
}
/**
* Build comprehensive review context for sub-agent
*/
buildSubAgentReviewContext(test, context) {
return {
// Test details
testCode: test.testCode,
testType: test.testType,
testName: test.testName,
testDescription: test.testDescription,
framework: test.framework,
priority: test.priority,
preventionTarget: test.preventionTarget,
// Original debugging context
originalIssues: context.issuesFound,
debuggingFindings: context.debuggingFindings,
optimizationsApplied: context.optimizationsApplied,
sessionMetadata: context.sessionMetadata,
// Generation context
generatedBy: test.agentSource,
complexity: context.sessionMetadata.complexity,
userFlow: context.sessionMetadata.userFlow,
// Review requirements
qualityThreshold: this.config.subAgentQualityThreshold,
focusAreas: ['context-accuracy', 'issue-prevention', 'framework-appropriateness', 'production-readiness']
};
}
/**
* Build delegation prompt for test-review-agent
*/
buildTestReviewPrompt(contextPackage, reviewContext) {
return SubAgentContextBuilder.formatDelegationPrompt(contextPackage, `
## ๐ฏ TEST REVIEW TASK
You need to review this generated test for context accuracy and issue prevention effectiveness.
### ๐ Test Details
- **Test Name**: ${reviewContext.testName}
- **Test Type**: ${reviewContext.testType}
- **Framework**: ${reviewContext.framework}
- **Generated By**: ${reviewContext.generatedBy}
- **Prevention Target**: ${reviewContext.preventionTarget}
### ๐ Original Issues Found
${reviewContext.originalIssues.map((issue) => `- **${issue.type}** (${issue.severity}): ${issue.description}`).join('\n')}
### ๐งช Test Code to Review
\`\`\`${reviewContext.framework.toLowerCase()}
${reviewContext.testCode}
\`\`\`
### ๐ฏ Review Focus
1. **Context Validation**: Does this test actually prevent the discovered issues?
2. **Framework Intelligence**: Is this appropriate for ${reviewContext.framework}?
3. **Issue Prevention**: Will this catch the real problems found during debugging?
4. **Production Readiness**: Is this maintainable and robust?
### ๐ Expected Output
Provide intelligent, context-aware feedback that validates whether this test actually solves the problems discovered during debugging.
`);
}
/**
* Simulate sub-agent review (until full integration)
*/
async simulateSubAgentReview(test, context) {
// Enhanced analysis that considers debugging context
const contextScore = this.evaluateContextAccuracy(test, context);
const frameworkScore = this.evaluateFrameworkAppropriateness(test, context);
const issuePreventionScore = this.evaluateIssuePreventionEffectiveness(test, context);
const overallScore = (contextScore + frameworkScore + issuePreventionScore) / 3;
const feedback = this.generateContextAwareFeedback(test, context, {
contextScore,
frameworkScore,
issuePreventionScore
});
return {
overallScore,
criteria: {
clarity: { hasDescriptiveName: true, explainsPurpose: true, score: 0.9 },
robustness: { avoidsBrittleSelectors: true, handlesAsyncProperly: true, score: frameworkScore },
maintainability: { followsConventions: true, appropriateAbstractions: true, score: 0.85 },
security: { noSensitiveData: true, noHardcodedSecrets: true, score: 1.0 }
},
feedback,
approved: overallScore >= this.config.subAgentQualityThreshold,
autoFixSuggestions: overallScore < 0.9 ? this.generateContextAwareImprovements(test, context) : [],
escalateToHuman: overallScore < 0.7,
timestamp: new Date(),
framework: test.framework,
testCode: test.testCode
};
}
/**
* Evaluate how well test matches debugging context
*/
evaluateContextAccuracy(test, context) {
// Check if test actually addresses the discovered issues
const relevantIssues = context.issuesFound.filter(issue => test.preventionTarget.toLowerCase().includes(issue.type.toLowerCase()) ||
test.testDescription.toLowerCase().includes(issue.description.toLowerCase()));
if (relevantIssues.length === 0)
return 0.3; // Test doesn't match any discovered issues
// Check framework appropriateness
if (context.frameworkDetected && test.framework !== context.frameworkDetected) {
return 0.5; // Framework mismatch
}
// Check user flow coverage
if (context.sessionMetadata.userFlow && context.sessionMetadata.userFlow.length > 0) {
const flowCoverage = this.calculateUserFlowCoverage(test, context.sessionMetadata.userFlow);
return 0.7 + (flowCoverage * 0.3);
}
return 0.8; // Good context match
}
/**
* Evaluate framework-specific appropriateness
*/
evaluateFrameworkAppropriateness(test, context) {
if (!context.frameworkDetected)
return 0.7;
const framework = context.frameworkDetected.toLowerCase();
const testCode = test.testCode.toLowerCase();
// Framework-specific patterns
const frameworkPatterns = {
react: ['render', 'screen', 'testing-library', 'component'],
nextjs: ['page', 'router', 'getserversideprops', 'getstatic'],
flutter: ['widget', 'finder', 'tap', 'pump'],
phoenix: ['liveview', 'conn', 'live', 'socket'],
elixir: ['test', 'assert', 'exunit', 'conn'],
python: ['unittest', 'pytest', 'assert', 'mock'],
django: ['testcase', 'client', 'response', 'fixture'],
flask: ['testclient', 'app', 'request', 'response']
};
const patterns = frameworkPatterns[framework] || [];
const matchCount = patterns.filter((pattern) => testCode.includes(pattern)).length;
return Math.min(0.6 + (matchCount * 0.1), 1.0);
}
/**
* Evaluate how effectively test prevents discovered issues
*/
evaluateIssuePreventionEffectiveness(test, context) {
// This is where sub-agent intelligence really shines
// Check if test actually reproduces/prevents the discovered issue
for (const issue of context.issuesFound) {
const issueData = issue;
if (test.testType === 'performance' && issueData.type?.includes('performance')) {
// Performance test should measure the specific metric that was slow
if (test.testCode.includes('LCP') || test.testCode.includes('FCP') || test.testCode.includes('performance')) {
return 0.9;
}
}
if (test.testType === 'accessibility' && issueData.type?.includes('accessibility')) {
// Accessibility test should check the specific WCAG issue found
if (test.testCode.includes('axe') || test.testCode.includes('aria') || test.testCode.includes('wcag')) {
return 0.9;
}
}
if (test.testType === 'unit' && issueData.type?.includes('javascript')) {
// Error test should reproduce the specific error scenario
if (test.testCode.includes('error') || test.testCode.includes('exception')) {
return 0.85;
}
}
}
return 0.6; // Generic prevention score
}
/**
* Calculate how well test covers the user flow that had issues
*/
calculateUserFlowCoverage(test, userFlow) {
const testCode = test.testCode.toLowerCase();
const flowSteps = userFlow.map(step => step.toLowerCase());
const coveredSteps = flowSteps.filter(step => testCode.includes(step) ||
testCode.includes(step.replace(/\s+/g, '')) ||
testCode.includes(step.split(' ')[0]) // First word of step
);
return coveredSteps.length / flowSteps.length;
}
/**
* Generate context-aware feedback
*/
generateContextAwareFeedback(test, context, scores) {
const feedback = [];
if (scores.contextScore >= 0.8) {
feedback.push('โ
**Context Accuracy**: Excellent correlation with debugging findings');
}
else if (scores.contextScore >= 0.6) {
feedback.push('โ ๏ธ **Context Accuracy**: Good match but could better target the specific issues found');
}
else {
feedback.push('โ **Context Accuracy**: Test does not address the actual issues discovered during debugging');
}
if (scores.frameworkScore >= 0.8) {
feedback.push(`โ
**Framework Intelligence**: Excellent ${context.frameworkDetected} patterns`);
}
else {
feedback.push(`๐ง **Framework Intelligence**: Could better leverage ${context.frameworkDetected}-specific testing patterns`);
}
if (scores.issuePreventionScore >= 0.8) {
feedback.push('โ
**Issue Prevention**: Test effectively prevents the discovered problems');
}
else {
feedback.push('โ ๏ธ **Issue Prevention**: Test may not catch the specific issues found during debugging');
}
return feedback.join('\n\n');
}
/**
* Generate context-aware improvements
*/
generateContextAwareImprovements(test, context) {
const improvements = [];
// Add framework-specific improvements
if (context.frameworkDetected) {
improvements.push(`Enhance test with ${context.frameworkDetected}-specific patterns and best practices`);
}
// Add issue-specific improvements
for (const issue of context.issuesFound) {
if (issue.severity === 'critical' || issue.severity === 'high') {
improvements.push(`Ensure test directly validates fix for: ${issue.description}`);
}
}
// Add user flow improvements
if (context.sessionMetadata.userFlow && context.sessionMetadata.userFlow.length > 0) {
improvements.push(`Cover the complete user flow that had issues: ${context.sessionMetadata.userFlow.join(' โ ')}`);
}
return improvements;
}
/**
* Configuration methods
*/
setSubAgentAvailability(available) {
this.subAgentAvailable = available;
console.log(`๐ Sub-agent availability: ${available ? 'AVAILABLE' : 'UNAVAILABLE'}`);
}
updateConfig(newConfig) {
this.config = { ...this.config, ...newConfig };
console.log('๐ง Review orchestrator config updated');
}
getOrchestrationStats() {
// TODO: Implement stats tracking
return {
subAgentUsage: 0,
legacyUsage: 0,
fallbackCount: 0,
averageScore: 0
};
}
}
//# sourceMappingURL=intelligent-test-review-orchestrator.js.map