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
JavaScript
;
/**
* 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==