tasq/node_modules/agentic-flow/dist/hooks/p2p-swarm-hooks.js

260 lines
7.3 KiB
JavaScript

/**
* P2P Swarm V2 Hooks Integration
*
* Provides hook handlers for P2P swarm coordination:
* - PreToolUse: Check swarm connection, validate capabilities
* - PostToolUse: Sync learning data to swarm
* - SessionStart: Initialize swarm connection
* - Stop: Cleanup swarm connection
*/
import { createP2PSwarmV2 } from '../swarm/p2p-swarm-v2.js';
import { logger } from '../utils/logger.js';
// Global swarm instance for hooks
let hooksSwarmInstance = null;
/**
* Get or create swarm instance for hooks
*/
export async function getHooksSwarm(agentId, swarmKey) {
if (!hooksSwarmInstance) {
const id = agentId || `hooks-agent-${Date.now().toString(36)}`;
hooksSwarmInstance = await createP2PSwarmV2(id, swarmKey);
logger.info('P2P Swarm initialized for hooks', { agentId: id });
}
return hooksSwarmInstance;
}
/**
* Disconnect hooks swarm
*/
export function disconnectHooksSwarm() {
if (hooksSwarmInstance) {
hooksSwarmInstance.disconnect();
hooksSwarmInstance = null;
logger.info('P2P Swarm disconnected from hooks');
}
}
/**
* SessionStart hook - Initialize P2P swarm connection
*/
export async function onSessionStart(config) {
try {
// Check if swarm is enabled
if (process.env.AGENTIC_FLOW_P2P_SWARM !== 'true') {
return {
connected: false,
agentId: '',
swarmId: '',
swarmKey: '',
memberCount: 0,
};
}
const swarm = await getHooksSwarm(config?.agentId || process.env.AGENTIC_FLOW_SWARM_AGENT_ID, config?.swarmKey || process.env.AGENTIC_FLOW_SWARM_KEY);
if (config?.enableExecutor) {
swarm.startTaskExecutor();
}
const status = swarm.getStatus();
return {
connected: status.connected,
agentId: status.agentId,
swarmId: status.swarmId,
swarmKey: swarm.getSwarmKey(),
memberCount: swarm.getLiveMemberCount(),
};
}
catch (error) {
logger.error('Failed to initialize P2P swarm on session start', { error });
return {
connected: false,
agentId: '',
swarmId: '',
swarmKey: '',
memberCount: 0,
};
}
}
/**
* Stop hook - Cleanup P2P swarm connection
*/
export function onStop() {
disconnectHooksSwarm();
}
/**
* PreToolUse hook - Check swarm status before tool execution
*/
export async function onPreToolUse(toolName, params) {
if (!hooksSwarmInstance) {
return {
allow: true, // Allow if swarm not initialized
swarmConnected: false,
liveMembers: 0,
};
}
const status = hooksSwarmInstance.getStatus();
const liveMembers = hooksSwarmInstance.getLiveMemberCount();
// Provide recommendations based on swarm state
let recommendation;
if (toolName === 'Bash' || toolName === 'Edit' || toolName === 'Write') {
// Suggest syncing after file operations
recommendation = 'Consider syncing learning data to swarm after this operation';
}
return {
allow: true,
swarmConnected: status.connected,
liveMembers,
recommendation,
};
}
/**
* PostToolUse hook - Sync learning data after tool execution
*/
export async function onPostToolUse(toolName, params, result) {
if (!hooksSwarmInstance) {
return { synced: false };
}
try {
// Sync relevant data based on tool type
if (toolName === 'Edit' || toolName === 'Write') {
// Publish file change notification
const messageId = await hooksSwarmInstance.publish('file_changes', {
tool: toolName,
file: params.file_path || params.path,
timestamp: Date.now(),
success: !result?.error,
});
return {
synced: true,
syncType: 'file_change',
messageId,
};
}
if (toolName === 'Bash') {
// Publish command execution notification
const messageId = await hooksSwarmInstance.publish('commands', {
command: (params.command || '').substring(0, 100),
timestamp: Date.now(),
success: result?.exitCode === 0,
});
return {
synced: true,
syncType: 'command',
messageId,
};
}
return { synced: false };
}
catch (error) {
logger.warn('Failed to sync to P2P swarm', { error, toolName });
return { synced: false };
}
}
/**
* Sync Q-table to swarm (for learning coordination)
*/
export async function syncQTable(qTable) {
if (!hooksSwarmInstance) {
return {
success: false,
error: 'P2P swarm not connected',
};
}
try {
const pointer = await hooksSwarmInstance.syncQTable(qTable);
return {
success: true,
cid: pointer.cid,
};
}
catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : String(error),
};
}
}
/**
* Sync memory vectors to swarm
*/
export async function syncMemory(vectors, namespace = 'default') {
if (!hooksSwarmInstance) {
return {
success: false,
error: 'P2P swarm not connected',
};
}
try {
const pointer = await hooksSwarmInstance.syncMemory(vectors, namespace);
return {
success: true,
cid: pointer.cid,
};
}
catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : String(error),
};
}
}
/**
* Get swarm status for hooks context
*/
export function getSwarmStatus() {
if (!hooksSwarmInstance) {
return {
connected: false,
liveMembers: 0,
};
}
const status = hooksSwarmInstance.getStatus();
return {
connected: status.connected,
agentId: status.agentId,
swarmId: status.swarmId,
liveMembers: hooksSwarmInstance.getLiveMemberCount(),
relays: {
healthy: status.relays.healthy,
total: status.relays.total,
},
};
}
/**
* Subscribe to swarm topic for real-time updates
*/
export function subscribeToTopic(topic, callback) {
if (!hooksSwarmInstance) {
logger.warn('Cannot subscribe: P2P swarm not connected');
return;
}
hooksSwarmInstance.subscribe(topic, callback);
}
/**
* Publish to swarm topic
*/
export async function publishToTopic(topic, payload) {
if (!hooksSwarmInstance) {
logger.warn('Cannot publish: P2P swarm not connected');
return null;
}
try {
return await hooksSwarmInstance.publish(topic, payload);
}
catch (error) {
logger.error('Failed to publish to swarm', { error, topic });
return null;
}
}
// Export hook handlers for registration
export const p2pSwarmHooks = {
onSessionStart,
onStop,
onPreToolUse,
onPostToolUse,
syncQTable,
syncMemory,
getSwarmStatus,
subscribeToTopic,
publishToTopic,
getHooksSwarm,
disconnectHooksSwarm,
};
export default p2pSwarmHooks;
//# sourceMappingURL=p2p-swarm-hooks.js.map