@devilsdev/rag-pipeline-utils 2.3.1 → 2.4.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/README.md +293 -369
- package/contracts/loader-contract.json +11 -6
- package/contracts/reranker-contract.json +18 -26
- package/dist/index.cjs +21190 -47
- package/dist/index.d.ts +298 -68
- package/dist/index.mjs +9 -76
- package/package.json +20 -8
- package/src/agentic/agentic-pipeline.js +235 -0
- package/src/agentic/iterative-retriever.js +213 -0
- package/src/agentic/query-planner.js +208 -0
- package/src/agentic/self-critique.js +102 -0
- package/src/ai/adaptive-retrieval.js +0 -3
- package/src/ai/federated-learning.js +0 -3
- package/src/ai/federation.js +1 -6
- package/src/ai/index.js +9 -20
- package/src/ai/model-training.js +0 -3
- package/src/ai/multimodal-processing.js +0 -3
- package/src/ai/multimodal.js +1 -6
- package/src/ai/orchestrator.js +1 -6
- package/src/ai/retrieval-engine.js +1 -6
- package/src/chunking/chunking-engine.js +142 -0
- package/src/chunking/strategies/fixed-size.js +54 -0
- package/src/chunking/strategies/recursive.js +127 -0
- package/src/chunking/strategies/semantic.js +128 -0
- package/src/chunking/strategies/sentence.js +32 -0
- package/src/chunking/strategies/structure-aware.js +138 -0
- package/src/citation/citation-tracker.js +161 -0
- package/src/citation/hallucination-detector.js +74 -0
- package/src/citation/source-mapper.js +95 -0
- package/src/cli/commands/ai-ml/adaptive-commands.js +178 -0
- package/src/cli/commands/ai-ml/federated-commands.js +207 -0
- package/src/cli/commands/ai-ml/index.js +17 -0
- package/src/cli/commands/ai-ml/multimodal-commands.js +187 -0
- package/src/cli/commands/ai-ml/shared.js +51 -0
- package/src/cli/commands/ai-ml/training-commands.js +228 -0
- package/src/cli/commands/ai-ml.js +176 -757
- package/src/cli/commands/plugin-hub/certification-commands.js +221 -0
- package/src/cli/commands/plugin-hub/event-handlers.js +64 -0
- package/src/cli/commands/plugin-hub/hub-commands.js +290 -0
- package/src/cli/commands/plugin-hub/review-commands.js +78 -0
- package/src/cli/commands/plugin-hub.js +106 -782
- package/src/cli/diagnostics/config-checker.js +81 -0
- package/src/cli/diagnostics/dependency-checker.js +69 -0
- package/src/cli/diagnostics/environment-checker.js +45 -0
- package/src/cli/diagnostics/performance-checker.js +51 -0
- package/src/cli/diagnostics/plugin-checker.js +106 -0
- package/src/cli/diagnostics/security-checker.js +61 -0
- package/src/cli/doctor-command.js +70 -369
- package/src/cli/enhanced-cli-commands.js +162 -706
- package/src/cli/handlers/config-handler.js +126 -0
- package/src/cli/handlers/diagnostics-handler.js +113 -0
- package/src/cli/handlers/ingest-handler.js +42 -0
- package/src/cli/handlers/init-handler.js +51 -0
- package/src/cli/handlers/query-handler.js +45 -0
- package/src/cli/handlers/run-handler.js +181 -0
- package/src/cli/interactive-wizard.js +99 -723
- package/src/cli/shared/cli-utils.js +89 -0
- package/src/cli/wizard/configuration.js +148 -0
- package/src/cli/wizard/observability.js +79 -0
- package/src/cli/wizard/performance.js +76 -0
- package/src/cli/wizard/plugin-selection.js +297 -0
- package/src/cli/wizard/preview-save.js +172 -0
- package/src/cli/wizard/project-setup.js +66 -0
- package/src/config/memory-optimization.js +3 -3
- package/src/connectors/anthropic-connector.js +179 -0
- package/src/connectors/base-connector.js +94 -0
- package/src/connectors/cohere-connector.js +143 -0
- package/src/connectors/local-embedder.js +171 -0
- package/src/connectors/memory-retriever.js +150 -0
- package/src/connectors/ollama-connector.js +205 -0
- package/src/connectors/openai-connector.js +173 -0
- package/src/core/create-pipeline.js +21 -1
- package/src/core/observability/tracing.js +2 -1
- package/src/core/pipeline-factory.js +0 -1
- package/src/core/plugin-registry.js +14 -14
- package/src/cost/cost-calculator.js +146 -0
- package/src/cost/cost-tracker.js +260 -0
- package/src/cost/token-budget.js +245 -0
- package/src/dag/core/execution-scheduler.js +2 -1
- package/src/dag/core/topology-validation.js +0 -3
- package/src/dag/dag-engine.js +3 -5
- package/src/dag/dag-node.js +0 -1
- package/src/dag/enhanced-dag-engine.js +171 -99
- package/src/dashboard/dashboard-generator.js +642 -0
- package/src/dashboard/metrics-aggregator.js +409 -0
- package/src/debug/execution-tracer.js +210 -0
- package/src/debug/trace-inspector.js +281 -0
- package/src/dev/dev-server.js +5 -5
- package/src/dev/hot-reload.js +3 -2
- package/src/dx/integration-templates.js +0 -3
- package/src/ecosystem/plugin-analytics-dashboard.js +2 -2
- package/src/ecosystem/plugin-hub.js +2 -2
- package/src/enterprise/audit-logging.js +2 -2
- package/src/enterprise/sso-integration.js +52 -32
- package/src/evaluate/context-metrics.js +127 -0
- package/src/evaluate/evaluator.js +4 -2
- package/src/evaluate/faithfulness.js +117 -0
- package/src/evaluate/groundedness.js +60 -0
- package/src/evaluate/pipeline-evaluator.js +156 -0
- package/src/evaluate/relevance.js +129 -0
- package/src/evaluate/scoring.js +27 -0
- package/src/graph/entity-extractor.js +183 -0
- package/src/graph/graph-index.js +113 -0
- package/src/graph/graph-retriever.js +244 -0
- package/src/graph/knowledge-graph.js +256 -0
- package/src/guardrails/guardrails-pipeline.js +136 -0
- package/src/guardrails/post-generation-guard.js +170 -0
- package/src/guardrails/pre-retrieval-guard.js +161 -0
- package/src/guardrails/retrieval-guard.js +126 -0
- package/src/index.js +255 -9
- package/src/loader/html-loader.js +4 -15
- package/src/loader/markdown-loader.js +4 -15
- package/src/mcp/mcp-server.js +199 -0
- package/src/mcp/mcp-tool-builder.js +121 -0
- package/src/observability/audit-logger.js +0 -2
- package/src/observability/event-logger.js +2 -1
- package/src/observability/security-monitor.js +0 -2
- package/src/observability/telemetry.js +0 -2
- package/src/reranker/cascade-reranker.js +79 -0
- package/src/reranker/embedding-reranker.js +124 -0
- package/src/reranker/llm-reranker.js +6 -3
- package/src/reranker/scoring-reranker.js +123 -0
- package/src/retrieval/bm25-search.js +157 -0
- package/src/retrieval/hybrid-retriever.js +111 -0
- package/src/retrieval/rank-fusion.js +62 -0
- package/src/security/jwt-config.js +4 -3
- package/src/security/jwt-validator.js +2 -1
- package/src/security/plugin-sandbox.js +0 -3
- package/src/security/plugin-signature-verifier.js +4 -6
- package/src/security/validator.js +0 -2
- package/src/streaming/embedding-stream.js +197 -0
- package/src/streaming/sse-adapter.js +168 -0
- package/src/streaming/stream-router.js +210 -0
- package/src/streaming/streaming-embedder.js +231 -0
- package/src/streaming/websocket-adapter.js +171 -0
- package/src/templates/scaffold.js +147 -0
- package/src/templates/template-registry.js +272 -0
- package/src/utils/contract-validator.js +2 -1
- package/src/utils/input-sanitizer.js +80 -99
- package/src/utils/performance-monitor.js +0 -3
- package/src/utils/plugin-scaffolder.js +9 -16
- package/src/utils/rate-limiter.js +0 -1
- package/src/utils/retry-policy.js +0 -3
- package/src/utils/safe-expression-evaluator.js +0 -3
- package/src/utils/secure-logger-config.js +2 -4
- package/src/utils/secure-logging.js +0 -3
- package/src/utils/structured-logger.js +0 -3
- package/src/ai/index-fixed.js +0 -509
- package/src/ai/module-template.js +0 -37
- package/src/ci/workflow-analyzer.js +0 -71
- package/src/cli/plugin-marketplace-commands.js +0 -869
- package/src/dev/README.md +0 -126
- package/src/dev/examples/hot-reload-usage.js +0 -355
- package/src/mocks/openai-embedder.js +0 -119
- package/src/mocks/openai-llm.js +0 -77
- package/src/mocks/pdf-loader.js +0 -21
- package/src/mocks/pinecone-retriever.js +0 -106
- package/src/scripts/script-utilities.js +0 -36
- package/src/utils/ci/diagnostic-reporter.js +0 -57
- package/src/utils/examples/error-formatter-usage.js +0 -351
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
const fs = require('fs');
|
|
14
14
|
const path = require('path');
|
|
15
15
|
const { SecureLogger } = require('./secure-logger');
|
|
16
|
+
const { logger } = require('./logger');
|
|
16
17
|
|
|
17
18
|
/**
|
|
18
19
|
* Load configuration from JSON file
|
|
@@ -213,10 +214,7 @@ function loadDefaultConfig(environment) {
|
|
|
213
214
|
try {
|
|
214
215
|
return createLoggerFromConfig(configPath, environment);
|
|
215
216
|
} catch (error) {
|
|
216
|
-
|
|
217
|
-
`Failed to load config from ${configPath}:`,
|
|
218
|
-
error.message,
|
|
219
|
-
);
|
|
217
|
+
logger.warn(`Failed to load config from ${configPath}:`, error.message);
|
|
220
218
|
}
|
|
221
219
|
}
|
|
222
220
|
}
|
package/src/ai/index-fixed.js
DELETED
|
@@ -1,509 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* AI/ML Module Index - Fixed CommonJS Exports
|
|
3
|
-
* Standardized exports for Jest/Node.js compatibility
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
const { EventEmitter } = require("events");
|
|
7
|
-
// eslint-disable-line global-require
|
|
8
|
-
const crypto = require("crypto");
|
|
9
|
-
// eslint-disable-line global-require
|
|
10
|
-
|
|
11
|
-
// Model Training Orchestrator
|
|
12
|
-
class ModelTrainingOrchestrator extends EventEmitter {
|
|
13
|
-
constructor(_options = {}) {
|
|
14
|
-
super();
|
|
15
|
-
this._config = {
|
|
16
|
-
batchSize: _options.batchSize || 32,
|
|
17
|
-
learningRate: _options.learningRate || 1e-4,
|
|
18
|
-
epochs: _options.epochs || 10,
|
|
19
|
-
};
|
|
20
|
-
this.trainingJobs = new Map();
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
async createTrainingJob(tenantId, _config = {}) {
|
|
24
|
-
const jobId = crypto.randomUUID();
|
|
25
|
-
const job = {
|
|
26
|
-
id: jobId,
|
|
27
|
-
tenantId,
|
|
28
|
-
status: "created",
|
|
29
|
-
_config,
|
|
30
|
-
createdAt: Date.now(),
|
|
31
|
-
progress: 0,
|
|
32
|
-
};
|
|
33
|
-
this.trainingJobs.set(jobId, job);
|
|
34
|
-
this.emit("jobCreated", { jobId, tenantId });
|
|
35
|
-
return jobId;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
async startTraining(jobId, data = null, _config = {}) {
|
|
39
|
-
const job = this.trainingJobs.get(jobId);
|
|
40
|
-
if (!job) {
|
|
41
|
-
throw new Error(`Training job ${jobId} not found`);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
job.status = "training";
|
|
45
|
-
job.startedAt = Date.now();
|
|
46
|
-
this.emit("trainingStarted", { jobId });
|
|
47
|
-
|
|
48
|
-
// Simulate training progress
|
|
49
|
-
setTimeout(() => {
|
|
50
|
-
job.progress = 0.5;
|
|
51
|
-
this.emit("progressUpdated", { jobId, progress: 0.5 });
|
|
52
|
-
}, 100);
|
|
53
|
-
|
|
54
|
-
setTimeout(() => {
|
|
55
|
-
job.status = "completed";
|
|
56
|
-
job.progress = 1.0;
|
|
57
|
-
job.completedAt = Date.now();
|
|
58
|
-
this.emit("trainingCompleted", { jobId });
|
|
59
|
-
}, 200);
|
|
60
|
-
|
|
61
|
-
return { jobId, status: "started" };
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
getTrainingStatus(jobId) {
|
|
65
|
-
return this.trainingJobs.get(jobId);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
async stopTraining(jobId) {
|
|
69
|
-
const job = this.trainingJobs.get(jobId);
|
|
70
|
-
if (job && job.status === "training") {
|
|
71
|
-
job.status = "stopped";
|
|
72
|
-
this.emit("trainingStopped", { jobId });
|
|
73
|
-
return true;
|
|
74
|
-
}
|
|
75
|
-
return false;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
async deployModel(jobId, deploymentConfig = {}) {
|
|
79
|
-
const job = this.trainingJobs.get(jobId);
|
|
80
|
-
if (!job) {
|
|
81
|
-
throw new Error(`Training job ${jobId} not found`);
|
|
82
|
-
}
|
|
83
|
-
if (job.status !== "completed") {
|
|
84
|
-
throw new Error(
|
|
85
|
-
`Cannot deploy model: job ${jobId} is not completed (status: ${job.status})`,
|
|
86
|
-
);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const deploymentId = crypto.randomUUID();
|
|
90
|
-
const deployment = {
|
|
91
|
-
id: deploymentId,
|
|
92
|
-
jobId,
|
|
93
|
-
modelId: `model_${jobId}`,
|
|
94
|
-
environment: deploymentConfig.environment || "production",
|
|
95
|
-
status: "deploying",
|
|
96
|
-
deployedAt: Date.now(),
|
|
97
|
-
_config: deploymentConfig,
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
// Simulate deployment process
|
|
101
|
-
setTimeout(() => {
|
|
102
|
-
deployment.status = "deployed";
|
|
103
|
-
this.emit("modelDeployed", {
|
|
104
|
-
deploymentId,
|
|
105
|
-
jobId,
|
|
106
|
-
environment: deployment.environment,
|
|
107
|
-
});
|
|
108
|
-
}, 500);
|
|
109
|
-
|
|
110
|
-
this.emit("deploymentStarted", { deploymentId, jobId });
|
|
111
|
-
return deploymentId;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
// Adaptive Retrieval Engine
|
|
116
|
-
class AdaptiveRetrievalEngine extends EventEmitter {
|
|
117
|
-
constructor(_options = {}) {
|
|
118
|
-
super();
|
|
119
|
-
this._config = {
|
|
120
|
-
learning: {
|
|
121
|
-
algorithm: _options.algorithm || "contextual_bandit",
|
|
122
|
-
explorationRate: _options.explorationRate || 0.1,
|
|
123
|
-
learningRate: _options.learningRate || 0.01,
|
|
124
|
-
},
|
|
125
|
-
..._options,
|
|
126
|
-
};
|
|
127
|
-
this.userProfiles = new Map();
|
|
128
|
-
this.queryHistory = new Map();
|
|
129
|
-
this.feedbackHistory = [];
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
async initializeUserProfile(userId, preferences = {}) {
|
|
133
|
-
const profile = {
|
|
134
|
-
userId,
|
|
135
|
-
interests: preferences.interests || [],
|
|
136
|
-
preferences: preferences,
|
|
137
|
-
createdAt: Date.now(),
|
|
138
|
-
interactions: 0,
|
|
139
|
-
personalizedRankings: new Map(),
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
this.userProfiles.set(userId, profile);
|
|
143
|
-
this.emit("userProfileInitialized", { userId, profile });
|
|
144
|
-
return profile;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
async generatePersonalizedRankings(userId, results, context = {}) {
|
|
148
|
-
const profile = this.userProfiles.get(userId);
|
|
149
|
-
if (!profile) {
|
|
150
|
-
throw new Error(`User profile not found for ${userId}`);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// Simulate personalized ranking based on user interests
|
|
154
|
-
const rankedResults = results
|
|
155
|
-
.map((result, ___index) => ({
|
|
156
|
-
...result,
|
|
157
|
-
personalizedScore: Math.random() * 0.5 + 0.5,
|
|
158
|
-
relevanceFactors: profile.interests.slice(0, 2),
|
|
159
|
-
}))
|
|
160
|
-
.sort((a, b) => b.personalizedScore - a.personalizedScore);
|
|
161
|
-
|
|
162
|
-
this.emit("personalizedRankingsGenerated", {
|
|
163
|
-
userId,
|
|
164
|
-
resultsCount: rankedResults.length,
|
|
165
|
-
});
|
|
166
|
-
return rankedResults;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
async optimizeRetrieval(query, context = {}) {
|
|
170
|
-
const optimizedQuery = `optimized: ${query}`;
|
|
171
|
-
const retrievalStrategy = "adaptive";
|
|
172
|
-
|
|
173
|
-
this.emit("retrievalOptimized", {
|
|
174
|
-
originalQuery: query,
|
|
175
|
-
optimizedQuery,
|
|
176
|
-
strategy: retrievalStrategy,
|
|
177
|
-
context,
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
return {
|
|
181
|
-
query: optimizedQuery,
|
|
182
|
-
strategy: retrievalStrategy,
|
|
183
|
-
confidence: Math.random() * 0.3 + 0.7,
|
|
184
|
-
};
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
// Multi-Modal Processor
|
|
189
|
-
class MultiModalProcessor extends EventEmitter {
|
|
190
|
-
constructor(_options = {}) {
|
|
191
|
-
super();
|
|
192
|
-
this._config = {
|
|
193
|
-
supportedModalities: ["text", "image", "audio", "video"],
|
|
194
|
-
embeddingDimension: _options.embeddingDimension || 768,
|
|
195
|
-
..._options,
|
|
196
|
-
};
|
|
197
|
-
this.processors = new Map();
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
async processContent(content, modality, _options = {}) {
|
|
201
|
-
const processingId = crypto.randomUUID();
|
|
202
|
-
|
|
203
|
-
// Handle case where modality might be passed as an object
|
|
204
|
-
let modalityType = modality;
|
|
205
|
-
if (typeof modality === "object" && modality._type) {
|
|
206
|
-
modalityType = modality._type;
|
|
207
|
-
} else if (typeof modality === "object") {
|
|
208
|
-
modalityType = "text"; // Default fallback
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
this.emit("processingStarted", { processingId, modality: modalityType });
|
|
212
|
-
|
|
213
|
-
// Simulate processing based on modality
|
|
214
|
-
let result;
|
|
215
|
-
switch (modalityType) {
|
|
216
|
-
case "text":
|
|
217
|
-
result = await this._processText(content, _options);
|
|
218
|
-
break;
|
|
219
|
-
case "image":
|
|
220
|
-
result = await this._processImage(content, _options);
|
|
221
|
-
break;
|
|
222
|
-
case "audio":
|
|
223
|
-
result = await this._processAudio(content, _options);
|
|
224
|
-
break;
|
|
225
|
-
case "video":
|
|
226
|
-
result = await this._processVideo(content, _options);
|
|
227
|
-
break;
|
|
228
|
-
default:
|
|
229
|
-
throw new Error(
|
|
230
|
-
`Unsupported modality: ${modalityType} (original: ${JSON.stringify(modality)})`,
|
|
231
|
-
);
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
this.emit("processingCompleted", {
|
|
235
|
-
processingId,
|
|
236
|
-
modality: modalityType,
|
|
237
|
-
result,
|
|
238
|
-
});
|
|
239
|
-
return result;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
async _processText(content, ___options) {
|
|
243
|
-
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
244
|
-
return {
|
|
245
|
-
modality: "text",
|
|
246
|
-
embedding: Array.from({ length: this._config.embeddingDimension }, () =>
|
|
247
|
-
Math.random(),
|
|
248
|
-
),
|
|
249
|
-
features: {
|
|
250
|
-
length: content.length,
|
|
251
|
-
wordCount: content.split(" ").length,
|
|
252
|
-
},
|
|
253
|
-
processed: true,
|
|
254
|
-
};
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
async _processImage(___content, ___options) {
|
|
258
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
259
|
-
return {
|
|
260
|
-
modality: "image",
|
|
261
|
-
embedding: Array.from({ length: this._config.embeddingDimension }, () =>
|
|
262
|
-
Math.random(),
|
|
263
|
-
),
|
|
264
|
-
features: { width: 1024, height: 768, channels: 3 },
|
|
265
|
-
processed: true,
|
|
266
|
-
};
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
async _processAudio(___content, ___options) {
|
|
270
|
-
await new Promise((resolve) => setTimeout(resolve, 75));
|
|
271
|
-
return {
|
|
272
|
-
modality: "audio",
|
|
273
|
-
embedding: Array.from({ length: this._config.embeddingDimension }, () =>
|
|
274
|
-
Math.random(),
|
|
275
|
-
),
|
|
276
|
-
features: { duration: 30, sampleRate: 44100, channels: 2 },
|
|
277
|
-
processed: true,
|
|
278
|
-
};
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
async _processVideo(___content, ___options) {
|
|
282
|
-
await new Promise((resolve) => setTimeout(resolve, 150));
|
|
283
|
-
return {
|
|
284
|
-
modality: "video",
|
|
285
|
-
embedding: Array.from({ length: this._config.embeddingDimension }, () =>
|
|
286
|
-
Math.random(),
|
|
287
|
-
),
|
|
288
|
-
features: { duration: 60, fps: 30, resolution: "1920x1080" },
|
|
289
|
-
processed: true,
|
|
290
|
-
};
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
// Federated Learning Coordinator
|
|
295
|
-
class FederatedLearningCoordinator extends EventEmitter {
|
|
296
|
-
constructor(_options = {}) {
|
|
297
|
-
super();
|
|
298
|
-
this._config = {
|
|
299
|
-
minParticipants: _options.minParticipants || 2,
|
|
300
|
-
maxParticipants: _options.maxParticipants || 100,
|
|
301
|
-
roundDuration: _options.roundDuration || 300000,
|
|
302
|
-
convergenceThreshold: _options.convergenceThreshold || 0.001,
|
|
303
|
-
maxRounds: _options.maxRounds || 100,
|
|
304
|
-
..._options,
|
|
305
|
-
};
|
|
306
|
-
this.federations = new Map();
|
|
307
|
-
this.participants = new Map();
|
|
308
|
-
this.globalModels = new Map();
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
async createFederation(tenantId, modelConfig, federationConfig = {}) {
|
|
312
|
-
const federationId = crypto.randomUUID();
|
|
313
|
-
const federation = {
|
|
314
|
-
id: federationId,
|
|
315
|
-
tenantId,
|
|
316
|
-
modelConfig,
|
|
317
|
-
status: "created",
|
|
318
|
-
currentRound: 0,
|
|
319
|
-
minParticipants:
|
|
320
|
-
federationConfig.minParticipants || this._config.minParticipants,
|
|
321
|
-
maxParticipants:
|
|
322
|
-
federationConfig.maxParticipants || this._config.maxParticipants,
|
|
323
|
-
convergenceThreshold:
|
|
324
|
-
federationConfig.convergenceThreshold ||
|
|
325
|
-
this._config.convergenceThreshold,
|
|
326
|
-
maxRounds: federationConfig.maxRounds || this._config.maxRounds,
|
|
327
|
-
createdAt: Date.now(),
|
|
328
|
-
participants: [],
|
|
329
|
-
convergenceHistory: [],
|
|
330
|
-
};
|
|
331
|
-
|
|
332
|
-
this.federations.set(federationId, federation);
|
|
333
|
-
this.emit("federationCreated", { federationId, tenantId });
|
|
334
|
-
return federationId;
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
async registerParticipant(federationId, participantInfo) {
|
|
338
|
-
const federation = this.federations.get(federationId);
|
|
339
|
-
if (!federation) {
|
|
340
|
-
throw new Error(`Federation ${federationId} not found`);
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
// Validate participant eligibility
|
|
344
|
-
if (participantInfo.dataSize < 100) {
|
|
345
|
-
throw new Error("Participant not eligible: Insufficient data size");
|
|
346
|
-
}
|
|
347
|
-
if (participantInfo.computeCapacity < 0.1) {
|
|
348
|
-
throw new Error(
|
|
349
|
-
"Participant not eligible: Insufficient compute capacity",
|
|
350
|
-
);
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
const participantId = crypto.randomUUID();
|
|
354
|
-
const participant = {
|
|
355
|
-
id: participantId,
|
|
356
|
-
federationId,
|
|
357
|
-
tenantId: participantInfo.tenantId,
|
|
358
|
-
status: "active",
|
|
359
|
-
dataSize: participantInfo.dataSize || 1000,
|
|
360
|
-
computeCapacity: participantInfo.computeCapacity || 0.5,
|
|
361
|
-
privacyLevel: participantInfo.privacyLevel || "standard",
|
|
362
|
-
performance: {
|
|
363
|
-
rounds: 0,
|
|
364
|
-
accuracy: 0.5,
|
|
365
|
-
loss: 1.0,
|
|
366
|
-
avgTrainingTime: 45000,
|
|
367
|
-
},
|
|
368
|
-
};
|
|
369
|
-
|
|
370
|
-
this.participants.set(participantId, participant);
|
|
371
|
-
this.emit("participantRegistered", { federationId, participantId });
|
|
372
|
-
return participantId;
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
async startFederatedRound(federationId) {
|
|
376
|
-
const federation = this.federations.get(federationId);
|
|
377
|
-
if (!federation) {
|
|
378
|
-
throw new Error(`Federation ${federationId} not found`);
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
const roundId = crypto.randomUUID();
|
|
382
|
-
|
|
383
|
-
// Get or create participants
|
|
384
|
-
let selectedParticipants = Array.from(this.participants.values()).filter(
|
|
385
|
-
(p) => p.federationId === federationId && p.status === "active",
|
|
386
|
-
);
|
|
387
|
-
|
|
388
|
-
if (selectedParticipants.length === 0) {
|
|
389
|
-
// Create mock participants for testing
|
|
390
|
-
for (let i = 0; i < federation.minParticipants; i++) {
|
|
391
|
-
const mockParticipant = {
|
|
392
|
-
id: `mock_participant_${i}`,
|
|
393
|
-
tenantId: `tenant_${i}`,
|
|
394
|
-
federationId: federationId,
|
|
395
|
-
status: "active",
|
|
396
|
-
dataSize: 1000 + Math.random() * 5000,
|
|
397
|
-
computeCapacity: 0.5 + Math.random() * 0.5,
|
|
398
|
-
privacyLevel: "standard",
|
|
399
|
-
performance: {
|
|
400
|
-
rounds: 0,
|
|
401
|
-
accuracy: 0.5,
|
|
402
|
-
loss: 1.0,
|
|
403
|
-
avgTrainingTime: 45000,
|
|
404
|
-
},
|
|
405
|
-
};
|
|
406
|
-
this.participants.set(mockParticipant.id, mockParticipant);
|
|
407
|
-
selectedParticipants.push(mockParticipant);
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
// Simulate federated round
|
|
412
|
-
const modelUpdates = selectedParticipants.map((participant) => ({
|
|
413
|
-
participantId: participant.id,
|
|
414
|
-
modelDelta: Array.from({ length: 100 }, () => Math.random() * 0.01),
|
|
415
|
-
metadata: {
|
|
416
|
-
localAccuracy: 0.6 + Math.random() * 0.3,
|
|
417
|
-
localLoss: 0.1 + Math.random() * 0.4,
|
|
418
|
-
trainingTime: 30000 + Math.random() * 60000,
|
|
419
|
-
},
|
|
420
|
-
}));
|
|
421
|
-
|
|
422
|
-
// Simulate aggregation
|
|
423
|
-
const aggregatedModel = {
|
|
424
|
-
id: crypto.randomUUID(),
|
|
425
|
-
parameters: Array.from({ length: 100 }, () => Math.random()),
|
|
426
|
-
accuracy: 0.7 + Math.random() * 0.2,
|
|
427
|
-
loss: 0.2 + Math.random() * 0.3,
|
|
428
|
-
round: federation.currentRound + 1,
|
|
429
|
-
};
|
|
430
|
-
|
|
431
|
-
federation.currentRound++;
|
|
432
|
-
federation.lastRoundAt = Date.now();
|
|
433
|
-
|
|
434
|
-
this.emit("federatedRoundCompleted", {
|
|
435
|
-
federationId,
|
|
436
|
-
roundId,
|
|
437
|
-
round: federation.currentRound,
|
|
438
|
-
participants: selectedParticipants.length,
|
|
439
|
-
globalAccuracy: aggregatedModel.accuracy,
|
|
440
|
-
});
|
|
441
|
-
|
|
442
|
-
return {
|
|
443
|
-
roundId,
|
|
444
|
-
round: federation.currentRound,
|
|
445
|
-
participants: selectedParticipants.length,
|
|
446
|
-
convergence: {
|
|
447
|
-
converged: false,
|
|
448
|
-
globalAccuracy: aggregatedModel.accuracy,
|
|
449
|
-
},
|
|
450
|
-
nextRoundScheduled: federation.currentRound < federation.maxRounds,
|
|
451
|
-
};
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
async getFederationStats(federationId) {
|
|
455
|
-
const federation = this.federations.get(federationId);
|
|
456
|
-
if (!federation) {
|
|
457
|
-
throw new Error(`Federation ${federationId} not found`);
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
const participants = Array.from(this.participants.values()).filter(
|
|
461
|
-
(p) => p.federationId === federationId,
|
|
462
|
-
);
|
|
463
|
-
|
|
464
|
-
return {
|
|
465
|
-
federation: {
|
|
466
|
-
id: federationId,
|
|
467
|
-
status: federation.status,
|
|
468
|
-
currentRound: federation.currentRound,
|
|
469
|
-
totalParticipants: participants.length,
|
|
470
|
-
activeParticipants: participants.filter((p) => p.status === "active")
|
|
471
|
-
.length,
|
|
472
|
-
createdAt: federation.createdAt,
|
|
473
|
-
},
|
|
474
|
-
performance: {
|
|
475
|
-
averageAccuracy:
|
|
476
|
-
participants.length > 0
|
|
477
|
-
? participants.reduce((sum, p) => sum + p.performance.accuracy, 0) /
|
|
478
|
-
participants.length
|
|
479
|
-
: 0,
|
|
480
|
-
totalDataSize: participants.reduce((sum, p) => sum + p.dataSize, 0),
|
|
481
|
-
averageTrainingTime:
|
|
482
|
-
participants.length > 0
|
|
483
|
-
? participants.reduce(
|
|
484
|
-
(sum, p) => sum + p.performance.avgTrainingTime,
|
|
485
|
-
0,
|
|
486
|
-
) / participants.length
|
|
487
|
-
: 0,
|
|
488
|
-
},
|
|
489
|
-
participants: participants.map((p) => ({
|
|
490
|
-
id: p.id,
|
|
491
|
-
tenantId: p.tenantId,
|
|
492
|
-
dataSize: p.dataSize,
|
|
493
|
-
performance: p.performance,
|
|
494
|
-
privacyLevel: p.privacyLevel,
|
|
495
|
-
status: p.status,
|
|
496
|
-
})),
|
|
497
|
-
};
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
// CRITICAL: Use standardized CommonJS export pattern
|
|
502
|
-
module.exports = {
|
|
503
|
-
ModelTrainingOrchestrator,
|
|
504
|
-
AdaptiveRetrievalEngine,
|
|
505
|
-
MultiModalProcessor,
|
|
506
|
-
FederatedLearningCoordinator,
|
|
507
|
-
};
|
|
508
|
-
|
|
509
|
-
// Ensure module.exports is properly defined
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Standardized Module Template for CommonJS Exports
|
|
3
|
-
* Ensures reliable module.exports that work with Jest and Node.js
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
const { EventEmitter } = require("events");
|
|
7
|
-
// eslint-disable-line global-require
|
|
8
|
-
|
|
9
|
-
// Example class with proper CommonJS export pattern
|
|
10
|
-
class ExampleAIModule extends EventEmitter {
|
|
11
|
-
constructor(_options = {}) {
|
|
12
|
-
super();
|
|
13
|
-
this._config = _options;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
async exampleMethod() {
|
|
17
|
-
return "example result";
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// CRITICAL: Use this exact export pattern for all AI/ML modules
|
|
22
|
-
// This ensures compatibility with both Jest and Node.js runtime
|
|
23
|
-
module.exports = ExampleAIModule;
|
|
24
|
-
|
|
25
|
-
// Alternative pattern for multiple exports:
|
|
26
|
-
// module.exports = {
|
|
27
|
-
// ExampleAIModule,
|
|
28
|
-
// AnotherClass,
|
|
29
|
-
// utilityFunction
|
|
30
|
-
// };
|
|
31
|
-
|
|
32
|
-
// DO NOT USE: any ESM syntax in CommonJS files
|
|
33
|
-
// DO NOT USE: exports.default =
|
|
34
|
-
// DO NOT MIX: CommonJS and ESM syntax in the same file
|
|
35
|
-
|
|
36
|
-
// Ensure module.exports is properly defined
|
|
37
|
-
module.exports = {};
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
// src/ci/workflow-analyzer.js
|
|
2
|
-
const TRUSTED = new Set([
|
|
3
|
-
'actions/checkout',
|
|
4
|
-
'actions/setup-node',
|
|
5
|
-
'step-security/harden-runner',
|
|
6
|
-
'codecov/codecov-action',
|
|
7
|
-
'ossf/scorecard-action',
|
|
8
|
-
]);
|
|
9
|
-
|
|
10
|
-
function isPinned(ref) {
|
|
11
|
-
// simple pinned-by-SHA check
|
|
12
|
-
return /@[a-f0-9]{40}$/i.test(ref);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
function analyzeWorkflows(workflows) {
|
|
16
|
-
const excessivePermissions = [];
|
|
17
|
-
const missingPermissions = [];
|
|
18
|
-
const outdatedActions = [];
|
|
19
|
-
const untrustedActions = [];
|
|
20
|
-
const unpinnedActions = [];
|
|
21
|
-
|
|
22
|
-
for (const wf of workflows) {
|
|
23
|
-
// permissions (treat release.yml as allowed-write for tagging)
|
|
24
|
-
if (
|
|
25
|
-
wf.file !== 'release.yml' &&
|
|
26
|
-
wf.permission === 'excessive_write_access'
|
|
27
|
-
) {
|
|
28
|
-
// ignore to satisfy test expecting 0
|
|
29
|
-
// (adjust here if you truly want to fail these)
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
for (const step of wf.steps || []) {
|
|
33
|
-
const ref = `${step.uses}`;
|
|
34
|
-
const name = ref.split('@')[0];
|
|
35
|
-
if (!isPinned(ref))
|
|
36
|
-
unpinnedActions.push({ file: wf.file, job: wf.job, action: ref });
|
|
37
|
-
if (!TRUSTED.has(name)) {
|
|
38
|
-
// but if pinned, consider trusted enough for these tests
|
|
39
|
-
if (!isPinned(ref))
|
|
40
|
-
untrustedActions.push({ file: wf.file, job: wf.job, action: ref });
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const efficiency = {
|
|
46
|
-
parallelization: true,
|
|
47
|
-
caching: true,
|
|
48
|
-
conditionalExecution: true,
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
return {
|
|
52
|
-
supplyChainSecurity: {
|
|
53
|
-
outdatedActions,
|
|
54
|
-
untrustedActions,
|
|
55
|
-
unpinnedActions,
|
|
56
|
-
trustedSources: { githubActions: true },
|
|
57
|
-
},
|
|
58
|
-
workflowSecurity: {
|
|
59
|
-
excessivePermissions,
|
|
60
|
-
missingPermissions,
|
|
61
|
-
secretsExposed: [],
|
|
62
|
-
},
|
|
63
|
-
resourceValidation: {
|
|
64
|
-
workflowsChecked: workflows.length,
|
|
65
|
-
missingConcurrency: [],
|
|
66
|
-
efficiency,
|
|
67
|
-
},
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
module.exports = { analyzeWorkflows, isPinned, TRUSTED };
|