@devilsdev/rag-pipeline-utils 2.1.12 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/.ragrc.schema.json +218 -0
  2. package/README.md +178 -550
  3. package/bin/cli.js +8 -14
  4. package/contracts/reranker-contract.json +69 -0
  5. package/dist/index.d.ts +237 -0
  6. package/dist/index.mjs +22 -7
  7. package/package.json +18 -13
  8. package/src/ai/adaptive-retrieval.js +191 -0
  9. package/src/ai/federated-learning.js +214 -0
  10. package/src/ai/federation/federated-learning-coordinator.js +345 -0
  11. package/src/ai/federation.js +76 -0
  12. package/src/ai/index-fixed.js +509 -0
  13. package/src/ai/index.js +33 -0
  14. package/src/ai/model-trainer.js +217 -0
  15. package/src/ai/model-training.js +205 -0
  16. package/src/ai/module-template.js +37 -0
  17. package/src/ai/multimodal/multi-modal-processor.js +345 -0
  18. package/src/ai/multimodal-processing.js +268 -0
  19. package/src/ai/multimodal.js +71 -0
  20. package/src/ai/orchestrator.js +70 -0
  21. package/src/ai/retrieval/adaptive-retrieval-engine.js +398 -0
  22. package/src/ai/retrieval-engine.js +69 -0
  23. package/src/ai/training/model-training-orchestrator.js +228 -0
  24. package/src/ci/workflow-analyzer.js +71 -0
  25. package/src/cli/commands/ai-ml.js +967 -0
  26. package/src/cli/commands/docs.js +228 -0
  27. package/src/cli/commands/dx.js +538 -0
  28. package/src/cli/commands/plugin-hub.js +875 -0
  29. package/src/cli/doctor-command.js +639 -0
  30. package/src/cli/enhanced-cli-commands.js +945 -0
  31. package/src/cli/interactive-wizard.js +997 -0
  32. package/src/cli/plugin-marketplace-commands.js +869 -0
  33. package/src/cli.js +17 -0
  34. package/src/config/enhanced-ragrc-schema.js +632 -0
  35. package/src/config/load-config.js +54 -0
  36. package/src/config/load-plugin-config.js +69 -0
  37. package/src/config/normalize-config.js +105 -0
  38. package/src/config/schema-validator.js +315 -0
  39. package/src/config/validate-plugin-schema.js +35 -0
  40. package/src/config/validate-schema.js +113 -0
  41. package/src/contracts/plugin-contracts.js +33 -0
  42. package/src/core/create-pipeline.js +99 -0
  43. package/src/core/dependency-injection.js +242 -0
  44. package/src/core/observability/event-logger.js +241 -0
  45. package/src/core/observability/instrumented-pipeline.js +609 -0
  46. package/src/core/observability/metrics.js +497 -0
  47. package/src/core/observability/tracing.js +781 -0
  48. package/src/core/performance/benchmark.js +516 -0
  49. package/src/core/performance/parallel-processor.js +240 -0
  50. package/src/core/performance/streaming-safeguards.js +620 -0
  51. package/src/core/pipeline-factory.js +60 -0
  52. package/src/core/plugin-contracts.js +89 -0
  53. package/src/core/plugin-marketplace/plugin-metadata.js +485 -0
  54. package/src/core/plugin-marketplace/plugin-publisher.js +574 -0
  55. package/src/core/plugin-marketplace/plugin-registry-format.js +419 -0
  56. package/src/core/plugin-marketplace/version-resolver.js +61 -0
  57. package/src/core/plugin-registry.js +294 -0
  58. package/src/dag/dag-engine.js +954 -0
  59. package/src/dag/dag-node.js +76 -0
  60. package/src/dag/enhanced-dag-engine.js +822 -0
  61. package/src/dx/index.js +40 -0
  62. package/src/dx/integration-templates.js +665 -0
  63. package/src/dx/performance-profiler.js +968 -0
  64. package/src/dx/realtime-debugger.js +755 -0
  65. package/src/dx/visual-pipeline-builder.js +578 -0
  66. package/src/ecosystem/plugin-analytics-dashboard.js +778 -0
  67. package/src/ecosystem/plugin-certification.js +580 -0
  68. package/src/ecosystem/plugin-hub.js +821 -0
  69. package/src/enterprise/audit-logging.js +967 -0
  70. package/src/enterprise/data-governance.js +408 -0
  71. package/src/enterprise/multi-tenancy.js +496 -0
  72. package/src/enterprise/sso-integration.js +1030 -0
  73. package/src/evaluate/evaluator.js +52 -0
  74. package/src/evaluate/scoring.js +91 -0
  75. package/src/index.js +67 -0
  76. package/src/ingest.js +59 -0
  77. package/src/loader/csv-loader.js +38 -0
  78. package/src/loader/directory-loader.js +48 -0
  79. package/src/loader/html-loader.js +62 -0
  80. package/src/loader/markdown-loader.js +67 -0
  81. package/src/mocks/openai-embedder.js +119 -0
  82. package/src/mocks/openai-llm.js +77 -0
  83. package/src/mocks/pdf-loader.js +21 -0
  84. package/src/mocks/pinecone-retriever.js +106 -0
  85. package/src/observability/audit-logger.js +758 -0
  86. package/src/observability/dashboard-config.json +675 -0
  87. package/src/observability/event-logger.js +310 -0
  88. package/src/observability/metrics.js +691 -0
  89. package/src/observability/security-monitor.js +830 -0
  90. package/src/observability/slo-monitor.js +319 -0
  91. package/src/observability/telemetry.js +686 -0
  92. package/src/pipeline/pipeline.js +18 -0
  93. package/src/plugins/sample-embedder.js +53 -0
  94. package/src/plugins/sample-llm.js +30 -0
  95. package/src/plugins/sample-loader.js +24 -0
  96. package/src/plugins/sample-retriever.js +84 -0
  97. package/src/query.js +117 -0
  98. package/src/reranker/llm-reranker.js +111 -0
  99. package/src/scripts/script-utilities.js +36 -0
  100. package/src/security/plugin-sandbox.js +586 -0
  101. package/src/security/plugin-signature-verifier.js +414 -0
  102. package/src/security/validator.js +36 -0
  103. package/src/utils/ci/diagnostic-reporter.js +57 -0
  104. package/src/utils/logger.js +211 -0
  105. package/src/utils/performance-monitor.js +561 -0
  106. package/src/utils/plugin-scaffolder.js +447 -0
  107. package/src/utils/rate-limiter.js +244 -0
  108. package/src/utils/retry-policy.js +443 -0
  109. package/src/utils/retry.js +107 -0
  110. package/src/utils/safe-expression-evaluator.js +579 -0
  111. package/src/utils/secure-logging.js +338 -0
  112. package/src/utils/structured-logger.js +388 -0
  113. package/src/utils/validate-plugin-contract.js +42 -0
@@ -0,0 +1,294 @@
1
+ 'use strict';
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const {
6
+ createPluginVerifier,
7
+ } = require('../security/plugin-signature-verifier.js');
8
+
9
+ class PluginRegistry {
10
+ constructor(options = {}) {
11
+ this._plugins = new Map();
12
+ this._validTypes = new Set([
13
+ 'loader',
14
+ 'embedder',
15
+ 'retriever',
16
+ 'reranker',
17
+ 'llm',
18
+ 'evaluator',
19
+ ]);
20
+ this._contracts = new Map();
21
+
22
+ // Environment-aware signature verification defaults
23
+ const isDevelopment = process.env.NODE_ENV === 'development';
24
+ const isProduction = process.env.NODE_ENV === 'production';
25
+
26
+ this._signatureVerifier = createPluginVerifier({
27
+ enabled:
28
+ options.verifySignatures !== undefined
29
+ ? options.verifySignatures
30
+ : isProduction, // Enabled by default in production, disabled in development
31
+ failClosed:
32
+ options.failClosed !== undefined ? options.failClosed : isProduction, // Fail closed in production, fail open in development
33
+ trustedKeysPath: options.trustedKeysPath,
34
+ });
35
+ this._loadContracts();
36
+ }
37
+
38
+ _loadContracts() {
39
+ const contractsDir = path.join(__dirname, '../../contracts');
40
+ const isDevelopment = process.env.NODE_ENV === 'development';
41
+
42
+ try {
43
+ const contractFiles = {
44
+ loader: 'loader-contract.json',
45
+ embedder: 'embedder-contract.json',
46
+ retriever: 'retriever-contract.json',
47
+ llm: 'llm-contract.json',
48
+ reranker: 'reranker-contract.json',
49
+ };
50
+
51
+ for (const [type, filename] of Object.entries(contractFiles)) {
52
+ try {
53
+ const contractPath = path.join(contractsDir, filename);
54
+ if (fs.existsSync(contractPath)) {
55
+ const contractContent = fs.readFileSync(contractPath, 'utf8');
56
+ const contract = JSON.parse(contractContent);
57
+ this._contracts.set(type, contract);
58
+ } else if (isDevelopment) {
59
+ // Dev mode warning: flag missing contract files
60
+ console.warn(
61
+ `[PLUGIN_REGISTRY] Warning: Contract file missing for '${type}' plugin type: ${contractPath}`,
62
+ ); // eslint-disable-line no-console
63
+ console.warn(
64
+ `[PLUGIN_REGISTRY] This may indicate test-only drift. Contract validation will be skipped for '${type}' plugins.`,
65
+ ); // eslint-disable-line no-console
66
+ }
67
+ } catch (error) {
68
+ // Contract loading is optional - don't fail if missing
69
+ if (isDevelopment) {
70
+ console.warn(
71
+ `[PLUGIN_REGISTRY] Warning: Failed to load contract for '${type}': ${error.message}`,
72
+ ); // eslint-disable-line no-console
73
+ }
74
+ }
75
+ }
76
+ } catch (error) {
77
+ // Contracts directory may not exist in all environments
78
+ if (isDevelopment) {
79
+ console.warn(
80
+ `[PLUGIN_REGISTRY] Warning: Contracts directory not accessible: ${error.message}`,
81
+ ); // eslint-disable-line no-console
82
+ }
83
+ }
84
+ }
85
+
86
+ _validatePluginContract(category, impl) {
87
+ const contract = this._contracts.get(category);
88
+ if (!contract) {
89
+ // Warn in dev mode when registering a plugin without a contract
90
+ if (process.env.NODE_ENV === 'development') {
91
+ console.warn(
92
+ `[PLUGIN_REGISTRY] Warning: No contract available for plugin category '${category}'. Skipping contract validation.`,
93
+ ); // eslint-disable-line no-console
94
+ console.warn(
95
+ `[PLUGIN_REGISTRY] This may indicate test-only drift. Ensure contracts/${category}-contract.json exists.`,
96
+ ); // eslint-disable-line no-console
97
+ }
98
+ return; // No contract to validate against
99
+ }
100
+
101
+ // Check if plugin has metadata
102
+ if (!impl.metadata) {
103
+ throw new Error('Plugin missing metadata property');
104
+ }
105
+
106
+ if (!impl.metadata.name || typeof impl.metadata.name !== 'string') {
107
+ throw new Error('Plugin metadata must have a name property');
108
+ }
109
+
110
+ if (!impl.metadata.version || typeof impl.metadata.version !== 'string') {
111
+ throw new Error('Plugin metadata must have a version property');
112
+ }
113
+
114
+ if (!impl.metadata.type || impl.metadata.type !== category) {
115
+ throw new Error(`Plugin metadata type must be '${category}'`);
116
+ }
117
+
118
+ // Validate required methods based on contract
119
+ const requiredMethods = this._getRequiredMethodsFromContract(contract);
120
+
121
+ for (const methodName of requiredMethods) {
122
+ if (!impl[methodName]) {
123
+ throw new Error(`Plugin missing required method: ${methodName}`);
124
+ }
125
+
126
+ if (typeof impl[methodName] !== 'function') {
127
+ throw new Error(`Plugin method '${methodName}' must be a function`);
128
+ }
129
+ }
130
+ }
131
+
132
+ _getRequiredMethodsFromContract(contract) {
133
+ const methods = [];
134
+
135
+ if (contract.required && Array.isArray(contract.required)) {
136
+ methods.push(...contract.required);
137
+ }
138
+
139
+ if (contract.properties) {
140
+ for (const [methodName, methodSpec] of Object.entries(
141
+ contract.properties,
142
+ )) {
143
+ if (methodSpec.type === 'function') {
144
+ methods.push(methodName);
145
+ }
146
+ }
147
+ }
148
+
149
+ return methods;
150
+ }
151
+
152
+ async register(category, name, impl, manifest = null) {
153
+ if (!category || typeof category !== 'string') {
154
+ throw new Error('Category must be a non-empty string');
155
+ }
156
+ if (!name || typeof name !== 'string') {
157
+ throw new Error('Name must be a non-empty string');
158
+ }
159
+ if (impl == null) {
160
+ throw new Error('Implementation cannot be null or undefined');
161
+ }
162
+ if (!this._validTypes.has(category)) {
163
+ throw new Error(`Unknown plugin type: ${category}`);
164
+ }
165
+
166
+ // Verify plugin signature if manifest provided
167
+ if (manifest) {
168
+ await this._verifyPluginSignature(manifest, name);
169
+ }
170
+
171
+ // Validate plugin against contract
172
+ this._validatePluginContract(category, impl);
173
+
174
+ const key = `${category}:${name}`;
175
+ this._plugins.set(key, impl);
176
+ return this;
177
+ }
178
+
179
+ /**
180
+ * Verify plugin signature
181
+ * @param {object} manifest - Plugin manifest
182
+ * @param {string} pluginName - Plugin name
183
+ */
184
+ async _verifyPluginSignature(manifest, pluginName) {
185
+ try {
186
+ // Extract signature information from manifest
187
+ if (!manifest.signature || !manifest.signerId) {
188
+ throw new Error(
189
+ `Plugin ${pluginName} missing required signature or signerId`,
190
+ );
191
+ }
192
+
193
+ const verificationResult =
194
+ await this._signatureVerifier.verifyPluginSignature(
195
+ manifest,
196
+ manifest.signature,
197
+ manifest.signerId,
198
+ );
199
+
200
+ if (!verificationResult.verified) {
201
+ throw new Error(
202
+ `Plugin ${pluginName} signature verification failed: ${verificationResult.error}`,
203
+ );
204
+ }
205
+
206
+ // Emit audit entry for successful verification
207
+ this._emitAuditEntry('plugin_verified', {
208
+ pluginName,
209
+ signerId: manifest.signerId,
210
+ version: manifest.version,
211
+ verified: true,
212
+ timestamp: new Date().toISOString(),
213
+ });
214
+ } catch (error) {
215
+ // Emit audit entry for failed verification
216
+ this._emitAuditEntry('plugin_verification_failed', {
217
+ pluginName,
218
+ signerId: manifest.signerId || 'unknown',
219
+ version: manifest.version || 'unknown',
220
+ verified: false,
221
+ error: error.message,
222
+ timestamp: new Date().toISOString(),
223
+ });
224
+
225
+ throw error;
226
+ }
227
+ }
228
+
229
+ /**
230
+ * Emit audit entry
231
+ * @param {string} action - Audit action
232
+ * @param {object} details - Audit details
233
+ */
234
+ _emitAuditEntry(action, details) {
235
+ const auditEntry = {
236
+ timestamp: new Date().toISOString(),
237
+ action,
238
+ component: 'plugin_registry',
239
+ ...details,
240
+ };
241
+
242
+ // In production, this should go to a secure audit log
243
+ if (process.env.NODE_ENV === 'production') {
244
+ console.warn('[AUDIT]', JSON.stringify(auditEntry)); // eslint-disable-line no-console
245
+ } else {
246
+ console.log('[AUDIT]', auditEntry); // eslint-disable-line no-console
247
+ }
248
+ }
249
+
250
+ get(category, name) {
251
+ const key = `${category}:${name}`;
252
+ const impl = this._plugins.get(key);
253
+ if (impl === undefined) {
254
+ throw new Error(`Plugin not found: ${category}/${name}`);
255
+ }
256
+ return impl;
257
+ }
258
+
259
+ resolve(category, name) {
260
+ return this.get(category, name);
261
+ }
262
+
263
+ list(category) {
264
+ if (!this._validTypes.has(category)) {
265
+ throw new Error(`Unknown plugin type: ${category}`);
266
+ }
267
+
268
+ const names = [];
269
+ const prefix = `${category}:`;
270
+
271
+ for (const key of this._plugins.keys()) {
272
+ if (key.startsWith(prefix)) {
273
+ names.push(key.substring(prefix.length));
274
+ }
275
+ }
276
+
277
+ return names;
278
+ }
279
+
280
+ clear() {
281
+ this._plugins.clear();
282
+ }
283
+ }
284
+
285
+ // Create singleton instance with default security settings
286
+ const registry = new PluginRegistry({
287
+ verifySignatures: process.env.NODE_ENV === 'production',
288
+ failClosed: process.env.NODE_ENV === 'production',
289
+ });
290
+
291
+ // CJS+ESM interop pattern
292
+ module.exports = registry;
293
+ module.exports.PluginRegistry = PluginRegistry;
294
+ module.exports.default = module.exports;