UNPKG

@tehreet/conduit

Version:

LLM API gateway with intelligent routing, robust process management, and health monitoring

165 lines 6.71 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.PluginManager = exports.DefaultPluginManager = void 0; const promises_1 = require("fs/promises"); const path_1 = require("path"); const log_1 = require("../utils/log"); class DefaultPluginManager { constructor() { this.plugins = new Map(); } registerPlugin(plugin) { if (this.plugins.has(plugin.name)) { (0, log_1.log)(`Plugin ${plugin.name} is already registered, replacing...`); } this.plugins.set(plugin.name, plugin); (0, log_1.log)(`Registered plugin: ${plugin.name} v${plugin.version}`); } async loadPlugins(pluginDir) { try { const exists = await (0, promises_1.stat)(pluginDir) .then(() => true) .catch(() => false); if (!exists) { (0, log_1.log)(`Plugin directory ${pluginDir} does not exist, skipping plugin loading`); return; } const entries = await (0, promises_1.readdir)(pluginDir, { withFileTypes: true }); for (const entry of entries) { if (entry.isFile() && ((0, path_1.extname)(entry.name) === '.js' || (0, path_1.extname)(entry.name) === '.ts')) { await this.loadPluginFile((0, path_1.join)(pluginDir, entry.name)); } else if (entry.isDirectory()) { // Look for index.js or index.ts in subdirectories const indexFiles = ['index.js', 'index.ts']; for (const indexFile of indexFiles) { const indexPath = (0, path_1.join)(pluginDir, entry.name, indexFile); const indexExists = await (0, promises_1.stat)(indexPath) .then(() => true) .catch(() => false); if (indexExists) { await this.loadPluginFile(indexPath); break; } } } } } catch (error) { (0, log_1.log)(`Error loading plugins from ${pluginDir}:`, error); } } async loadPluginFile(filePath) { try { // Dynamic import for ES modules and CommonJS compatibility const pluginModule = await Promise.resolve(`${filePath}`).then(s => __importStar(require(s))); const PluginClass = pluginModule.default || pluginModule; if (typeof PluginClass === 'function') { const plugin = new PluginClass(); if (this.isValidPlugin(plugin)) { this.registerPlugin(plugin); } else { (0, log_1.log)(`Invalid plugin in file ${filePath}: missing required properties`); } } else if (this.isValidPlugin(PluginClass)) { this.registerPlugin(PluginClass); } else { (0, log_1.log)(`Invalid plugin export in file ${filePath}`); } } catch (error) { (0, log_1.log)(`Error loading plugin from ${filePath}:`, error); } } isValidPlugin(obj) { return (obj && typeof obj.name === 'string' && typeof obj.version === 'string' && (obj.beforeRouting || obj.afterRouting || obj.onModelSelected || obj.customRouter)); } async executeHook(hookName, data) { let result = data; for (const [pluginName, plugin] of this.plugins) { try { const hookFn = plugin[hookName]; if (typeof hookFn === 'function') { (0, log_1.log)(`Executing ${hookName} hook for plugin ${pluginName}`); result = await hookFn.call(plugin, result); } } catch (error) { (0, log_1.log)(`Error executing ${hookName} hook for plugin ${pluginName}:`, error); // Continue with other plugins even if one fails } } return result; } async executeCustomRouting(context) { for (const [pluginName, plugin] of this.plugins) { try { if (plugin.customRouter) { (0, log_1.log)(`Trying custom router for plugin ${pluginName}`); const result = await plugin.customRouter(context); if (result) { (0, log_1.log)(`Plugin ${pluginName} provided custom routing: ${result.model}`); return result; } } } catch (error) { (0, log_1.log)(`Error in custom router for plugin ${pluginName}:`, error); // Continue with other plugins even if one fails } } return null; } getRegisteredPlugins() { return Array.from(this.plugins.keys()); } getPlugin(name) { return this.plugins.get(name); } } exports.DefaultPluginManager = DefaultPluginManager; exports.PluginManager = DefaultPluginManager; //# sourceMappingURL=plugin-manager.js.map