@devilsdev/rag-pipeline-utils 2.4.5 → 2.5.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 +83 -192
- package/CHANGELOG.md +345 -0
- package/README.md +418 -117
- package/SECURITY.md +5 -5
- package/dist/experimental.cjs +2 -0
- package/dist/experimental.d.ts +1 -0
- package/dist/experimental.mjs +5 -0
- package/dist/index.cjs +4992 -1242
- package/dist/index.d.ts +80 -2
- package/dist/index.mjs +1 -1
- package/dist/types/agentic/agentic-pipeline.d.ts +103 -0
- package/dist/types/agentic/iterative-retriever.d.ts +85 -0
- package/dist/types/agentic/query-planner.d.ts +145 -0
- package/dist/types/agentic/self-critique.d.ts +45 -0
- package/dist/types/ai/adaptive-retrieval.d.ts +44 -0
- package/dist/types/ai/federation/federated-learning-coordinator.d.ts +62 -0
- package/dist/types/ai/multimodal-processing.d.ts +32 -0
- package/dist/types/ai/multimodal.d.ts +39 -0
- package/dist/types/ai/retrieval-engine.d.ts +37 -0
- package/dist/types/ai/training/model-training-orchestrator.d.ts +31 -0
- package/dist/types/chunking/chunking-engine.d.ts +70 -0
- package/dist/types/chunking/strategies/fixed-size.d.ts +17 -0
- package/dist/types/chunking/strategies/recursive.d.ts +20 -0
- package/dist/types/chunking/strategies/semantic.d.ts +19 -0
- package/dist/types/chunking/strategies/sentence.d.ts +13 -0
- package/dist/types/chunking/strategies/structure-aware.d.ts +19 -0
- package/dist/types/citation/citation-tracker.d.ts +64 -0
- package/dist/types/citation/hallucination-detector.d.ts +40 -0
- package/dist/types/citation/source-mapper.d.ts +37 -0
- package/dist/types/connectors/anthropic-connector.d.ts +92 -0
- package/dist/types/connectors/base-connector.d.ts +87 -0
- package/dist/types/connectors/cohere-connector.d.ts +89 -0
- package/dist/types/connectors/connector-utils.d.ts +110 -0
- package/dist/types/connectors/local-embedder.d.ts +86 -0
- package/dist/types/connectors/memory-retriever.d.ts +91 -0
- package/dist/types/connectors/ollama-connector.d.ts +110 -0
- package/dist/types/connectors/openai-connector.d.ts +114 -0
- package/dist/types/connectors/rag-prompt.d.ts +40 -0
- package/dist/types/cost/cost-calculator.d.ts +152 -0
- package/dist/types/cost/cost-tracker.d.ts +126 -0
- package/dist/types/cost/token-budget.d.ts +110 -0
- package/dist/types/dag/core/error-context.d.ts +239 -0
- package/dist/types/dag/core/execution-scheduler.d.ts +191 -0
- package/dist/types/dag/core/topology-validation.d.ts +226 -0
- package/dist/types/dag/dag-engine.d.ts +156 -0
- package/dist/types/dag/dag-node.d.ts +37 -0
- package/dist/types/dashboard/dashboard-generator.d.ts +127 -0
- package/dist/types/dashboard/metrics-aggregator.d.ts +218 -0
- package/dist/types/debug/execution-tracer.d.ts +57 -0
- package/dist/types/debug/trace-inspector.d.ts +31 -0
- package/dist/types/ecosystem/plugin-certification.d.ts +169 -0
- package/dist/types/enterprise/data-governance.d.ts +203 -0
- package/dist/types/enterprise/multi-tenancy.d.ts +137 -0
- package/dist/types/enterprise/sso-integration.d.ts +420 -0
- package/dist/types/evaluate/context-metrics.d.ts +55 -0
- package/dist/types/evaluate/faithfulness.d.ts +41 -0
- package/dist/types/evaluate/groundedness.d.ts +60 -0
- package/dist/types/evaluate/pipeline-evaluator.d.ts +88 -0
- package/dist/types/evaluate/relevance.d.ts +21 -0
- package/dist/types/evaluate/scoring.d.ts +123 -0
- package/dist/types/experimental.d.ts +15 -0
- package/dist/types/graph/entity-extractor.d.ts +84 -0
- package/dist/types/graph/graph-index.d.ts +49 -0
- package/dist/types/graph/graph-retriever.d.ts +81 -0
- package/dist/types/graph/knowledge-graph.d.ts +129 -0
- package/dist/types/guardrails/guardrails-pipeline.d.ts +63 -0
- package/dist/types/guardrails/injection-detector.d.ts +47 -0
- package/dist/types/guardrails/post-generation-guard.d.ts +61 -0
- package/dist/types/guardrails/pre-retrieval-guard.d.ts +64 -0
- package/dist/types/guardrails/retrieval-guard.d.ts +57 -0
- package/dist/types/mcp/mcp-server.d.ts +85 -0
- package/dist/types/mcp/mcp-tool-builder.d.ts +55 -0
- package/dist/types/reranker/cascade-reranker.d.ts +40 -0
- package/dist/types/reranker/embedding-reranker.d.ts +77 -0
- package/dist/types/reranker/scoring-reranker.d.ts +41 -0
- package/dist/types/retrieval/bm25-search.d.ts +43 -0
- package/dist/types/retrieval/file-vector-store.d.ts +87 -0
- package/dist/types/retrieval/hybrid-retriever.d.ts +35 -0
- package/dist/types/retrieval/rank-fusion.d.ts +10 -0
- package/dist/types/security/jwt-config.d.ts +80 -0
- package/dist/types/security/jwt-validator.d.ts +195 -0
- package/dist/types/security/plugin-sandbox.d.ts +158 -0
- package/dist/types/security/plugin-signature-verifier.d.ts +139 -0
- package/dist/types/security/validator.d.ts +5 -0
- package/dist/types/streaming/embedding-stream.d.ts +65 -0
- package/dist/types/streaming/sse-adapter.d.ts +59 -0
- package/dist/types/streaming/stream-router.d.ts +88 -0
- package/dist/types/streaming/streaming-embedder.d.ts +99 -0
- package/dist/types/streaming/websocket-adapter.d.ts +71 -0
- package/dist/types/templates/scaffold.d.ts +55 -0
- package/dist/types/templates/template-registry.d.ts +63 -0
- package/dist/types/utils/embed-query.d.ts +20 -0
- package/dist/types/utils/logger.d.ts +50 -0
- package/dist/types/utils/rate-limiter.d.ts +66 -0
- package/dist/types/utils/retry.d.ts +27 -0
- package/dist/types/utils/run-abort.d.ts +34 -0
- package/dist/types/utils/secure-logging.d.ts +51 -0
- package/dist/types/utils/structured-logger.d.ts +126 -0
- package/package.json +53 -29
- package/src/agentic/agentic-pipeline.js +75 -7
- package/src/agentic/iterative-retriever.js +47 -10
- package/src/agentic/query-planner.js +329 -78
- package/src/citation/citation-tracker.js +6 -4
- package/src/citation/hallucination-detector.js +2 -2
- package/src/citation/source-mapper.js +15 -28
- package/src/cli/commands/ai.js +101 -0
- package/src/cli/commands/plugin-hub/event-handlers.js +6 -0
- package/src/cli/commands/plugin-hub/hub-commands.js +0 -74
- package/src/cli/commands/plugin-hub/local-commands.js +143 -0
- package/src/cli/commands/plugin-hub.js +96 -36
- package/src/cli/diagnostics/config-checker.js +76 -63
- package/src/cli/diagnostics/environment-checker.js +62 -31
- package/src/cli/diagnostics/plugin-checker.js +36 -89
- package/src/cli/doctor-command.js +39 -5
- package/src/cli/enhanced-cli-commands.js +72 -217
- package/src/cli/handlers/ai-handler.js +364 -0
- package/src/cli/handlers/diagnostics-handler.js +78 -31
- package/src/cli/handlers/ingest-handler.js +28 -22
- package/src/cli/handlers/init-handler.js +148 -25
- package/src/cli/handlers/query-handler.js +41 -26
- package/src/cli/handlers/run-handler.js +16 -167
- package/src/cli/handlers/serve-handler.js +60 -0
- package/src/cli/services/bench-stats.js +54 -0
- package/src/cli/services/benchmark.js +161 -0
- package/src/cli/services/feedback.js +155 -0
- package/src/cli/services/rag-service.js +322 -0
- package/src/cli/shared/cli-utils.js +24 -7
- package/src/cli/shared/config-context.js +21 -0
- package/src/cli/wizard/config-builder.js +81 -0
- package/src/cli/wizard/init-wizard.js +617 -0
- package/src/config/component-factory.js +125 -0
- package/src/config/load-config.js +29 -10
- package/src/config/load-plugin-config.js +46 -2
- package/src/connectors/anthropic-connector.js +93 -55
- package/src/connectors/base-connector.js +74 -19
- package/src/connectors/cohere-connector.js +88 -32
- package/src/connectors/connector-utils.js +302 -0
- package/src/connectors/local-embedder.js +43 -5
- package/src/connectors/memory-retriever.js +108 -15
- package/src/connectors/ollama-connector.js +83 -49
- package/src/connectors/openai-connector.js +108 -44
- package/src/connectors/rag-prompt.js +88 -0
- package/src/core/create-pipeline.js +209 -60
- package/src/core/plugin-registry.js +87 -11
- package/src/cost/cost-calculator.js +205 -32
- package/src/dev/dev-server.js +166 -11
- package/src/dev/hot-reload.js +40 -1
- package/src/ecosystem/plugin-checks.js +181 -0
- package/src/ecosystem/plugin-hub.js +50 -125
- package/src/ecosystem/plugin-installer.js +298 -0
- package/src/ecosystem/plugin-probe.js +127 -0
- package/src/ecosystem/plugin-scanner.js +185 -0
- package/src/ecosystem/tar-extract.js +114 -0
- package/src/enterprise/audit-logging.js +158 -29
- package/src/enterprise/sso-integration.js +715 -228
- package/src/evaluate/context-metrics.js +28 -16
- package/src/evaluate/evaluator.js +3 -3
- package/src/evaluate/faithfulness.js +18 -14
- package/src/evaluate/groundedness.js +43 -12
- package/src/evaluate/pipeline-evaluator.js +35 -8
- package/src/evaluate/scoring.js +251 -3
- package/src/experimental.js +71 -0
- package/src/guardrails/guardrails-pipeline.js +69 -7
- package/src/guardrails/injection-detector.js +283 -0
- package/src/guardrails/post-generation-guard.js +19 -0
- package/src/guardrails/pre-retrieval-guard.js +36 -36
- package/src/guardrails/retrieval-guard.js +58 -8
- package/src/index.js +36 -1
- package/src/loader/document-reader.js +91 -0
- package/src/reranker/cascade-reranker.js +3 -0
- package/src/reranker/embedding-reranker.js +136 -21
- package/src/reranker/llm-reranker.js +79 -12
- package/src/reranker/scoring-reranker.js +3 -0
- package/src/retrieval/bm25-search.js +12 -6
- package/src/retrieval/file-vector-store.js +212 -0
- package/src/retrieval/hybrid-retriever.js +22 -19
- package/src/security/jwt-config.js +13 -2
- package/src/security/jwt-validator.js +134 -30
- package/src/security/plugin-sandbox.js +18 -1
- package/src/security/plugin-signature-verifier.js +245 -70
- package/src/utils/deprecate.js +69 -0
- package/src/utils/embed-query.js +33 -0
- package/src/utils/input-sanitizer.js +19 -4
- package/src/utils/logger.js +34 -4
- package/src/utils/run-abort.js +102 -0
- package/src/ai/federated-learning.js +0 -211
- package/src/ai/federation.js +0 -71
- package/src/ai/index.js +0 -22
- package/src/ai/model-trainer.js +0 -217
- package/src/ai/model-training.js +0 -202
- package/src/ai/multimodal/multi-modal-processor.js +0 -345
- package/src/ai/orchestrator.js +0 -65
- package/src/ai/retrieval/adaptive-retrieval-engine.js +0 -398
- package/src/cli/commands/ai-ml/adaptive-commands.js +0 -178
- package/src/cli/commands/ai-ml/federated-commands.js +0 -207
- package/src/cli/commands/ai-ml/index.js +0 -17
- package/src/cli/commands/ai-ml/multimodal-commands.js +0 -187
- package/src/cli/commands/ai-ml/shared.js +0 -51
- package/src/cli/commands/ai-ml/training-commands.js +0 -228
- package/src/cli/commands/ai-ml.js +0 -386
- package/src/cli/commands/docs.js +0 -228
- package/src/cli/commands/dx.js +0 -538
- package/src/cli/commands/wizard.js +0 -627
- package/src/cli/input-sanitization-middleware.js +0 -356
- package/src/cli/interactive-wizard.js +0 -373
- package/src/cli/templates/development.template.json +0 -64
- package/src/cli/templates/minimal.template.json +0 -33
- package/src/cli/templates/production.template.json +0 -104
- package/src/cli/templates/testing.template.json +0 -45
- package/src/cli/wizard/configuration.js +0 -148
- package/src/cli/wizard/observability.js +0 -79
- package/src/cli/wizard/performance.js +0 -76
- package/src/cli/wizard/plugin-selection.js +0 -297
- package/src/cli/wizard/preview-save.js +0 -172
- package/src/cli/wizard/project-setup.js +0 -66
- package/src/core/pipeline-factory.js +0 -59
- package/src/dag/enhanced-dag-engine.js +0 -894
- package/src/dx/index.js +0 -40
- package/src/dx/integration-templates.js +0 -662
- package/src/dx/performance-profiler.js +0 -968
- package/src/dx/realtime-debugger.js +0 -755
- package/src/dx/visual-pipeline-builder.js +0 -578
- package/src/ingest.js +0 -59
- package/src/pipeline/pipeline.js +0 -18
- package/src/query.js +0 -117
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/** Message used for a run that exceeded its timeout. */
|
|
4
|
+
const TIMEOUT_MESSAGE = 'Execution timeout';
|
|
5
|
+
/** Message used for a run cancelled through the caller's AbortSignal. */
|
|
6
|
+
const ABORTED_MESSAGE = 'Execution aborted';
|
|
7
|
+
|
|
8
|
+
function timeoutError() {
|
|
9
|
+
const err = new Error(TIMEOUT_MESSAGE);
|
|
10
|
+
err.name = 'TimeoutError';
|
|
11
|
+
err.code = 'ETIMEDOUT';
|
|
12
|
+
return err;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function callerAbortError(signal) {
|
|
16
|
+
const err = new Error(ABORTED_MESSAGE);
|
|
17
|
+
err.name = 'AbortError';
|
|
18
|
+
err.code = 'ABORT_ERR';
|
|
19
|
+
if (signal && signal.reason !== undefined) err.cause = signal.reason;
|
|
20
|
+
return err;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Per-run cancellation: one AbortController that is aborted when `timeout`
|
|
25
|
+
* elapses or when the caller's `signal` aborts. Its `signal` is handed to
|
|
26
|
+
* every component call; `race()` makes the run settle as soon as it is
|
|
27
|
+
* aborted even if a component ignores the signal; `throwIfAborted()` stops
|
|
28
|
+
* work between stages.
|
|
29
|
+
*
|
|
30
|
+
* @param {object} [options]
|
|
31
|
+
* @param {number} [options.timeout] - Milliseconds before the run is aborted
|
|
32
|
+
* @param {AbortSignal} [options.signal] - Caller's signal to follow
|
|
33
|
+
* @returns {{
|
|
34
|
+
* signal: AbortSignal,
|
|
35
|
+
* race: (promise: Promise<any>) => Promise<any>,
|
|
36
|
+
* throwIfAborted: () => void,
|
|
37
|
+
* clearTimer: () => void,
|
|
38
|
+
* detach: () => void,
|
|
39
|
+
* cleanup: () => void
|
|
40
|
+
* }}
|
|
41
|
+
*/
|
|
42
|
+
function createRunAbort({ timeout, signal } = {}) {
|
|
43
|
+
const controller = new AbortController();
|
|
44
|
+
let timer = null;
|
|
45
|
+
let onCallerAbort = null;
|
|
46
|
+
let rejectAborted;
|
|
47
|
+
const aborted = new Promise((_, reject) => {
|
|
48
|
+
rejectAborted = reject;
|
|
49
|
+
});
|
|
50
|
+
// The rejection is observed through race(); never report it as unhandled.
|
|
51
|
+
aborted.catch(() => {});
|
|
52
|
+
|
|
53
|
+
const abort = (error) => {
|
|
54
|
+
if (controller.signal.aborted) return;
|
|
55
|
+
controller.abort(error);
|
|
56
|
+
rejectAborted(error);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
if (typeof timeout === 'number' && timeout > 0) {
|
|
60
|
+
timer = setTimeout(() => abort(timeoutError()), timeout);
|
|
61
|
+
}
|
|
62
|
+
if (signal && typeof signal.addEventListener === 'function') {
|
|
63
|
+
if (signal.aborted) {
|
|
64
|
+
abort(callerAbortError(signal));
|
|
65
|
+
} else {
|
|
66
|
+
onCallerAbort = () => abort(callerAbortError(signal));
|
|
67
|
+
signal.addEventListener('abort', onCallerAbort, { once: true });
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const clearTimer = () => {
|
|
72
|
+
if (timer) clearTimeout(timer);
|
|
73
|
+
timer = null;
|
|
74
|
+
};
|
|
75
|
+
const detach = () => {
|
|
76
|
+
if (onCallerAbort) signal.removeEventListener('abort', onCallerAbort);
|
|
77
|
+
onCallerAbort = null;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
return {
|
|
81
|
+
signal: controller.signal,
|
|
82
|
+
race(promise) {
|
|
83
|
+
if (controller.signal.aborted) {
|
|
84
|
+
// Swallow the late outcome of work that is no longer awaited.
|
|
85
|
+
Promise.resolve(promise).catch(() => {});
|
|
86
|
+
return Promise.reject(controller.signal.reason);
|
|
87
|
+
}
|
|
88
|
+
return Promise.race([promise, aborted]);
|
|
89
|
+
},
|
|
90
|
+
throwIfAborted() {
|
|
91
|
+
if (controller.signal.aborted) throw controller.signal.reason;
|
|
92
|
+
},
|
|
93
|
+
clearTimer,
|
|
94
|
+
detach,
|
|
95
|
+
cleanup() {
|
|
96
|
+
clearTimer();
|
|
97
|
+
detach();
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
module.exports = { createRunAbort, TIMEOUT_MESSAGE, ABORTED_MESSAGE };
|
|
@@ -1,211 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Federated Learning Coordinator
|
|
3
|
-
* Event-driven federated learning with deterministic aggregation
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
"use strict";
|
|
7
|
-
|
|
8
|
-
const { EventEmitter } = require("events");
|
|
9
|
-
|
|
10
|
-
// In-memory storage for federations
|
|
11
|
-
const federations = new Map();
|
|
12
|
-
let federationCounter = 0;
|
|
13
|
-
|
|
14
|
-
// Create EventEmitter instance
|
|
15
|
-
const eventEmitter = new EventEmitter();
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Create a new federation
|
|
19
|
-
* @param {string} tenantId - Tenant identifier
|
|
20
|
-
* @param {object} modelConfig - Model configuration
|
|
21
|
-
* @param {object} options - Federation options
|
|
22
|
-
* @returns {string} Federation ID
|
|
23
|
-
*/
|
|
24
|
-
function createFederation(tenantId, modelConfig, options = {}) {
|
|
25
|
-
const federationId = `fed-${++federationCounter}`;
|
|
26
|
-
const federation = {
|
|
27
|
-
tenantId,
|
|
28
|
-
modelConfig,
|
|
29
|
-
options,
|
|
30
|
-
rounds: 0,
|
|
31
|
-
participants: [],
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
federations.set(federationId, federation);
|
|
35
|
-
return federationId;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Register multiple participants in a federation
|
|
40
|
-
* @param {string} federationId - Federation ID
|
|
41
|
-
* @param {array} participantsArray - Participants to register
|
|
42
|
-
* @returns {Promise<string|array>} Single string ID if one participant, array of IDs if multiple
|
|
43
|
-
*/
|
|
44
|
-
async function registerParticipants(federationId, participantsArray) {
|
|
45
|
-
const federation = federations.get(federationId);
|
|
46
|
-
if (!federation) {
|
|
47
|
-
throw new Error(`Federation ${federationId} not found`);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const participantIds = [];
|
|
51
|
-
for (const participant of participantsArray) {
|
|
52
|
-
// Validate participant - throw error if invalid
|
|
53
|
-
if (!participant || typeof participant !== "object") {
|
|
54
|
-
throw new Error("Participant not eligible");
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// Check data size requirement
|
|
58
|
-
if (
|
|
59
|
-
typeof participant.dataSize === "number" &&
|
|
60
|
-
participant.dataSize < 100
|
|
61
|
-
) {
|
|
62
|
-
throw new Error("Participant not eligible");
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const participantId =
|
|
66
|
-
participant.id || `p-${federation.participants.length + 1}`;
|
|
67
|
-
federation.participants.push({
|
|
68
|
-
id: participantId,
|
|
69
|
-
status: "active",
|
|
70
|
-
weight: participant.weight || 1,
|
|
71
|
-
...participant,
|
|
72
|
-
});
|
|
73
|
-
participantIds.push(participantId);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// Return single string if only one participant, array if multiple (for test compatibility)
|
|
77
|
-
return participantsArray.length === 1 ? participantIds[0] : participantIds;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Conduct a federated learning round
|
|
82
|
-
* @param {string} federationId - Federation ID
|
|
83
|
-
* @returns {object} Round result
|
|
84
|
-
*/
|
|
85
|
-
function conductRound(federationId) {
|
|
86
|
-
const federation = federations.get(federationId);
|
|
87
|
-
if (!federation) {
|
|
88
|
-
throw new Error(`Federation ${federationId} not found`);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
const round = ++federation.rounds;
|
|
92
|
-
const roundId = `r-${Date.now()}`;
|
|
93
|
-
|
|
94
|
-
// Emit round started event
|
|
95
|
-
eventEmitter.emit("federated_round_started", {
|
|
96
|
-
federationId,
|
|
97
|
-
round,
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
// Compute deterministic convergence metrics
|
|
101
|
-
const participants = federation.participants;
|
|
102
|
-
const globalAccuracy = 0.9 + participants.length * 0.01; // Slight improvement with more participants
|
|
103
|
-
const loss = Math.max(0.1 - participants.length * 0.005, 0.01); // Lower loss with more participants
|
|
104
|
-
|
|
105
|
-
// Emit round completed event
|
|
106
|
-
eventEmitter.emit("federated_round_completed", {
|
|
107
|
-
federationId,
|
|
108
|
-
metrics: { globalAccuracy, loss },
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
return {
|
|
112
|
-
roundId,
|
|
113
|
-
round,
|
|
114
|
-
participants: participants.length,
|
|
115
|
-
convergence: {
|
|
116
|
-
globalAccuracy: Math.round(globalAccuracy * 1000) / 1000,
|
|
117
|
-
loss: Math.round(loss * 1000) / 1000,
|
|
118
|
-
},
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Get federation statistics
|
|
124
|
-
* @param {string} federationId - Federation ID
|
|
125
|
-
* @returns {object} Federation stats
|
|
126
|
-
*/
|
|
127
|
-
function getStats(federationId) {
|
|
128
|
-
const federation = federations.get(federationId);
|
|
129
|
-
if (!federation) {
|
|
130
|
-
throw new Error(`Federation ${federationId} not found`);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
return {
|
|
134
|
-
federation: {
|
|
135
|
-
id: federationId,
|
|
136
|
-
rounds: federation.rounds,
|
|
137
|
-
},
|
|
138
|
-
participants: federation.participants.map((p) => ({
|
|
139
|
-
id: p.id,
|
|
140
|
-
status: p.status || "active",
|
|
141
|
-
weight: p.weight || 1,
|
|
142
|
-
})),
|
|
143
|
-
performance: {
|
|
144
|
-
averageAccuracy: 0.92,
|
|
145
|
-
convergenceRate: 0.85,
|
|
146
|
-
communicationRounds: federation.rounds,
|
|
147
|
-
},
|
|
148
|
-
privacy: {
|
|
149
|
-
differentialPrivacy: federation.options.differentialPrivacy || false,
|
|
150
|
-
encryptionEnabled: federation.options.encryptionEnabled || true,
|
|
151
|
-
dataLocality: "preserved",
|
|
152
|
-
},
|
|
153
|
-
};
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Validate participant eligibility
|
|
158
|
-
* @param {object} participant - Participant to validate
|
|
159
|
-
* @returns {boolean} Whether participant is valid
|
|
160
|
-
*/
|
|
161
|
-
function validateParticipant(participant) {
|
|
162
|
-
if (!participant || typeof participant !== "object") {
|
|
163
|
-
return false;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// Check if participant has non-empty string id
|
|
167
|
-
if (
|
|
168
|
-
!participant.id ||
|
|
169
|
-
typeof participant.id !== "string" ||
|
|
170
|
-
participant.id.trim() === ""
|
|
171
|
-
) {
|
|
172
|
-
return false;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
// Check if participant is explicitly marked as ineligible
|
|
176
|
-
if (participant.eligible === false) {
|
|
177
|
-
return false;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
return true;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* Clear all stored data (for testing)
|
|
185
|
-
*/
|
|
186
|
-
function clear() {
|
|
187
|
-
federations.clear();
|
|
188
|
-
federationCounter = 0;
|
|
189
|
-
eventEmitter.removeAllListeners();
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// Singleton object with required methods and EventEmitter functionality
|
|
193
|
-
const federatedLearningCoordinator = {
|
|
194
|
-
// Core federated learning methods
|
|
195
|
-
createFederation,
|
|
196
|
-
registerParticipants,
|
|
197
|
-
conductRound,
|
|
198
|
-
getStats,
|
|
199
|
-
validateParticipant,
|
|
200
|
-
|
|
201
|
-
// EventEmitter methods
|
|
202
|
-
on: eventEmitter.on.bind(eventEmitter),
|
|
203
|
-
off: eventEmitter.removeListener.bind(eventEmitter),
|
|
204
|
-
emit: eventEmitter.emit.bind(eventEmitter),
|
|
205
|
-
|
|
206
|
-
// Additional utility methods
|
|
207
|
-
clear,
|
|
208
|
-
};
|
|
209
|
-
|
|
210
|
-
// Export singleton as default
|
|
211
|
-
module.exports = federatedLearningCoordinator;
|
package/src/ai/federation.js
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Federated Learning Coordinator
|
|
3
|
-
* Manages distributed learning across multiple participants
|
|
4
|
-
* Extracted from ai/index.js per CLAUDE.md decomposition requirements
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
"use strict";
|
|
8
|
-
|
|
9
|
-
// Import the existing federated learning implementation
|
|
10
|
-
const federatedLearning = require("./federated-learning");
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* FederatedLearningCoordinator class
|
|
14
|
-
* Coordinates federated learning processes across multiple nodes
|
|
15
|
-
*/
|
|
16
|
-
class FederatedLearningCoordinator {
|
|
17
|
-
constructor() {
|
|
18
|
-
this.participants = new Map();
|
|
19
|
-
this.rounds = new Map();
|
|
20
|
-
this.modelVersions = new Map();
|
|
21
|
-
this.aggregationStrategies = new Set(["fedavg", "fedprox", "scaffold"]);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Start federated learning round
|
|
26
|
-
* @param {string} tenantId - Tenant identifier
|
|
27
|
-
* @param {object} roundConfig - Round configuration
|
|
28
|
-
* @returns {Promise<string>} Round ID
|
|
29
|
-
*/
|
|
30
|
-
async startRound(tenantId, roundConfig) {
|
|
31
|
-
return await federatedLearning.startRound(tenantId, roundConfig);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Register participant in federated learning
|
|
36
|
-
* @param {string} tenantId - Tenant identifier
|
|
37
|
-
* @param {string} participantId - Participant identifier
|
|
38
|
-
* @param {object} capabilities - Participant capabilities
|
|
39
|
-
* @returns {Promise<boolean>} Registration success
|
|
40
|
-
*/
|
|
41
|
-
async registerParticipant(tenantId, participantId, capabilities) {
|
|
42
|
-
return await federatedLearning.registerParticipant(
|
|
43
|
-
tenantId,
|
|
44
|
-
participantId,
|
|
45
|
-
capabilities,
|
|
46
|
-
);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Aggregate model updates from participants
|
|
51
|
-
* @param {string} tenantId - Tenant identifier
|
|
52
|
-
* @param {string} roundId - Round identifier
|
|
53
|
-
* @param {Array} updates - Model updates from participants
|
|
54
|
-
* @returns {Promise<object>} Aggregated model
|
|
55
|
-
*/
|
|
56
|
-
async aggregateUpdates(tenantId, roundId, updates) {
|
|
57
|
-
return await federatedLearning.aggregateUpdates(tenantId, roundId, updates);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Get federated learning progress
|
|
62
|
-
* @param {string} tenantId - Tenant identifier
|
|
63
|
-
* @param {string} roundId - Round identifier
|
|
64
|
-
* @returns {Promise<object>} Progress information
|
|
65
|
-
*/
|
|
66
|
-
async getRoundProgress(tenantId, roundId) {
|
|
67
|
-
return await federatedLearning.getRoundProgress(tenantId, roundId);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
module.exports = { FederatedLearningCoordinator };
|
package/src/ai/index.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* AI/ML Module Index - Decomposed Architecture
|
|
3
|
-
* Provides unified interface to 4 separate AI modules
|
|
4
|
-
*
|
|
5
|
-
* Decomposed modules:
|
|
6
|
-
* - orchestrator.js - ModelTrainingOrchestrator
|
|
7
|
-
* - retrieval-engine.js - AdaptiveRetrievalEngine
|
|
8
|
-
* - multimodal.js - MultiModalProcessor
|
|
9
|
-
* - federation.js - FederatedLearningCoordinator
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
const { ModelTrainingOrchestrator } = require("./orchestrator");
|
|
13
|
-
const { AdaptiveRetrievalEngine } = require("./retrieval-engine");
|
|
14
|
-
const { MultiModalProcessor } = require("./multimodal");
|
|
15
|
-
const { FederatedLearningCoordinator } = require("./federation");
|
|
16
|
-
|
|
17
|
-
module.exports = {
|
|
18
|
-
ModelTrainingOrchestrator,
|
|
19
|
-
AdaptiveRetrievalEngine,
|
|
20
|
-
MultiModalProcessor,
|
|
21
|
-
FederatedLearningCoordinator,
|
|
22
|
-
};
|
package/src/ai/model-trainer.js
DELETED
|
@@ -1,217 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Model Trainer - In-memory deterministic training orchestration
|
|
3
|
-
*
|
|
4
|
-
* Google-style implementation with dependency injection for clocks/RNG.
|
|
5
|
-
* Provides training job management, hyperparameter optimization, and model deployment.
|
|
6
|
-
*
|
|
7
|
-
* @module ModelTrainer
|
|
8
|
-
* @exports {ModelTrainer, modelTrainer}
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
const EventEmitter = require("events");
|
|
12
|
-
|
|
13
|
-
class ModelTrainer extends EventEmitter {
|
|
14
|
-
constructor(options = {}) {
|
|
15
|
-
super();
|
|
16
|
-
this.now = options.now || (() => Date.now());
|
|
17
|
-
this.sleep =
|
|
18
|
-
options.sleep ||
|
|
19
|
-
((ms) => new Promise((resolve) => setTimeout(resolve, Math.min(ms, 5))));
|
|
20
|
-
this.jobs = new Map();
|
|
21
|
-
this.optimizations = new Map();
|
|
22
|
-
this.deployments = new Map();
|
|
23
|
-
this.jobCounter = 0;
|
|
24
|
-
this.optCounter = 0;
|
|
25
|
-
this.deployCounter = 0;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Create a training job
|
|
30
|
-
* @param {string} tenantId - Tenant identifier
|
|
31
|
-
* @param {object} config - Training configuration
|
|
32
|
-
* @returns {string} Job ID
|
|
33
|
-
*/
|
|
34
|
-
createTrainingJob(tenantId, config) {
|
|
35
|
-
if (!tenantId || !config) {
|
|
36
|
-
const error = new Error("Tenant ID and config are required");
|
|
37
|
-
error.code = "INVALID_ARGUMENT";
|
|
38
|
-
throw error;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const jobId = `job-${++this.jobCounter}`;
|
|
42
|
-
const job = {
|
|
43
|
-
id: jobId,
|
|
44
|
-
tenantId,
|
|
45
|
-
config,
|
|
46
|
-
status: "created",
|
|
47
|
-
createdAt: this.now(),
|
|
48
|
-
progress: 0,
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
this.jobs.set(jobId, job);
|
|
52
|
-
return jobId;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Start training for a job
|
|
57
|
-
* @param {string} jobId - Job identifier
|
|
58
|
-
* @returns {Promise<void>}
|
|
59
|
-
*/
|
|
60
|
-
async startTraining(jobId) {
|
|
61
|
-
const job = this.jobs.get(jobId);
|
|
62
|
-
if (!job) {
|
|
63
|
-
const error = new Error(`Training job not found: ${jobId}`);
|
|
64
|
-
error.code = "NOT_FOUND";
|
|
65
|
-
throw error;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
job.status = "running";
|
|
69
|
-
job.startedAt = this.now();
|
|
70
|
-
this.emit("training_started", { jobId, tenantId: job.tenantId });
|
|
71
|
-
|
|
72
|
-
// Simulate training with tiny delay
|
|
73
|
-
await this.sleep(2);
|
|
74
|
-
|
|
75
|
-
job.status = "completed";
|
|
76
|
-
job.completedAt = this.now();
|
|
77
|
-
job.progress = 100;
|
|
78
|
-
this.emit("training_completed", {
|
|
79
|
-
jobId,
|
|
80
|
-
tenantId: job.tenantId,
|
|
81
|
-
status: "completed",
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Optimize hyperparameters
|
|
87
|
-
* @param {string} tenantId - Tenant identifier
|
|
88
|
-
* @param {object} config - Optimization configuration
|
|
89
|
-
* @returns {string} Optimization ID
|
|
90
|
-
*/
|
|
91
|
-
optimizeHyperparameters(tenantId, config) {
|
|
92
|
-
if (!tenantId || !config) {
|
|
93
|
-
const error = new Error("Tenant ID and config are required");
|
|
94
|
-
error.code = "INVALID_ARGUMENT";
|
|
95
|
-
throw error;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
const optId = `opt-${++this.optCounter}`;
|
|
99
|
-
const optimization = {
|
|
100
|
-
id: optId,
|
|
101
|
-
tenantId,
|
|
102
|
-
config,
|
|
103
|
-
status: "running",
|
|
104
|
-
createdAt: this.now(),
|
|
105
|
-
trials: [
|
|
106
|
-
{ params: { lr: 0.001, batch_size: 32 }, score: 0.85 },
|
|
107
|
-
{ params: { lr: 0.01, batch_size: 64 }, score: 0.92 },
|
|
108
|
-
{ params: { lr: 0.005, batch_size: 32 }, score: 0.89 },
|
|
109
|
-
],
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
this.optimizations.set(optId, optimization);
|
|
113
|
-
|
|
114
|
-
// Emit completion immediately for deterministic tests
|
|
115
|
-
setImmediate(() => {
|
|
116
|
-
optimization.status = "completed";
|
|
117
|
-
optimization.completedAt = this.now();
|
|
118
|
-
this.emit("hpo_completed", { optId, tenantId, bestScore: 0.92 });
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
return optId;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Get optimization results
|
|
126
|
-
* @param {string} optId - Optimization identifier
|
|
127
|
-
* @returns {Array} Array of trials
|
|
128
|
-
*/
|
|
129
|
-
getOptimizationResults(optId) {
|
|
130
|
-
const optimization = this.optimizations.get(optId);
|
|
131
|
-
if (!optimization) {
|
|
132
|
-
const error = new Error(`Optimization not found: ${optId}`);
|
|
133
|
-
error.code = "NOT_FOUND";
|
|
134
|
-
throw error;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
return optimization.trials;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Deploy a trained model
|
|
142
|
-
* @param {string} jobId - Training job identifier
|
|
143
|
-
* @param {object} options - Deployment options
|
|
144
|
-
* @returns {string} Deployment ID
|
|
145
|
-
*/
|
|
146
|
-
deployModel(jobId, options = {}) {
|
|
147
|
-
const job = this.jobs.get(jobId);
|
|
148
|
-
if (!job) {
|
|
149
|
-
const error = new Error(`Training job not found: ${jobId}`);
|
|
150
|
-
error.code = "NOT_FOUND";
|
|
151
|
-
throw error;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
if (job.status !== "completed") {
|
|
155
|
-
const error = new Error("Job must be completed before deployment");
|
|
156
|
-
error.code = "FAILED_PRECONDITION";
|
|
157
|
-
throw error;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
const deploymentId = `deploy-${++this.deployCounter}`;
|
|
161
|
-
const deployment = {
|
|
162
|
-
id: deploymentId,
|
|
163
|
-
jobId,
|
|
164
|
-
tenantId: job.tenantId,
|
|
165
|
-
environment: options.environment || "staging",
|
|
166
|
-
status: "deployed",
|
|
167
|
-
deployedAt: this.now(),
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
this.deployments.set(deploymentId, deployment);
|
|
171
|
-
this.emit("model_deployed", {
|
|
172
|
-
deploymentId,
|
|
173
|
-
jobId,
|
|
174
|
-
environment: deployment.environment,
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
return deploymentId;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* Get deployment status
|
|
182
|
-
* @param {string} deploymentId - Deployment identifier
|
|
183
|
-
* @returns {object} Deployment status
|
|
184
|
-
*/
|
|
185
|
-
getDeploymentStatus(deploymentId) {
|
|
186
|
-
const deployment = this.deployments.get(deploymentId);
|
|
187
|
-
if (!deployment) {
|
|
188
|
-
const error = new Error(`Deployment not found: ${deploymentId}`);
|
|
189
|
-
error.code = "NOT_FOUND";
|
|
190
|
-
throw error;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
return {
|
|
194
|
-
id: deployment.id,
|
|
195
|
-
status: deployment.status,
|
|
196
|
-
environment: deployment.environment,
|
|
197
|
-
deployedAt: deployment.deployedAt,
|
|
198
|
-
};
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* Clear all data (for testing)
|
|
203
|
-
*/
|
|
204
|
-
clear() {
|
|
205
|
-
this.jobs.clear();
|
|
206
|
-
this.optimizations.clear();
|
|
207
|
-
this.deployments.clear();
|
|
208
|
-
this.jobCounter = 0;
|
|
209
|
-
this.optCounter = 0;
|
|
210
|
-
this.deployCounter = 0;
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// Default instance
|
|
215
|
-
const modelTrainer = new ModelTrainer();
|
|
216
|
-
|
|
217
|
-
module.exports = { ModelTrainer, modelTrainer };
|