@devilsdev/rag-pipeline-utils 2.1.12 → 2.2.0

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 (110) hide show
  1. package/.ragrc.schema.json +218 -0
  2. package/README.md +292 -32
  3. package/bin/cli.js +8 -14
  4. package/dist/index.d.ts +237 -0
  5. package/dist/index.mjs +22 -7
  6. package/package.json +17 -13
  7. package/src/ai/adaptive-retrieval.js +191 -0
  8. package/src/ai/federated-learning.js +214 -0
  9. package/src/ai/federation/federated-learning-coordinator.js +345 -0
  10. package/src/ai/federation.js +76 -0
  11. package/src/ai/index-fixed.js +509 -0
  12. package/src/ai/index.js +33 -0
  13. package/src/ai/model-trainer.js +217 -0
  14. package/src/ai/model-training.js +205 -0
  15. package/src/ai/module-template.js +37 -0
  16. package/src/ai/multimodal/multi-modal-processor.js +345 -0
  17. package/src/ai/multimodal-processing.js +268 -0
  18. package/src/ai/multimodal.js +71 -0
  19. package/src/ai/orchestrator.js +70 -0
  20. package/src/ai/retrieval/adaptive-retrieval-engine.js +398 -0
  21. package/src/ai/retrieval-engine.js +69 -0
  22. package/src/ai/training/model-training-orchestrator.js +228 -0
  23. package/src/ci/workflow-analyzer.js +71 -0
  24. package/src/cli/commands/ai-ml.js +967 -0
  25. package/src/cli/commands/docs.js +228 -0
  26. package/src/cli/commands/dx.js +538 -0
  27. package/src/cli/commands/plugin-hub.js +875 -0
  28. package/src/cli/doctor-command.js +639 -0
  29. package/src/cli/enhanced-cli-commands.js +945 -0
  30. package/src/cli/interactive-wizard.js +997 -0
  31. package/src/cli/plugin-marketplace-commands.js +869 -0
  32. package/src/cli.js +17 -0
  33. package/src/config/enhanced-ragrc-schema.js +632 -0
  34. package/src/config/load-config.js +54 -0
  35. package/src/config/load-plugin-config.js +69 -0
  36. package/src/config/normalize-config.js +105 -0
  37. package/src/config/schema-validator.js +315 -0
  38. package/src/config/validate-plugin-schema.js +35 -0
  39. package/src/config/validate-schema.js +113 -0
  40. package/src/contracts/plugin-contracts.js +33 -0
  41. package/src/core/create-pipeline.js +99 -0
  42. package/src/core/dependency-injection.js +242 -0
  43. package/src/core/observability/event-logger.js +241 -0
  44. package/src/core/observability/instrumented-pipeline.js +609 -0
  45. package/src/core/observability/metrics.js +497 -0
  46. package/src/core/observability/tracing.js +781 -0
  47. package/src/core/performance/benchmark.js +516 -0
  48. package/src/core/performance/parallel-processor.js +240 -0
  49. package/src/core/performance/streaming-safeguards.js +611 -0
  50. package/src/core/pipeline-factory.js +60 -0
  51. package/src/core/plugin-contracts.js +89 -0
  52. package/src/core/plugin-marketplace/plugin-metadata.js +485 -0
  53. package/src/core/plugin-marketplace/plugin-publisher.js +574 -0
  54. package/src/core/plugin-marketplace/plugin-registry-format.js +419 -0
  55. package/src/core/plugin-marketplace/version-resolver.js +61 -0
  56. package/src/core/plugin-registry.js +265 -0
  57. package/src/dag/dag-engine.js +954 -0
  58. package/src/dag/dag-node.js +76 -0
  59. package/src/dag/enhanced-dag-engine.js +822 -0
  60. package/src/dx/index.js +40 -0
  61. package/src/dx/integration-templates.js +665 -0
  62. package/src/dx/performance-profiler.js +968 -0
  63. package/src/dx/realtime-debugger.js +755 -0
  64. package/src/dx/visual-pipeline-builder.js +578 -0
  65. package/src/ecosystem/plugin-analytics-dashboard.js +778 -0
  66. package/src/ecosystem/plugin-certification.js +580 -0
  67. package/src/ecosystem/plugin-hub.js +821 -0
  68. package/src/enterprise/audit-logging.js +967 -0
  69. package/src/enterprise/data-governance.js +408 -0
  70. package/src/enterprise/multi-tenancy.js +496 -0
  71. package/src/enterprise/sso-integration.js +903 -0
  72. package/src/evaluate/evaluator.js +52 -0
  73. package/src/evaluate/scoring.js +91 -0
  74. package/src/index.js +67 -0
  75. package/src/ingest.js +59 -0
  76. package/src/loader/csv-loader.js +38 -0
  77. package/src/loader/directory-loader.js +48 -0
  78. package/src/loader/html-loader.js +62 -0
  79. package/src/loader/markdown-loader.js +67 -0
  80. package/src/mocks/openai-embedder.js +119 -0
  81. package/src/mocks/openai-llm.js +77 -0
  82. package/src/mocks/pdf-loader.js +21 -0
  83. package/src/mocks/pinecone-retriever.js +106 -0
  84. package/src/observability/audit-logger.js +758 -0
  85. package/src/observability/dashboard-config.json +675 -0
  86. package/src/observability/event-logger.js +310 -0
  87. package/src/observability/metrics.js +691 -0
  88. package/src/observability/security-monitor.js +830 -0
  89. package/src/observability/slo-monitor.js +319 -0
  90. package/src/observability/telemetry.js +686 -0
  91. package/src/pipeline/pipeline.js +18 -0
  92. package/src/plugins/sample-embedder.js +53 -0
  93. package/src/plugins/sample-llm.js +30 -0
  94. package/src/plugins/sample-loader.js +24 -0
  95. package/src/plugins/sample-retriever.js +84 -0
  96. package/src/query.js +117 -0
  97. package/src/reranker/llm-reranker.js +85 -0
  98. package/src/scripts/script-utilities.js +36 -0
  99. package/src/security/plugin-sandbox.js +586 -0
  100. package/src/security/plugin-signature-verifier.js +414 -0
  101. package/src/security/validator.js +36 -0
  102. package/src/utils/ci/diagnostic-reporter.js +57 -0
  103. package/src/utils/logger.js +211 -0
  104. package/src/utils/performance-monitor.js +561 -0
  105. package/src/utils/plugin-scaffolder.js +447 -0
  106. package/src/utils/retry-policy.js +443 -0
  107. package/src/utils/retry.js +107 -0
  108. package/src/utils/safe-expression-evaluator.js +579 -0
  109. package/src/utils/structured-logger.js +361 -0
  110. package/src/utils/validate-plugin-contract.js +42 -0
@@ -0,0 +1,496 @@
1
+ /**
2
+ * Enterprise Multi-tenancy Support
3
+ * Isolated workspaces, resource quotas, and tenant management
4
+ */
5
+
6
+ const fs = require('fs').promises;
7
+ // eslint-disable-line global-require
8
+ const path = require('path');
9
+ // eslint-disable-line global-require
10
+ const crypto = require('crypto');
11
+ // eslint-disable-line global-require
12
+ const { EventEmitter } = require('events');
13
+ // eslint-disable-line global-require
14
+
15
+ class TenantManager extends EventEmitter {
16
+ constructor(_options = {}) {
17
+ super();
18
+
19
+ this._config = {
20
+ dataDir: _options.dataDir || path.join(process.cwd(), '.rag-enterprise'),
21
+ defaultQuotas: {
22
+ maxUsers: 100,
23
+ maxWorkspaces: 10,
24
+ maxStorageGB: 50,
25
+ maxAPICallsPerMonth: 100000,
26
+ maxConcurrentPipelines: 5,
27
+ maxPlugins: 50,
28
+ },
29
+ isolation: {
30
+ networkIsolation: true,
31
+ storageIsolation: true,
32
+ resourceIsolation: true,
33
+ },
34
+ ..._options,
35
+ };
36
+
37
+ this.tenants = new Map();
38
+ this.workspaces = new Map();
39
+ this.resourceMonitor = new ResourceMonitor(this._config);
40
+ }
41
+
42
+ /**
43
+ * Create a new tenant with isolated resources
44
+ */
45
+ async createTenant(tenantData) {
46
+ const _tenantId = crypto.randomUUID();
47
+
48
+ const tenant = {
49
+ id: _tenantId,
50
+ name: tenantData.name,
51
+ domain: tenantData.domain,
52
+ plan: tenantData.plan || 'enterprise',
53
+ quotas: { ...this._config.defaultQuotas, ...tenantData.quotas },
54
+ settings: {
55
+ ssoEnabled: tenantData.ssoEnabled || false,
56
+ auditLoggingEnabled: true,
57
+ dataGovernanceEnabled: true,
58
+ encryptionAtRest: true,
59
+ ...tenantData.settings,
60
+ },
61
+ metadata: {
62
+ createdAt: new Date().toISOString(),
63
+ createdBy: tenantData.createdBy,
64
+ status: 'active',
65
+ lastActivity: new Date().toISOString(),
66
+ },
67
+ isolation: {
68
+ dataPath: path.join(this._config.dataDir, 'tenants', _tenantId),
69
+ networkNamespace: `tenant-${_tenantId}`,
70
+ resourceLimits: this._calculateResourceLimits(tenantData.plan),
71
+ },
72
+ };
73
+
74
+ // Create isolated tenant directory structure
75
+ await this._createTenantInfrastructure(tenant);
76
+
77
+ // Initialize tenant-specific services
78
+ await this._initializeTenantServices(tenant);
79
+
80
+ this.tenants.set(_tenantId, tenant);
81
+
82
+ this.emit('tenant_created', { _tenantId, tenant });
83
+
84
+ return tenant;
85
+ }
86
+
87
+ /**
88
+ * Create isolated workspace within a tenant
89
+ */
90
+ async createWorkspace(_tenantId, workspaceData) {
91
+ const tenant = this.tenants.get(_tenantId);
92
+ if (!tenant) {
93
+ throw new Error(`Tenant ${_tenantId} not found`);
94
+ }
95
+
96
+ // Check workspace quota
97
+ const existingWorkspaces = Array.from(this.workspaces.values()).filter(
98
+ (w) => w.tenantId === _tenantId,
99
+ );
100
+
101
+ if (existingWorkspaces.length >= tenant.quotas.maxWorkspaces) {
102
+ throw new Error(`Workspace quota exceeded for tenant ${_tenantId}`);
103
+ }
104
+
105
+ const _workspaceId = crypto.randomUUID();
106
+
107
+ const workspace = {
108
+ id: _workspaceId,
109
+ _tenantId,
110
+ name: workspaceData.name,
111
+ description: workspaceData.description,
112
+ settings: {
113
+ privacy: workspaceData.privacy || 'private',
114
+ collaborationEnabled: workspaceData.collaborationEnabled || false,
115
+ pluginsEnabled: workspaceData.pluginsEnabled || true,
116
+ ...workspaceData.settings,
117
+ },
118
+ resources: {
119
+ storageUsedMB: 0,
120
+ apiCallsThisMonth: 0,
121
+ activePipelines: 0,
122
+ installedPlugins: 0,
123
+ },
124
+ isolation: {
125
+ dataPath: path.join(
126
+ tenant.isolation.dataPath,
127
+ 'workspaces',
128
+ _workspaceId,
129
+ ),
130
+ configPath: path.join(
131
+ tenant.isolation.dataPath,
132
+ 'workspaces',
133
+ _workspaceId,
134
+ '.ragrc.json',
135
+ ),
136
+ pluginsPath: path.join(
137
+ tenant.isolation.dataPath,
138
+ 'workspaces',
139
+ _workspaceId,
140
+ 'plugins',
141
+ ),
142
+ },
143
+ metadata: {
144
+ createdAt: new Date().toISOString(),
145
+ createdBy: workspaceData.createdBy,
146
+ lastActivity: new Date().toISOString(),
147
+ version: '1.0.0',
148
+ },
149
+ };
150
+
151
+ // Create isolated workspace infrastructure
152
+ await this._createWorkspaceInfrastructure(workspace);
153
+
154
+ this.workspaces.set(_workspaceId, workspace);
155
+
156
+ this.emit('workspace_created', { _tenantId, _workspaceId, workspace });
157
+
158
+ return workspace;
159
+ }
160
+
161
+ /**
162
+ * Get tenant with resource usage
163
+ */
164
+ async getTenant(_tenantId) {
165
+ const tenant = this.tenants.get(_tenantId);
166
+ if (!tenant) {
167
+ return null;
168
+ }
169
+
170
+ // Get current resource usage
171
+ const usage = await this.resourceMonitor.getTenantUsage(_tenantId);
172
+
173
+ return {
174
+ ...tenant,
175
+ usage,
176
+ quotaUtilization: this._calculateQuotaUtilization(tenant.quotas, usage),
177
+ };
178
+ }
179
+
180
+ /**
181
+ * List workspaces for a tenant
182
+ */
183
+ async getWorkspaces(_tenantId, _options = {}) {
184
+ const workspaces = Array.from(this.workspaces.values()).filter(
185
+ (w) => w._tenantId === _tenantId,
186
+ );
187
+
188
+ if (_options.includeUsage) {
189
+ for (const workspace of workspaces) {
190
+ workspace.usage = await this.resourceMonitor.getWorkspaceUsage(
191
+ workspace.id,
192
+ );
193
+ }
194
+ }
195
+
196
+ return workspaces;
197
+ }
198
+
199
+ /**
200
+ * Update tenant quotas
201
+ */
202
+ async updateTenantQuotas(_tenantId, newQuotas) {
203
+ const tenant = this.tenants.get(_tenantId);
204
+ if (!tenant) {
205
+ throw new Error(`Tenant ${_tenantId} not found`);
206
+ }
207
+
208
+ const oldQuotas = { ...tenant.quotas };
209
+ tenant.quotas = { ...tenant.quotas, ...newQuotas };
210
+ tenant.metadata.lastUpdated = new Date().toISOString();
211
+
212
+ // Persist changes
213
+ await this._persistTenant(tenant);
214
+
215
+ this.emit('tenant_quotas_updated', {
216
+ _tenantId,
217
+ oldQuotas,
218
+ newQuotas: tenant.quotas,
219
+ });
220
+
221
+ return tenant;
222
+ }
223
+
224
+ /**
225
+ * Enforce resource quotas
226
+ */
227
+ async enforceQuotas(_tenantId, operation, resourceType, amount) {
228
+ const tenant = this.tenants.get(_tenantId);
229
+ if (!tenant) {
230
+ throw new Error(`Tenant ${_tenantId} not found`);
231
+ }
232
+
233
+ const usage = await this.resourceMonitor.getTenantUsage(_tenantId);
234
+
235
+ switch (resourceType) {
236
+ case 'storage':
237
+ if (usage.storageUsedGB + amount / 1024 > tenant.quotas.maxStorageGB) {
238
+ throw new Error(`Storage quota exceeded for tenant ${_tenantId}`);
239
+ }
240
+ break;
241
+
242
+ case 'apiCalls':
243
+ if (
244
+ usage.apiCallsThisMonth + amount >
245
+ tenant.quotas.maxAPICallsPerMonth
246
+ ) {
247
+ throw new Error(`API calls quota exceeded for tenant ${_tenantId}`);
248
+ }
249
+ break;
250
+
251
+ case 'concurrentPipelines':
252
+ if (usage.activePipelines >= tenant.quotas.maxConcurrentPipelines) {
253
+ throw new Error(
254
+ `Concurrent pipelines quota exceeded for tenant ${_tenantId}`,
255
+ );
256
+ }
257
+ break;
258
+
259
+ case 'plugins':
260
+ if (usage.installedPlugins >= tenant.quotas.maxPlugins) {
261
+ throw new Error(`Plugins quota exceeded for tenant ${_tenantId}`);
262
+ }
263
+ break;
264
+ }
265
+
266
+ return true;
267
+ }
268
+
269
+ /**
270
+ * Delete tenant and all associated data
271
+ */
272
+ async deleteTenant(_tenantId, _options = {}) {
273
+ const tenant = this.tenants.get(_tenantId);
274
+ if (!tenant) {
275
+ throw new Error(`Tenant ${_tenantId} not found`);
276
+ }
277
+
278
+ // Soft delete by default for compliance
279
+ if (!_options.hardDelete) {
280
+ tenant.metadata.status = 'deleted';
281
+ tenant.metadata.deletedAt = new Date().toISOString();
282
+ tenant.metadata.deletedBy = _options.deletedBy;
283
+
284
+ await this._persistTenant(tenant);
285
+
286
+ this.emit('tenant_soft_deleted', { _tenantId, tenant });
287
+ return { deleted: true, hardDelete: false };
288
+ }
289
+
290
+ // Hard delete - remove all data
291
+ const workspaces = Array.from(this.workspaces.values()).filter(
292
+ (w) => w.tenantId === _tenantId,
293
+ );
294
+
295
+ for (const workspace of workspaces) {
296
+ await this.deleteWorkspace(workspace.id, { hardDelete: true });
297
+ }
298
+
299
+ // Remove tenant data directory
300
+ await fs.rmdir(tenant.isolation.dataPath, { recursive: true });
301
+
302
+ this.tenants.delete(_tenantId);
303
+
304
+ this.emit('tenant_hard_deleted', { _tenantId });
305
+ return { deleted: true, hardDelete: true };
306
+ }
307
+
308
+ /**
309
+ * Delete workspace
310
+ */
311
+ async deleteWorkspace(_workspaceId, _options = {}) {
312
+ const workspace = this.workspaces.get(_workspaceId);
313
+ if (!workspace) {
314
+ throw new Error(`Workspace ${_workspaceId} not found`);
315
+ }
316
+
317
+ if (!_options.hardDelete) {
318
+ workspace.metadata.status = 'deleted';
319
+ workspace.metadata.deletedAt = new Date().toISOString();
320
+ workspace.metadata.deletedBy = _options.deletedBy;
321
+
322
+ await this._persistWorkspace(workspace);
323
+
324
+ this.emit('workspace_soft_deleted', { _workspaceId, workspace });
325
+ return { deleted: true, hardDelete: false };
326
+ }
327
+
328
+ // Hard delete
329
+ await fs.rmdir(workspace.isolation.dataPath, { recursive: true });
330
+ this.workspaces.delete(_workspaceId);
331
+
332
+ this.emit('workspace_hard_deleted', { _workspaceId });
333
+ return { deleted: true, hardDelete: true };
334
+ }
335
+
336
+ // Private methods
337
+ async _createTenantInfrastructure(tenant) {
338
+ const tenantDir = tenant.isolation.dataPath;
339
+
340
+ await fs.mkdir(tenantDir, { recursive: true });
341
+ await fs.mkdir(path.join(tenantDir, 'workspaces'), { recursive: true });
342
+ await fs.mkdir(path.join(tenantDir, 'audit-logs'), { recursive: true });
343
+ await fs.mkdir(path.join(tenantDir, 'backups'), { recursive: true });
344
+
345
+ // Create tenant configuration
346
+ const tenantConfig = {
347
+ tenant: {
348
+ id: tenant.id,
349
+ name: tenant.name,
350
+ domain: tenant.domain,
351
+ },
352
+ quotas: tenant.quotas,
353
+ settings: tenant.settings,
354
+ };
355
+
356
+ await fs.writeFile(
357
+ path.join(tenantDir, 'tenant.json'),
358
+ JSON.stringify(tenantConfig, null, 2),
359
+ );
360
+ }
361
+
362
+ async _createWorkspaceInfrastructure(workspace) {
363
+ const workspaceDir = workspace.isolation.dataPath;
364
+
365
+ await fs.mkdir(workspaceDir, { recursive: true });
366
+ await fs.mkdir(workspace.isolation.pluginsPath, { recursive: true });
367
+ await fs.mkdir(path.join(workspaceDir, 'data'), { recursive: true });
368
+ await fs.mkdir(path.join(workspaceDir, 'cache'), { recursive: true });
369
+
370
+ // Create default .ragrc.json for workspace
371
+ const defaultConfig = {
372
+ workspace: {
373
+ id: workspace.id,
374
+ name: workspace.name,
375
+ tenantId: workspace._tenantId,
376
+ },
377
+ plugins: {},
378
+ settings: workspace.settings,
379
+ };
380
+
381
+ await fs.writeFile(
382
+ workspace.isolation.configPath,
383
+ JSON.stringify(defaultConfig, null, 2),
384
+ );
385
+ }
386
+
387
+ async _initializeTenantServices(tenant) {
388
+ // Initialize tenant-specific services
389
+ // This would include setting up isolated databases, message queues, etc.
390
+
391
+ // For now, we'll create service configuration files
392
+ const servicesConfig = {
393
+ database: {
394
+ connectionString: `tenant_${tenant.id}_db`,
395
+ isolation: true,
396
+ },
397
+ cache: {
398
+ namespace: `tenant:${tenant.id}`,
399
+ isolation: true,
400
+ },
401
+ messaging: {
402
+ topic: `tenant-${tenant.id}`,
403
+ isolation: true,
404
+ },
405
+ };
406
+
407
+ await fs.writeFile(
408
+ path.join(tenant.isolation.dataPath, 'services.json'),
409
+ JSON.stringify(servicesConfig, null, 2),
410
+ );
411
+ }
412
+
413
+ _calculateResourceLimits(plan) {
414
+ const limits = {
415
+ starter: {
416
+ cpu: '1000m',
417
+ memory: '2Gi',
418
+ storage: '10Gi',
419
+ },
420
+ professional: {
421
+ cpu: '2000m',
422
+ memory: '4Gi',
423
+ storage: '50Gi',
424
+ },
425
+ enterprise: {
426
+ cpu: '4000m',
427
+ memory: '8Gi',
428
+ storage: '200Gi',
429
+ },
430
+ };
431
+
432
+ return limits[plan] || limits.enterprise;
433
+ }
434
+
435
+ _calculateQuotaUtilization(quotas, usage) {
436
+ return {
437
+ users: (usage.activeUsers / quotas.maxUsers) * 100,
438
+ workspaces: (usage.workspaces / quotas.maxWorkspaces) * 100,
439
+ storage: (usage.storageUsedGB / quotas.maxStorageGB) * 100,
440
+ apiCalls: (usage.apiCallsThisMonth / quotas.maxAPICallsPerMonth) * 100,
441
+ pipelines: (usage.activePipelines / quotas.maxConcurrentPipelines) * 100,
442
+ plugins: (usage.installedPlugins / quotas.maxPlugins) * 100,
443
+ };
444
+ }
445
+
446
+ async _persistTenant(tenant) {
447
+ const tenantFile = path.join(tenant.isolation.dataPath, 'tenant.json');
448
+ await fs.writeFile(tenantFile, JSON.stringify(tenant, null, 2));
449
+ }
450
+
451
+ async _persistWorkspace(workspace) {
452
+ const workspaceFile = path.join(
453
+ workspace.isolation.dataPath,
454
+ 'workspace.json',
455
+ );
456
+ await fs.writeFile(workspaceFile, JSON.stringify(workspace, null, 2));
457
+ }
458
+ }
459
+
460
+ class ResourceMonitor {
461
+ constructor(_config) {
462
+ this._config = _config;
463
+ this.metrics = new Map();
464
+ }
465
+
466
+ async getTenantUsage(_tenantId) {
467
+ // Mock implementation - would integrate with actual monitoring systems
468
+ return {
469
+ activeUsers: Math.floor(Math.random() * 50),
470
+ workspaces: Math.floor(Math.random() * 5),
471
+ storageUsedGB: Math.floor(Math.random() * 30),
472
+ apiCallsThisMonth: Math.floor(Math.random() * 50000),
473
+ activePipelines: Math.floor(Math.random() * 3),
474
+ installedPlugins: Math.floor(Math.random() * 20),
475
+ lastUpdated: new Date().toISOString(),
476
+ };
477
+ }
478
+
479
+ async getWorkspaceUsage(_workspaceId) {
480
+ // Mock implementation
481
+ return {
482
+ storageUsedMB: Math.floor(Math.random() * 1000),
483
+ apiCallsThisMonth: Math.floor(Math.random() * 5000),
484
+ activePipelines: Math.floor(Math.random() * 2),
485
+ installedPlugins: Math.floor(Math.random() * 10),
486
+ lastActivity: new Date().toISOString(),
487
+ };
488
+ }
489
+ }
490
+
491
+ module.exports = {
492
+ TenantManager,
493
+ ResourceMonitor,
494
+ };
495
+
496
+ // Ensure module.exports is properly defined