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

315 lines
9.3 KiB
JavaScript

/**
* P2P Swarm V2 WASM Integration
*
* Provides WASM-accelerated components for P2P Swarm:
* - Ed25519 identity (faster key generation)
* - HNSW indexing (fast member/capability search)
* - Semantic matching (intelligent task routing)
*/
import { initRuVectorWasm, isWasmInitialized, generateIdentity, signData, verifySignature, RuVectorHnswIndex, RuVectorSemanticMatcher, } from '../wasm/ruvector-edge.js';
import { logger } from '../utils/logger.js';
//=============================================================================
// WASM-Enhanced Identity Manager
//=============================================================================
/**
* WASM-accelerated identity manager for P2P Swarm
* Falls back to Node.js crypto when WASM unavailable
*/
export class WasmIdentityManager {
publicKey = null;
secretKey = null;
publicKeyHex = '';
initialized = false;
sendCounter = 0;
recvCounters = new Map();
seenNonces = new Map();
maxNonceAge = 300000; // 5 minutes
async initialize() {
if (this.initialized)
return;
// Try to initialize WASM
await initRuVectorWasm();
// Generate identity (uses WASM if available)
const identity = await generateIdentity();
this.publicKey = identity.publicKey;
this.secretKey = identity.secretKey;
this.publicKeyHex = identity.publicKeyHex;
this.initialized = true;
logger.info('WASM identity manager initialized', {
wasmAccelerated: isWasmInitialized(),
publicKeyPrefix: this.publicKeyHex.slice(0, 16),
});
}
/**
* Get public key as hex string
*/
getPublicKeyHex() {
return this.publicKeyHex;
}
/**
* Get public key as Uint8Array
*/
getPublicKey() {
if (!this.publicKey)
throw new Error('Identity not initialized');
return this.publicKey;
}
/**
* Sign data and return base64 signature
*/
async sign(data) {
if (!this.secretKey)
throw new Error('Identity not initialized');
const signature = await signData(new Uint8Array(Buffer.from(data)), this.secretKey);
return Buffer.from(signature).toString('base64');
}
/**
* Verify signature from peer
*/
async verify(data, signature, peerPublicKeyHex) {
try {
const pubKey = new Uint8Array(Buffer.from(peerPublicKeyHex, 'hex'));
const sig = new Uint8Array(Buffer.from(signature, 'base64'));
const dataBytes = new Uint8Array(Buffer.from(data));
return await verifySignature(dataBytes, sig, pubKey);
}
catch (error) {
logger.warn('Signature verification failed', { error });
return false;
}
}
/**
* Get next send counter (monotonic)
*/
getNextCounter() {
return ++this.sendCounter;
}
/**
* Validate counter from peer (must be strictly increasing)
*/
validateCounter(peerId, counter) {
const lastSeen = this.recvCounters.get(peerId) || 0;
if (counter <= lastSeen) {
return false;
}
this.recvCounters.set(peerId, counter);
return true;
}
/**
* Generate and track nonce
*/
generateNonce() {
const crypto = require('crypto');
return crypto.randomBytes(16).toString('hex');
}
/**
* Validate nonce (replay protection)
*/
validateNonce(senderId, nonce, timestamp) {
// Reject old messages
if (Date.now() - timestamp > this.maxNonceAge) {
return false;
}
// Get or create nonce set for sender
if (!this.seenNonces.has(senderId)) {
this.seenNonces.set(senderId, new Map());
}
const senderNonces = this.seenNonces.get(senderId);
// Reject replayed nonces
if (senderNonces.has(nonce)) {
return false;
}
senderNonces.set(nonce, timestamp);
return true;
}
/**
* Check if WASM acceleration is active
*/
isWasmAccelerated() {
return isWasmInitialized();
}
}
/**
* WASM-accelerated member index for fast capability search
*/
export class WasmMemberIndex {
hnswIndex;
members = new Map();
indexToAgentId = new Map();
dimensions;
constructor(dimensions = 128) {
this.dimensions = dimensions;
this.hnswIndex = new RuVectorHnswIndex(dimensions, 16, 200);
}
/**
* Add or update member
*/
addMember(member) {
this.members.set(member.agentId, member);
// If member has embedding, add to HNSW index
if (member.embedding) {
const idx = this.hnswIndex.add(member.embedding);
this.indexToAgentId.set(idx, member.agentId);
}
}
/**
* Remove member
*/
removeMember(agentId) {
this.members.delete(agentId);
// Note: HNSW doesn't support removal, but member won't be returned in searches
}
/**
* Get member by ID
*/
getMember(agentId) {
return this.members.get(agentId);
}
/**
* Find members with specific capabilities
*/
findByCapabilities(capabilities) {
const results = [];
for (const member of this.members.values()) {
const hasAll = capabilities.every(cap => member.capabilities.includes(cap));
if (hasAll) {
results.push(member);
}
}
return results;
}
/**
* Find k nearest members by embedding similarity
*/
findSimilar(queryEmbedding, k = 5) {
const searchResults = this.hnswIndex.search(queryEmbedding, k);
const members = [];
for (const result of searchResults) {
const agentId = this.indexToAgentId.get(result.index);
if (agentId) {
const member = this.members.get(agentId);
if (member) {
members.push(member);
}
}
}
return members;
}
/**
* Get all live members (last seen within threshold)
*/
getLiveMembers(maxAge = 30000) {
const now = Date.now();
const live = [];
for (const member of this.members.values()) {
if (now - member.lastSeen < maxAge) {
live.push(member);
}
}
return live;
}
/**
* Get total member count
*/
size() {
return this.members.size;
}
/**
* Check if WASM acceleration is active
*/
isWasmAccelerated() {
return this.hnswIndex.isWasmAccelerated();
}
}
//=============================================================================
// WASM-Enhanced Task Router
//=============================================================================
/**
* WASM-accelerated task router for intelligent agent selection
*/
export class WasmTaskRouter {
semanticMatcher;
dimensions;
constructor(dimensions = 128) {
this.dimensions = dimensions;
this.semanticMatcher = new RuVectorSemanticMatcher();
}
/**
* Register agent for task routing
*/
registerAgent(agentId, embedding, capabilities) {
this.semanticMatcher.registerAgent(agentId, embedding, capabilities);
}
/**
* Route task to best matching agents
*/
routeTask(taskEmbedding, requiredCapabilities, topK = 3) {
const matches = this.semanticMatcher.matchTask(taskEmbedding, topK * 2);
// Filter by required capabilities if specified
if (requiredCapabilities && requiredCapabilities.length > 0) {
return matches
.filter(m => requiredCapabilities.every(cap => m.capabilities.includes(cap)))
.slice(0, topK)
.map(m => ({
agentId: m.agent,
score: m.score,
capabilities: m.capabilities,
}));
}
return matches.slice(0, topK).map(m => ({
agentId: m.agent,
score: m.score,
capabilities: m.capabilities,
}));
}
/**
* Check if WASM acceleration is active
*/
isWasmAccelerated() {
return this.semanticMatcher.isWasmAccelerated();
}
}
//=============================================================================
// Factory Functions
//=============================================================================
/**
* Create WASM-enhanced identity manager
*/
export async function createWasmIdentityManager() {
const manager = new WasmIdentityManager();
await manager.initialize();
return manager;
}
/**
* Create WASM-enhanced member index
*/
export function createWasmMemberIndex(dimensions = 128) {
return new WasmMemberIndex(dimensions);
}
/**
* Create WASM-enhanced task router
*/
export function createWasmTaskRouter(dimensions = 128) {
return new WasmTaskRouter(dimensions);
}
/**
* Get WASM acceleration status
*/
export function getWasmStatus() {
return {
initialized: isWasmInitialized(),
features: isWasmInitialized()
? ['WasmIdentity', 'WasmHnswIndex', 'WasmSemanticMatcher']
: ['JS Fallback'],
};
}
export default {
WasmIdentityManager,
WasmMemberIndex,
WasmTaskRouter,
createWasmIdentityManager,
createWasmMemberIndex,
createWasmTaskRouter,
getWasmStatus,
};
//# sourceMappingURL=p2p-swarm-wasm.js.map