jay-code
Version:
Streamlined AI CLI orchestration engine with mathematical rigor and enterprise-grade reliability
460 lines (397 loc) • 11.6 kB
text/typescript
/**
* Hive Mind Communication Protocol
* Defines how agents communicate, vote, and share knowledge
*/
import { EventEmitter } from 'events';
import { generateId } from '../utils/helpers.js';
export interface HiveMessage {
id: string;
from: string;
to: string | 'broadcast';
type: HiveMessageType;
payload: any;
timestamp: number;
priority: 'urgent' | 'high' | 'normal' | 'low';
requiresResponse?: boolean;
inReplyTo?: string;
}
export type HiveMessageType =
| 'task_proposal'
| 'vote_request'
| 'vote_response'
| 'status_update'
| 'knowledge_share'
| 'help_request'
| 'consensus_check'
| 'quality_report'
| 'coordination_sync';
export interface HiveChannel {
id: string;
name: string;
type: 'broadcast' | 'consensus' | 'coordination' | 'knowledge';
members: Set<string>;
messages: HiveMessage[];
}
export class HiveCommunicationProtocol extends EventEmitter {
private channels: Map<string, HiveChannel> = new Map();
private messageQueue: Map<string, HiveMessage[]> = new Map();
private knowledgeBase: Map<string, any> = new Map();
private consensusThreshold: number;
constructor(options: { consensusThreshold?: number } = {}) {
super();
this.consensusThreshold = options.consensusThreshold || 0.6;
this.initializeChannels();
}
/**
* Initialize default communication channels
*/
private initializeChannels() {
// Broadcast channel for all agents
this.createChannel('broadcast', 'broadcast', 'General announcements and updates');
// Consensus channel for voting
this.createChannel('consensus', 'consensus', 'Voting and decision making');
// Coordination channel for task management
this.createChannel('coordination', 'coordination', 'Task assignment and progress');
// Knowledge channel for sharing insights
this.createChannel('knowledge', 'knowledge', 'Knowledge sharing and learning');
}
/**
* Create a new communication channel
*/
createChannel(name: string, type: HiveChannel['type'], description: string): HiveChannel {
const channel: HiveChannel = {
id: generateId('channel'),
name,
type,
members: new Set(),
messages: [],
};
this.channels.set(channel.id, channel);
this.emit('channel:created', { channel, description });
return channel;
}
/**
* Join an agent to a channel
*/
joinChannel(channelId: string, agentId: string) {
const channel = this.channels.get(channelId);
if (!channel) throw new Error(`Channel ${channelId} not found`);
channel.members.add(agentId);
this.emit('channel:joined', { channelId, agentId });
}
/**
* Send a message through the protocol
*/
sendMessage(message: Omit<HiveMessage, 'id' | 'timestamp'>): HiveMessage {
const fullMessage: HiveMessage = {
...message,
id: generateId('msg'),
timestamp: Date.now(),
};
// Route message based on type
this.routeMessage(fullMessage);
// Store in appropriate channel
const channelType = this.getChannelTypeForMessage(fullMessage.type);
const channel = Array.from(this.channels.values()).find((c) => c.type === channelType);
if (channel) {
channel.messages.push(fullMessage);
}
// Queue for recipient(s)
if (fullMessage.to === 'broadcast') {
// Queue for all agents
for (const channel of this.channels.values()) {
for (const member of channel.members) {
this.queueMessage(member, fullMessage);
}
}
} else {
// Queue for specific recipient
this.queueMessage(fullMessage.to, fullMessage);
}
this.emit('message:sent', fullMessage);
return fullMessage;
}
/**
* Route message based on type
*/
private routeMessage(message: HiveMessage) {
switch (message.type) {
case 'vote_request':
this.handleVoteRequest(message);
break;
case 'knowledge_share':
this.handleKnowledgeShare(message);
break;
case 'consensus_check':
this.handleConsensusCheck(message);
break;
case 'quality_report':
this.handleQualityReport(message);
break;
}
}
/**
* Get channel type for message type
*/
private getChannelTypeForMessage(messageType: HiveMessageType): HiveChannel['type'] {
switch (messageType) {
case 'vote_request':
case 'vote_response':
case 'consensus_check':
return 'consensus';
case 'task_proposal':
case 'status_update':
case 'coordination_sync':
return 'coordination';
case 'knowledge_share':
return 'knowledge';
default:
return 'broadcast';
}
}
/**
* Queue message for agent
*/
private queueMessage(agentId: string, message: HiveMessage) {
if (!this.messageQueue.has(agentId)) {
this.messageQueue.set(agentId, []);
}
this.messageQueue.get(agentId)!.push(message);
}
/**
* Retrieve messages for agent
*/
getMessages(agentId: string): HiveMessage[] {
const messages = this.messageQueue.get(agentId) || [];
this.messageQueue.set(agentId, []); // Clear after retrieval
return messages;
}
/**
* Handle vote request
*/
private handleVoteRequest(message: HiveMessage) {
const { proposal, deadline } = message.payload;
this.emit('vote:requested', {
messageId: message.id,
proposal,
deadline,
from: message.from,
});
// Set timeout for vote collection
if (deadline) {
setTimeout(() => {
this.collectVotes(message.id);
}, deadline - Date.now());
}
}
/**
* Submit a vote response
*/
submitVote(requestId: string, agentId: string, vote: boolean, confidence: number = 1.0) {
const voteMessage = this.sendMessage({
from: agentId,
to: 'consensus',
type: 'vote_response',
payload: {
requestId,
vote,
confidence,
reasoning: this.generateVoteReasoning(vote, confidence),
},
priority: 'high',
});
this.emit('vote:submitted', {
requestId,
agentId,
vote,
confidence,
});
return voteMessage;
}
/**
* Generate reasoning for vote
*/
private generateVoteReasoning(vote: boolean, confidence: number): string {
if (vote && confidence > 0.8) {
return 'Strong alignment with objectives and capabilities';
} else if (vote && confidence > 0.5) {
return 'Moderate alignment, some concerns but manageable';
} else if (!vote && confidence > 0.8) {
return 'Significant concerns or misalignment detected';
} else {
return 'Insufficient information or capability mismatch';
}
}
/**
* Collect and evaluate votes
*/
private collectVotes(requestId: string) {
const votes = new Map<string, { vote: boolean; confidence: number }>();
// Collect all vote responses for this request
for (const channel of this.channels.values()) {
for (const message of channel.messages) {
if (message.type === 'vote_response' && message.payload.requestId === requestId) {
votes.set(message.from, {
vote: message.payload.vote,
confidence: message.payload.confidence,
});
}
}
}
// Calculate consensus
const consensus = this.calculateConsensus(votes);
this.emit('consensus:reached', {
requestId,
consensus,
votes: Array.from(votes.entries()),
});
}
/**
* Calculate consensus from votes
*/
private calculateConsensus(votes: Map<string, { vote: boolean; confidence: number }>): {
approved: boolean;
confidence: number;
} {
if (votes.size === 0) {
return { approved: false, confidence: 0 };
}
let totalWeight = 0;
let approvalWeight = 0;
for (const [_, { vote, confidence }] of votes) {
totalWeight += confidence;
if (vote) {
approvalWeight += confidence;
}
}
const approvalRate = approvalWeight / totalWeight;
const approved = approvalRate >= this.consensusThreshold;
return { approved, confidence: approvalRate };
}
/**
* Handle knowledge sharing
*/
private handleKnowledgeShare(message: HiveMessage) {
const { key, value, metadata } = message.payload;
// Store in knowledge base
this.knowledgeBase.set(key, {
value,
metadata,
contributor: message.from,
timestamp: message.timestamp,
});
this.emit('knowledge:shared', {
key,
contributor: message.from,
timestamp: message.timestamp,
});
}
/**
* Query knowledge base
*/
queryKnowledge(pattern: string): any[] {
const results = [];
for (const [key, data] of this.knowledgeBase) {
if (key.includes(pattern)) {
results.push({ key, ...data });
}
}
return results;
}
/**
* Handle consensus check
*/
private handleConsensusCheck(message: HiveMessage) {
const { topic, options } = message.payload;
// Initiate voting round
const voteRequest = this.sendMessage({
from: 'consensus-system',
to: 'broadcast',
type: 'vote_request',
payload: {
topic,
options,
deadline: Date.now() + 30000, // 30 second deadline
},
priority: 'urgent',
requiresResponse: true,
});
this.emit('consensus:initiated', {
topic,
options,
requestId: voteRequest.id,
});
}
/**
* Handle quality report
*/
private handleQualityReport(message: HiveMessage) {
const { taskId, metrics, issues } = message.payload;
// Store quality metrics
this.knowledgeBase.set(`quality/${taskId}`, {
metrics,
issues,
reporter: message.from,
timestamp: message.timestamp,
});
// Check if quality threshold breached
if (metrics.score < 0.7) {
this.emit('quality:alert', {
taskId,
score: metrics.score,
issues,
reporter: message.from,
});
}
}
/**
* Get communication statistics
*/
getStatistics() {
const stats = {
totalMessages: 0,
messagesByType: new Map<HiveMessageType, number>(),
messagesByPriority: new Map<string, number>(),
activeChannels: this.channels.size,
knowledgeEntries: this.knowledgeBase.size,
avgResponseTime: 0,
};
// Aggregate message statistics
for (const channel of this.channels.values()) {
stats.totalMessages += channel.messages.length;
for (const message of channel.messages) {
const typeCount = stats.messagesByType.get(message.type) || 0;
stats.messagesByType.set(message.type, typeCount + 1);
const priorityCount = stats.messagesByPriority.get(message.priority) || 0;
stats.messagesByPriority.set(message.priority, priorityCount + 1);
}
}
return stats;
}
/**
* Export communication log
*/
exportLog(): any {
const log = {
channels: Array.from(this.channels.values()).map((channel) => ({
id: channel.id,
name: channel.name,
type: channel.type,
memberCount: channel.members.size,
messageCount: channel.messages.length,
})),
messages: [],
knowledge: Array.from(this.knowledgeBase.entries()).map(([key, value]) => ({
key,
...value,
})),
};
// Collect all messages
for (const channel of this.channels.values()) {
log.messages.push(...channel.messages);
}
// Sort by timestamp
log.messages.sort((a, b) => a.timestamp - b.timestamp);
return log;
}
}