@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.
- package/.ragrc.schema.json +218 -0
- package/README.md +292 -32
- package/bin/cli.js +8 -14
- package/dist/index.d.ts +237 -0
- package/dist/index.mjs +22 -7
- package/package.json +17 -13
- package/src/ai/adaptive-retrieval.js +191 -0
- package/src/ai/federated-learning.js +214 -0
- package/src/ai/federation/federated-learning-coordinator.js +345 -0
- package/src/ai/federation.js +76 -0
- package/src/ai/index-fixed.js +509 -0
- package/src/ai/index.js +33 -0
- package/src/ai/model-trainer.js +217 -0
- package/src/ai/model-training.js +205 -0
- package/src/ai/module-template.js +37 -0
- package/src/ai/multimodal/multi-modal-processor.js +345 -0
- package/src/ai/multimodal-processing.js +268 -0
- package/src/ai/multimodal.js +71 -0
- package/src/ai/orchestrator.js +70 -0
- package/src/ai/retrieval/adaptive-retrieval-engine.js +398 -0
- package/src/ai/retrieval-engine.js +69 -0
- package/src/ai/training/model-training-orchestrator.js +228 -0
- package/src/ci/workflow-analyzer.js +71 -0
- package/src/cli/commands/ai-ml.js +967 -0
- package/src/cli/commands/docs.js +228 -0
- package/src/cli/commands/dx.js +538 -0
- package/src/cli/commands/plugin-hub.js +875 -0
- package/src/cli/doctor-command.js +639 -0
- package/src/cli/enhanced-cli-commands.js +945 -0
- package/src/cli/interactive-wizard.js +997 -0
- package/src/cli/plugin-marketplace-commands.js +869 -0
- package/src/cli.js +17 -0
- package/src/config/enhanced-ragrc-schema.js +632 -0
- package/src/config/load-config.js +54 -0
- package/src/config/load-plugin-config.js +69 -0
- package/src/config/normalize-config.js +105 -0
- package/src/config/schema-validator.js +315 -0
- package/src/config/validate-plugin-schema.js +35 -0
- package/src/config/validate-schema.js +113 -0
- package/src/contracts/plugin-contracts.js +33 -0
- package/src/core/create-pipeline.js +99 -0
- package/src/core/dependency-injection.js +242 -0
- package/src/core/observability/event-logger.js +241 -0
- package/src/core/observability/instrumented-pipeline.js +609 -0
- package/src/core/observability/metrics.js +497 -0
- package/src/core/observability/tracing.js +781 -0
- package/src/core/performance/benchmark.js +516 -0
- package/src/core/performance/parallel-processor.js +240 -0
- package/src/core/performance/streaming-safeguards.js +611 -0
- package/src/core/pipeline-factory.js +60 -0
- package/src/core/plugin-contracts.js +89 -0
- package/src/core/plugin-marketplace/plugin-metadata.js +485 -0
- package/src/core/plugin-marketplace/plugin-publisher.js +574 -0
- package/src/core/plugin-marketplace/plugin-registry-format.js +419 -0
- package/src/core/plugin-marketplace/version-resolver.js +61 -0
- package/src/core/plugin-registry.js +265 -0
- package/src/dag/dag-engine.js +954 -0
- package/src/dag/dag-node.js +76 -0
- package/src/dag/enhanced-dag-engine.js +822 -0
- package/src/dx/index.js +40 -0
- package/src/dx/integration-templates.js +665 -0
- package/src/dx/performance-profiler.js +968 -0
- package/src/dx/realtime-debugger.js +755 -0
- package/src/dx/visual-pipeline-builder.js +578 -0
- package/src/ecosystem/plugin-analytics-dashboard.js +778 -0
- package/src/ecosystem/plugin-certification.js +580 -0
- package/src/ecosystem/plugin-hub.js +821 -0
- package/src/enterprise/audit-logging.js +967 -0
- package/src/enterprise/data-governance.js +408 -0
- package/src/enterprise/multi-tenancy.js +496 -0
- package/src/enterprise/sso-integration.js +903 -0
- package/src/evaluate/evaluator.js +52 -0
- package/src/evaluate/scoring.js +91 -0
- package/src/index.js +67 -0
- package/src/ingest.js +59 -0
- package/src/loader/csv-loader.js +38 -0
- package/src/loader/directory-loader.js +48 -0
- package/src/loader/html-loader.js +62 -0
- package/src/loader/markdown-loader.js +67 -0
- package/src/mocks/openai-embedder.js +119 -0
- package/src/mocks/openai-llm.js +77 -0
- package/src/mocks/pdf-loader.js +21 -0
- package/src/mocks/pinecone-retriever.js +106 -0
- package/src/observability/audit-logger.js +758 -0
- package/src/observability/dashboard-config.json +675 -0
- package/src/observability/event-logger.js +310 -0
- package/src/observability/metrics.js +691 -0
- package/src/observability/security-monitor.js +830 -0
- package/src/observability/slo-monitor.js +319 -0
- package/src/observability/telemetry.js +686 -0
- package/src/pipeline/pipeline.js +18 -0
- package/src/plugins/sample-embedder.js +53 -0
- package/src/plugins/sample-llm.js +30 -0
- package/src/plugins/sample-loader.js +24 -0
- package/src/plugins/sample-retriever.js +84 -0
- package/src/query.js +117 -0
- package/src/reranker/llm-reranker.js +85 -0
- package/src/scripts/script-utilities.js +36 -0
- package/src/security/plugin-sandbox.js +586 -0
- package/src/security/plugin-signature-verifier.js +414 -0
- package/src/security/validator.js +36 -0
- package/src/utils/ci/diagnostic-reporter.js +57 -0
- package/src/utils/logger.js +211 -0
- package/src/utils/performance-monitor.js +561 -0
- package/src/utils/plugin-scaffolder.js +447 -0
- package/src/utils/retry-policy.js +443 -0
- package/src/utils/retry.js +107 -0
- package/src/utils/safe-expression-evaluator.js +579 -0
- package/src/utils/structured-logger.js +361 -0
- package/src/utils/validate-plugin-contract.js +42 -0
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SLO (Service Level Objective) Monitoring System
|
|
3
|
+
* Addresses T-2 remediation: Production observability with SLOs
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const { logger } = require('../utils/logger');
|
|
7
|
+
const EventEmitter = require('events');
|
|
8
|
+
|
|
9
|
+
class SLOMonitor extends EventEmitter {
|
|
10
|
+
constructor(config = {}) {
|
|
11
|
+
super();
|
|
12
|
+
this.config = {
|
|
13
|
+
measurementWindow: config.measurementWindow || 30 * 24 * 60 * 60 * 1000, // 30 days
|
|
14
|
+
alertThreshold: config.alertThreshold || 0.95, // Alert when SLO drops below 95%
|
|
15
|
+
...config,
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
this.metrics = new Map();
|
|
19
|
+
this.slos = new Map();
|
|
20
|
+
this.alerts = [];
|
|
21
|
+
|
|
22
|
+
this._initializeDefaultSLOs();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
_initializeDefaultSLOs() {
|
|
26
|
+
// Availability SLO: 99.9% uptime
|
|
27
|
+
this.defineSLO('availability', {
|
|
28
|
+
target: 0.999,
|
|
29
|
+
measurementWindow: this.config.measurementWindow,
|
|
30
|
+
description: 'System availability percentage',
|
|
31
|
+
errorBudget: 0.001,
|
|
32
|
+
alertThreshold: 0.995,
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
// Deployment Success SLO: 95% successful deployments
|
|
36
|
+
this.defineSLO('deployment_success', {
|
|
37
|
+
target: 0.95,
|
|
38
|
+
measurementWindow: 7 * 24 * 60 * 60 * 1000, // 7 days
|
|
39
|
+
description: 'Deployment success rate',
|
|
40
|
+
errorBudget: 0.05,
|
|
41
|
+
alertThreshold: 0.9,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// Test Reliability SLO: 95% test pass rate
|
|
45
|
+
this.defineSLO('test_reliability', {
|
|
46
|
+
target: 0.95,
|
|
47
|
+
measurementWindow: 7 * 24 * 60 * 60 * 1000, // 7 days
|
|
48
|
+
description: 'Test suite reliability',
|
|
49
|
+
errorBudget: 0.05,
|
|
50
|
+
alertThreshold: 0.9,
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// Security Compliance SLO: 100% security scans pass
|
|
54
|
+
this.defineSLO('security_compliance', {
|
|
55
|
+
target: 1.0,
|
|
56
|
+
measurementWindow: 24 * 60 * 60 * 1000, // 1 day
|
|
57
|
+
description: 'Security compliance rate',
|
|
58
|
+
errorBudget: 0.0,
|
|
59
|
+
alertThreshold: 0.99,
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// Response Time SLO: 95% of requests under 2s
|
|
63
|
+
this.defineSLO('response_time', {
|
|
64
|
+
target: 0.95,
|
|
65
|
+
measurementWindow: this.config.measurementWindow,
|
|
66
|
+
description: '95th percentile response time under 2s',
|
|
67
|
+
errorBudget: 0.05,
|
|
68
|
+
alertThreshold: 0.9,
|
|
69
|
+
threshold: 2000, // 2 seconds
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
defineSLO(name, config) {
|
|
74
|
+
this.slos.set(name, {
|
|
75
|
+
...config,
|
|
76
|
+
createdAt: Date.now(),
|
|
77
|
+
measurements: [],
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
logger.info('SLO defined', {
|
|
81
|
+
slo: name,
|
|
82
|
+
target: config.target,
|
|
83
|
+
description: config.description,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
recordMeasurement(sloName, success, metadata = {}) {
|
|
88
|
+
if (!this.slos.has(sloName)) {
|
|
89
|
+
throw new Error(`SLO not found: ${sloName}`);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const slo = this.slos.get(sloName);
|
|
93
|
+
const measurement = {
|
|
94
|
+
timestamp: Date.now(),
|
|
95
|
+
success: Boolean(success),
|
|
96
|
+
metadata,
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
slo.measurements.push(measurement);
|
|
100
|
+
this._cleanupOldMeasurements(sloName);
|
|
101
|
+
|
|
102
|
+
const currentSLI = this.calculateSLI(sloName);
|
|
103
|
+
|
|
104
|
+
logger.debug('SLO measurement recorded', {
|
|
105
|
+
slo: sloName,
|
|
106
|
+
success,
|
|
107
|
+
currentSLI,
|
|
108
|
+
metadata,
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// Check for SLO violations
|
|
112
|
+
if (currentSLI < slo.alertThreshold) {
|
|
113
|
+
this._triggerAlert(sloName, currentSLI, slo);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
this.emit('measurement', {
|
|
117
|
+
slo: sloName,
|
|
118
|
+
success,
|
|
119
|
+
currentSLI,
|
|
120
|
+
metadata,
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
return currentSLI;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
calculateSLI(sloName) {
|
|
127
|
+
const slo = this.slos.get(sloName);
|
|
128
|
+
if (!slo || slo.measurements.length === 0) {
|
|
129
|
+
return 1.0; // No data means perfect SLI
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const now = Date.now();
|
|
133
|
+
const windowStart = now - slo.measurementWindow;
|
|
134
|
+
|
|
135
|
+
const relevantMeasurements = slo.measurements.filter(
|
|
136
|
+
(m) => m.timestamp >= windowStart,
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
if (relevantMeasurements.length === 0) {
|
|
140
|
+
return 1.0;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const successCount = relevantMeasurements.filter((m) => m.success).length;
|
|
144
|
+
return successCount / relevantMeasurements.length;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
getErrorBudget(sloName) {
|
|
148
|
+
const slo = this.slos.get(sloName);
|
|
149
|
+
if (!slo) {
|
|
150
|
+
throw new Error(`SLO not found: ${sloName}`);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const currentSLI = this.calculateSLI(sloName);
|
|
154
|
+
const errorBudgetUsed = Math.max(0, slo.target - currentSLI);
|
|
155
|
+
const errorBudgetRemaining = Math.max(0, slo.errorBudget - errorBudgetUsed);
|
|
156
|
+
|
|
157
|
+
return {
|
|
158
|
+
target: slo.target,
|
|
159
|
+
current: currentSLI,
|
|
160
|
+
errorBudget: slo.errorBudget,
|
|
161
|
+
errorBudgetUsed,
|
|
162
|
+
errorBudgetRemaining,
|
|
163
|
+
errorBudgetPercentage: (errorBudgetRemaining / slo.errorBudget) * 100,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
getSLOStatus(sloName) {
|
|
168
|
+
const slo = this.slos.get(sloName);
|
|
169
|
+
if (!slo) {
|
|
170
|
+
throw new Error(`SLO not found: ${sloName}`);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const currentSLI = this.calculateSLI(sloName);
|
|
174
|
+
const errorBudget = this.getErrorBudget(sloName);
|
|
175
|
+
const isHealthy = currentSLI >= slo.target;
|
|
176
|
+
const isAtRisk = currentSLI < slo.alertThreshold;
|
|
177
|
+
|
|
178
|
+
return {
|
|
179
|
+
name: sloName,
|
|
180
|
+
description: slo.description,
|
|
181
|
+
target: slo.target,
|
|
182
|
+
current: currentSLI,
|
|
183
|
+
isHealthy,
|
|
184
|
+
isAtRisk,
|
|
185
|
+
errorBudget,
|
|
186
|
+
measurementCount: slo.measurements.length,
|
|
187
|
+
lastMeasurement: slo.measurements[slo.measurements.length - 1]?.timestamp,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
getAllSLOStatus() {
|
|
192
|
+
const status = {};
|
|
193
|
+
for (const sloName of this.slos.keys()) {
|
|
194
|
+
status[sloName] = this.getSLOStatus(sloName);
|
|
195
|
+
}
|
|
196
|
+
return status;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
_cleanupOldMeasurements(sloName) {
|
|
200
|
+
const slo = this.slos.get(sloName);
|
|
201
|
+
const now = Date.now();
|
|
202
|
+
const windowStart = now - slo.measurementWindow;
|
|
203
|
+
|
|
204
|
+
slo.measurements = slo.measurements.filter(
|
|
205
|
+
(m) => m.timestamp >= windowStart,
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
_triggerAlert(sloName, currentSLI, slo) {
|
|
210
|
+
const alert = {
|
|
211
|
+
id: `slo-${sloName}-${Date.now()}`,
|
|
212
|
+
slo: sloName,
|
|
213
|
+
severity: 'warning',
|
|
214
|
+
message: `SLO ${sloName} is below alert threshold`,
|
|
215
|
+
currentSLI,
|
|
216
|
+
target: slo.target,
|
|
217
|
+
alertThreshold: slo.alertThreshold,
|
|
218
|
+
timestamp: Date.now(),
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
this.alerts.push(alert);
|
|
222
|
+
|
|
223
|
+
logger.warn('SLO alert triggered', alert);
|
|
224
|
+
|
|
225
|
+
this.emit('alert', alert);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
getActiveAlerts() {
|
|
229
|
+
const now = Date.now();
|
|
230
|
+
const alertWindow = 24 * 60 * 60 * 1000; // 24 hours
|
|
231
|
+
|
|
232
|
+
return this.alerts.filter((alert) => now - alert.timestamp < alertWindow);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
generateReport() {
|
|
236
|
+
const allStatus = this.getAllSLOStatus();
|
|
237
|
+
const activeAlerts = this.getActiveAlerts();
|
|
238
|
+
|
|
239
|
+
const report = {
|
|
240
|
+
timestamp: Date.now(),
|
|
241
|
+
summary: {
|
|
242
|
+
totalSLOs: this.slos.size,
|
|
243
|
+
healthySLOs: Object.values(allStatus).filter((s) => s.isHealthy).length,
|
|
244
|
+
atRiskSLOs: Object.values(allStatus).filter((s) => s.isAtRisk).length,
|
|
245
|
+
activeAlerts: activeAlerts.length,
|
|
246
|
+
},
|
|
247
|
+
slos: allStatus,
|
|
248
|
+
alerts: activeAlerts,
|
|
249
|
+
recommendations: this._generateRecommendations(allStatus),
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
logger.info('SLO report generated', {
|
|
253
|
+
totalSLOs: report.summary.totalSLOs,
|
|
254
|
+
healthySLOs: report.summary.healthySLOs,
|
|
255
|
+
atRiskSLOs: report.summary.atRiskSLOs,
|
|
256
|
+
activeAlerts: report.summary.activeAlerts,
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
return report;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
_generateRecommendations(sloStatus) {
|
|
263
|
+
const recommendations = [];
|
|
264
|
+
|
|
265
|
+
Object.values(sloStatus).forEach((slo) => {
|
|
266
|
+
if (slo.isAtRisk) {
|
|
267
|
+
recommendations.push({
|
|
268
|
+
type: 'urgent',
|
|
269
|
+
slo: slo.name,
|
|
270
|
+
message: `SLO ${slo.name} is at risk. Current: ${(slo.current * 100).toFixed(2)}%, Target: ${(slo.target * 100).toFixed(2)}%`,
|
|
271
|
+
action: 'Investigate root cause and implement fixes',
|
|
272
|
+
});
|
|
273
|
+
} else if (slo.errorBudget.errorBudgetPercentage < 25) {
|
|
274
|
+
recommendations.push({
|
|
275
|
+
type: 'warning',
|
|
276
|
+
slo: slo.name,
|
|
277
|
+
message: `Error budget for ${slo.name} is running low (${slo.errorBudget.errorBudgetPercentage.toFixed(1)}% remaining)`,
|
|
278
|
+
action: 'Monitor closely and consider preventive measures',
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
return recommendations;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// Convenience methods for common measurements
|
|
287
|
+
recordAvailability(isUp, metadata = {}) {
|
|
288
|
+
return this.recordMeasurement('availability', isUp, metadata);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
recordDeployment(success, metadata = {}) {
|
|
292
|
+
return this.recordMeasurement('deployment_success', success, metadata);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
recordTestRun(success, metadata = {}) {
|
|
296
|
+
return this.recordMeasurement('test_reliability', success, metadata);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
recordSecurityScan(passed, metadata = {}) {
|
|
300
|
+
return this.recordMeasurement('security_compliance', passed, metadata);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
recordResponseTime(responseTimeMs, metadata = {}) {
|
|
304
|
+
const slo = this.slos.get('response_time');
|
|
305
|
+
const success = responseTimeMs <= (slo?.threshold || 2000);
|
|
306
|
+
return this.recordMeasurement('response_time', success, {
|
|
307
|
+
...metadata,
|
|
308
|
+
responseTime: responseTimeMs,
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// Create default monitor instance
|
|
314
|
+
const defaultMonitor = new SLOMonitor();
|
|
315
|
+
|
|
316
|
+
module.exports = {
|
|
317
|
+
SLOMonitor,
|
|
318
|
+
defaultMonitor,
|
|
319
|
+
};
|