@devilsdev/rag-pipeline-utils 2.3.1 → 2.4.1
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 +94 -480
- 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 +37 -11
- 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
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config command handlers
|
|
3
|
+
* Handles config show, set, and get commands
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const fs = require("fs/promises");
|
|
7
|
+
const { logger } = require("../../utils/logger.js");
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Handle config show command
|
|
11
|
+
* @param {object} globalOptions - Global CLI options from program.opts()
|
|
12
|
+
* @param {object} options - Command-specific options
|
|
13
|
+
*/
|
|
14
|
+
async function handleConfigShow(globalOptions, options) {
|
|
15
|
+
try {
|
|
16
|
+
const config = JSON.parse(await fs.readFile(globalOptions.config, "utf-8"));
|
|
17
|
+
|
|
18
|
+
let output = config;
|
|
19
|
+
if (options.section) {
|
|
20
|
+
const sections = options.section.split(".");
|
|
21
|
+
for (const section of sections) {
|
|
22
|
+
output = output[section];
|
|
23
|
+
if (output === undefined) {
|
|
24
|
+
console.log(`❌ Section not found: ${options.section}`);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
console.log(JSON.stringify(output, null, 2));
|
|
31
|
+
} catch (error) {
|
|
32
|
+
logger.error("❌ Failed to show configuration:", error.message);
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Handle config set command
|
|
39
|
+
* @param {object} globalOptions - Global CLI options from program.opts()
|
|
40
|
+
* @param {string} key - Configuration key (dot notation)
|
|
41
|
+
* @param {string} value - Configuration value
|
|
42
|
+
*/
|
|
43
|
+
async function handleConfigSet(globalOptions, key, value) {
|
|
44
|
+
try {
|
|
45
|
+
const config = JSON.parse(await fs.readFile(globalOptions.config, "utf-8"));
|
|
46
|
+
|
|
47
|
+
// Parse value
|
|
48
|
+
let parsedValue;
|
|
49
|
+
try {
|
|
50
|
+
parsedValue = JSON.parse(value);
|
|
51
|
+
} catch (error) {
|
|
52
|
+
parsedValue = value; // Keep as string
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Validate key segments against prototype pollution
|
|
56
|
+
const keySegments = key.split(".");
|
|
57
|
+
const forbidden = new Set(["__proto__", "constructor", "prototype"]);
|
|
58
|
+
if (keySegments.some((k) => forbidden.has(k))) {
|
|
59
|
+
logger.error("Invalid configuration key: contains restricted property");
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Build a patch object from the key path, then merge via JSON round-trip
|
|
64
|
+
// This avoids dynamic property assignment entirely (no prototype pollution risk)
|
|
65
|
+
const patch = JSON.parse(
|
|
66
|
+
keySegments.reduceRight(
|
|
67
|
+
(val, seg) => JSON.stringify({ [seg]: JSON.parse(val) }),
|
|
68
|
+
JSON.stringify(parsedValue),
|
|
69
|
+
),
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
// Shallow-merge at each level
|
|
73
|
+
function safeMerge(target, source) {
|
|
74
|
+
for (const k of Object.keys(source)) {
|
|
75
|
+
if (
|
|
76
|
+
source[k] &&
|
|
77
|
+
typeof source[k] === "object" &&
|
|
78
|
+
!Array.isArray(source[k]) &&
|
|
79
|
+
target[k] &&
|
|
80
|
+
typeof target[k] === "object"
|
|
81
|
+
) {
|
|
82
|
+
safeMerge(target[k], source[k]);
|
|
83
|
+
} else {
|
|
84
|
+
target[k] = source[k];
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
safeMerge(config, patch);
|
|
89
|
+
|
|
90
|
+
// Save configuration
|
|
91
|
+
await fs.writeFile(globalOptions.config, JSON.stringify(config, null, 2));
|
|
92
|
+
console.log("✅ Configuration updated");
|
|
93
|
+
} catch (error) {
|
|
94
|
+
logger.error("❌ Failed to set configuration:", error.message);
|
|
95
|
+
process.exit(1);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Handle config get command
|
|
101
|
+
* @param {object} globalOptions - Global CLI options from program.opts()
|
|
102
|
+
* @param {string} key - Configuration key (dot notation)
|
|
103
|
+
*/
|
|
104
|
+
async function handleConfigGet(globalOptions, key) {
|
|
105
|
+
try {
|
|
106
|
+
const config = JSON.parse(await fs.readFile(globalOptions.config, "utf-8"));
|
|
107
|
+
|
|
108
|
+
const keys = key.split(".");
|
|
109
|
+
let value = config;
|
|
110
|
+
|
|
111
|
+
for (const k of keys) {
|
|
112
|
+
value = value[k];
|
|
113
|
+
if (value === undefined) {
|
|
114
|
+
console.log("❌ Key not found");
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
console.log(JSON.stringify(value, null, 2));
|
|
120
|
+
} catch (error) {
|
|
121
|
+
logger.error("❌ Failed to get configuration:", error.message);
|
|
122
|
+
process.exit(1);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
module.exports = { handleConfigShow, handleConfigSet, handleConfigGet };
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Diagnostics command handlers
|
|
3
|
+
* Handles doctor, validate, and info commands
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const fs = require("fs/promises");
|
|
7
|
+
const { logger } = require("../../utils/logger.js");
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Handle doctor command
|
|
11
|
+
* @param {object} globalOptions - Global CLI options from program.opts()
|
|
12
|
+
* @param {object} options - Command-specific options
|
|
13
|
+
* @param {Function} pipelineDoctorFn - Pipeline doctor function
|
|
14
|
+
*/
|
|
15
|
+
async function handleDoctor(globalOptions, options, pipelineDoctorFn) {
|
|
16
|
+
try {
|
|
17
|
+
const doctorOptions = {
|
|
18
|
+
configPath: globalOptions.config,
|
|
19
|
+
verbose: globalOptions.verbose,
|
|
20
|
+
autoFix: options.autoFix,
|
|
21
|
+
categories: options.category,
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const report = await pipelineDoctorFn(doctorOptions);
|
|
25
|
+
|
|
26
|
+
if (options.report) {
|
|
27
|
+
await fs.writeFile(options.report, JSON.stringify(report, null, 2));
|
|
28
|
+
console.log(`📋 Diagnostic report saved to: ${options.report}`);
|
|
29
|
+
}
|
|
30
|
+
} catch (error) {
|
|
31
|
+
logger.error("❌ Doctor command failed:", error.message);
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Handle validate command
|
|
38
|
+
* @param {object} globalOptions - Global CLI options from program.opts()
|
|
39
|
+
* @param {object} options - Command-specific options
|
|
40
|
+
* @param {Function} validateSchemaFn - Schema validation function
|
|
41
|
+
*/
|
|
42
|
+
async function handleValidate(globalOptions, options, validateSchemaFn) {
|
|
43
|
+
try {
|
|
44
|
+
const configPath = globalOptions.config;
|
|
45
|
+
|
|
46
|
+
console.log(`🔍 Validating configuration: ${configPath}`);
|
|
47
|
+
|
|
48
|
+
// Load and validate configuration
|
|
49
|
+
const configContent = await fs.readFile(configPath, "utf-8");
|
|
50
|
+
const config = JSON.parse(configContent);
|
|
51
|
+
|
|
52
|
+
const validation = validateSchemaFn(config);
|
|
53
|
+
|
|
54
|
+
if (validation.valid) {
|
|
55
|
+
console.log("✅ Configuration is valid");
|
|
56
|
+
|
|
57
|
+
if (validation.legacy) {
|
|
58
|
+
console.log("⚠️ Using legacy format - consider upgrading");
|
|
59
|
+
}
|
|
60
|
+
} else {
|
|
61
|
+
console.log("❌ Configuration validation failed:");
|
|
62
|
+
validation.errors?.forEach((error) => {
|
|
63
|
+
console.log(` ${error.instancePath || "root"}: ${error.message}`);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
} catch (error) {
|
|
67
|
+
logger.error("❌ Validation failed:", error.message);
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Handle info command
|
|
74
|
+
* @param {object} globalOptions - Global CLI options from program.opts()
|
|
75
|
+
* @param {object} options - Command-specific options
|
|
76
|
+
*/
|
|
77
|
+
async function handleInfo(globalOptions, options) {
|
|
78
|
+
try {
|
|
79
|
+
console.log("📊 RAG Pipeline Information\n");
|
|
80
|
+
|
|
81
|
+
// System information
|
|
82
|
+
if ((!options.plugins && !options.config) || options.system) {
|
|
83
|
+
console.log("System:");
|
|
84
|
+
console.log(` Node.js: ${process.version}`);
|
|
85
|
+
console.log(` Platform: ${process.platform} ${process.arch}`);
|
|
86
|
+
console.log(
|
|
87
|
+
` Memory: ${Math.round(process.memoryUsage().heapUsed / 1024 / 1024)}MB used`,
|
|
88
|
+
);
|
|
89
|
+
console.log("");
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Configuration summary
|
|
93
|
+
if ((!options.system && !options.plugins) || options.config) {
|
|
94
|
+
try {
|
|
95
|
+
const config = JSON.parse(
|
|
96
|
+
await fs.readFile(globalOptions.config, "utf-8"),
|
|
97
|
+
);
|
|
98
|
+
console.log("Configuration:");
|
|
99
|
+
console.log(` File: ${globalOptions.config}`);
|
|
100
|
+
console.log(` Format: ${config.plugins ? "Enhanced" : "Legacy"}`);
|
|
101
|
+
console.log("");
|
|
102
|
+
} catch (error) {
|
|
103
|
+
console.log("Configuration: Not found or invalid");
|
|
104
|
+
console.log("");
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
} catch (error) {
|
|
108
|
+
logger.error("❌ Failed to get system information:", error.message);
|
|
109
|
+
process.exit(1);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
module.exports = { handleDoctor, handleValidate, handleInfo };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ingest command handler
|
|
3
|
+
* Handles document ingestion into the pipeline
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const { logger } = require("../../utils/logger.js");
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Handle ingest command
|
|
10
|
+
* @param {object} globalOptions - Global CLI options from program.opts()
|
|
11
|
+
* @param {string} file - Document file path
|
|
12
|
+
* @param {object} options - Command-specific options
|
|
13
|
+
*/
|
|
14
|
+
async function handleIngest(globalOptions, file, options) {
|
|
15
|
+
try {
|
|
16
|
+
if (globalOptions.dryRun) {
|
|
17
|
+
console.log("🧪 Dry run: Would ingest document");
|
|
18
|
+
console.log(`File: ${file}`);
|
|
19
|
+
console.log(
|
|
20
|
+
`Parallel processing: ${options.parallel ? "enabled" : "disabled"}`,
|
|
21
|
+
);
|
|
22
|
+
console.log(`Streaming: ${options.streaming ? "enabled" : "disabled"}`);
|
|
23
|
+
console.log(`Tracing: ${options.trace ? "enabled" : "disabled"}`);
|
|
24
|
+
|
|
25
|
+
if (options.preview) {
|
|
26
|
+
console.log("📄 Document Preview:");
|
|
27
|
+
}
|
|
28
|
+
if (options.validate) {
|
|
29
|
+
console.log("File validation passed");
|
|
30
|
+
}
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
console.log(`📄 Ingesting document: ${file}`);
|
|
35
|
+
console.log("✅ Document ingested successfully!");
|
|
36
|
+
} catch (error) {
|
|
37
|
+
logger.error("❌ Document ingestion failed:", error.message);
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
module.exports = { handleIngest };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Init command handler
|
|
3
|
+
* Handles RAG pipeline configuration initialization
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const fs = require("fs/promises");
|
|
7
|
+
const { logger } = require("../../utils/logger.js");
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Handle init command
|
|
11
|
+
* @param {object} globalOptions - Global CLI options from program.opts()
|
|
12
|
+
* @param {object} options - Command-specific options
|
|
13
|
+
* @param {Function} createBasicConfigFn - Function to create basic config
|
|
14
|
+
*/
|
|
15
|
+
async function handleInit(globalOptions, options, createBasicConfigFn) {
|
|
16
|
+
try {
|
|
17
|
+
if (globalOptions.dryRun) {
|
|
18
|
+
console.log("🧪 Dry run: Would initialize RAG pipeline configuration");
|
|
19
|
+
console.log(`Output file: ${options.output}`);
|
|
20
|
+
console.log(`Interactive mode: ${!options.noInteractive}`);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Check if config already exists
|
|
25
|
+
if (!options.force) {
|
|
26
|
+
try {
|
|
27
|
+
await fs.access(options.output);
|
|
28
|
+
console.log(`❌ Configuration file already exists: ${options.output}`);
|
|
29
|
+
console.log(
|
|
30
|
+
"Use --force to overwrite or choose a different output path.",
|
|
31
|
+
);
|
|
32
|
+
return;
|
|
33
|
+
} catch (error) {
|
|
34
|
+
// File doesn't exist, which is good
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (!options.noInteractive) {
|
|
39
|
+
console.log("🧙♂️ Starting interactive configuration wizard...\n");
|
|
40
|
+
// Mock interactive wizard
|
|
41
|
+
await createBasicConfigFn(options.output);
|
|
42
|
+
} else {
|
|
43
|
+
await createBasicConfigFn(options.output);
|
|
44
|
+
}
|
|
45
|
+
} catch (error) {
|
|
46
|
+
logger.error("❌ Initialization failed:", error.message);
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
module.exports = { handleInit };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Query command handler
|
|
3
|
+
* Handles RAG pipeline queries
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const { logger } = require("../../utils/logger.js");
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Handle query command
|
|
10
|
+
* @param {object} globalOptions - Global CLI options from program.opts()
|
|
11
|
+
* @param {string} prompt - Query prompt
|
|
12
|
+
* @param {object} options - Command-specific options
|
|
13
|
+
*/
|
|
14
|
+
async function handleQuery(globalOptions, prompt, options) {
|
|
15
|
+
try {
|
|
16
|
+
if (globalOptions.dryRun) {
|
|
17
|
+
console.log("🧪 Dry run: Would execute query");
|
|
18
|
+
console.log(
|
|
19
|
+
`Prompt: ${prompt.substring(0, 100)}${prompt.length > 100 ? "..." : ""}`,
|
|
20
|
+
);
|
|
21
|
+
console.log(`Streaming: ${options.stream ? "enabled" : "disabled"}`);
|
|
22
|
+
|
|
23
|
+
if (options.explain) {
|
|
24
|
+
console.log("🔍 Query Explanation:");
|
|
25
|
+
console.log("Processing steps:");
|
|
26
|
+
console.log(" 1. Text embedding generation");
|
|
27
|
+
console.log(" 2. Vector similarity search");
|
|
28
|
+
console.log(" 3. Context retrieval");
|
|
29
|
+
console.log(" 4. Language model generation");
|
|
30
|
+
}
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
console.log(
|
|
35
|
+
`🤔 Processing query: ${prompt.substring(0, 100)}${prompt.length > 100 ? "..." : ""}`,
|
|
36
|
+
);
|
|
37
|
+
console.log("\n📝 Response:");
|
|
38
|
+
console.log("Mock response to query");
|
|
39
|
+
} catch (error) {
|
|
40
|
+
logger.error("❌ Query processing failed:", error.message);
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
module.exports = { handleQuery };
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run command handler
|
|
3
|
+
* Handles pipeline execution with streaming, abort, and progress support
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const { logger } = require("../../utils/logger.js");
|
|
7
|
+
const { createProgressBar } = require("../shared/cli-utils.js");
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Handle run command
|
|
11
|
+
* @param {object} globalOptions - Global CLI options from program.opts()
|
|
12
|
+
* @param {object} options - Command-specific options
|
|
13
|
+
*/
|
|
14
|
+
async function handleRun(globalOptions, options) {
|
|
15
|
+
if (globalOptions.dryRun) {
|
|
16
|
+
logger.info("🧪 Dry run: Would execute pipeline operation");
|
|
17
|
+
if (options.ingest) logger.info(`Would ingest: ${options.ingest}`);
|
|
18
|
+
if (options.query)
|
|
19
|
+
logger.info(`Would query: ${options.query.substring(0, 100)}...`);
|
|
20
|
+
logger.info(`Streaming: ${options.stream ? "enabled" : "disabled"}`);
|
|
21
|
+
logger.info(`Parallel: ${options.parallel ? "enabled" : "disabled"}`);
|
|
22
|
+
if (options.abortTimeout)
|
|
23
|
+
logger.info(`Abort timeout: ${options.abortTimeout}ms`);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
try {
|
|
28
|
+
// Load configuration
|
|
29
|
+
const { loadRagConfig } = require("../../config/load-config.js");
|
|
30
|
+
const config = await loadRagConfig(globalOptions.config);
|
|
31
|
+
|
|
32
|
+
// Create AbortController for timeout handling
|
|
33
|
+
const abortController = new AbortController();
|
|
34
|
+
let timeoutId;
|
|
35
|
+
|
|
36
|
+
if (options.abortTimeout) {
|
|
37
|
+
timeoutId = setTimeout(() => {
|
|
38
|
+
logger.warn(
|
|
39
|
+
`Operation aborted after ${options.abortTimeout}ms timeout`,
|
|
40
|
+
);
|
|
41
|
+
abortController.abort();
|
|
42
|
+
}, options.abortTimeout);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Setup SIGINT handling for clean shutdown
|
|
46
|
+
const sigintHandler = () => {
|
|
47
|
+
logger.info("Received SIGINT, aborting operation...");
|
|
48
|
+
abortController.abort();
|
|
49
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
50
|
+
};
|
|
51
|
+
process.once("SIGINT", sigintHandler);
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
// Create pipeline with performance options
|
|
55
|
+
const { createRagPipeline } = require("../../core/create-pipeline.js");
|
|
56
|
+
const pipeline = createRagPipeline(config.pipeline[0], {
|
|
57
|
+
useParallelProcessing: options.parallel,
|
|
58
|
+
useStreamingSafeguards: options.stream,
|
|
59
|
+
useLogging: true,
|
|
60
|
+
useRetry: true,
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// Execute operation based on options
|
|
64
|
+
if (options.ingest) {
|
|
65
|
+
logger.info(`Starting ingestion of: ${options.ingest}`);
|
|
66
|
+
|
|
67
|
+
if (options.stream) {
|
|
68
|
+
let lastProgressTime = Date.now();
|
|
69
|
+
for await (const progress of pipeline.ingestStream(options.ingest)) {
|
|
70
|
+
if (abortController.signal.aborted) {
|
|
71
|
+
logger.info("Ingestion aborted");
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const now = Date.now();
|
|
76
|
+
if (progress.type === "chunk_processed") {
|
|
77
|
+
// Show progress ticks every 500ms or every 10 chunks
|
|
78
|
+
if (
|
|
79
|
+
now - lastProgressTime > 500 ||
|
|
80
|
+
progress.progress.processed % 10 === 0
|
|
81
|
+
) {
|
|
82
|
+
const percentage = Math.round(
|
|
83
|
+
(progress.progress.processed / progress.progress.total) * 100,
|
|
84
|
+
);
|
|
85
|
+
const progressBar = createProgressBar(percentage, 20);
|
|
86
|
+
process.stdout.write(
|
|
87
|
+
`\r${progressBar} ${percentage}% (${progress.progress.processed}/${progress.progress.total}) `,
|
|
88
|
+
);
|
|
89
|
+
lastProgressTime = now;
|
|
90
|
+
}
|
|
91
|
+
} else if (progress.type === "ingest_complete") {
|
|
92
|
+
process.stdout.write("\n");
|
|
93
|
+
logger.info(
|
|
94
|
+
`✅ Ingestion complete: ${progress.summary.processedChunks}/${progress.summary.totalChunks} chunks processed`,
|
|
95
|
+
);
|
|
96
|
+
if (progress.summary.failedChunks > 0) {
|
|
97
|
+
logger.warn(
|
|
98
|
+
`⚠️ ${progress.summary.failedChunks} chunks failed`,
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
} else if (progress.type === "chunk_failed") {
|
|
102
|
+
process.stdout.write("✗");
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
} else {
|
|
106
|
+
// Non-streaming ingestion with progress callback
|
|
107
|
+
let currentStage = "";
|
|
108
|
+
const progressCallback = (progress) => {
|
|
109
|
+
if (progress.stage !== currentStage) {
|
|
110
|
+
if (currentStage) process.stdout.write("\n");
|
|
111
|
+
currentStage = progress.stage;
|
|
112
|
+
logger.info(
|
|
113
|
+
`${progress.stage}: ${progress.message || "Processing..."}`,
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
if (
|
|
117
|
+
progress.completed !== undefined &&
|
|
118
|
+
progress.total !== undefined
|
|
119
|
+
) {
|
|
120
|
+
const percentage = Math.round(
|
|
121
|
+
(progress.completed / progress.total) * 100,
|
|
122
|
+
);
|
|
123
|
+
const progressBar = createProgressBar(percentage, 20);
|
|
124
|
+
process.stdout.write(
|
|
125
|
+
`\r${progressBar} ${percentage}% (${progress.completed}/${progress.total}) `,
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
const pipelineWithProgress = createRagPipeline(config.pipeline[0], {
|
|
131
|
+
useParallelProcessing: options.parallel,
|
|
132
|
+
useStreamingSafeguards: false,
|
|
133
|
+
useLogging: true,
|
|
134
|
+
useRetry: true,
|
|
135
|
+
onProgress: progressCallback,
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
await pipelineWithProgress.ingest(options.ingest);
|
|
139
|
+
process.stdout.write("\n");
|
|
140
|
+
logger.info("✅ Ingestion completed successfully");
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (options.query) {
|
|
145
|
+
logger.info(`Executing query: ${options.query.substring(0, 100)}...`);
|
|
146
|
+
|
|
147
|
+
if (options.stream) {
|
|
148
|
+
process.stdout.write("\nResponse: ");
|
|
149
|
+
for await (const token of pipeline.queryStream(options.query)) {
|
|
150
|
+
if (abortController.signal.aborted) {
|
|
151
|
+
logger.info("\nQuery aborted");
|
|
152
|
+
break;
|
|
153
|
+
}
|
|
154
|
+
process.stdout.write(token);
|
|
155
|
+
}
|
|
156
|
+
process.stdout.write("\n\n");
|
|
157
|
+
} else {
|
|
158
|
+
const response = await pipeline.query(options.query);
|
|
159
|
+
logger.info("Query completed successfully");
|
|
160
|
+
console.log("\nResponse:", response);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (!options.ingest && !options.query) {
|
|
165
|
+
logger.error(
|
|
166
|
+
"No operation specified. Use --ingest <file> or --query <prompt>",
|
|
167
|
+
);
|
|
168
|
+
process.exit(1);
|
|
169
|
+
}
|
|
170
|
+
} finally {
|
|
171
|
+
// Cleanup
|
|
172
|
+
process.removeListener("SIGINT", sigintHandler);
|
|
173
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
174
|
+
}
|
|
175
|
+
} catch (error) {
|
|
176
|
+
logger.error("Pipeline operation failed", { error: error.message });
|
|
177
|
+
process.exit(1);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
module.exports = { handleRun };
|