UNPKG

@juspay/neurolink

Version:

Universal AI Development Platform with working MCP integration, multi-provider support, and professional CLI. Built-in tools operational, 58+ external MCP servers discoverable. Connect to filesystem, GitHub, database operations, and more. Build, test, and

284 lines (283 loc) 9.97 kB
import { logger } from "../utils/logger.js"; /** * Global middleware registry for NeuroLink * Manages registration, configuration, and execution of middleware */ export class MiddlewareRegistry { middleware = new Map(); globalConfigs = new Map(); executionStats = new Map(); /** * Register a middleware */ register(middleware, options = {}) { const { replace = false, defaultEnabled = false, globalConfig } = options; // Check if middleware already exists if (this.middleware.has(middleware.metadata.id) && !replace) { throw new Error(`Middleware with ID '${middleware.metadata.id}' already exists. Use replace: true to override.`); } // Set default enabled state if (middleware.metadata.defaultEnabled === undefined) { middleware.metadata.defaultEnabled = defaultEnabled; } // Store middleware this.middleware.set(middleware.metadata.id, middleware); // Store global configuration if provided if (globalConfig) { this.globalConfigs.set(middleware.metadata.id, globalConfig); } logger.debug(`Middleware registered: ${middleware.metadata.id}`, { name: middleware.metadata.name, priority: middleware.metadata.priority || 0, defaultEnabled: middleware.metadata.defaultEnabled, }); } /** * Unregister a middleware */ unregister(middlewareId) { const removed = this.middleware.delete(middlewareId); this.globalConfigs.delete(middlewareId); this.executionStats.delete(middlewareId); if (removed) { logger.debug(`Middleware unregistered: ${middlewareId}`); } return removed; } /** * Get a registered middleware */ get(middlewareId) { return this.middleware.get(middlewareId); } /** * List all registered middleware */ list() { return Array.from(this.middleware.values()); } /** * Get middleware IDs sorted by priority */ getSortedIds() { return Array.from(this.middleware.values()) .sort((a, b) => (b.metadata.priority || 0) - (a.metadata.priority || 0)) .map((m) => m.metadata.id); } /** * Build middleware chain based on configuration */ buildChain(context, config = {}) { const chain = []; const sortedIds = this.getSortedIds(); for (const middlewareId of sortedIds) { const middleware = this.middleware.get(middlewareId); if (!middleware) { continue; } const middlewareConfig = config[middlewareId]; const globalConfig = this.globalConfigs.get(middlewareId); // Determine if middleware should be applied const shouldApply = this.shouldApplyMiddleware(middleware, middlewareConfig, context); if (shouldApply) { // Create configured middleware instance const configuredMiddleware = this.configureMiddleware(middleware, middlewareConfig, globalConfig, context); chain.push(configuredMiddleware); logger.debug(`Added middleware to chain: ${middlewareId}`, { priority: middleware.metadata.priority || 0, chainLength: chain.length, }); } } return chain; } /** * Determine if middleware should be applied based on conditions */ shouldApplyMiddleware(middleware, config, context) { // Check if explicitly disabled if (config?.enabled === false) { return false; } // Check if explicitly enabled or default enabled const isEnabled = config?.enabled === true || (config?.enabled === undefined && middleware.metadata.defaultEnabled); if (!isEnabled) { return false; } // Check conditions const conditions = config?.conditions; if (!conditions) { return true; } // Check provider conditions if (conditions.providers && !conditions.providers.includes(context.provider)) { return false; } // Check model conditions if (conditions.models && !conditions.models.includes(context.model)) { return false; } // Check option conditions if (conditions.options) { for (const [key, value] of Object.entries(conditions.options)) { if (context.options[key] !== value) { return false; } } } // Check custom condition if (conditions.custom && !conditions.custom(context)) { return false; } return true; } /** * Configure middleware with runtime configuration */ configureMiddleware(middleware, config, globalConfig, context) { // Merge configurations: global < middleware config < runtime config const mergedConfig = { ...globalConfig, ...config?.config, }; // Create wrapper that tracks execution const wrappedMiddleware = {}; if (middleware.transformParams) { wrappedMiddleware.transformParams = async (args) => { const startTime = Date.now(); try { const result = await middleware.transformParams(args); this.recordExecution(middleware.metadata.id, startTime, true); return result; } catch (error) { this.recordExecution(middleware.metadata.id, startTime, false, error); throw error; } }; } if (middleware.wrapGenerate) { wrappedMiddleware.wrapGenerate = async (args) => { const startTime = Date.now(); try { const result = await middleware.wrapGenerate(args); this.recordExecution(middleware.metadata.id, startTime, true); return result; } catch (error) { this.recordExecution(middleware.metadata.id, startTime, false, error); throw error; } }; } if (middleware.wrapStream) { wrappedMiddleware.wrapStream = async (args) => { const startTime = Date.now(); try { const result = await middleware.wrapStream(args); this.recordExecution(middleware.metadata.id, startTime, true); return result; } catch (error) { this.recordExecution(middleware.metadata.id, startTime, false, error); throw error; } }; } return wrappedMiddleware; } /** * Record middleware execution statistics */ recordExecution(middlewareId, startTime, success, error) { const executionTime = Date.now() - startTime; const result = { applied: true, executionTime, error, }; if (!this.executionStats.has(middlewareId)) { this.executionStats.set(middlewareId, []); } const stats = this.executionStats.get(middlewareId) || []; stats.push(result); // Keep only last 100 executions per middleware if (stats.length > 100) { stats.shift(); } if (error) { logger.warn(`Middleware execution failed: ${middlewareId}`, { executionTime, error: error.message, }); } else { logger.debug(`Middleware executed: ${middlewareId}`, { executionTime, success, }); } } /** * Get execution statistics for a middleware */ getExecutionStats(middlewareId) { return this.executionStats.get(middlewareId) || []; } /** * Get aggregated statistics for all middleware */ getAggregatedStats() { const stats = {}; for (const [middlewareId, executions] of this.executionStats.entries()) { const successful = executions.filter((e) => !e.error).length; const failed = executions.filter((e) => e.error).length; const totalTime = executions.reduce((sum, e) => sum + e.executionTime, 0); const lastExecution = executions[executions.length - 1]; stats[middlewareId] = { totalExecutions: executions.length, successfulExecutions: successful, failedExecutions: failed, averageExecutionTime: executions.length > 0 ? totalTime / executions.length : 0, lastExecutionTime: lastExecution?.executionTime || 0, }; } return stats; } /** * Clear execution statistics */ clearStats(middlewareId) { if (middlewareId) { this.executionStats.delete(middlewareId); } else { this.executionStats.clear(); } } /** * Check if a middleware is registered */ has(middlewareId) { return this.middleware.has(middlewareId); } /** * Get the number of registered middleware */ size() { return this.middleware.size; } /** * Clear all registered middleware */ clear() { this.middleware.clear(); this.globalConfigs.clear(); this.executionStats.clear(); logger.debug("All middleware cleared from registry"); } } // Global middleware registry instance export const middlewareRegistry = new MiddlewareRegistry();