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
396 lines • 16.6 kB
JavaScript
/**
* Bidirectional Context Sharing Manager
* Enables seamless context exchange between primary agent and sub-agents
* Ensures both are aware of the critical importance of context sharing
*/
import { EventEmitter } from 'events';
/**
* Bidirectional Context Manager
* Central hub for context sharing between all agents
*/
export class BidirectionalContextManager extends EventEmitter {
contextStore = new Map();
agentAwareness = new Map();
contextSubscriptions = new Map(); // contextType -> agentIds
contextDependencies = new Map(); // agentId -> contextIds they need
sharingMetrics = {
totalContextsShared: 0,
successfulSyncs: 0,
missedCriticalContext: 0,
averageSyncLatency: 0
};
constructor() {
super();
this.setupCriticalSharingMonitoring();
}
/**
* Register an agent with context sharing awareness
*/
registerAgent(agentId, agentType, config) {
const awareness = {
agentId,
agentType,
awarenessLevel: 'full',
lastContextSync: new Date(),
contextDependencies: config.contextDependencies,
contextContributions: config.contextContributions,
sharingImportanceScore: config.sharingImportanceScore
};
this.agentAwareness.set(agentId, awareness);
// Subscribe agent to context types they depend on
for (const contextType of config.contextDependencies) {
if (!this.contextSubscriptions.has(contextType)) {
this.contextSubscriptions.set(contextType, new Set());
}
this.contextSubscriptions.get(contextType).add(agentId);
}
this.emit('agent_registered', { agentId, awareness });
}
/**
* Share context from any agent to relevant agents
*/
async shareContext(context) {
const contextId = `ctx-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
const contextEntry = {
id: contextId,
timestamp: new Date(),
...context
};
this.contextStore.set(contextId, contextEntry);
this.sharingMetrics.totalContextsShared++;
// Determine target agents based on sharing configuration and subscriptions
const targetAgents = this.determineTargetAgents(contextEntry);
// Create synchronization event
const syncEvent = {
eventType: 'context_added',
targetAgents,
contextId,
urgency: this.calculateUrgency(contextEntry),
syncMetadata: {
requiredFor: contextEntry.content.title,
deadline: contextEntry.priority === 'critical' ? new Date(Date.now() + 60000) : undefined
}
};
// Perform bidirectional synchronization
await this.synchronizeContext(syncEvent);
// Emit context sharing event
this.emit('context_shared', { contextEntry, targetAgents, syncEvent });
return contextId;
}
/**
* Request specific context (pull model)
*/
async requestContext(requestingAgentId, contextType, criteria) {
const relevantContexts = Array.from(this.contextStore.values())
.filter(ctx => {
// Match type
if (ctx.type !== contextType)
return false;
// Match priority if specified
if (criteria.priority && ctx.priority !== criteria.priority)
return false;
// Check age if specified
if (criteria.maxAge) {
const age = Date.now() - ctx.timestamp.getTime();
if (age > criteria.maxAge)
return false;
}
return true;
})
.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime()); // Newest first
// Record context request
this.emit('context_requested', {
requestingAgentId,
contextType,
criteria,
foundCount: relevantContexts.length
});
// Update agent's last sync time
const awareness = this.agentAwareness.get(requestingAgentId);
if (awareness) {
awareness.lastContextSync = new Date();
this.agentAwareness.set(requestingAgentId, awareness);
}
// Track dependency
if (!this.contextDependencies.has(requestingAgentId)) {
this.contextDependencies.set(requestingAgentId, []);
}
const dependencies = this.contextDependencies.get(requestingAgentId);
const contextIds = relevantContexts.map(ctx => ctx.id);
this.contextDependencies.set(requestingAgentId, [...new Set([...dependencies, ...contextIds])]);
return relevantContexts;
}
/**
* Update existing context (collaborative refinement)
*/
async updateContext(contextId, updatingAgentId, updates) {
const context = this.contextStore.get(contextId);
if (!context)
return false;
// Merge updates
const updatedContext = {
...context,
content: { ...context.content, ...updates.content },
contextual: { ...context.contextual, ...updates.contextual }
};
// Add updating agent's insights
if (updates.additionalInsights) {
if (!updatedContext.content.recommendations) {
updatedContext.content.recommendations = [];
}
updatedContext.content.recommendations.push(...updates.additionalInsights.map(insight => `[${updatingAgentId}]: ${insight}`));
}
this.contextStore.set(contextId, updatedContext);
// Notify other agents of the update
const targetAgents = this.determineTargetAgents(updatedContext)
.filter(agentId => agentId !== updatingAgentId); // Don't notify the updating agent
const syncEvent = {
eventType: 'context_updated',
targetAgents,
contextId,
urgency: 'normal',
syncMetadata: {
requiredFor: `Context update by ${updatingAgentId}`
}
};
await this.synchronizeContext(syncEvent);
this.emit('context_updated', { contextId, updatingAgentId, updates, targetAgents });
return true;
}
/**
* Get agent's context awareness status
*/
getAgentAwareness(agentId) {
return this.agentAwareness.get(agentId) || null;
}
/**
* Get comprehensive context sharing status
*/
getContextSharingStatus() {
const recentActivity = Array.from(this.contextStore.values())
.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime())
.slice(0, 10);
const criticalGaps = this.identifyCriticalContextGaps();
return {
totalContexts: this.contextStore.size,
activeAgents: this.agentAwareness.size,
sharingMetrics: { ...this.sharingMetrics },
recentActivity,
criticalGaps
};
}
/**
* Emphasize context sharing importance to agents
*/
emphasizeContextSharingImportance(agentId, scenario) {
const awareness = this.agentAwareness.get(agentId);
if (!awareness) {
return {
importance: 'critical',
reasoning: 'Agent not registered - context sharing is essential for coordination',
recommendations: ['Register with context manager immediately', 'Share all discoveries and decisions']
};
}
const importance = this.calculateContextImportance(awareness, scenario);
const reasoning = this.generateImportanceReasoning(awareness, scenario, importance);
const recommendations = this.generateContextSharingRecommendations(awareness, scenario);
return { importance, reasoning, recommendations };
}
/**
* Determine target agents for context sharing
*/
determineTargetAgents(context) {
const targets = new Set();
// Add agents subscribed to this context type
const subscribers = this.contextSubscriptions.get(context.type) || new Set();
subscribers.forEach(agentId => targets.add(agentId));
// Add specific sharing targets based on configuration
if (context.sharing.shareWithPrimary) {
const primaryAgents = Array.from(this.agentAwareness.values())
.filter(a => a.agentType === 'primary')
.map(a => a.agentId);
primaryAgents.forEach(agentId => targets.add(agentId));
}
if (context.sharing.shareWithSubAgents) {
const subAgents = Array.from(this.agentAwareness.values())
.filter(a => a.agentType === 'sub')
.map(a => a.agentId);
subAgents.forEach(agentId => targets.add(agentId));
}
if (context.sharing.shareWithBackground) {
const backgroundAgents = Array.from(this.agentAwareness.values())
.filter(a => a.agentType === 'background')
.map(a => a.agentId);
backgroundAgents.forEach(agentId => targets.add(agentId));
}
// Don't include the source agent
targets.delete(context.sourceId);
return Array.from(targets);
}
/**
* Calculate urgency for context synchronization
*/
calculateUrgency(context) {
if (context.priority === 'critical')
return 'immediate';
if (context.priority === 'high')
return 'high';
if (context.sharing.criticalForDecisionMaking)
return 'high';
if (context.type === 'error')
return 'high';
return 'normal';
}
/**
* Perform bidirectional context synchronization
*/
async synchronizeContext(syncEvent) {
const startTime = Date.now();
for (const targetAgentId of syncEvent.targetAgents) {
try {
await this.syncContextToAgent(targetAgentId, syncEvent);
this.sharingMetrics.successfulSyncs++;
}
catch (error) {
this.emit('sync_error', { targetAgentId, syncEvent, error });
if (syncEvent.urgency === 'immediate') {
this.sharingMetrics.missedCriticalContext++;
}
}
}
const syncLatency = Date.now() - startTime;
this.sharingMetrics.averageSyncLatency =
(this.sharingMetrics.averageSyncLatency + syncLatency) / 2;
this.emit('context_synchronized', { syncEvent, syncLatency });
}
/**
* Sync context to a specific agent
*/
async syncContextToAgent(agentId, syncEvent) {
const awareness = this.agentAwareness.get(agentId);
if (!awareness) {
throw new Error(`Agent ${agentId} not registered for context sharing`);
}
const context = this.contextStore.get(syncEvent.contextId);
if (!context) {
throw new Error(`Context ${syncEvent.contextId} not found`);
}
// Update agent's last sync time
awareness.lastContextSync = new Date();
this.agentAwareness.set(agentId, awareness);
// Emit agent-specific sync event
this.emit('agent_context_sync', {
agentId,
context,
syncEvent,
awareness
});
}
/**
* Setup monitoring for critical context sharing
*/
setupCriticalSharingMonitoring() {
// Monitor for agents that haven't synced recently
setInterval(() => {
const staleThreshold = 300000; // 5 minutes
const now = Date.now();
for (const [agentId, awareness] of this.agentAwareness.entries()) {
const timeSinceSync = now - awareness.lastContextSync.getTime();
if (timeSinceSync > staleThreshold && awareness.sharingImportanceScore > 0.7) {
this.emit('agent_context_stale', {
agentId,
awareness,
timeSinceSync
});
}
}
}, 60000); // Check every minute
// Monitor for critical context that wasn't acknowledged
this.on('context_shared', ({ contextEntry, targetAgents }) => {
if (contextEntry.sharing.requiresAcknowledgment) {
setTimeout(() => {
this.emit('acknowledgment_timeout', {
contextId: contextEntry.id,
targetAgents,
context: contextEntry
});
}, 30000); // 30 second timeout for acknowledgment
}
});
}
/**
* Identify critical context gaps
*/
identifyCriticalContextGaps() {
const gaps = [];
// Check for agents with high sharing importance but low recent activity
for (const [agentId, awareness] of this.agentAwareness.entries()) {
if (awareness.sharingImportanceScore > 0.8) {
const timeSinceSync = Date.now() - awareness.lastContextSync.getTime();
if (timeSinceSync > 600000) { // 10 minutes
gaps.push(`Agent ${agentId} has high sharing importance but hasn't synced in ${Math.round(timeSinceSync / 60000)} minutes`);
}
}
}
// Check for missing critical context types
const criticalTypes = ['error', 'decision', 'discovery'];
const recentContextTypes = new Set(Array.from(this.contextStore.values())
.filter(ctx => Date.now() - ctx.timestamp.getTime() < 300000) // Last 5 minutes
.map(ctx => ctx.type));
for (const criticalType of criticalTypes) {
if (!recentContextTypes.has(criticalType)) {
gaps.push(`No recent ${criticalType} context shared - may indicate communication gap`);
}
}
return gaps;
}
/**
* Calculate context sharing importance for an agent
*/
calculateContextImportance(awareness, scenario) {
if (awareness.sharingImportanceScore > 0.8)
return 'critical';
if (awareness.sharingImportanceScore > 0.6)
return 'high';
return 'medium';
}
/**
* Generate reasoning for context sharing importance
*/
generateImportanceReasoning(awareness, scenario, importance) {
const baseReasoning = `Context sharing is ${importance} for ${awareness.agentType} agent ${awareness.agentId}`;
if (importance === 'critical') {
return `${baseReasoning} because coordinated decision-making depends on shared understanding. Without bidirectional context, agents make suboptimal decisions that impact the entire system.`;
}
else if (importance === 'high') {
return `${baseReasoning} because effective collaboration requires shared situational awareness. Context gaps lead to duplicated work and missed optimizations.`;
}
else {
return `${baseReasoning} for maintaining coordination and avoiding conflicts between agent actions.`;
}
}
/**
* Generate context sharing recommendations
*/
generateContextSharingRecommendations(awareness, scenario) {
const recommendations = [];
if (awareness.agentType === 'primary') {
recommendations.push('Share all major decisions and discoveries with sub-agents immediately');
recommendations.push('Request progress updates from sub-agents every 2-3 minutes');
recommendations.push('Maintain awareness of background agent findings');
}
else if (awareness.agentType === 'sub') {
recommendations.push('Continuously update primary agent on progress and findings');
recommendations.push('Share insights that could affect other sub-agents');
recommendations.push('Request context when encountering unfamiliar situations');
}
else {
recommendations.push('Proactively share critical findings and alerts');
recommendations.push('Provide context about system state changes');
}
recommendations.push('Use high-priority sharing for time-sensitive information');
recommendations.push('Update shared context collaboratively when new insights emerge');
return recommendations;
}
}
//# sourceMappingURL=bidirectional-context-manager.js.map