UNPKG

zai-mcp-server

Version:

🚀 REVOLUTIONARY AI-to-AI Collaboration Platform v6.1! NEW: Advanced Debugging Tools with Screenshot Analysis, Console Error Parsing, Automated Fix Generation, 5 Specialized Debugging Agents, Visual UI Analysis, JavaScript Error Intelligence, CSS/HTML Fix

652 lines (566 loc) • 21.2 kB
import { EventEmitter } from 'events'; /** * Enhanced Communication Protocols for AI-to-AI Communication * Standardizes communication format and handles clarification requests */ export class CommunicationProtocol extends EventEmitter { constructor() { super(); this.communicationHistory = new Map(); // loopId -> communication history this.clarificationRequests = new Map(); // loopId -> pending clarifications this.responseTemplates = this.initializeResponseTemplates(); this.qualityThresholds = this.initializeQualityThresholds(); } /** * Initialize response templates * @returns {Object} - Response templates */ initializeResponseTemplates() { return { implementation: { required: ['implementation', 'results', 'code_changes', 'next_steps', 'status'], format: { implementation: 'Detailed steps taken to implement the improvement', results: 'Specific outcomes and improvements achieved', code_changes: 'Any code modifications, optimizations, or new features added', next_steps: 'Concrete suggestions for the next iteration', status: 'Current status and continuation directive' } }, analysis: { required: ['analysis', 'findings', 'recommendations', 'impact', 'next_steps'], format: { analysis: 'Detailed analysis of the current state', findings: 'Key findings and insights discovered', recommendations: 'Specific recommendations for improvement', impact: 'Expected impact and benefits', next_steps: 'Suggested next steps for implementation' } }, testing: { required: ['test_results', 'coverage', 'issues', 'fixes', 'next_steps'], format: { test_results: 'Test execution results and statistics', coverage: 'Code coverage metrics and analysis', issues: 'Issues found and their severity', fixes: 'Fixes applied and their effectiveness', next_steps: 'Next testing priorities and improvements' } } }; } /** * Initialize quality thresholds * @returns {Object} - Quality thresholds */ initializeQualityThresholds() { return { minResponseLength: 200, maxResponseLength: 5000, requiredSections: 3, clarificationThreshold: 0.7, // Confidence threshold for clarification implementationConfidence: 0.8, detailLevel: { low: 0.3, medium: 0.6, high: 0.9 } }; } /** * Standardize agent communication * @param {string} loopId - Loop ID * @param {string} response - Agent response * @param {string} type - Response type * @returns {Object} - Standardized communication */ standardizeAgentCommunication(loopId, response, type = 'implementation') { console.error(`[COMMUNICATION PROTOCOL] Standardizing ${type} response for loop ${loopId}`); const template = this.responseTemplates[type] || this.responseTemplates.implementation; const standardized = { loopId, timestamp: new Date(), type, originalResponse: response, structured: this.extractStructuredData(response, template), metadata: this.extractMetadata(response), quality: this.assessResponseQuality(response, template), confidence: this.calculateConfidence(response, template), clarificationNeeded: false, clarificationRequests: [] }; // Check if clarification is needed if (standardized.confidence < this.qualityThresholds.clarificationThreshold) { standardized.clarificationNeeded = true; standardized.clarificationRequests = this.generateClarificationRequests(response, template); } // Store communication history this.storeCommunication(loopId, standardized); this.emit('communicationStandardized', standardized); return standardized; } /** * Extract structured data from response * @param {string} response - Agent response * @param {Object} template - Response template * @returns {Object} - Structured data */ extractStructuredData(response, template) { const structured = {}; template.required.forEach(section => { structured[section] = this.extractSection(response, section, template.format[section]); }); return structured; } /** * Extract section from response * @param {string} response - Full response * @param {string} sectionName - Section name * @param {string} description - Section description * @returns {Object} - Section data */ extractSection(response, sectionName, description) { const sectionPatterns = [ new RegExp(`\\*\\*${sectionName}[:\\s]*\\*\\*([^*]+)`, 'i'), new RegExp(`${sectionName}[:\\s]*([^\\n]+)`, 'i'), new RegExp(`## ${sectionName}([^#]+)`, 'i') ]; let content = null; let confidence = 0; for (const pattern of sectionPatterns) { const match = response.match(pattern); if (match) { content = match[1].trim(); confidence = this.calculateSectionConfidence(content, description); break; } } // Fallback: search for keywords related to the section if (!content) { content = this.extractByKeywords(response, sectionName); confidence = content ? 0.3 : 0; } return { content: content || `No ${sectionName} information found`, confidence, extracted: !!content, length: content ? content.length : 0 }; } /** * Extract by keywords * @param {string} response - Response text * @param {string} sectionName - Section name * @returns {string} - Extracted content */ extractByKeywords(response, sectionName) { const keywords = { implementation: ['implemented', 'created', 'added', 'modified', 'built'], results: ['achieved', 'improved', 'enhanced', 'optimized', 'result'], code_changes: ['changed', 'updated', 'refactored', 'modified', 'code'], next_steps: ['next', 'continue', 'future', 'plan', 'step'], analysis: ['analyzed', 'examined', 'reviewed', 'studied', 'found'], findings: ['discovered', 'identified', 'observed', 'noted', 'found'], recommendations: ['recommend', 'suggest', 'propose', 'advise', 'should'] }; const sectionKeywords = keywords[sectionName] || []; const sentences = response.split(/[.!?]+/); const relevantSentences = sentences.filter(sentence => sectionKeywords.some(keyword => sentence.toLowerCase().includes(keyword) ) ); return relevantSentences.slice(0, 3).join('. ').trim(); } /** * Calculate section confidence * @param {string} content - Section content * @param {string} description - Expected description * @returns {number} - Confidence score (0-1) */ calculateSectionConfidence(content, description) { if (!content || content.length < 10) {return 0;} let confidence = 0.5; // Base confidence // Length-based confidence if (content.length > 50) {confidence += 0.2;} if (content.length > 100) {confidence += 0.1;} // Keyword relevance const descriptionWords = description.toLowerCase().split(' '); const contentWords = content.toLowerCase().split(' '); const relevantWords = descriptionWords.filter(word => contentWords.some(cWord => cWord.includes(word) || word.includes(cWord)) ); confidence += (relevantWords.length / descriptionWords.length) * 0.3; return Math.min(confidence, 1); } /** * Extract metadata from response * @param {string} response - Agent response * @returns {Object} - Metadata */ extractMetadata(response) { return { length: response.length, wordCount: response.split(/\s+/).length, sectionCount: (response.match(/\*\*[^*]+\*\*/g) || []).length, codeBlocks: (response.match(/```[^`]*```/g) || []).length, lists: (response.match(/^\s*[-*+]\s/gm) || []).length, hasImplementationDetails: /implement|create|add|modify|build/i.test(response), hasResults: /result|achieve|improve|enhance|optimize/i.test(response), hasNextSteps: /next|continue|future|plan|step/i.test(response), sentiment: this.analyzeSentiment(response) }; } /** * Analyze sentiment of response * @param {string} response - Response text * @returns {string} - Sentiment (positive, neutral, negative) */ analyzeSentiment(response) { const positiveWords = ['success', 'improve', 'enhance', 'optimize', 'achieve', 'complete', 'good', 'better', 'excellent']; const negativeWords = ['fail', 'error', 'problem', 'issue', 'difficult', 'challenge', 'bad', 'worse', 'broken']; const text = response.toLowerCase(); const positiveCount = positiveWords.filter(word => text.includes(word)).length; const negativeCount = negativeWords.filter(word => text.includes(word)).length; if (positiveCount > negativeCount) {return 'positive';} if (negativeCount > positiveCount) {return 'negative';} return 'neutral'; } /** * Assess response quality * @param {string} response - Agent response * @param {Object} template - Response template * @returns {Object} - Quality assessment */ assessResponseQuality(response, template) { const metadata = this.extractMetadata(response); let score = 0; const issues = []; const strengths = []; // Length assessment if (metadata.length < this.qualityThresholds.minResponseLength) { issues.push('Response too short'); score -= 0.2; } else if (metadata.length > this.qualityThresholds.maxResponseLength) { issues.push('Response too long'); score -= 0.1; } else { strengths.push('Appropriate length'); score += 0.2; } // Structure assessment if (metadata.sectionCount >= this.qualityThresholds.requiredSections) { strengths.push('Well-structured'); score += 0.3; } else { issues.push('Lacks proper structure'); score -= 0.2; } // Content assessment if (metadata.hasImplementationDetails) { strengths.push('Contains implementation details'); score += 0.2; } else { issues.push('Missing implementation details'); score -= 0.2; } if (metadata.hasResults) { strengths.push('Includes results'); score += 0.1; } if (metadata.hasNextSteps) { strengths.push('Provides next steps'); score += 0.1; } else { issues.push('Missing next steps'); score -= 0.1; } // Code blocks bonus if (metadata.codeBlocks > 0) { strengths.push('Includes code examples'); score += 0.1; } const finalScore = Math.max(0, Math.min(1, 0.5 + score)); return { score: finalScore, grade: this.getQualityGrade(finalScore), issues, strengths, metadata }; } /** * Get quality grade * @param {number} score - Quality score * @returns {string} - Quality grade */ getQualityGrade(score) { if (score >= 0.9) {return 'A';} if (score >= 0.8) {return 'B';} if (score >= 0.7) {return 'C';} if (score >= 0.6) {return 'D';} return 'F'; } /** * Calculate confidence * @param {string} response - Agent response * @param {Object} template - Response template * @returns {number} - Confidence score (0-1) */ calculateConfidence(response, template) { const structured = this.extractStructuredData(response, template); const quality = this.assessResponseQuality(response, template); // Average section confidence const sectionConfidences = Object.values(structured).map(section => section.confidence); const avgSectionConfidence = sectionConfidences.reduce((sum, conf) => sum + conf, 0) / sectionConfidences.length; // Combined confidence return (avgSectionConfidence * 0.6) + (quality.score * 0.4); } /** * Generate clarification requests * @param {string} response - Agent response * @param {Object} template - Response template * @returns {Array} - Clarification requests */ generateClarificationRequests(response, template) { const requests = []; const structured = this.extractStructuredData(response, template); template.required.forEach(section => { const sectionData = structured[section]; if (!sectionData.extracted || sectionData.confidence < 0.5) { requests.push({ section, type: 'missing_content', question: `Could you provide more details about ${section}? ${template.format[section]}`, priority: this.getSectionPriority(section) }); } }); // Check for ambiguous statements const ambiguousPatterns = [ /maybe|perhaps|might|could be|not sure|unclear/i, /some|various|several|many|few/i, /probably|likely|possibly/i ]; ambiguousPatterns.forEach((pattern, index) => { if (pattern.test(response)) { requests.push({ section: 'general', type: 'ambiguity', question: 'Could you be more specific about the uncertain aspects mentioned?', priority: 'medium' }); } }); return requests.sort((a, b) => this.getPriorityWeight(b.priority) - this.getPriorityWeight(a.priority)); } /** * Get section priority * @param {string} section - Section name * @returns {string} - Priority level */ getSectionPriority(section) { const priorities = { implementation: 'high', results: 'high', code_changes: 'medium', next_steps: 'medium', analysis: 'high', findings: 'high', recommendations: 'medium' }; return priorities[section] || 'low'; } /** * Get priority weight * @param {string} priority - Priority level * @returns {number} - Priority weight */ getPriorityWeight(priority) { const weights = { high: 3, medium: 2, low: 1 }; return weights[priority] || 1; } /** * Request clarification * @param {string} loopId - Loop ID * @param {Object} ambiguousRequirement - Ambiguous requirement * @returns {Object} - Clarification request */ requestClarification(loopId, ambiguousRequirement) { const clarificationId = `clarification_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`; const clarification = { id: clarificationId, loopId, timestamp: new Date(), requirement: ambiguousRequirement, questions: this.generateClarificationQuestions(ambiguousRequirement), status: 'pending', response: null }; // Store clarification request if (!this.clarificationRequests.has(loopId)) { this.clarificationRequests.set(loopId, []); } this.clarificationRequests.get(loopId).push(clarification); console.error(`[COMMUNICATION PROTOCOL] Clarification requested for loop ${loopId}: ${clarificationId}`); this.emit('clarificationRequested', clarification); return clarification; } /** * Generate clarification questions * @param {Object} requirement - Ambiguous requirement * @returns {Array} - Clarification questions */ generateClarificationQuestions(requirement) { const questions = []; if (requirement.type === 'vague_goal') { questions.push( 'What specific outcomes are you looking to achieve?', 'Are there particular areas or components you want to focus on?', 'What would success look like for this improvement?' ); } else if (requirement.type === 'technical_ambiguity') { questions.push( 'Which specific technologies or frameworks should be used?', 'Are there any constraints or requirements to consider?', 'What is the preferred approach or methodology?' ); } else if (requirement.type === 'scope_unclear') { questions.push( 'What is the scope of this change (file, component, system)?', 'Should this be a minimal change or comprehensive overhaul?', 'Are there dependencies that need to be considered?' ); } else { questions.push( 'Could you provide more specific details about this requirement?', 'What are the key priorities for this improvement?', 'Are there any specific constraints or preferences?' ); } return questions; } /** * Store communication * @param {string} loopId - Loop ID * @param {Object} communication - Communication data */ storeCommunication(loopId, communication) { if (!this.communicationHistory.has(loopId)) { this.communicationHistory.set(loopId, []); } const history = this.communicationHistory.get(loopId); history.push(communication); // Keep only last 20 communications if (history.length > 20) { history.splice(0, history.length - 20); } } /** * Get communication history * @param {string} loopId - Loop ID * @returns {Array} - Communication history */ getCommunicationHistory(loopId) { return this.communicationHistory.get(loopId) || []; } /** * Get communication quality trends * @param {string} loopId - Loop ID * @returns {Object} - Quality trends */ getCommunicationQualityTrends(loopId) { const history = this.getCommunicationHistory(loopId); if (history.length === 0) {return null;} const recentHistory = history.slice(-10); // Last 10 communications const qualityScores = recentHistory.map(comm => comm.quality.score); const confidenceScores = recentHistory.map(comm => comm.confidence); const avgQuality = qualityScores.reduce((sum, score) => sum + score, 0) / qualityScores.length; const avgConfidence = confidenceScores.reduce((sum, score) => sum + score, 0) / confidenceScores.length; // Calculate trends const qualityTrend = this.calculateTrend(qualityScores); const confidenceTrend = this.calculateTrend(confidenceScores); return { averageQuality: avgQuality, averageConfidence: avgConfidence, qualityTrend, confidenceTrend, totalCommunications: history.length, recentCommunications: recentHistory.length, clarificationRate: recentHistory.filter(comm => comm.clarificationNeeded).length / recentHistory.length }; } /** * Calculate trend * @param {Array} values - Array of values * @returns {string} - Trend direction */ calculateTrend(values) { if (values.length < 3) {return 'stable';} const recent = values.slice(-3); const earlier = values.slice(-6, -3); if (earlier.length === 0) {return 'stable';} const recentAvg = recent.reduce((sum, val) => sum + val, 0) / recent.length; const earlierAvg = earlier.reduce((sum, val) => sum + val, 0) / earlier.length; const change = (recentAvg - earlierAvg) / earlierAvg; if (change > 0.1) {return 'improving';} if (change < -0.1) {return 'declining';} return 'stable'; } /** * Generate communication report * @param {string} loopId - Loop ID * @returns {Object} - Communication report */ generateCommunicationReport(loopId) { const history = this.getCommunicationHistory(loopId); const trends = this.getCommunicationQualityTrends(loopId); const clarifications = this.clarificationRequests.get(loopId) || []; return { loopId, timestamp: new Date(), summary: { totalCommunications: history.length, averageQuality: trends?.averageQuality || 0, averageConfidence: trends?.averageConfidence || 0, clarificationRequests: clarifications.length, pendingClarifications: clarifications.filter(c => c.status === 'pending').length }, trends, recentQuality: history.slice(-5).map(comm => ({ timestamp: comm.timestamp, quality: comm.quality.score, confidence: comm.confidence, grade: comm.quality.grade })), recommendations: this.generateCommunicationRecommendations(trends, clarifications) }; } /** * Generate communication recommendations * @param {Object} trends - Quality trends * @param {Array} clarifications - Clarification requests * @returns {Array} - Recommendations */ generateCommunicationRecommendations(trends, clarifications) { const recommendations = []; if (trends) { if (trends.averageQuality < 0.6) { recommendations.push('Consider providing more detailed prompts to improve response quality'); } if (trends.averageConfidence < 0.7) { recommendations.push('Responses show low confidence - consider breaking down complex tasks'); } if (trends.clarificationRate > 0.3) { recommendations.push('High clarification rate - consider more specific initial requirements'); } if (trends.qualityTrend === 'declining') { recommendations.push('Quality trend is declining - review communication approach'); } } if (clarifications.length > 5) { recommendations.push('Many clarification requests - consider improving initial prompt clarity'); } return recommendations; } }