@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,497 @@
1
+ // src/core/observability/metrics.js
2
+ const MetricType = {
3
+ COUNTER: 'counter',
4
+ HISTOGRAM: 'histogram',
5
+ GAUGE: 'gauge',
6
+ };
7
+
8
+ /** Counter */
9
+ class Counter {
10
+ constructor(name, description = '', labels = {}) {
11
+ this._type = MetricType.COUNTER;
12
+ this.name = name;
13
+ this.description = description;
14
+ this.labels = labels || {};
15
+ this.value = 0;
16
+ }
17
+ inc(n = 1) {
18
+ if (n < 0)
19
+ throw new Error('Counter can only be incremented by non-negative values');
20
+ this.value += n;
21
+ }
22
+ reset() {
23
+ this.value = 0;
24
+ }
25
+ toJSON() {
26
+ return {
27
+ name: this.name,
28
+ description: this.description,
29
+ type: this._type,
30
+ value: this.value,
31
+ labels: this.labels,
32
+ timestamp: new Date().toISOString(),
33
+ };
34
+ }
35
+ }
36
+
37
+ /** Gauge */
38
+ class Gauge {
39
+ constructor(name, description = '', labels = {}) {
40
+ this._type = MetricType.GAUGE;
41
+ this.name = name;
42
+ this.description = description;
43
+ this.labels = labels || {};
44
+ this.value = 0;
45
+ }
46
+ set(v) {
47
+ this.value = v;
48
+ }
49
+ inc(n = 1) {
50
+ this.value += n;
51
+ }
52
+ dec(n = 1) {
53
+ this.value -= n;
54
+ }
55
+ reset() {
56
+ this.value = 0;
57
+ }
58
+ toJSON() {
59
+ return {
60
+ name: this.name,
61
+ description: this.description,
62
+ type: this._type,
63
+ value: this.value,
64
+ labels: this.labels,
65
+ timestamp: new Date().toISOString(),
66
+ };
67
+ }
68
+ }
69
+
70
+ /** Histogram with cumulative bucketCounts and raw observations for stats/percentiles */
71
+ class Histogram {
72
+ constructor(
73
+ name,
74
+ description = '',
75
+ labels = {},
76
+ buckets = [1, 5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000, 10000],
77
+ ) {
78
+ this._type = MetricType.HISTOGRAM;
79
+ this.name = name;
80
+ this.description = description;
81
+ this.labels = labels || {};
82
+ this.buckets = [...buckets].sort((a, b) => a - b);
83
+ this.bucketCounts = Array(this.buckets.length + 1).fill(0); // cumulative, last = +Inf
84
+ this.sum = 0;
85
+ this.count = 0;
86
+ this.min = Infinity;
87
+ this.max = -Infinity;
88
+ this._obs = [];
89
+ }
90
+
91
+ observe(v) {
92
+ if (typeof v !== 'number' || Number.isNaN(v)) return;
93
+ this._obs.push(v);
94
+ this.sum += v;
95
+ this.count += 1;
96
+ if (v < this.min) this.min = v;
97
+ if (v > this.max) this.max = v;
98
+
99
+ // find first bucket index where v <= bucket
100
+ let idx = this.buckets.findIndex((b) => v <= b);
101
+ if (idx === -1) idx = this.buckets.length; // +Inf
102
+
103
+ // cumulative: increment from idx to end
104
+ for (let i = idx; i < this.bucketCounts.length; i++)
105
+ this.bucketCounts[i] += 1;
106
+ }
107
+
108
+ getPercentiles(percentiles = [50, 95, 99]) {
109
+ if (this._obs.length === 0)
110
+ return Object.fromEntries(percentiles.map((p) => [p, 0]));
111
+ const arr = [...this._obs].sort((a, b) => a - b);
112
+ const n = arr.length;
113
+ const out = {};
114
+ for (const p of percentiles) {
115
+ // nearest-rank method
116
+ let rank = Math.ceil((p / 100) * n);
117
+ if (rank < 1) rank = 1;
118
+ if (rank > n) rank = n;
119
+ out[p] = arr[rank - 1];
120
+ }
121
+ return out;
122
+ }
123
+
124
+ getStatistics() {
125
+ if (this.count === 0) {
126
+ return {
127
+ mean: 0,
128
+ stdDev: 0,
129
+ min: Infinity,
130
+ max: -Infinity,
131
+ count: 0,
132
+ sum: 0,
133
+ };
134
+ }
135
+ const mean = this.sum / this.count;
136
+ // population std dev
137
+ const variance =
138
+ this._obs.reduce((acc, x) => acc + Math.pow(x - mean, 2), 0) / this.count;
139
+ const stdDev = Math.sqrt(variance);
140
+ return {
141
+ mean,
142
+ stdDev,
143
+ min: this.min,
144
+ max: this.max,
145
+ count: this.count,
146
+ sum: this.sum,
147
+ };
148
+ }
149
+
150
+ reset() {
151
+ this.bucketCounts.fill(0);
152
+ this.sum = 0;
153
+ this.count = 0;
154
+ this.min = Infinity;
155
+ this.max = -Infinity;
156
+ this._obs = [];
157
+ }
158
+ export() {
159
+ // Map bucket value -> cumulative count
160
+ const bucketsObj = {};
161
+ for (let i = 0; i < this.buckets.length; i++)
162
+ bucketsObj[this.buckets[i]] = this.bucketCounts[i];
163
+ bucketsObj['+Inf'] = this.bucketCounts[this.bucketCounts.length - 1];
164
+ const stats = this.getStatistics();
165
+ return { buckets: bucketsObj, ...stats };
166
+ }
167
+ toJSON() {
168
+ return {
169
+ name: this.name,
170
+ description: this.description,
171
+ type: this._type,
172
+ count: this.count,
173
+ sum: this.sum,
174
+ buckets: this.buckets,
175
+ bucketCounts: this.bucketCounts,
176
+ labels: this.labels,
177
+ timestamp: new Date().toISOString(),
178
+ };
179
+ }
180
+ }
181
+
182
+ /** Metrics registry (simple) */
183
+ class MetricsRegistry {
184
+ constructor() {
185
+ this._metrics = new Map(); // name -> metric instance
186
+ }
187
+ register(metric) {
188
+ if (this._metrics.has(metric.name)) {
189
+ throw new Error(
190
+ `Metric with name "${metric.name}" is already registered`,
191
+ );
192
+ }
193
+ this._metrics.set(metric.name, metric);
194
+ }
195
+ getMetric(name) {
196
+ return this._metrics.get(name);
197
+ }
198
+ getAllMetrics() {
199
+ return Array.from(this._metrics.values());
200
+ }
201
+ clear() {
202
+ this._metrics.clear();
203
+ }
204
+ getOrCreateCounter(name, description, labels = {}) {
205
+ if (this._metrics.has(name)) {
206
+ return this._metrics.get(name);
207
+ }
208
+ const counter = new Counter(name, description, labels);
209
+ this.register(counter);
210
+ return counter;
211
+ }
212
+ getOrCreateHistogram(name, description, labels = {}, buckets) {
213
+ if (this._metrics.has(name)) {
214
+ return this._metrics.get(name);
215
+ }
216
+ const histogram = new Histogram(name, description, labels, buckets);
217
+ this.register(histogram);
218
+ return histogram;
219
+ }
220
+ getOrCreateGauge(name, description, labels = {}) {
221
+ if (this._metrics.has(name)) {
222
+ return this._metrics.get(name);
223
+ }
224
+ const gauge = new Gauge(name, description, labels);
225
+ this.register(gauge);
226
+ return gauge;
227
+ }
228
+ exportMetrics() {
229
+ return JSON.stringify({
230
+ timestamp: new Date().toISOString(),
231
+ metrics: this.getAllMetrics().map((m) => m.toJSON()),
232
+ });
233
+ }
234
+ }
235
+
236
+ /** Pipeline-level convenience aggregator used by tests */
237
+ class PipelineMetrics {
238
+ constructor() {
239
+ this.counters = {
240
+ operationsTotal: new Counter('operations_total', 'Total operations'),
241
+ operationsSuccessful: new Counter(
242
+ 'operations_successful',
243
+ 'Successful operations',
244
+ ),
245
+ operationsFailed: new Counter('operations_failed', 'Failed operations'),
246
+ operationsActive: new Counter('operations_active', 'Active operations'),
247
+ };
248
+ this.errorsByType = { plugin: 0, stage: 0 };
249
+ this.errorsByPlugin = {};
250
+ this.backpressureSamples = [];
251
+ this.backpressureApplied = 0;
252
+ this.backpressureReleased = 0;
253
+ this.memory = { heapUsed: 0, heapTotal: 0, usagePercentage: 0 };
254
+
255
+ // Additional metrics for test compatibility
256
+ this.embedding = {
257
+ operations: 0,
258
+ totalDuration: 0,
259
+ totalTokens: 0,
260
+ totalBatches: 0,
261
+ durations: [],
262
+ };
263
+ this.retrieval = {
264
+ operations: 0,
265
+ totalDuration: 0,
266
+ totalResults: 0,
267
+ durations: [],
268
+ };
269
+ this.llm = {
270
+ operations: 0,
271
+ totalDuration: 0,
272
+ totalInputTokens: 0,
273
+ totalOutputTokens: 0,
274
+ streamingOps: 0,
275
+ durations: [],
276
+ inputTokens: [],
277
+ outputTokens: [],
278
+ };
279
+ this.concurrency = { maxConcurrency: 0, concurrencyValues: [] };
280
+ }
281
+
282
+ recordEmbedding(provider, duration, tokens, batches) {
283
+ this.embedding.operations++;
284
+ this.embedding.totalDuration += duration;
285
+ this.embedding.totalTokens += tokens;
286
+ this.embedding.totalBatches += batches;
287
+ this.embedding.durations.push(duration);
288
+ }
289
+
290
+ recordRetrieval(provider, duration, results) {
291
+ this.retrieval.operations++;
292
+ this.retrieval.totalDuration += duration;
293
+ this.retrieval.totalResults += results;
294
+ this.retrieval.durations.push(duration);
295
+ }
296
+
297
+ recordLLM(provider, duration, inputTokens, outputTokens, streaming) {
298
+ this.llm.operations++;
299
+ this.llm.totalDuration += duration;
300
+ this.llm.totalInputTokens += inputTokens;
301
+ this.llm.totalOutputTokens += outputTokens;
302
+ if (streaming) this.llm.streamingOps++;
303
+ this.llm.durations.push(duration);
304
+ this.llm.inputTokens.push(inputTokens);
305
+ this.llm.outputTokens.push(outputTokens);
306
+ }
307
+
308
+ recordMemoryUsage() {
309
+ const memUsage = process.memoryUsage();
310
+ this.memory.heapUsed = memUsage.heapUsed;
311
+ this.memory.heapTotal = memUsage.heapTotal;
312
+ this.memory.usagePercentage = Math.round(
313
+ (memUsage.heapUsed / memUsage.heapTotal) * 100,
314
+ );
315
+ }
316
+
317
+ recordError(type, component, provider, error) {
318
+ if (type && type in this.errorsByType) this.errorsByType[type]++;
319
+ if (component)
320
+ this.errorsByPlugin[component] =
321
+ (this.errorsByPlugin[component] || 0) + 1;
322
+ }
323
+
324
+ recordOperationStart(type, component, provider) {
325
+ this.counters.operationsTotal.inc(1);
326
+ this.counters.operationsActive.inc(1);
327
+ }
328
+
329
+ recordOperationEnd(type, component, provider, duration, status) {
330
+ this.counters.operationsActive.value = Math.max(
331
+ 0,
332
+ this.counters.operationsActive.value - 1,
333
+ );
334
+ if (status === 'error' || status === 'failed')
335
+ this.counters.operationsFailed.inc(1);
336
+ else this.counters.operationsSuccessful.inc(1);
337
+ }
338
+
339
+ recordConcurrency(maxConcurrency, avgConcurrency) {
340
+ this.concurrency.maxConcurrency = Math.max(
341
+ this.concurrency.maxConcurrency,
342
+ maxConcurrency,
343
+ );
344
+ this.concurrency.concurrencyValues.push(avgConcurrency);
345
+ }
346
+
347
+ recordBackpressure(action, bufferSize, threshold) {
348
+ if (action === 'applied') this.backpressureApplied++;
349
+ if (action === 'released') this.backpressureReleased++;
350
+ if (typeof bufferSize === 'number')
351
+ this.backpressureSamples.push(bufferSize);
352
+ }
353
+
354
+ getSummary() {
355
+ const backpressureMean = this.backpressureSamples.length
356
+ ? this.backpressureSamples.reduce((a, b) => a + b, 0) /
357
+ this.backpressureSamples.length
358
+ : 0;
359
+
360
+ const concurrencyMean = this.concurrency.concurrencyValues.length
361
+ ? this.concurrency.concurrencyValues.reduce((a, b) => a + b, 0) /
362
+ this.concurrency.concurrencyValues.length
363
+ : 0;
364
+
365
+ return {
366
+ embedding: {
367
+ totalOperations: this.embedding.operations,
368
+ totalDuration: this.embedding.totalDuration,
369
+ totalTokens: this.embedding.totalTokens,
370
+ totalBatches: this.embedding.totalBatches,
371
+ avgDuration: {
372
+ mean: this.embedding.operations
373
+ ? this.embedding.totalDuration / this.embedding.operations
374
+ : 0,
375
+ },
376
+ },
377
+ retrieval: {
378
+ totalOperations: this.retrieval.operations,
379
+ totalResults: this.retrieval.totalResults,
380
+ avgDuration: {
381
+ mean: this.retrieval.operations
382
+ ? this.retrieval.totalDuration / this.retrieval.operations
383
+ : 0,
384
+ },
385
+ },
386
+ llm: {
387
+ totalOperations: this.llm.operations,
388
+ streamingOperations: this.llm.streamingOps,
389
+ avgDuration: {
390
+ mean: this.llm.operations
391
+ ? this.llm.totalDuration / this.llm.operations
392
+ : 0,
393
+ },
394
+ avgInputTokens: {
395
+ mean: this.llm.operations
396
+ ? this.llm.totalInputTokens / this.llm.operations
397
+ : 0,
398
+ },
399
+ avgOutputTokens: {
400
+ mean: this.llm.operations
401
+ ? this.llm.totalOutputTokens / this.llm.operations
402
+ : 0,
403
+ },
404
+ },
405
+ memory: this.memory,
406
+ errors: {
407
+ total: Object.values(this.errorsByType).reduce((a, b) => a + b, 0),
408
+ byType: this.errorsByType,
409
+ byPlugin: this.errorsByPlugin,
410
+ },
411
+ operations: {
412
+ total: this.counters.operationsTotal.value,
413
+ successful: this.counters.operationsSuccessful.value,
414
+ failed: this.counters.operationsFailed.value,
415
+ },
416
+ concurrency: {
417
+ maxConcurrency: this.concurrency.maxConcurrency,
418
+ avgConcurrency: { mean: Number(concurrencyMean.toFixed(1)) },
419
+ },
420
+ backpressure: {
421
+ totalEvents: this.backpressureApplied + this.backpressureReleased,
422
+ appliedEvents: this.backpressureApplied,
423
+ releasedEvents: this.backpressureReleased,
424
+ avgBufferSize: { mean: Number(backpressureMean.toFixed(1)) },
425
+ },
426
+ };
427
+ }
428
+
429
+ exportMetrics() {
430
+ return {
431
+ timestamp: new Date().toISOString(),
432
+ summary: this.getSummary(),
433
+ rawMetrics: {
434
+ counters: this.counters,
435
+ embedding: this.embedding,
436
+ retrieval: this.retrieval,
437
+ llm: this.llm,
438
+ memory: this.memory,
439
+ errors: { byType: this.errorsByType, byPlugin: this.errorsByPlugin },
440
+ concurrency: this.concurrency,
441
+ backpressure: {
442
+ samples: this.backpressureSamples,
443
+ applied: this.backpressureApplied,
444
+ released: this.backpressureReleased,
445
+ },
446
+ },
447
+ };
448
+ }
449
+
450
+ clearMetrics() {
451
+ this.counters.operationsTotal.reset();
452
+ this.counters.operationsSuccessful.reset();
453
+ this.counters.operationsFailed.reset();
454
+ this.counters.operationsActive.reset();
455
+ this.errorsByType = { plugin: 0, stage: 0 };
456
+ this.errorsByPlugin = {};
457
+ this.backpressureSamples = [];
458
+ this.backpressureApplied = 0;
459
+ this.backpressureReleased = 0;
460
+ this.memory = { heapUsed: 0, heapTotal: 0, usagePercentage: 0 };
461
+ this.embedding = {
462
+ operations: 0,
463
+ totalDuration: 0,
464
+ totalTokens: 0,
465
+ totalBatches: 0,
466
+ durations: [],
467
+ };
468
+ this.retrieval = {
469
+ operations: 0,
470
+ totalDuration: 0,
471
+ totalResults: 0,
472
+ durations: [],
473
+ };
474
+ this.llm = {
475
+ operations: 0,
476
+ totalDuration: 0,
477
+ totalInputTokens: 0,
478
+ totalOutputTokens: 0,
479
+ streamingOps: 0,
480
+ durations: [],
481
+ inputTokens: [],
482
+ outputTokens: [],
483
+ };
484
+ this.concurrency = { maxConcurrency: 0, concurrencyValues: [] };
485
+ }
486
+ }
487
+
488
+ const pipelineMetrics = new PipelineMetrics();
489
+
490
+ module.exports = {
491
+ Counter,
492
+ Histogram,
493
+ Gauge,
494
+ PipelineMetrics,
495
+ MetricsRegistry,
496
+ pipelineMetrics,
497
+ };