UNPKG

@devilsdev/rag-pipeline-utils

Version:

A modular toolkit for building RAG (Retrieval-Augmented Generation) pipelines in Node.js

57 lines (47 loc) 1.82 kB
/** * Version: 1.1.1 * Description: Dynamic plugin loader with direct type:name registry mapping * Author: Ali Kahwaji */ import fs from 'fs'; import path from 'path'; import { pathToFileURL } from 'url'; import registry from '../core/plugin-registry.js'; import { validatePluginSchema } from './validate-schema.js'; import { logger } from '../utils/logger.js'; /** * Loads plugins from validated config path and registers them. * @param {string} configPath */ export async function loadPluginsFromJson(configPath) { if (!fs.existsSync(configPath)) { throw new Error(`Plugin config missing: ${configPath}`); } const raw = fs.readFileSync(configPath, 'utf-8'); const config = JSON.parse(raw); const validation = validatePluginSchema(config); if (!validation.valid) { logger.error({ errors: validation.errors }, 'Invalid plugin config'); throw new Error('Plugin config validation failed'); } for (const [type, namedPlugins] of Object.entries(config)) { if (!['loader', 'embedder', 'retriever', 'llm'].includes(type)) continue; for (const [name, relPath] of Object.entries(namedPlugins)) { const absPath = path.resolve(path.dirname(configPath), relPath); const fileUrl = pathToFileURL(absPath).href; try { const mod = await import(fileUrl); const PluginClass = mod?.default; if (typeof PluginClass !== 'function') { throw new Error(`Invalid export in plugin [${type}:${name}] at ${absPath}`); } const instance = new PluginClass(); registry.register(type, name, instance); logger.info({ type, name }, `Registered plugin: ${type}:${name}`); } catch (err) { logger.error({ type, name, err }, `Failed to register plugin [${type}:${name}]`); throw err; } } } }