UNPKG

llmverify

Version:

AI Output Verification Toolkit — Local-first LLM safety, hallucination detection, PII redaction, prompt injection defense, and runtime monitoring. Zero telemetry. OWASP LLM Top 10 aligned.

165 lines 15 kB
"use strict"; /** * Plugin Registry System * * Extensible rule system for custom verification logic * * @module plugins/registry */ Object.defineProperty(exports, "__esModule", { value: true }); exports.PluginRegistry = void 0; exports.getPluginRegistry = getPluginRegistry; exports.resetPluginRegistry = resetPluginRegistry; /** * Plugin registry */ class PluginRegistry { constructor() { this.plugins = new Map(); } /** * Register a plugin */ register(plugin) { if (this.plugins.has(plugin.id)) { throw new Error(`Plugin ${plugin.id} is already registered`); } // Validate plugin this.validatePlugin(plugin); this.plugins.set(plugin.id, plugin); } /** * Validate plugin structure */ validatePlugin(plugin) { if (!plugin.id || typeof plugin.id !== 'string') { throw new Error('Plugin must have a valid id'); } if (!plugin.name || typeof plugin.name !== 'string') { throw new Error('Plugin must have a valid name'); } if (typeof plugin.execute !== 'function') { throw new Error('Plugin must have an execute function'); } } /** * Unregister a plugin */ unregister(pluginId) { return this.plugins.delete(pluginId); } /** * Get a plugin */ get(pluginId) { return this.plugins.get(pluginId); } /** * Get all plugins */ getAll() { return Array.from(this.plugins.values()); } /** * Get enabled plugins */ getEnabled() { return this.getAll() .filter(p => p.enabled) .sort((a, b) => (b.priority || 0) - (a.priority || 0)); } /** * Get plugins by category */ getByCategory(category) { return this.getAll().filter(p => p.category === category); } /** * Enable a plugin */ enable(pluginId) { const plugin = this.plugins.get(pluginId); if (plugin) { plugin.enabled = true; } } /** * Disable a plugin */ disable(pluginId) { const plugin = this.plugins.get(pluginId); if (plugin) { plugin.enabled = false; } } /** * Execute all enabled plugins */ async executeAll(context) { const enabledPlugins = this.getEnabled(); const results = []; for (const plugin of enabledPlugins) { try { const result = await plugin.execute(context); results.push(result); } catch (error) { console.error(`Plugin ${plugin.id} failed:`, error); // Continue with other plugins } } return results; } /** * Execute specific plugins */ async execute(pluginIds, context) { const results = []; for (const id of pluginIds) { const plugin = this.plugins.get(id); if (plugin && plugin.enabled) { try { const result = await plugin.execute(context); results.push(result); } catch (error) { console.error(`Plugin ${id} failed:`, error); } } } return results; } /** * Clear all plugins */ clear() { this.plugins.clear(); } /** * Get plugin count */ count() { return this.plugins.size; } } exports.PluginRegistry = PluginRegistry; /** * Global plugin registry */ let globalRegistry = null; /** * Get global plugin registry */ function getPluginRegistry() { if (!globalRegistry) { globalRegistry = new PluginRegistry(); } return globalRegistry; } /** * Reset global registry */ function resetPluginRegistry() { globalRegistry = null; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVnaXN0cnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcGx1Z2lucy9yZWdpc3RyeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7OztHQU1HOzs7QUE0TUgsOENBS0M7QUFLRCxrREFFQztBQTFLRDs7R0FFRztBQUNILE1BQWEsY0FBYztJQUEzQjtRQUNVLFlBQU8sR0FBd0IsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQWdKbkQsQ0FBQztJQTlJQzs7T0FFRztJQUNJLFFBQVEsQ0FBQyxNQUFjO1FBQzVCLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7WUFDaEMsTUFBTSxJQUFJLEtBQUssQ0FBQyxVQUFVLE1BQU0sQ0FBQyxFQUFFLHdCQUF3QixDQUFDLENBQUM7UUFDL0QsQ0FBQztRQUVELGtCQUFrQjtRQUNsQixJQUFJLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRTVCLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDdEMsQ0FBQztJQUVEOztPQUVHO0lBQ0ssY0FBYyxDQUFDLE1BQWM7UUFDbkMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLElBQUksT0FBTyxNQUFNLENBQUMsRUFBRSxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQ2hELE1BQU0sSUFBSSxLQUFLLENBQUMsNkJBQTZCLENBQUMsQ0FBQztRQUNqRCxDQUFDO1FBRUQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLElBQUksT0FBTyxNQUFNLENBQUMsSUFBSSxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQ3BELE1BQU0sSUFBSSxLQUFLLENBQUMsK0JBQStCLENBQUMsQ0FBQztRQUNuRCxDQUFDO1FBRUQsSUFBSSxPQUFPLE1BQU0sQ0FBQyxPQUFPLEtBQUssVUFBVSxFQUFFLENBQUM7WUFDekMsTUFB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QUFDO2dCQUM3QixJQUFJLENBQUM7b0JBQ0gsTUFBTSxNQUFNLEdBQUcsTUFBTSxNQUFNLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO29CQUM3QyxPQUFPLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUN2QixDQUFDO2dCQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7b0JBQ2YsT0FBTyxDQUFDLEtBQUssQ0FBQyxVQUFVLEVBQUUsVUFBVSxFQUFFLEtBQUssQ0FBQyxDQUFDO2dCQUMvQyxDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUM7UUFFRCxPQUFPLE9BQU8sQ0FBQztJQUNqQixDQUFDO0lBRUQ7O09BRUc7SUFDSSxLQUFLO1FBQ1YsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUN2QixDQUFDO0lBRUQ7O09BRUc7SUFDSSxLQUFLO1FBQ1YsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQztJQUMzQixDQUFDO0NBQ0Y7QUFqSkQsd0NBaUpDO0FBRUQ7O0dBRUc7QUFDSCxJQUFJLGNBQWMsR0FBMEIsSUFBSSxDQUFDO0FBRWpEOztHQUVHO0FBQ0gsU0FBZ0IsaUJBQWlCO0lBQy9CLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUNwQixjQUFjLEdBQUcsSUFBSSxjQUFjLEVBQUUsQ0FBQztJQUN4QyxDQUFDO0lBQ0QsT0FBTyxjQUFjLENBQUM7QUFDeEIsQ0FBQztBQUVEOztHQUVHO0FBQ0gsU0FBZ0IsbUJBQW1CO0lBQ2pDLGNBQWMsR0FBRyxJQUFJLENBQUM7QUFDeEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogUGx1Z2luIFJlZ2lzdHJ5IFN5c3RlbVxuICogXG4gKiBFeHRlbnNpYmxlIHJ1bGUgc3lzdGVtIGZvciBjdXN0b20gdmVyaWZpY2F0aW9uIGxvZ2ljXG4gKiBcbiAqIEBtb2R1bGUgcGx1Z2lucy9yZWdpc3RyeVxuICovXG5cbi8qKlxuICogUGx1Z2luIGNvbnRleHQgcHJvdmlkZWQgdG8gcnVsZXNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQbHVnaW5Db250ZXh0IHtcbiAgY29udGVudDogc3RyaW5nO1xuICBwcm9tcHQ/OiBzdHJpbmc7XG4gIGNvbmZpZz86IGFueTtcbiAgbWV0YWRhdGE/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xufVxuXG4vKipcbiAqIFBsdWdpbiByZXN1bHRcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQbHVnaW5SZXN1bHQge1xuICBmaW5kaW5nczogQXJyYXk8e1xuICAgIGNhdGVnb3J5OiBzdHJpbmc7XG4gICAgc2V2ZXJpdHk6IHN0cmluZztcbiAgICBtZXNzYWdlOiBzdHJpbmc7XG4gICAgbWV0YWRhdGE/OiBhbnk7XG4gIH0+O1xuICBzY29yZT86IG51bWJlcjtcbiAgbWV0YWRhdGE/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xufVxuXG4vKipcbiAqIFBsdWdpbiBmdW5jdGlvbiBzaWduYXR1cmVcbiAqL1xuZXhwb3J0IHR5cGUgUGx1Z2luRnVuY3Rpb24gPSAoY29udGV4dDogUGx1Z2luQ29udGV4dCkgPT4gUGx1Z2luUmVzdWx0IHwgUHJvbWlzZTxQbHVnaW5SZXN1bHQ+O1xuXG4vKipcbiAqIFBsdWdpbiBkZWZpbml0aW9uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUGx1Z2luIHtcbiAgaWQ6IHN0cmluZztcbiAgbmFtZTogc3RyaW5nO1xuICB2ZXJzaW9uOiBzdHJpbmc7XG4gIGRlc2NyaXB0aW9uPzogc3RyaW5nO1xuICBhdXRob3I/OiBzdHJpbmc7XG4gIGNhdGVnb3J5OiAnc2VjdXJpdHknIHwgJ3ByaXZhY3knIHwgJ3NhZmV0eScgfCAncXVhbGl0eScgfCAnY3VzdG9tJztcbiAgZW5hYmxlZDogYm9vbGVhbjtcbiAgcHJpb3JpdHk/OiBudW1iZXI7IC8vIEhpZ2hlciBwcmlvcml0eSBydW5zIGZpcnN0XG4gIGV4ZWN1dGU6IFBsdWdpbkZ1bmN0aW9uO1xufVxuXG4vKipcbiAqIFBsdWdpbiByZWdpc3RyeVxuICovXG5leHBvcnQgY2xhc3MgUGx1Z2luUmVnaXN0cnkge1xuICBwcml2YXRlIHBsdWdpbnM6IE1hcDxzdHJpbmcsIFBsdWdpbj4gPSBuZXcgTWFwKCk7XG4gIFxuICAvKipcbiAgICogUmVnaXN0ZXIgYSBwbHVnaW5cbiAgICovXG4gIHB1YmxpYyByZWdpc3RlcihwbHVnaW46IFBsdWdpbik6IHZvaWQge1xuICAgIGlmICh0aGlzLnBsdWdpbnMuaGFzKHBsdWdpbi5pZCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgUGx1Z2luICR7cGx1Z2luLmlkfSBpcyBhbHJlYWR5IHJlZ2lzdGVyZWRgKTtcbiAgICB9XG4gICAgXG4gICAgLy8gVmFsaWRhdGUgcGx1Z2luXG4gICAgdGhpcy52YWxpZGF0ZVBsdWdpbihwbHVnaW4pO1xuICAgIFxuICAgIHRoaXMucGx1Z2lucy5zZXQocGx1Z2luLmlkLCBwbHVnaW4pO1xuICB9XG4gIFxuICAvKipcbiAgICogVmFsaWRhdGUgcGx1Z2luIHN0cnVjdHVyZVxuICAgKi9cbiAgcHJpdmF0ZSB2YWxpZGF0ZVBsdWdpbihwbHVnaW46IFBsdWdpbik6IHZvaWQge1xuICAgIGlmICghcGx1Z2luLmlkIHx8IHR5cGVvZiBwbHVnaW4uaWQgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1BsdWdpbiBtdXN0IGhhdmUgYSB2YWxpZCBpZCcpO1xuICAgIH1cbiAgICBcbiAgICBpZiAoIXBsdWdpbi5uYW1lIHx8IHR5cGVvZiBwbHVnaW4ubmFtZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUGx1Z2luIG11c3QgaGF2ZSBhIHZhbGlkIG5hbWUnKTtcbiAgICB9XG4gICAgXG4gICAgaWYgKHR5cGVvZiBwbHVnaW4uZXhlY3V0ZSAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdQbHVnaW4gbXVzdCBoYXZlIGFuIGV4ZWN1dGUgZnVuY3Rpb24nKTtcbiAgICB9XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBVbnJlZ2lzdGVyIGEgcGx1Z2luXG4gICAqL1xuICBwdWJsaWMgdW5yZWdpc3RlcihwbHVnaW5JZDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMucGx1Z2lucy5kZWxldGUocGx1Z2luSWQpO1xuICB9XG4gIFxuICAvKipcbiAgICogR2V0IGEgcGx1Z2luXG4gICAqL1xuICBwdWJsaWMgZ2V0KHBsdWdpbklkOiBzdHJpbmcpOiBQbHVnaW4gfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLnBsdWdpbnMuZ2V0KHBsdWdpbklkKTtcbiAgfVxuICBcbiAgLyoqXG4gICAqIEdldCBhbGwgcGx1Z2luc1xuICAgKi9cbiAgcHVibGljIGdldEFsbCgpOiBQbHVnaW5bXSB7XG4gICAgcmV0dXJuIEFycmF5LmZyb20odGhpcy5wbHVnaW5zLnZhbHVlcygpKTtcbiAgfVxuICBcbiAgLyoqXG4gICAqIEdldCBlbmFibGVkIHBsdWdpbnNcbiAgICovXG4gIHB1YmxpYyBnZXRFbmFibGVkKCk6IFBsdWdpbltdIHtcbiAgICByZXR1cm4gdGhpcy5nZXRBbGwoKVxuICAgICAgLmZpbHRlcihwID0+IHAuZW5hYmxlZClcbiAgICAgIC5zb3J0KChhLCBiKSA9PiAoYi5wcmlvcml0eSB8fCAwKSAtIChhLnByaW9yaXR5IHx8IDApKTtcbiAgfVxuICBcbiAgLyoqXG4gICAqIEdldCBwbHVnaW5zIGJ5IGNhdGVnb3J5XG4gICAqL1xuICBwdWJsaWMgZ2V0QnlDYXRlZ29yeShjYXRlZ29yeTogUGx1Z2luWydjYXRlZ29yeSddKTogUGx1Z2luW10ge1xuICAgIHJldHVybiB0aGlzLmdldEFsbCgpLmZpbHRlcihwID0+IHAuY2F0ZWdvcnkgPT09IGNhdGVnb3J5KTtcbiAgfVxuICBcbiAgLyoqXG4gICAqIEVuYWJsZSBhIHBsdWdpblxuICAgKi9cbiAgcHVibGljIGVuYWJsZShwbHVnaW5JZDogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgcGx1Z2luID0gdGhpcy5wbHVnaW5zLmdldChwbHVnaW5JZCk7XG4gICAgaWYgKHBsdWdpbikge1xuICAgICAgcGx1Z2luLmVuYWJsZWQgPSB0cnVlO1xuICAgIH1cbiAgfVxuICBcbiAgLyoqXG4gICAqIERpc2FibGUgYSBwbHVnaW5cbiAgICovXG4gIHB1YmxpYyBkaXNhYmxlKHBsdWdpbklkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBwbHVnaW4gPSB0aGlzLnBsdWdpbnMuZ2V0KHBsdWdpbklkKTtcbiAgICBpZiAocGx1Z2luKSB7XG4gICAgICBwbHVnaW4uZW5hYmxlZCA9IGZhbHNlO1xuICAgIH1cbiAgfVxuICBcbiAgLyoqXG4gICAqIEV4ZWN1dGUgYWxsIGVuYWJsZWQgcGx1Z2luc1xuICAgKi9cbiAgcHVibGljIGFzeW5jIGV4ZWN1dGVBbGwoY29udGV4dDogUGx1Z2luQ29udGV4dCk6IFByb21pc2U8UGx1Z2luUmVzdWx0W10+IHtcbiAgICBjb25zdCBlbmFibGVkUGx1Z2lucyA9IHRoaXMuZ2V0RW5hYmxlZCgpO1xuICAgIGNvbnN0IHJlc3VsdHM6IFBsdWdpblJlc3VsdFtdID0gW107XG4gICAgXG4gICAgZm9yIChjb25zdCBwbHVnaW4gb2YgZW5hYmxlZFBsdWdpbnMpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHBsdWdpbi5leGVjdXRlKGNvbnRleHQpO1xuICAgICAgICByZXN1bHRzLnB1c2gocmVzdWx0KTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoYFBsdWdpbiAke3BsdWdpbi5pZH0gZmFpbGVkOmAsIGVycm9yKTtcbiAgICAgICAgLy8gQ29udGludWUgd2l0aCBvdGhlciBwbHVnaW5zXG4gICAgICB9XG4gICAgfVxuICAgIFxuICAgIHJldHVybiByZXN1bHRzO1xuICB9XG4gIFxuICAvKipcbiAgICogRXhlY3V0ZSBzcGVjaWZpYyBwbHVnaW5zXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZXhlY3V0ZShwbHVnaW5JZHM6IHN0cmluZ1tdLCBjb250ZXh0OiBQbHVnaW5Db250ZXh0KTogUHJvbWlzZTxQbHVnaW5SZXN1bHRbXT4ge1xuICAgIGNvbnN0IHJlc3VsdHM6IFBsdWdpblJlc3VsdFtdID0gW107XG4gICAgXG4gICAgZm9yIChjb25zdCBpZCBvZiBwbHVnaW5JZHMpIHtcbiAgICAgIGNvbnN0IHBsdWdpbiA9IHRoaXMucGx1Z2lucy5nZXQoaWQpO1xuICAgICAgaWYgKHBsdWdpbiAmJiBwbHVnaW4uZW5hYmxlZCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHBsdWdpbi5leGVjdXRlKGNvbnRleHQpO1xuICAgICAgICAgIHJlc3VsdHMucHVzaChyZXN1bHQpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYFBsdWdpbiAke2lkfSBmYWlsZWQ6YCwgZXJyb3IpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIFxuICAgIHJldHVybiByZXN1bHRzO1xuICB9XG4gIFxuICAvKipcbiAgICogQ2xlYXIgYWxsIHBsdWdpbnNcbiAgICovXG4gIHB1YmxpYyBjbGVhcigpOiB2b2lkIHtcbiAgICB0aGlzLnBsdWdpbnMuY2xlYXIoKTtcbiAgfVxuICBcbiAgLyoqXG4gICAqIEdldCBwbHVnaW4gY291bnRcbiAgICovXG4gIHB1YmxpYyBjb3VudCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLnBsdWdpbnMuc2l6ZTtcbiAgfVxufVxuXG4vKipcbiAqIEdsb2JhbCBwbHVnaW4gcmVnaXN0cnlcbiAqL1xubGV0IGdsb2JhbFJlZ2lzdHJ5OiBQbHVnaW5SZWdpc3RyeSB8IG51bGwgPSBudWxsO1xuXG4vKipcbiAqIEdldCBnbG9iYWwgcGx1Z2luIHJlZ2lzdHJ5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRQbHVnaW5SZWdpc3RyeSgpOiBQbHVnaW5SZWdpc3RyeSB7XG4gIGlmICghZ2xvYmFsUmVnaXN0cnkpIHtcbiAgICBnbG9iYWxSZWdpc3RyeSA9IG5ldyBQbHVnaW5SZWdpc3RyeSgpO1xuICB9XG4gIHJldHVybiBnbG9iYWxSZWdpc3RyeTtcbn1cblxuLyoqXG4gKiBSZXNldCBnbG9iYWwgcmVnaXN0cnlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc2V0UGx1Z2luUmVnaXN0cnkoKTogdm9pZCB7XG4gIGdsb2JhbFJlZ2lzdHJ5ID0gbnVsbDtcbn1cbiJdfQ==