@devilsdev/rag-pipeline-utils 2.3.0 → 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.
Files changed (160) hide show
  1. package/README.md +293 -361
  2. package/contracts/loader-contract.json +11 -6
  3. package/contracts/reranker-contract.json +18 -26
  4. package/dist/index.cjs +21190 -47
  5. package/dist/index.d.ts +298 -68
  6. package/dist/index.mjs +9 -76
  7. package/package.json +20 -8
  8. package/src/agentic/agentic-pipeline.js +235 -0
  9. package/src/agentic/iterative-retriever.js +213 -0
  10. package/src/agentic/query-planner.js +208 -0
  11. package/src/agentic/self-critique.js +102 -0
  12. package/src/ai/adaptive-retrieval.js +0 -3
  13. package/src/ai/federated-learning.js +0 -3
  14. package/src/ai/federation.js +1 -6
  15. package/src/ai/index.js +9 -20
  16. package/src/ai/model-training.js +0 -3
  17. package/src/ai/multimodal-processing.js +0 -3
  18. package/src/ai/multimodal.js +1 -6
  19. package/src/ai/orchestrator.js +1 -6
  20. package/src/ai/retrieval-engine.js +1 -6
  21. package/src/chunking/chunking-engine.js +142 -0
  22. package/src/chunking/strategies/fixed-size.js +54 -0
  23. package/src/chunking/strategies/recursive.js +127 -0
  24. package/src/chunking/strategies/semantic.js +128 -0
  25. package/src/chunking/strategies/sentence.js +32 -0
  26. package/src/chunking/strategies/structure-aware.js +138 -0
  27. package/src/citation/citation-tracker.js +161 -0
  28. package/src/citation/hallucination-detector.js +74 -0
  29. package/src/citation/source-mapper.js +95 -0
  30. package/src/cli/commands/ai-ml/adaptive-commands.js +178 -0
  31. package/src/cli/commands/ai-ml/federated-commands.js +207 -0
  32. package/src/cli/commands/ai-ml/index.js +17 -0
  33. package/src/cli/commands/ai-ml/multimodal-commands.js +187 -0
  34. package/src/cli/commands/ai-ml/shared.js +51 -0
  35. package/src/cli/commands/ai-ml/training-commands.js +228 -0
  36. package/src/cli/commands/ai-ml.js +176 -757
  37. package/src/cli/commands/plugin-hub/certification-commands.js +221 -0
  38. package/src/cli/commands/plugin-hub/event-handlers.js +64 -0
  39. package/src/cli/commands/plugin-hub/hub-commands.js +290 -0
  40. package/src/cli/commands/plugin-hub/review-commands.js +78 -0
  41. package/src/cli/commands/plugin-hub.js +106 -782
  42. package/src/cli/diagnostics/config-checker.js +81 -0
  43. package/src/cli/diagnostics/dependency-checker.js +69 -0
  44. package/src/cli/diagnostics/environment-checker.js +45 -0
  45. package/src/cli/diagnostics/performance-checker.js +51 -0
  46. package/src/cli/diagnostics/plugin-checker.js +106 -0
  47. package/src/cli/diagnostics/security-checker.js +61 -0
  48. package/src/cli/doctor-command.js +70 -369
  49. package/src/cli/enhanced-cli-commands.js +162 -706
  50. package/src/cli/handlers/config-handler.js +126 -0
  51. package/src/cli/handlers/diagnostics-handler.js +113 -0
  52. package/src/cli/handlers/ingest-handler.js +42 -0
  53. package/src/cli/handlers/init-handler.js +51 -0
  54. package/src/cli/handlers/query-handler.js +45 -0
  55. package/src/cli/handlers/run-handler.js +181 -0
  56. package/src/cli/interactive-wizard.js +99 -723
  57. package/src/cli/shared/cli-utils.js +89 -0
  58. package/src/cli/wizard/configuration.js +148 -0
  59. package/src/cli/wizard/observability.js +79 -0
  60. package/src/cli/wizard/performance.js +76 -0
  61. package/src/cli/wizard/plugin-selection.js +297 -0
  62. package/src/cli/wizard/preview-save.js +172 -0
  63. package/src/cli/wizard/project-setup.js +66 -0
  64. package/src/config/memory-optimization.js +3 -3
  65. package/src/connectors/anthropic-connector.js +179 -0
  66. package/src/connectors/base-connector.js +94 -0
  67. package/src/connectors/cohere-connector.js +143 -0
  68. package/src/connectors/local-embedder.js +171 -0
  69. package/src/connectors/memory-retriever.js +150 -0
  70. package/src/connectors/ollama-connector.js +205 -0
  71. package/src/connectors/openai-connector.js +173 -0
  72. package/src/core/create-pipeline.js +21 -1
  73. package/src/core/observability/tracing.js +2 -1
  74. package/src/core/pipeline-factory.js +0 -1
  75. package/src/core/plugin-registry.js +14 -14
  76. package/src/cost/cost-calculator.js +146 -0
  77. package/src/cost/cost-tracker.js +260 -0
  78. package/src/cost/token-budget.js +245 -0
  79. package/src/dag/core/execution-scheduler.js +2 -1
  80. package/src/dag/core/topology-validation.js +0 -3
  81. package/src/dag/dag-engine.js +3 -5
  82. package/src/dag/dag-node.js +0 -1
  83. package/src/dag/enhanced-dag-engine.js +171 -99
  84. package/src/dashboard/dashboard-generator.js +642 -0
  85. package/src/dashboard/metrics-aggregator.js +409 -0
  86. package/src/debug/execution-tracer.js +210 -0
  87. package/src/debug/trace-inspector.js +281 -0
  88. package/src/dev/dev-server.js +5 -5
  89. package/src/dev/hot-reload.js +3 -2
  90. package/src/dx/integration-templates.js +0 -3
  91. package/src/ecosystem/plugin-analytics-dashboard.js +2 -2
  92. package/src/ecosystem/plugin-hub.js +2 -2
  93. package/src/enterprise/audit-logging.js +2 -2
  94. package/src/enterprise/sso-integration.js +52 -32
  95. package/src/evaluate/context-metrics.js +127 -0
  96. package/src/evaluate/evaluator.js +4 -2
  97. package/src/evaluate/faithfulness.js +117 -0
  98. package/src/evaluate/groundedness.js +60 -0
  99. package/src/evaluate/pipeline-evaluator.js +156 -0
  100. package/src/evaluate/relevance.js +129 -0
  101. package/src/evaluate/scoring.js +27 -0
  102. package/src/graph/entity-extractor.js +183 -0
  103. package/src/graph/graph-index.js +113 -0
  104. package/src/graph/graph-retriever.js +244 -0
  105. package/src/graph/knowledge-graph.js +256 -0
  106. package/src/guardrails/guardrails-pipeline.js +136 -0
  107. package/src/guardrails/post-generation-guard.js +170 -0
  108. package/src/guardrails/pre-retrieval-guard.js +161 -0
  109. package/src/guardrails/retrieval-guard.js +126 -0
  110. package/src/index.js +255 -9
  111. package/src/loader/html-loader.js +4 -15
  112. package/src/loader/markdown-loader.js +4 -15
  113. package/src/mcp/mcp-server.js +199 -0
  114. package/src/mcp/mcp-tool-builder.js +121 -0
  115. package/src/observability/audit-logger.js +0 -2
  116. package/src/observability/event-logger.js +2 -1
  117. package/src/observability/security-monitor.js +0 -2
  118. package/src/observability/telemetry.js +0 -2
  119. package/src/reranker/cascade-reranker.js +79 -0
  120. package/src/reranker/embedding-reranker.js +124 -0
  121. package/src/reranker/llm-reranker.js +6 -3
  122. package/src/reranker/scoring-reranker.js +123 -0
  123. package/src/retrieval/bm25-search.js +157 -0
  124. package/src/retrieval/hybrid-retriever.js +111 -0
  125. package/src/retrieval/rank-fusion.js +62 -0
  126. package/src/security/jwt-config.js +4 -3
  127. package/src/security/jwt-validator.js +2 -1
  128. package/src/security/plugin-sandbox.js +0 -3
  129. package/src/security/plugin-signature-verifier.js +4 -6
  130. package/src/security/validator.js +0 -2
  131. package/src/streaming/embedding-stream.js +197 -0
  132. package/src/streaming/sse-adapter.js +168 -0
  133. package/src/streaming/stream-router.js +210 -0
  134. package/src/streaming/streaming-embedder.js +231 -0
  135. package/src/streaming/websocket-adapter.js +171 -0
  136. package/src/templates/scaffold.js +147 -0
  137. package/src/templates/template-registry.js +272 -0
  138. package/src/utils/contract-validator.js +2 -1
  139. package/src/utils/input-sanitizer.js +80 -99
  140. package/src/utils/performance-monitor.js +0 -3
  141. package/src/utils/plugin-scaffolder.js +9 -16
  142. package/src/utils/rate-limiter.js +0 -1
  143. package/src/utils/retry-policy.js +0 -3
  144. package/src/utils/safe-expression-evaluator.js +0 -3
  145. package/src/utils/secure-logger-config.js +2 -4
  146. package/src/utils/secure-logging.js +0 -3
  147. package/src/utils/structured-logger.js +0 -3
  148. package/src/ai/index-fixed.js +0 -509
  149. package/src/ai/module-template.js +0 -37
  150. package/src/ci/workflow-analyzer.js +0 -71
  151. package/src/cli/plugin-marketplace-commands.js +0 -869
  152. package/src/dev/README.md +0 -126
  153. package/src/dev/examples/hot-reload-usage.js +0 -355
  154. package/src/mocks/openai-embedder.js +0 -119
  155. package/src/mocks/openai-llm.js +0 -77
  156. package/src/mocks/pdf-loader.js +0 -21
  157. package/src/mocks/pinecone-retriever.js +0 -106
  158. package/src/scripts/script-utilities.js +0 -36
  159. package/src/utils/ci/diagnostic-reporter.js +0 -57
  160. package/src/utils/examples/error-formatter-usage.js +0 -351
@@ -438,6 +438,3 @@ module.exports = {
438
438
  aggressivePolicy,
439
439
  conservativePolicy,
440
440
  };
441
-
442
- // CommonJS/ESM interop
443
- module.exports.default = module.exports;
@@ -574,6 +574,3 @@ module.exports = {
574
574
  createSafeEvaluator,
575
575
  evaluateExpression,
576
576
  };
577
-
578
- // CommonJS/ESM interop
579
- module.exports.default = module.exports;
@@ -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
- console.warn(
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
  }
@@ -333,6 +333,3 @@ module.exports = {
333
333
  SECRET_PATTERNS,
334
334
  REDACTED,
335
335
  };
336
-
337
- // CommonJS/ESM interop
338
- module.exports.default = module.exports;
@@ -383,6 +383,3 @@ module.exports = {
383
383
  logger: defaultLogger,
384
384
  withCorrelation: defaultLogger.withCorrelation.bind(defaultLogger),
385
385
  };
386
-
387
- // CommonJS/ESM interop
388
- module.exports.default = module.exports;
@@ -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 };