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
312 lines • 12.5 kB
JavaScript
/**
* Conversational Orchestrator - Enables dialog between main agent and sub-agents
*/
export class ConversationalOrchestrator {
name = 'conversational_orchestrator';
description = `COLLABORATIVE DIALOG MODE. Enables back-and-forth conversation with sub-agents for complex problem solving.`;
toolExecutor; // Will be injected by UniversalRealHandler
conversationHistory = [];
maxTurns = 10;
async orchestrate(task) {
const startTime = Date.now();
const initialQuery = task.description || task.task || '';
try {
this.conversationHistory = [];
this.addMessage('main', initialQuery);
const relevantAgents = this.determineRelevantAgents(initialQuery);
const insights = await this.conductConversation(initialQuery, relevantAgents, task.maxTurns || this.maxTurns);
const synthesis = this.synthesizeConversation(insights);
return {
success: true,
summary: synthesis.summary,
findings: {
critical: [],
warnings: [],
info: synthesis.needsMoreInfo.map(q => ({
id: `question-${Date.now()}`,
type: 'unanswered_question',
severity: 'info',
title: 'Needs clarification',
description: q.message
}))
},
suggestions: synthesis.actionItems.map((item, i) => ({
id: `action-${i}`,
title: item,
description: '',
priority: 'medium',
effort: 'medium'
})),
nextSteps: synthesis.recommendations,
metadata: {
duration: Date.now() - startTime,
agentsUsed: relevantAgents,
confidence: synthesis.consensusReached ? 0.8 : 0.5,
conversationTurns: this.conversationHistory.length,
consensus: synthesis.consensus,
disagreements: synthesis.disagreements
}
};
}
catch (error) {
return {
success: false,
summary: `Conversational orchestration failed: ${error instanceof Error ? error.message : String(error)}`,
metadata: {
duration: Date.now() - startTime,
agentsUsed: [],
confidence: 0
}
};
}
}
async conductConversation(initialQuery, agents, maxTurns) {
const insights = {
keyPoints: [],
questions: [],
proposals: [],
verifications: []
};
let turn = 0;
let needsMoreInfo = true;
while (needsMoreInfo && turn < maxTurns) {
turn++;
for (const agent of agents) {
const response = await this.getAgentResponse(agent, this.conversationHistory);
if (response.type === 'question') {
insights.questions.push(response);
this.addMessage('sub-agent', response.message, agent);
const clarification = await this.getClarification(response);
this.addMessage('main', clarification);
}
else if (response.type === 'proposal') {
insights.proposals.push(response);
this.addMessage('sub-agent', response.message, agent);
const comments = await this.getAgentComments(response, agents.filter(a => a !== agent));
comments.forEach(comment => {
this.addMessage('sub-agent', comment.message, comment.agent);
});
}
else if (response.type === 'verification') {
insights.verifications.push(response);
const verificationResult = await this.performVerification(response);
this.addMessage('system', `Verification result: ${JSON.stringify(verificationResult)}`);
}
else if (response.type === 'insight') {
insights.keyPoints.push(response);
this.addMessage('sub-agent', response.message, agent);
}
}
needsMoreInfo = await this.assessIfNeedsMoreInfo(insights);
}
return insights;
}
determineRelevantAgents(query) {
const agents = [];
const lowerQuery = query.toLowerCase();
agents.push('debug_agent');
if (lowerQuery.includes('performance') || lowerQuery.includes('slow')) {
agents.push('performance_agent');
}
if (lowerQuery.includes('test') || lowerQuery.includes('verify')) {
agents.push('test_agent');
}
if (lowerQuery.includes('error') || lowerQuery.includes('bug')) {
agents.push('error_investigation_agent');
}
return agents.slice(0, 3);
}
async getAgentResponse(agent, history) {
const context = this.buildContextForAgent(agent, history);
if (this.needsClarification(context)) {
return {
type: 'question',
agent,
message: `I need more information about: ${this.identifyMissingInfo(context)}`,
priority: 'high'
};
}
if (this.hasProposal(context)) {
return {
type: 'proposal',
agent,
message: `I propose we: ${this.generateProposal(context)}`,
confidence: 0.8
};
}
if (this.needsVerification(context)) {
return {
type: 'verification',
agent,
message: `Let me verify: ${this.identifyVerificationNeed(context)}`,
tools: this.selectVerificationTools(context)
};
}
return {
type: 'insight',
agent,
message: `Based on the discussion: ${this.generateInsight(context)}`
};
}
async getClarification(question) {
return `Regarding "${question.message}": [clarification would go here based on available context]`;
}
async getAgentComments(proposal, otherAgents) {
const comments = [];
for (const agent of otherAgents) {
const evaluation = await this.evaluateProposal(agent, proposal);
if (evaluation.hasComment) {
comments.push({
agent,
message: evaluation.comment,
agrees: evaluation.agrees,
concerns: evaluation.concerns
});
}
}
return comments;
}
async performVerification(verification) {
const results = {};
for (const tool of (verification.tools || [])) {
try {
results[tool] = await this.executeTool(tool, verification.context);
}
catch (error) {
results[tool] = { error: error instanceof Error ? error.message : String(error) };
}
}
return results;
}
synthesizeConversation(insights) {
const consensus = this.findConsensus(insights);
const disagreements = this.findDisagreements(insights);
const actionItems = this.extractActionItems(insights);
return {
summary: this.generateSummary(insights),
consensus,
disagreements,
actionItems,
needsMoreInfo: insights.questions.filter(q => !q.answered),
recommendations: this.generateRecommendations(consensus, actionItems),
consensusReached: consensus.length > 0 && disagreements.length === 0
};
}
addMessage(role, message, agent) {
this.conversationHistory.push({
role,
agent,
message,
timestamp: new Date()
});
}
// Helper methods
needsClarification(context) {
return context.ambiguities?.length > 0 || context.missingInfo?.length > 0;
}
hasProposal(context) {
return context.confidence > 0.7 && context.possibleSolutions?.length > 0;
}
needsVerification(context) {
return context.unverifiedClaims?.length > 0 || context.assumptions?.length > 0;
}
buildContextForAgent(agent, history) {
return {
agent,
history: history.slice(-5),
domain: this.getAgentDomain(agent),
capabilities: this.getAgentCapabilities(agent)
};
}
identifyMissingInfo(context) {
return "specific error messages or reproduction steps";
}
generateProposal(context) {
return "investigate the issue using specific debugging tools";
}
identifyVerificationNeed(context) {
return "if the reported error actually exists";
}
selectVerificationTools(context) {
return ['take_screenshot', 'get_console_logs'];
}
generateInsight(context) {
return "this appears to be a state management issue";
}
async evaluateProposal(agent, proposal) {
return {
hasComment: true,
comment: "This approach makes sense, but we should also check...",
agrees: true,
concerns: []
};
}
async assessIfNeedsMoreInfo(insights) {
const unansweredQuestions = insights.questions.filter(q => !q.answered);
const hasConsensus = insights.proposals.some(p => (p.confidence || 0) > 0.8);
return unansweredQuestions.length > 0 || !hasConsensus;
}
findConsensus(insights) {
return insights.keyPoints
.filter(point => point.agreedByAll)
.map(point => point.message);
}
findDisagreements(insights) {
return insights.proposals
.filter(p => p.disputed)
.map(p => p.message);
}
extractActionItems(insights) {
return insights.proposals
.filter(p => (p.confidence || 0) > 0.7)
.map(p => p.actionItem || p.message);
}
generateSummary(insights) {
const keyPointsCount = insights.keyPoints.length;
const questionsCount = insights.questions.length;
const proposalsCount = insights.proposals.length;
return `Conversation yielded ${keyPointsCount} key insights, ${questionsCount} clarifying questions, and ${proposalsCount} proposals. ${insights.verifications.length > 0 ? `Performed ${insights.verifications.length} verifications.` : ''}`;
}
generateRecommendations(consensus, actionItems) {
const recommendations = [];
if (consensus.length > 0) {
recommendations.push(`Based on agent consensus: ${consensus[0]}`);
}
if (actionItems.length > 0) {
recommendations.push(`Recommended action: ${actionItems[0]}`);
}
return recommendations;
}
getAgentDomain(agent) {
const domains = {
debug_agent: 'general debugging',
performance_agent: 'performance optimization',
test_agent: 'testing and validation',
error_investigation_agent: 'error analysis'
};
return domains[agent] || 'general analysis';
}
getAgentCapabilities(agent) {
const capabilities = {
debug_agent: ['root cause analysis', 'system inspection'],
performance_agent: ['profiling', 'optimization'],
test_agent: ['test generation', 'validation'],
error_investigation_agent: ['error tracking', 'stack analysis']
};
return capabilities[agent] || [];
}
async executeTool(tool, context) {
// Use the real tool executor if available
if (this.toolExecutor) {
return await this.toolExecutor.execute(tool, {}, context);
}
// Fallback if no executor is set
console.warn(`⚠️ No tool executor available for ${tool}`);
return { error: 'Tool executor not initialized' };
}
// Method to inject the tool executor
setToolExecutor(executor) {
this.toolExecutor = executor;
}
}
//# sourceMappingURL=conversational-orchestrator.js.map