@devilsdev/rag-pipeline-utils 2.4.5 → 2.6.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 +431 -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 +6442 -1355
- package/dist/index.d.ts +129 -2
- package/dist/index.mjs +1 -1
- package/dist/testing.cjs +2 -0
- package/dist/testing.d.ts +1 -0
- package/dist/testing.mjs +5 -0
- package/dist/types/adapters/ai-sdk.d.ts +53 -0
- 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/cache/component-keys.d.ts +7 -0
- package/dist/types/cache/memory-cache.d.ts +54 -0
- package/dist/types/cache/pipeline-cache.d.ts +66 -0
- package/dist/types/cache/redis-cache.d.ts +46 -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 +97 -0
- package/dist/types/connectors/base-connector.d.ts +87 -0
- package/dist/types/connectors/cohere-connector.d.ts +94 -0
- package/dist/types/connectors/connector-utils.d.ts +110 -0
- package/dist/types/connectors/local-embedder.d.ts +95 -0
- package/dist/types/connectors/memory-retriever.d.ts +99 -0
- package/dist/types/connectors/ollama-connector.d.ts +115 -0
- package/dist/types/connectors/openai-connector.d.ts +129 -0
- package/dist/types/connectors/rag-prompt.d.ts +40 -0
- package/dist/types/core/create-pipeline.d.ts +8 -0
- package/dist/types/core/plugin-registry.d.ts +136 -0
- package/dist/types/core/stage-contracts.d.ts +36 -0
- package/dist/types/core/validate-plugin.d.ts +45 -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/evaluate/semantic-similarity.d.ts +14 -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/grounding/check-answer.d.ts +101 -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 +99 -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/testing.d.ts +168 -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 +72 -33
- package/src/adapters/ai-sdk.js +215 -0
- 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/cache/component-keys.js +38 -0
- package/src/cache/memory-cache.js +87 -0
- package/src/cache/pipeline-cache.js +260 -0
- package/src/cache/redis-cache.js +83 -0
- 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 +106 -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 +114 -49
- 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 +104 -233
- 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 +203 -25
- 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/instrument.js +83 -0
- package/src/cli/services/rag-service.js +361 -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 +602 -0
- package/src/config/component-factory.js +125 -0
- package/src/config/enhanced-ragrc-schema.js +0 -2
- package/src/config/load-config.js +29 -10
- package/src/config/load-plugin-config.js +46 -2
- package/src/config/validate-schema.js +4 -1
- package/src/connectors/anthropic-connector.js +115 -57
- package/src/connectors/base-connector.js +74 -19
- package/src/connectors/cohere-connector.js +108 -34
- package/src/connectors/connector-utils.js +302 -0
- package/src/connectors/local-embedder.js +63 -5
- package/src/connectors/memory-retriever.js +125 -14
- package/src/connectors/ollama-connector.js +112 -51
- package/src/connectors/openai-connector.js +153 -44
- package/src/connectors/rag-prompt.js +88 -0
- package/src/core/create-pipeline.js +307 -61
- package/src/core/performance/parallel-processor.js +62 -1
- package/src/core/plugin-registry.js +125 -26
- package/src/core/stage-contracts.js +36 -0
- package/src/core/validate-plugin.js +85 -0
- package/src/cost/cost-calculator.js +205 -32
- package/src/debug/execution-tracer.js +14 -4
- package/src/dev/dev-server.js +173 -11
- package/src/dev/hot-reload.js +44 -4
- 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 +716 -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/evaluate/semantic-similarity.js +79 -0
- package/src/experimental.js +71 -0
- package/src/grounding/check-answer.js +173 -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 +58 -1
- package/src/loader/csv-loader.js +3 -2
- package/src/loader/document-reader.js +91 -0
- package/src/loader/html-loader.js +3 -1
- package/src/loader/markdown-loader.js +3 -2
- 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 +241 -0
- package/src/retrieval/hybrid-retriever.js +22 -19
- package/src/security/jwt-config.js +13 -2
- package/src/security/jwt-validator.js +139 -34
- package/src/security/plugin-sandbox.js +18 -1
- package/src/security/plugin-signature-verifier.js +245 -70
- package/src/testing.js +254 -0
- 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
|
@@ -1,105 +1,52 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Plugin
|
|
3
|
-
*
|
|
2
|
+
* Plugin diagnostics: every custom plugin path under `plugins` exists and
|
|
3
|
+
* loads. Checked locally; no registry is contacted.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
const fs = require("fs
|
|
6
|
+
const fs = require("fs");
|
|
7
7
|
const path = require("path");
|
|
8
8
|
|
|
9
|
-
/**
|
|
10
|
-
* Check plugin issues
|
|
11
|
-
* @param {object} options - Doctor options (must include configPath)
|
|
12
|
-
* @returns {Promise<Array>} Array of plugin issues
|
|
13
|
-
*/
|
|
14
9
|
async function checkPlugins(options) {
|
|
15
|
-
const
|
|
16
|
-
|
|
10
|
+
const configPath = path.resolve(options.configPath);
|
|
11
|
+
let config;
|
|
17
12
|
try {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const config = JSON.parse(configContent);
|
|
23
|
-
|
|
24
|
-
if (config.plugins) {
|
|
25
|
-
// Process plugins in the order expected by tests: loader first, then embedder
|
|
26
|
-
const categories = ["loader", "embedder"];
|
|
27
|
-
for (const category of categories) {
|
|
28
|
-
if (config.plugins[category]) {
|
|
29
|
-
const plugins = config.plugins[category];
|
|
30
|
-
const sortedPlugins = Object.keys(plugins).sort();
|
|
31
|
-
for (const pluginName of sortedPlugins) {
|
|
32
|
-
try {
|
|
33
|
-
// Check if plugin file exists (simplified check)
|
|
34
|
-
await fs.access(path.join("node_modules", pluginName));
|
|
35
|
-
} catch (error) {
|
|
36
|
-
issues.push({
|
|
37
|
-
category: "plugins",
|
|
38
|
-
severity: "error",
|
|
39
|
-
code: "PLUGIN_MISSING",
|
|
40
|
-
message: `Plugin not found: ${pluginName}`,
|
|
41
|
-
fix: `Install plugin: npm install ${pluginName}`,
|
|
42
|
-
autoFixable: true,
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
13
|
+
config = JSON.parse(fs.readFileSync(configPath, "utf8"));
|
|
14
|
+
} catch {
|
|
15
|
+
return []; // reported by the configuration checker
|
|
16
|
+
}
|
|
48
17
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}
|
|
67
|
-
} catch (resolverError) {
|
|
68
|
-
// Version resolver not available, skip
|
|
18
|
+
const issues = [];
|
|
19
|
+
const configDir = path.dirname(configPath);
|
|
20
|
+
for (const [stage, plugins] of Object.entries(config.plugins || {})) {
|
|
21
|
+
if (!plugins || typeof plugins !== "object") continue;
|
|
22
|
+
for (const [name, modulePath] of Object.entries(plugins)) {
|
|
23
|
+
if (typeof modulePath !== "string") continue;
|
|
24
|
+
const resolved = path.resolve(configDir, modulePath);
|
|
25
|
+
if (!fs.existsSync(resolved)) {
|
|
26
|
+
issues.push({
|
|
27
|
+
category: "plugins",
|
|
28
|
+
severity: "error",
|
|
29
|
+
code: "PLUGIN_MISSING",
|
|
30
|
+
message: `Plugin ${stage}/${name} not found at ${modulePath}`,
|
|
31
|
+
fix: `Create ${modulePath} or fix the path in plugins.${stage}.${name}`,
|
|
32
|
+
autoFixable: false,
|
|
33
|
+
});
|
|
34
|
+
continue;
|
|
69
35
|
}
|
|
70
|
-
|
|
71
|
-
// Check for outdated plugins
|
|
72
36
|
try {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
category: "plugins",
|
|
84
|
-
severity: "info",
|
|
85
|
-
code: "PLUGIN_OUTDATED",
|
|
86
|
-
message: `Plugin outdated: ${pluginName}@${version} (latest: ${latest})`,
|
|
87
|
-
fix: `Update to latest version: rag-pipeline plugin install ${pluginName}@latest`,
|
|
88
|
-
autoFixable: true,
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
} catch (fetchError) {
|
|
96
|
-
// Registry not available, skip
|
|
37
|
+
require(resolved);
|
|
38
|
+
} catch (error) {
|
|
39
|
+
issues.push({
|
|
40
|
+
category: "plugins",
|
|
41
|
+
severity: "error",
|
|
42
|
+
code: "PLUGIN_LOAD_FAILED",
|
|
43
|
+
message: `Plugin ${stage}/${name} failed to load: ${error.message}`,
|
|
44
|
+
fix: `Fix the error in ${modulePath}`,
|
|
45
|
+
autoFixable: false,
|
|
46
|
+
});
|
|
97
47
|
}
|
|
98
48
|
}
|
|
99
|
-
} catch (configError) {
|
|
100
|
-
// Config issues handled in checkConfiguration
|
|
101
49
|
}
|
|
102
|
-
|
|
103
50
|
return issues;
|
|
104
51
|
}
|
|
105
52
|
|
|
@@ -38,6 +38,25 @@ const SEVERITY_LEVELS = {
|
|
|
38
38
|
SUCCESS: "success",
|
|
39
39
|
};
|
|
40
40
|
|
|
41
|
+
/**
|
|
42
|
+
* Locate npm's CLI script next to the running node binary (Windows layout:
|
|
43
|
+
* <node dir>/node_modules/npm/bin/npm-cli.js).
|
|
44
|
+
* @returns {string}
|
|
45
|
+
*/
|
|
46
|
+
function resolveNpmCli() {
|
|
47
|
+
const candidate = path.join(
|
|
48
|
+
path.dirname(process.execPath),
|
|
49
|
+
"node_modules",
|
|
50
|
+
"npm",
|
|
51
|
+
"bin",
|
|
52
|
+
"npm-cli.js",
|
|
53
|
+
);
|
|
54
|
+
if (!require("fs").existsSync(candidate)) {
|
|
55
|
+
throw new Error("npm not found next to node; run npm install manually");
|
|
56
|
+
}
|
|
57
|
+
return candidate;
|
|
58
|
+
}
|
|
59
|
+
|
|
41
60
|
/**
|
|
42
61
|
* Doctor command for pipeline diagnostics
|
|
43
62
|
*/
|
|
@@ -118,22 +137,32 @@ class PipelineDoctor {
|
|
|
118
137
|
throw new Error(`Command not allowed: ${command}`);
|
|
119
138
|
}
|
|
120
139
|
|
|
121
|
-
// Sanitize arguments
|
|
140
|
+
// Sanitize arguments. Backslashes are kept: there is no shell to
|
|
141
|
+
// interpret them, and they are path separators on Windows.
|
|
122
142
|
const sanitizedArgs = args.map((arg) => {
|
|
123
143
|
if (typeof arg !== "string") {
|
|
124
144
|
throw new Error("All arguments must be strings");
|
|
125
145
|
}
|
|
126
|
-
|
|
127
|
-
return arg.replace(/[;&|`$(){}[\]<>"'\\]/g, "");
|
|
146
|
+
return arg.replace(/[;&|`$(){}[\]<>"']/g, "");
|
|
128
147
|
});
|
|
129
148
|
|
|
130
149
|
const execOptions = {
|
|
131
|
-
shell: false, // Never use shell to prevent injection
|
|
132
150
|
timeout: options.timeout || 30000,
|
|
133
151
|
env: { ...process.env, PATH: process.env.PATH }, // Controlled environment
|
|
134
152
|
...options,
|
|
153
|
+
shell: false, // Never use a shell; set last so callers cannot override it
|
|
135
154
|
};
|
|
136
155
|
|
|
156
|
+
// npm is a .cmd shim on Windows, which execFile cannot run without a
|
|
157
|
+
// shell; run npm's JS entry point with node instead.
|
|
158
|
+
if (command === "npm" && process.platform === "win32") {
|
|
159
|
+
return await execFileAsync(
|
|
160
|
+
process.execPath,
|
|
161
|
+
[resolveNpmCli(), ...sanitizedArgs],
|
|
162
|
+
execOptions,
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
|
|
137
166
|
return await execFileAsync(command, sanitizedArgs, execOptions);
|
|
138
167
|
}
|
|
139
168
|
|
|
@@ -168,7 +197,12 @@ class PipelineDoctor {
|
|
|
168
197
|
// Validate config path is within project directory
|
|
169
198
|
const configPath = path.resolve(this.options.configPath);
|
|
170
199
|
const projectDir = path.resolve(".");
|
|
171
|
-
|
|
200
|
+
// Containment check: a bare startsWith(projectDir) also accepted
|
|
201
|
+
// sibling directories such as "/proj-evil".
|
|
202
|
+
const inside = ["/", "\\"].some((sep) =>
|
|
203
|
+
configPath.startsWith(projectDir + sep),
|
|
204
|
+
);
|
|
205
|
+
if (!inside) {
|
|
172
206
|
throw new Error("Config path outside project directory");
|
|
173
207
|
}
|
|
174
208
|
|
|
@@ -6,84 +6,38 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
const { Command } = require("commander");
|
|
9
|
-
const fs = require("fs/promises");
|
|
10
9
|
|
|
11
10
|
const { logger } = require("../utils/logger.js");
|
|
12
11
|
|
|
13
12
|
// Shared utilities
|
|
14
13
|
const {
|
|
15
|
-
createProgressBar,
|
|
16
14
|
parsePositiveInteger,
|
|
17
15
|
generateCompletionScript,
|
|
18
16
|
getVersion,
|
|
19
17
|
getExtendedHelp,
|
|
20
18
|
} = require("./shared/cli-utils.js");
|
|
21
19
|
|
|
22
|
-
// Handler modules
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
handleConfigGet,
|
|
34
|
-
} = require("./handlers/config-handler.js");
|
|
35
|
-
const { handleIngest } = require("./handlers/ingest-handler.js");
|
|
36
|
-
const { handleQuery } = require("./handlers/query-handler.js");
|
|
37
|
-
|
|
38
|
-
// Mock dependencies for test compatibility
|
|
39
|
-
const mockPluginMarketplaceCommands = () => {
|
|
40
|
-
const cmd = new Command("plugin");
|
|
41
|
-
cmd.description("Plugin marketplace commands");
|
|
42
|
-
cmd
|
|
43
|
-
.command("search")
|
|
44
|
-
.argument("[query]")
|
|
45
|
-
.action(() => {});
|
|
46
|
-
cmd
|
|
47
|
-
.command("install")
|
|
48
|
-
.argument("<name>")
|
|
49
|
-
.action(() => {});
|
|
50
|
-
cmd.command("publish").action(() => {});
|
|
51
|
-
return cmd;
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
const mockPipelineDoctor = async (options) => {
|
|
55
|
-
console.log("🏥 Running pipeline diagnostics");
|
|
56
|
-
if (options.categories) {
|
|
57
|
-
options.categories.forEach((cat) => {
|
|
58
|
-
console.log(`${cat.charAt(0).toUpperCase() + cat.slice(1)} Issues:`);
|
|
59
|
-
console.log(" ✅ No issues found");
|
|
60
|
-
});
|
|
61
|
-
} else {
|
|
62
|
-
console.log("✅ All systems operational");
|
|
63
|
-
}
|
|
64
|
-
return {
|
|
65
|
-
summary: { total: 0, passed: 0, warnings: 0, errors: 0 },
|
|
66
|
-
categories: {},
|
|
67
|
-
issues: [],
|
|
68
|
-
};
|
|
20
|
+
// Handler modules load when their command runs, so `--help` or one command
|
|
21
|
+
// does not pay for every other command's dependencies (inquirer, jsdom, ora,
|
|
22
|
+
// marked, csv-parse...).
|
|
23
|
+
/* eslint-disable global-require */
|
|
24
|
+
const handlers = {
|
|
25
|
+
run: () => require("./handlers/run-handler.js"),
|
|
26
|
+
init: () => require("./handlers/init-handler.js"),
|
|
27
|
+
diagnostics: () => require("./handlers/diagnostics-handler.js"),
|
|
28
|
+
config: () => require("./handlers/config-handler.js"),
|
|
29
|
+
ingest: () => require("./handlers/ingest-handler.js"),
|
|
30
|
+
query: () => require("./handlers/query-handler.js"),
|
|
69
31
|
};
|
|
32
|
+
/* eslint-enable global-require */
|
|
70
33
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
errors: [{ message: "Invalid configuration format" }],
|
|
76
|
-
};
|
|
34
|
+
function parseNonNegativeInt(value) {
|
|
35
|
+
const n = Number(value);
|
|
36
|
+
if (!Number.isInteger(n) || n < 0) {
|
|
37
|
+
throw new Error(`Expected a non-negative integer, got "${value}"`);
|
|
77
38
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
81
|
-
const isLegacy =
|
|
82
|
-
config.plugins &&
|
|
83
|
-
typeof config.plugins === "object" &&
|
|
84
|
-
Object.values(config.plugins).some((p) => typeof p === "string");
|
|
85
|
-
return { valid: true, legacy: isLegacy };
|
|
86
|
-
};
|
|
39
|
+
return n;
|
|
40
|
+
}
|
|
87
41
|
|
|
88
42
|
/**
|
|
89
43
|
* Enhanced CLI with improved UX and additional features
|
|
@@ -105,7 +59,7 @@ class EnhancedCLI {
|
|
|
105
59
|
.version(getVersion(), "-v, --version", "Display version information")
|
|
106
60
|
.option("--config <path>", "Configuration file path", ".ragrc.json")
|
|
107
61
|
.option("--verbose", "Enable verbose output")
|
|
108
|
-
.option("--quiet", "
|
|
62
|
+
.option("--quiet", "Print only results, no status messages")
|
|
109
63
|
.option("--no-color", "Disable colored output")
|
|
110
64
|
.option("--dry-run", "Show what would be done without executing")
|
|
111
65
|
.helpOption("-h, --help", "Display help information")
|
|
@@ -117,111 +71,116 @@ class EnhancedCLI {
|
|
|
117
71
|
* Setup all CLI commands
|
|
118
72
|
*/
|
|
119
73
|
setupCommands() {
|
|
120
|
-
// Interactive initialization command
|
|
121
74
|
this.program
|
|
122
75
|
.command("init")
|
|
123
|
-
.description("
|
|
124
|
-
.option("--interactive", "Use
|
|
125
|
-
.option(
|
|
126
|
-
|
|
76
|
+
.description("Create a .ragrc.json configuration")
|
|
77
|
+
.option("--no-interactive", "Use the template without prompting")
|
|
78
|
+
.option(
|
|
79
|
+
"--template <name>",
|
|
80
|
+
"Starting point: local, openai, ollama, anthropic",
|
|
81
|
+
"local",
|
|
82
|
+
)
|
|
127
83
|
.option("--output <path>", "Output configuration file", ".ragrc.json")
|
|
128
84
|
.option("--force", "Overwrite existing configuration")
|
|
129
85
|
.action(async (options) => {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
86
|
+
const result = await handlers
|
|
87
|
+
.init()
|
|
88
|
+
.handleInit(this.program.opts(), options);
|
|
89
|
+
// After a connection test, exit even if a provider call left a
|
|
90
|
+
// socket or timer open (see exitAfterConnectionTest).
|
|
91
|
+
handlers.init().exitAfterConnectionTest(result);
|
|
133
92
|
});
|
|
134
93
|
|
|
135
|
-
// Run pipeline command
|
|
136
94
|
this.program
|
|
137
95
|
.command("run")
|
|
138
|
-
.description("
|
|
139
|
-
.option("--ingest <
|
|
140
|
-
.option("--query <
|
|
141
|
-
.option("--
|
|
142
|
-
.option(
|
|
143
|
-
|
|
144
|
-
"Abort operation after timeout (milliseconds)",
|
|
145
|
-
parsePositiveInteger,
|
|
146
|
-
)
|
|
147
|
-
.option("--parallel", "Enable parallel processing")
|
|
96
|
+
.description("Ingest and/or query in one step")
|
|
97
|
+
.option("--ingest <path>", "File or directory to ingest first")
|
|
98
|
+
.option("--query <text>", "Question to ask after ingesting")
|
|
99
|
+
.option("--rebuild", "Discard the existing index before ingesting")
|
|
100
|
+
.option("--top-k <n>", "Passages to retrieve", parsePositiveInteger, 3)
|
|
101
|
+
.option("--json", "Print the query result as JSON")
|
|
148
102
|
.action(async (options) => {
|
|
149
|
-
await handleRun(this.program.opts(), options);
|
|
103
|
+
await handlers.run().handleRun(this.program.opts(), options);
|
|
150
104
|
});
|
|
151
105
|
|
|
152
|
-
// Doctor command for diagnostics
|
|
153
106
|
this.program
|
|
154
107
|
.command("doctor")
|
|
155
|
-
.description("Diagnose
|
|
156
|
-
.option(
|
|
157
|
-
|
|
158
|
-
|
|
108
|
+
.description("Diagnose configuration, plugins and environment")
|
|
109
|
+
.option(
|
|
110
|
+
"--category <categories...>",
|
|
111
|
+
"Only run: configuration, plugins, dependencies, performance, security, environment",
|
|
112
|
+
)
|
|
113
|
+
.option(
|
|
114
|
+
"--auto-fix",
|
|
115
|
+
"Fix issues where possible (npm install, file permissions)",
|
|
116
|
+
)
|
|
117
|
+
.option("--report <path>", "Save the diagnostic report as JSON")
|
|
159
118
|
.action(async (options) => {
|
|
160
|
-
await handleDoctor(this.program.opts(), options
|
|
119
|
+
await handlers.diagnostics().handleDoctor(this.program.opts(), options);
|
|
161
120
|
});
|
|
162
121
|
|
|
163
|
-
// Enhanced ingest command
|
|
164
122
|
this.program
|
|
165
123
|
.command("ingest")
|
|
166
|
-
.description("
|
|
167
|
-
.argument("<
|
|
168
|
-
.option("--
|
|
169
|
-
.
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
.option("--stats", "Show pipeline metrics summary at the end")
|
|
174
|
-
.option(
|
|
175
|
-
"--export-observability <file>",
|
|
176
|
-
"Export observability data to file",
|
|
177
|
-
)
|
|
178
|
-
.option(
|
|
179
|
-
"--max-concurrency <number>",
|
|
180
|
-
"Maximum concurrent operations",
|
|
181
|
-
"3",
|
|
182
|
-
)
|
|
183
|
-
.option(
|
|
184
|
-
"--batch-size <number>",
|
|
185
|
-
"Batch size for parallel processing",
|
|
186
|
-
"10",
|
|
187
|
-
)
|
|
188
|
-
.option("--max-memory <number>", "Maximum memory usage in MB", "512")
|
|
189
|
-
.action(async (file, options) => {
|
|
190
|
-
await handleIngest(this.program.opts(), file, options);
|
|
124
|
+
.description("Load, embed and index documents")
|
|
125
|
+
.argument("<path>", "File or directory (.md, .html, .csv, .txt)")
|
|
126
|
+
.option("--rebuild", "Discard the existing index before ingesting")
|
|
127
|
+
.action(async (inputPath, options) => {
|
|
128
|
+
await handlers
|
|
129
|
+
.ingest()
|
|
130
|
+
.handleIngest(this.program.opts(), inputPath, options);
|
|
191
131
|
});
|
|
192
132
|
|
|
193
|
-
// Enhanced query command
|
|
194
133
|
this.program
|
|
195
134
|
.command("query")
|
|
196
|
-
.description("
|
|
197
|
-
.argument("<
|
|
198
|
-
.option("--
|
|
199
|
-
.option("--
|
|
200
|
-
.option("--
|
|
201
|
-
.option("--trace", "Enable detailed tracing and event logging")
|
|
202
|
-
.option("--stats", "Show pipeline metrics summary at the end")
|
|
135
|
+
.description("Ask a question against the ingested documents")
|
|
136
|
+
.argument("<question>", "Question text")
|
|
137
|
+
.option("--top-k <n>", "Passages to retrieve", parsePositiveInteger, 3)
|
|
138
|
+
.option("--json", "Print the result as JSON")
|
|
139
|
+
.option("--streaming", "Print the answer as it is generated")
|
|
203
140
|
.option(
|
|
204
|
-
"--
|
|
205
|
-
"
|
|
141
|
+
"--timeout <ms>",
|
|
142
|
+
"Abort the query after this many milliseconds",
|
|
143
|
+
parsePositiveInteger,
|
|
144
|
+
)
|
|
145
|
+
.option("--trace", "Show time spent in each stage")
|
|
146
|
+
.option(
|
|
147
|
+
"--explain",
|
|
148
|
+
"Show passage scores and which passages support each answer sentence",
|
|
206
149
|
)
|
|
207
|
-
.
|
|
208
|
-
|
|
150
|
+
.option("--stats", "Show latency and estimated tokens and cost")
|
|
151
|
+
.action(async (question, options) => {
|
|
152
|
+
await handlers
|
|
153
|
+
.query()
|
|
154
|
+
.handleQuery(this.program.opts(), question, options);
|
|
209
155
|
});
|
|
210
156
|
|
|
211
|
-
// Configuration validation command
|
|
212
157
|
this.program
|
|
213
158
|
.command("validate")
|
|
214
|
-
.description("Validate configuration
|
|
215
|
-
.
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
159
|
+
.description("Validate the configuration and resolve its components")
|
|
160
|
+
.action(async () => {
|
|
161
|
+
await handlers.diagnostics().handleValidate(this.program.opts());
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
this.program
|
|
165
|
+
.command("serve")
|
|
166
|
+
.description("Serve GET /health and POST /query over HTTP (local use)")
|
|
167
|
+
.option(
|
|
168
|
+
"--port <n>",
|
|
169
|
+
"Port (0 picks a free one)",
|
|
170
|
+
parseNonNegativeInt,
|
|
171
|
+
3000,
|
|
172
|
+
)
|
|
173
|
+
.option("--host <host>", "Interface to bind", "127.0.0.1")
|
|
219
174
|
.action(async (options) => {
|
|
220
|
-
|
|
175
|
+
const { handleServe } = require("./handlers/serve-handler.js");
|
|
176
|
+
await handleServe(this.program.opts(), options);
|
|
221
177
|
});
|
|
222
178
|
|
|
223
|
-
|
|
224
|
-
this.program.addCommand(
|
|
179
|
+
const { PluginHubCLI } = require("./commands/plugin-hub.js");
|
|
180
|
+
this.program.addCommand(new PluginHubCLI().createCommands());
|
|
181
|
+
|
|
182
|
+
const { createAiCommand } = require("./commands/ai.js");
|
|
183
|
+
this.program.addCommand(createAiCommand(() => this.program.opts()));
|
|
225
184
|
|
|
226
185
|
// Configuration management commands
|
|
227
186
|
const configCmd = new Command("config");
|
|
@@ -230,10 +189,9 @@ class EnhancedCLI {
|
|
|
230
189
|
configCmd
|
|
231
190
|
.command("show")
|
|
232
191
|
.description("Show current configuration")
|
|
233
|
-
.option("--format <format>", "Output format (json, yaml, table)", "json")
|
|
234
192
|
.option("--section <section>", "Show specific configuration section")
|
|
235
193
|
.action(async (options) => {
|
|
236
|
-
await handleConfigShow(this.program.opts(), options);
|
|
194
|
+
await handlers.config().handleConfigShow(this.program.opts(), options);
|
|
237
195
|
});
|
|
238
196
|
|
|
239
197
|
configCmd
|
|
@@ -242,7 +200,9 @@ class EnhancedCLI {
|
|
|
242
200
|
.argument("<key>", "Configuration key (dot notation supported)")
|
|
243
201
|
.argument("<value>", "Configuration value")
|
|
244
202
|
.action(async (key, value, options) => {
|
|
245
|
-
await
|
|
203
|
+
await handlers
|
|
204
|
+
.config()
|
|
205
|
+
.handleConfigSet(this.program.opts(), key, value);
|
|
246
206
|
});
|
|
247
207
|
|
|
248
208
|
configCmd
|
|
@@ -250,7 +210,7 @@ class EnhancedCLI {
|
|
|
250
210
|
.description("Get configuration value")
|
|
251
211
|
.argument("<key>", "Configuration key (dot notation supported)")
|
|
252
212
|
.action(async (key, options) => {
|
|
253
|
-
await handleConfigGet(this.program.opts(), key);
|
|
213
|
+
await handlers.config().handleConfigGet(this.program.opts(), key);
|
|
254
214
|
});
|
|
255
215
|
|
|
256
216
|
this.program.addCommand(configCmd);
|
|
@@ -259,11 +219,11 @@ class EnhancedCLI {
|
|
|
259
219
|
this.program
|
|
260
220
|
.command("info")
|
|
261
221
|
.description("Show system and plugin information")
|
|
262
|
-
.option("--plugins", "Show
|
|
222
|
+
.option("--plugins", "Show built-in components and custom plugins")
|
|
263
223
|
.option("--system", "Show system information")
|
|
264
224
|
.option("--config", "Show configuration summary")
|
|
265
225
|
.action(async (options) => {
|
|
266
|
-
await handleInfo(this.program.opts(), options);
|
|
226
|
+
await handlers.diagnostics().handleInfo(this.program.opts(), options);
|
|
267
227
|
});
|
|
268
228
|
|
|
269
229
|
// Completion command for shell autocompletion
|
|
@@ -277,64 +237,6 @@ class EnhancedCLI {
|
|
|
277
237
|
});
|
|
278
238
|
}
|
|
279
239
|
|
|
280
|
-
/**
|
|
281
|
-
* Create basic configuration
|
|
282
|
-
*/
|
|
283
|
-
async createBasicConfig(outputPath) {
|
|
284
|
-
const { validateRagrc } = require("../config/enhanced-ragrc-schema.js");
|
|
285
|
-
|
|
286
|
-
const base = {
|
|
287
|
-
namespace: "default",
|
|
288
|
-
metadata: {
|
|
289
|
-
name: "rag-pipeline",
|
|
290
|
-
version: "1.0.0",
|
|
291
|
-
description: "RAG pipeline configuration",
|
|
292
|
-
createdAt: new Date().toISOString(),
|
|
293
|
-
},
|
|
294
|
-
pipeline: [
|
|
295
|
-
{ stage: "loader", name: "fs-loader", version: "1.0.0" },
|
|
296
|
-
{ stage: "embedder", name: "mock-embedder", version: "1.0.0" },
|
|
297
|
-
{ stage: "retriever", name: "mock-retriever", version: "1.0.0" },
|
|
298
|
-
{ stage: "llm", name: "mock-llm", version: "1.0.0" },
|
|
299
|
-
],
|
|
300
|
-
performance: {
|
|
301
|
-
parallel: {
|
|
302
|
-
enabled: false,
|
|
303
|
-
maxConcurrency: 3,
|
|
304
|
-
},
|
|
305
|
-
caching: {
|
|
306
|
-
enabled: false,
|
|
307
|
-
maxSize: 1000,
|
|
308
|
-
ttl: 3600,
|
|
309
|
-
},
|
|
310
|
-
},
|
|
311
|
-
observability: {
|
|
312
|
-
logging: {
|
|
313
|
-
level: "info",
|
|
314
|
-
structured: true,
|
|
315
|
-
},
|
|
316
|
-
},
|
|
317
|
-
};
|
|
318
|
-
|
|
319
|
-
const result = validateRagrc(base);
|
|
320
|
-
if (!result.valid) {
|
|
321
|
-
result.errors?.forEach((error) =>
|
|
322
|
-
console.error(` ${error.instancePath || ""}: ${error.message}`),
|
|
323
|
-
);
|
|
324
|
-
throw new Error("Failed to generate valid configuration");
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
if (outputPath) {
|
|
328
|
-
await fs.writeFile(
|
|
329
|
-
outputPath,
|
|
330
|
-
JSON.stringify(result.normalized, null, 2),
|
|
331
|
-
);
|
|
332
|
-
console.log(`✅ Basic configuration created: ${outputPath}`);
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
return result.normalized;
|
|
336
|
-
}
|
|
337
|
-
|
|
338
240
|
/**
|
|
339
241
|
* Run the CLI
|
|
340
242
|
*/
|
|
@@ -363,39 +265,8 @@ async function runEnhancedCLI(argv = process.argv) {
|
|
|
363
265
|
await enhancedCLI.run(argv);
|
|
364
266
|
}
|
|
365
267
|
|
|
366
|
-
// CLI command surface for tests
|
|
367
|
-
const init = async () => ({ ok: true });
|
|
368
|
-
const ingest = async () => ({ ok: true });
|
|
369
|
-
const query = async () => ({ ok: true });
|
|
370
|
-
const handleError = async () => ({ ok: true });
|
|
371
|
-
const validateArgs = () => true;
|
|
372
|
-
const showHelp = () => "help text";
|
|
373
|
-
|
|
374
|
-
// Extract createBasicConfig from the class for direct export
|
|
375
|
-
const createBasicConfig = async (outputPath) => {
|
|
376
|
-
const cli = new EnhancedCLI();
|
|
377
|
-
return await cli.createBasicConfig(outputPath);
|
|
378
|
-
};
|
|
379
|
-
|
|
380
|
-
const enhancedCliCommands = {
|
|
381
|
-
init,
|
|
382
|
-
ingest,
|
|
383
|
-
query,
|
|
384
|
-
handleError,
|
|
385
|
-
validateArgs,
|
|
386
|
-
showHelp,
|
|
387
|
-
};
|
|
388
|
-
|
|
389
268
|
module.exports = {
|
|
390
269
|
EnhancedCLI,
|
|
391
270
|
enhancedCLI,
|
|
392
271
|
runEnhancedCLI,
|
|
393
|
-
enhancedCliCommands,
|
|
394
|
-
init,
|
|
395
|
-
ingest,
|
|
396
|
-
query,
|
|
397
|
-
handleError,
|
|
398
|
-
validateArgs,
|
|
399
|
-
showHelp,
|
|
400
|
-
createBasicConfig,
|
|
401
272
|
};
|