@devilsdev/rag-pipeline-utils 2.1.11 → 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 +651 -393
- 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,580 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin Certification System
|
|
3
|
+
* Verified publisher program with automated and manual review processes
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const crypto = require('crypto'); // eslint-disable-line global-require
|
|
7
|
+
const { EventEmitter } = require('events'); // eslint-disable-line global-require
|
|
8
|
+
|
|
9
|
+
function pickFetch(pref) {
|
|
10
|
+
// Prefer a provided fetch if it is a function; otherwise fall back to globalThis.fetch if available.
|
|
11
|
+
if (typeof pref === 'function') return pref;
|
|
12
|
+
if (typeof globalThis.fetch === 'function') return globalThis.fetch;
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
class PluginCertification extends EventEmitter {
|
|
17
|
+
constructor(_options = {}) {
|
|
18
|
+
super();
|
|
19
|
+
|
|
20
|
+
this._config = {
|
|
21
|
+
registryUrl: _options.registryUrl || 'https://registry.rag-pipeline.dev',
|
|
22
|
+
apiKey: _options.apiKey || process.env.RAG_PLUGIN_HUB_API_KEY,
|
|
23
|
+
fetch: _options.fetch, // optional injected fetch for tests
|
|
24
|
+
certificationLevels: {
|
|
25
|
+
BASIC: { score: 60, automated: true },
|
|
26
|
+
VERIFIED: { score: 80, manual: true },
|
|
27
|
+
ENTERPRISE: { score: 95, manual: true, audit: true },
|
|
28
|
+
},
|
|
29
|
+
..._options,
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
this.validators = new Map();
|
|
33
|
+
this._initializeValidators();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Submit plugin for certification
|
|
38
|
+
*/
|
|
39
|
+
async submitForCertification(pluginId, level = 'BASIC') {
|
|
40
|
+
const submissionId = crypto.randomUUID();
|
|
41
|
+
|
|
42
|
+
try {
|
|
43
|
+
this.emit('certification_start', { pluginId, level, submissionId });
|
|
44
|
+
|
|
45
|
+
// Validate certification level
|
|
46
|
+
if (!this._config.certificationLevels[level]) {
|
|
47
|
+
throw new Error(`Invalid certification level: ${level}`);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const certLevel = this._config.certificationLevels[level];
|
|
51
|
+
|
|
52
|
+
// Run automated checks
|
|
53
|
+
this.emit('certification_progress', {
|
|
54
|
+
submissionId,
|
|
55
|
+
stage: 'automated_checks',
|
|
56
|
+
});
|
|
57
|
+
const automatedResults = await this._runAutomatedChecks(pluginId);
|
|
58
|
+
|
|
59
|
+
// Calculate initial score
|
|
60
|
+
const score = this._calculateScore(automatedResults);
|
|
61
|
+
|
|
62
|
+
if (score < certLevel.score) {
|
|
63
|
+
throw new Error(
|
|
64
|
+
`Plugin score ${score} below required ${certLevel.score} for ${level} certification`,
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Manual review if required
|
|
69
|
+
let manualResults = null;
|
|
70
|
+
if (certLevel.manual) {
|
|
71
|
+
this.emit('certification_progress', {
|
|
72
|
+
submissionId,
|
|
73
|
+
stage: 'manual_review',
|
|
74
|
+
});
|
|
75
|
+
manualResults = await this._submitForManualReview(
|
|
76
|
+
pluginId,
|
|
77
|
+
level,
|
|
78
|
+
automatedResults,
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Security audit if required
|
|
83
|
+
let auditResults = null;
|
|
84
|
+
if (certLevel.audit) {
|
|
85
|
+
this.emit('certification_progress', {
|
|
86
|
+
submissionId,
|
|
87
|
+
stage: 'security_audit',
|
|
88
|
+
});
|
|
89
|
+
auditResults = await this._performSecurityAudit(pluginId);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Generate certification
|
|
93
|
+
const certification = await this._generateCertification(pluginId, level, {
|
|
94
|
+
automated: automatedResults,
|
|
95
|
+
manual: manualResults,
|
|
96
|
+
audit: auditResults,
|
|
97
|
+
score,
|
|
98
|
+
submissionId,
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
this.emit('certification_complete', {
|
|
102
|
+
pluginId,
|
|
103
|
+
level,
|
|
104
|
+
submissionId,
|
|
105
|
+
certification,
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
return certification;
|
|
109
|
+
} catch (error) {
|
|
110
|
+
this.emit('certification_error', {
|
|
111
|
+
pluginId,
|
|
112
|
+
level,
|
|
113
|
+
submissionId,
|
|
114
|
+
error,
|
|
115
|
+
});
|
|
116
|
+
throw error;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Verify plugin certification
|
|
122
|
+
*/
|
|
123
|
+
async verifyCertification(pluginId, certificationId) {
|
|
124
|
+
try {
|
|
125
|
+
const response = await this._makeRequest(
|
|
126
|
+
'GET',
|
|
127
|
+
`/certifications/${certificationId}/verify`,
|
|
128
|
+
{
|
|
129
|
+
pluginId,
|
|
130
|
+
},
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
return {
|
|
134
|
+
valid: response.valid,
|
|
135
|
+
certification: response.certification,
|
|
136
|
+
expiresAt: response.expiresAt,
|
|
137
|
+
verifiedAt: new Date().toISOString(),
|
|
138
|
+
};
|
|
139
|
+
} catch (error) {
|
|
140
|
+
throw new Error(`Certification verification failed: ${error.message}`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Get certification requirements for a level
|
|
146
|
+
*/
|
|
147
|
+
getCertificationRequirements(level) {
|
|
148
|
+
const requirements = {
|
|
149
|
+
BASIC: {
|
|
150
|
+
automated: [
|
|
151
|
+
'Code quality analysis',
|
|
152
|
+
'Security vulnerability scan',
|
|
153
|
+
'Performance benchmarks',
|
|
154
|
+
'Documentation completeness',
|
|
155
|
+
'Test coverage analysis',
|
|
156
|
+
],
|
|
157
|
+
manual: [],
|
|
158
|
+
audit: [],
|
|
159
|
+
minScore: 60,
|
|
160
|
+
validityPeriod: '1 year',
|
|
161
|
+
},
|
|
162
|
+
VERIFIED: {
|
|
163
|
+
automated: [
|
|
164
|
+
'Code quality analysis',
|
|
165
|
+
'Security vulnerability scan',
|
|
166
|
+
'Performance benchmarks',
|
|
167
|
+
'Documentation completeness',
|
|
168
|
+
'Test coverage analysis',
|
|
169
|
+
'Dependency analysis',
|
|
170
|
+
'License compliance',
|
|
171
|
+
],
|
|
172
|
+
manual: [
|
|
173
|
+
'Code review by certified developer',
|
|
174
|
+
'Functionality verification',
|
|
175
|
+
'Integration testing',
|
|
176
|
+
'User experience evaluation',
|
|
177
|
+
],
|
|
178
|
+
audit: [],
|
|
179
|
+
minScore: 80,
|
|
180
|
+
validityPeriod: '2 years',
|
|
181
|
+
},
|
|
182
|
+
ENTERPRISE: {
|
|
183
|
+
automated: [
|
|
184
|
+
'Comprehensive code quality analysis',
|
|
185
|
+
'Advanced security vulnerability scan',
|
|
186
|
+
'Performance and load testing',
|
|
187
|
+
'Complete documentation review',
|
|
188
|
+
'Full test coverage analysis',
|
|
189
|
+
'Dependency security analysis',
|
|
190
|
+
'License and compliance check',
|
|
191
|
+
'Accessibility compliance',
|
|
192
|
+
],
|
|
193
|
+
manual: [
|
|
194
|
+
'Senior developer code review',
|
|
195
|
+
'Architecture review',
|
|
196
|
+
'Security expert review',
|
|
197
|
+
'Performance expert review',
|
|
198
|
+
'Documentation expert review',
|
|
199
|
+
],
|
|
200
|
+
audit: [
|
|
201
|
+
'Third-party security audit',
|
|
202
|
+
'Penetration testing',
|
|
203
|
+
'Compliance audit (SOC2, ISO27001)',
|
|
204
|
+
'Privacy impact assessment',
|
|
205
|
+
],
|
|
206
|
+
minScore: 95,
|
|
207
|
+
validityPeriod: '3 years',
|
|
208
|
+
},
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
return requirements[level] || null;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Get publisher verification status
|
|
216
|
+
*/
|
|
217
|
+
async getPublisherStatus(publisherId) {
|
|
218
|
+
try {
|
|
219
|
+
const response = await this._makeRequest(
|
|
220
|
+
'GET',
|
|
221
|
+
`/publishers/${publisherId}/status`,
|
|
222
|
+
);
|
|
223
|
+
|
|
224
|
+
return {
|
|
225
|
+
verified: response.verified,
|
|
226
|
+
level: response.level,
|
|
227
|
+
badges: response.badges || [],
|
|
228
|
+
certifiedPlugins: response.certifiedPlugins || 0,
|
|
229
|
+
reputation: response.reputation || 0,
|
|
230
|
+
joinedAt: response.joinedAt,
|
|
231
|
+
lastActivity: response.lastActivity,
|
|
232
|
+
};
|
|
233
|
+
} catch (error) {
|
|
234
|
+
throw new Error(`Failed to get publisher status: ${error.message}`);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Apply for publisher verification
|
|
240
|
+
*/
|
|
241
|
+
async applyForPublisherVerification(publisherInfo) {
|
|
242
|
+
const applicationId = crypto.randomUUID();
|
|
243
|
+
|
|
244
|
+
try {
|
|
245
|
+
const response = await this._makeRequest('POST', '/publishers/verify', {
|
|
246
|
+
...publisherInfo,
|
|
247
|
+
applicationId,
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
return {
|
|
251
|
+
applicationId,
|
|
252
|
+
status: response.status,
|
|
253
|
+
estimatedReviewTime: response.estimatedReviewTime,
|
|
254
|
+
requirements: response.requirements,
|
|
255
|
+
};
|
|
256
|
+
} catch (error) {
|
|
257
|
+
throw new Error(
|
|
258
|
+
`Publisher verification application failed: ${error.message}`,
|
|
259
|
+
);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// Private methods
|
|
264
|
+
_initializeValidators() {
|
|
265
|
+
// Code Quality Validator
|
|
266
|
+
this.validators.set('code_quality', {
|
|
267
|
+
weight: 25,
|
|
268
|
+
run: async (pluginId) => {
|
|
269
|
+
const results = await this._analyzeCodeQuality(pluginId);
|
|
270
|
+
return {
|
|
271
|
+
score: results.overallScore,
|
|
272
|
+
details: results.details,
|
|
273
|
+
issues: results.issues,
|
|
274
|
+
};
|
|
275
|
+
},
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
// Security Validator
|
|
279
|
+
this.validators.set('security', {
|
|
280
|
+
weight: 30,
|
|
281
|
+
run: async (pluginId) => {
|
|
282
|
+
const results = await this._scanSecurity(pluginId);
|
|
283
|
+
return {
|
|
284
|
+
score: results.securityScore,
|
|
285
|
+
vulnerabilities: results.vulnerabilities,
|
|
286
|
+
recommendations: results.recommendations,
|
|
287
|
+
};
|
|
288
|
+
},
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
// Performance Validator
|
|
292
|
+
this.validators.set('performance', {
|
|
293
|
+
weight: 20,
|
|
294
|
+
run: async (pluginId) => {
|
|
295
|
+
const results = await this._benchmarkPerformance(pluginId);
|
|
296
|
+
return {
|
|
297
|
+
score: results.performanceScore,
|
|
298
|
+
metrics: results.metrics,
|
|
299
|
+
bottlenecks: results.bottlenecks,
|
|
300
|
+
};
|
|
301
|
+
},
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
// Documentation Validator
|
|
305
|
+
this.validators.set('documentation', {
|
|
306
|
+
weight: 15,
|
|
307
|
+
run: async (pluginId) => {
|
|
308
|
+
const results = await this._analyzeDocumentation(pluginId);
|
|
309
|
+
return {
|
|
310
|
+
score: results.completenessScore,
|
|
311
|
+
coverage: results.coverage,
|
|
312
|
+
quality: results.quality,
|
|
313
|
+
};
|
|
314
|
+
},
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
// Testing Validator
|
|
318
|
+
this.validators.set('testing', {
|
|
319
|
+
weight: 10,
|
|
320
|
+
run: async (pluginId) => {
|
|
321
|
+
const results = await this._analyzeTests(pluginId);
|
|
322
|
+
return {
|
|
323
|
+
score: results.testScore,
|
|
324
|
+
coverage: results.coverage,
|
|
325
|
+
quality: results.testQuality,
|
|
326
|
+
};
|
|
327
|
+
},
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
async _runAutomatedChecks(pluginId) {
|
|
332
|
+
const results = {};
|
|
333
|
+
|
|
334
|
+
for (const [name, validator] of this.validators) {
|
|
335
|
+
try {
|
|
336
|
+
this.emit('validator_start', { pluginId, validator: name });
|
|
337
|
+
results[name] = await validator.run(pluginId);
|
|
338
|
+
this.emit('validator_complete', {
|
|
339
|
+
pluginId,
|
|
340
|
+
validator: name,
|
|
341
|
+
result: results[name],
|
|
342
|
+
});
|
|
343
|
+
} catch (error) {
|
|
344
|
+
this.emit('validator_error', { pluginId, validator: name, error });
|
|
345
|
+
results[name] = {
|
|
346
|
+
score: 0,
|
|
347
|
+
error: error.message,
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
return results;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
_calculateScore(results) {
|
|
356
|
+
let totalScore = 0;
|
|
357
|
+
let totalWeight = 0;
|
|
358
|
+
|
|
359
|
+
for (const [name, validator] of this.validators) {
|
|
360
|
+
if (results[name] && typeof results[name].score === 'number') {
|
|
361
|
+
totalScore += results[name].score * validator.weight;
|
|
362
|
+
totalWeight += validator.weight;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
return totalWeight > 0 ? Math.round(totalScore / totalWeight) : 0;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
async _submitForManualReview(pluginId, level, automatedResults) {
|
|
370
|
+
const reviewId = crypto.randomUUID();
|
|
371
|
+
|
|
372
|
+
const response = await this._makeRequest('POST', '/reviews/manual', {
|
|
373
|
+
pluginId,
|
|
374
|
+
level,
|
|
375
|
+
automatedResults,
|
|
376
|
+
reviewId,
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
return {
|
|
380
|
+
reviewId: response.reviewId,
|
|
381
|
+
status: response.status,
|
|
382
|
+
estimatedCompletion: response.estimatedCompletion,
|
|
383
|
+
reviewers: response.reviewers,
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
async _performSecurityAudit(pluginId) {
|
|
388
|
+
const auditId = crypto.randomUUID();
|
|
389
|
+
|
|
390
|
+
const response = await this._makeRequest('POST', '/audits/security', {
|
|
391
|
+
pluginId,
|
|
392
|
+
auditId,
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
return {
|
|
396
|
+
auditId: response.auditId,
|
|
397
|
+
status: response.status,
|
|
398
|
+
estimatedCompletion: response.estimatedCompletion,
|
|
399
|
+
auditor: response.auditor,
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
async _generateCertification(pluginId, level, results) {
|
|
404
|
+
const certificationId = crypto.randomUUID();
|
|
405
|
+
const issuedAt = new Date().toISOString();
|
|
406
|
+
const expiresAt = new Date(
|
|
407
|
+
Date.now() + 365 * 24 * 60 * 60 * 1000,
|
|
408
|
+
).toISOString(); // 1 year
|
|
409
|
+
|
|
410
|
+
const certification = {
|
|
411
|
+
id: certificationId,
|
|
412
|
+
pluginId,
|
|
413
|
+
level,
|
|
414
|
+
score: results.score,
|
|
415
|
+
issuedAt,
|
|
416
|
+
expiresAt,
|
|
417
|
+
results: {
|
|
418
|
+
automated: results.automated,
|
|
419
|
+
manual: results.manual,
|
|
420
|
+
audit: results.audit,
|
|
421
|
+
},
|
|
422
|
+
badge: this._generateBadge(level, results.score),
|
|
423
|
+
certificate: this._generateCertificate(
|
|
424
|
+
pluginId,
|
|
425
|
+
level,
|
|
426
|
+
certificationId,
|
|
427
|
+
issuedAt,
|
|
428
|
+
),
|
|
429
|
+
};
|
|
430
|
+
|
|
431
|
+
// Submit to registry
|
|
432
|
+
await this._makeRequest('POST', '/certifications', certification);
|
|
433
|
+
|
|
434
|
+
return certification;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
_generateBadge(level, score) {
|
|
438
|
+
const badges = {
|
|
439
|
+
BASIC: {
|
|
440
|
+
name: 'RAG Pipeline Certified',
|
|
441
|
+
color: '#28a745',
|
|
442
|
+
icon: '✓',
|
|
443
|
+
},
|
|
444
|
+
VERIFIED: {
|
|
445
|
+
name: 'RAG Pipeline Verified',
|
|
446
|
+
color: '#007bff',
|
|
447
|
+
icon: '✓✓',
|
|
448
|
+
},
|
|
449
|
+
ENTERPRISE: {
|
|
450
|
+
name: 'RAG Pipeline Enterprise',
|
|
451
|
+
color: '#6f42c1',
|
|
452
|
+
icon: '★',
|
|
453
|
+
},
|
|
454
|
+
};
|
|
455
|
+
|
|
456
|
+
const badge = badges[level];
|
|
457
|
+
|
|
458
|
+
return {
|
|
459
|
+
...badge,
|
|
460
|
+
score,
|
|
461
|
+
svg: this._generateBadgeSVG(badge, score),
|
|
462
|
+
markdown: `}.svg)`,
|
|
463
|
+
};
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
_generateBadgeSVG(badge, score) {
|
|
467
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" width="120" height="20">
|
|
468
|
+
<rect width="120" height="20" fill="${badge.color}"/>
|
|
469
|
+
<text x="10" y="15" fill="white" font-family="Arial" font-size="12">
|
|
470
|
+
${badge.icon} ${badge.name} (${score})
|
|
471
|
+
</text>
|
|
472
|
+
</svg>`;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
_generateCertificate(pluginId, level, certificationId, issuedAt) {
|
|
476
|
+
return {
|
|
477
|
+
id: certificationId,
|
|
478
|
+
pluginId,
|
|
479
|
+
level,
|
|
480
|
+
issuedAt,
|
|
481
|
+
issuer: 'RAG Pipeline Certification Authority',
|
|
482
|
+
signature: this._generateSignature(
|
|
483
|
+
certificationId,
|
|
484
|
+
pluginId,
|
|
485
|
+
level,
|
|
486
|
+
issuedAt,
|
|
487
|
+
),
|
|
488
|
+
verificationUrl: `https://registry.rag-pipeline.dev/certifications/${certificationId}/verify`,
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
_generateSignature(certificationId, pluginId, level, issuedAt) {
|
|
493
|
+
const data = `${certificationId}:${pluginId}:${level}:${issuedAt}`;
|
|
494
|
+
return crypto.createHash('sha256').update(data).digest('hex');
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
// Mock implementations for validators
|
|
498
|
+
async _analyzeCodeQuality() {
|
|
499
|
+
// Mock implementation - would integrate with ESLint, SonarQube, etc.
|
|
500
|
+
return {
|
|
501
|
+
overallScore: 85,
|
|
502
|
+
details: {
|
|
503
|
+
complexity: 'low',
|
|
504
|
+
maintainability: 'high',
|
|
505
|
+
reliability: 'high',
|
|
506
|
+
},
|
|
507
|
+
issues: [],
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
async _scanSecurity() {
|
|
512
|
+
// Mock implementation - would integrate with Snyk, OWASP, etc.
|
|
513
|
+
return {
|
|
514
|
+
securityScore: 90,
|
|
515
|
+
vulnerabilities: [],
|
|
516
|
+
recommendations: [],
|
|
517
|
+
};
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
async _benchmarkPerformance() {
|
|
521
|
+
// Mock implementation - would run actual performance tests
|
|
522
|
+
return {
|
|
523
|
+
performanceScore: 80,
|
|
524
|
+
metrics: {
|
|
525
|
+
avgResponseTime: '150ms',
|
|
526
|
+
throughput: '1000 ops/sec',
|
|
527
|
+
memoryUsage: '50MB',
|
|
528
|
+
},
|
|
529
|
+
bottlenecks: [],
|
|
530
|
+
};
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
async _analyzeDocumentation() {
|
|
534
|
+
// Mock implementation - would analyze README, JSDoc, etc.
|
|
535
|
+
return {
|
|
536
|
+
completenessScore: 75,
|
|
537
|
+
coverage: 0.8,
|
|
538
|
+
quality: 'good',
|
|
539
|
+
};
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
async _analyzeTests() {
|
|
543
|
+
// Mock implementation - would analyze test files and coverage
|
|
544
|
+
return {
|
|
545
|
+
testScore: 70,
|
|
546
|
+
coverage: 0.85,
|
|
547
|
+
testQuality: 'good',
|
|
548
|
+
};
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
async _makeRequest(method, endpoint, data = {}) {
|
|
552
|
+
const doFetch = pickFetch(this._config.fetch);
|
|
553
|
+
if (!doFetch) throw new Error('fetch is not available in this environment');
|
|
554
|
+
|
|
555
|
+
const url = `${this._config.registryUrl}${endpoint}`;
|
|
556
|
+
|
|
557
|
+
const _options = {
|
|
558
|
+
method,
|
|
559
|
+
headers: {
|
|
560
|
+
'Content-Type': 'application/json',
|
|
561
|
+
Authorization: `Bearer ${this._config.apiKey}`,
|
|
562
|
+
},
|
|
563
|
+
};
|
|
564
|
+
|
|
565
|
+
if (method !== 'GET') {
|
|
566
|
+
_options.body = JSON.stringify(data);
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
const response = await doFetch(url, _options);
|
|
570
|
+
|
|
571
|
+
if (!response.ok) {
|
|
572
|
+
const error = await response.json().catch(() => ({}));
|
|
573
|
+
throw new Error(error.message || `HTTP ${response.status}`);
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
return await response.json();
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
module.exports = { PluginCertification };
|