ragcode-context-engine 0.1.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/LICENSE +21 -0
- package/README.md +366 -0
- package/README.zh-CN.md +363 -0
- package/dist/src/cli/configure/app.d.ts +6 -0
- package/dist/src/cli/configure/app.js +81 -0
- package/dist/src/cli/configure/run.d.ts +5 -0
- package/dist/src/cli/configure/run.js +85 -0
- package/dist/src/cli/configure/state.d.ts +42 -0
- package/dist/src/cli/configure/state.js +174 -0
- package/dist/src/cli/configure.d.ts +31 -0
- package/dist/src/cli/configure.js +101 -0
- package/dist/src/cli/index.d.ts +2 -0
- package/dist/src/cli/index.js +503 -0
- package/dist/src/cli/tui/index-progress.d.ts +12 -0
- package/dist/src/cli/tui/index-progress.js +49 -0
- package/dist/src/cli/tui/watch-status.d.ts +10 -0
- package/dist/src/cli/tui/watch-status.js +27 -0
- package/dist/src/cli/update.d.ts +18 -0
- package/dist/src/cli/update.js +111 -0
- package/dist/src/config/dotenv.d.ts +1 -0
- package/dist/src/config/dotenv.js +14 -0
- package/dist/src/config/graph-runtime.d.ts +13 -0
- package/dist/src/config/graph-runtime.js +29 -0
- package/dist/src/config/runtime-config.d.ts +87 -0
- package/dist/src/config/runtime-config.js +215 -0
- package/dist/src/config/semantic-runtime.d.ts +24 -0
- package/dist/src/config/semantic-runtime.js +89 -0
- package/dist/src/context/context-builder.d.ts +20 -0
- package/dist/src/context/context-builder.js +277 -0
- package/dist/src/context/expansion-policy.d.ts +6 -0
- package/dist/src/context/expansion-policy.js +49 -0
- package/dist/src/context/skeletonizer.d.ts +2 -0
- package/dist/src/context/skeletonizer.js +79 -0
- package/dist/src/context/snippet-renderer.d.ts +2 -0
- package/dist/src/context/snippet-renderer.js +67 -0
- package/dist/src/core/contracts.d.ts +74 -0
- package/dist/src/core/contracts.js +1 -0
- package/dist/src/core/engine.d.ts +64 -0
- package/dist/src/core/engine.js +442 -0
- package/dist/src/core/types.d.ts +490 -0
- package/dist/src/core/types.js +1 -0
- package/dist/src/diagnostics/doctor.d.ts +66 -0
- package/dist/src/diagnostics/doctor.js +193 -0
- package/dist/src/diagnostics/embedding-test.d.ts +24 -0
- package/dist/src/diagnostics/embedding-test.js +83 -0
- package/dist/src/graph/diff-files.d.ts +1 -0
- package/dist/src/graph/diff-files.js +14 -0
- package/dist/src/graph/impact-report.d.ts +10 -0
- package/dist/src/graph/impact-report.js +173 -0
- package/dist/src/graph/in-memory-graph-store.d.ts +36 -0
- package/dist/src/graph/in-memory-graph-store.js +395 -0
- package/dist/src/graph/owner-ranking.d.ts +2 -0
- package/dist/src/graph/owner-ranking.js +41 -0
- package/dist/src/graph/sqlite-graph-store.d.ts +51 -0
- package/dist/src/graph/sqlite-graph-store.js +724 -0
- package/dist/src/graph/sqlite-statements.d.ts +36 -0
- package/dist/src/graph/sqlite-statements.js +105 -0
- package/dist/src/graph/target-matcher.d.ts +13 -0
- package/dist/src/graph/target-matcher.js +64 -0
- package/dist/src/index.d.ts +32 -0
- package/dist/src/index.js +32 -0
- package/dist/src/indexing/analyzers/fallback-analyzer.d.ts +6 -0
- package/dist/src/indexing/analyzers/fallback-analyzer.js +45 -0
- package/dist/src/indexing/analyzers/go-treesitter-analyzer.d.ts +2 -0
- package/dist/src/indexing/analyzers/go-treesitter-analyzer.js +87 -0
- package/dist/src/indexing/analyzers/java-treesitter-analyzer.d.ts +2 -0
- package/dist/src/indexing/analyzers/java-treesitter-analyzer.js +88 -0
- package/dist/src/indexing/analyzers/python-treesitter-analyzer.d.ts +2 -0
- package/dist/src/indexing/analyzers/python-treesitter-analyzer.js +96 -0
- package/dist/src/indexing/analyzers/registry.d.ts +5 -0
- package/dist/src/indexing/analyzers/registry.js +23 -0
- package/dist/src/indexing/analyzers/rust-treesitter-analyzer.d.ts +2 -0
- package/dist/src/indexing/analyzers/rust-treesitter-analyzer.js +96 -0
- package/dist/src/indexing/analyzers/tree-sitter-base.d.ts +30 -0
- package/dist/src/indexing/analyzers/tree-sitter-base.js +163 -0
- package/dist/src/indexing/analyzers/types.d.ts +17 -0
- package/dist/src/indexing/analyzers/types.js +1 -0
- package/dist/src/indexing/analyzers/typescript-analyzer.d.ts +5 -0
- package/dist/src/indexing/analyzers/typescript-analyzer.js +199 -0
- package/dist/src/indexing/ast-analyzer.d.ts +11 -0
- package/dist/src/indexing/ast-analyzer.js +11 -0
- package/dist/src/indexing/chunker.d.ts +11 -0
- package/dist/src/indexing/chunker.js +157 -0
- package/dist/src/indexing/ignore-policy.d.ts +6 -0
- package/dist/src/indexing/ignore-policy.js +40 -0
- package/dist/src/indexing/indexer.d.ts +13 -0
- package/dist/src/indexing/indexer.js +189 -0
- package/dist/src/indexing/language.d.ts +3 -0
- package/dist/src/indexing/language.js +24 -0
- package/dist/src/indexing/scanner.d.ts +13 -0
- package/dist/src/indexing/scanner.js +87 -0
- package/dist/src/lsp/definition-resolver.d.ts +6 -0
- package/dist/src/lsp/definition-resolver.js +60 -0
- package/dist/src/lsp/typescript-language-service.d.ts +21 -0
- package/dist/src/lsp/typescript-language-service.js +82 -0
- package/dist/src/mcp/server.d.ts +11 -0
- package/dist/src/mcp/server.js +64 -0
- package/dist/src/mcp/tools.d.ts +266 -0
- package/dist/src/mcp/tools.js +309 -0
- package/dist/src/project/project-identity.d.ts +2 -0
- package/dist/src/project/project-identity.js +24 -0
- package/dist/src/project/project-registry.d.ts +12 -0
- package/dist/src/project/project-registry.js +49 -0
- package/dist/src/project/workspace-resolver.d.ts +20 -0
- package/dist/src/project/workspace-resolver.js +62 -0
- package/dist/src/retrieval/graph-reranker.d.ts +11 -0
- package/dist/src/retrieval/graph-reranker.js +0 -0
- package/dist/src/retrieval/hybrid-retriever.d.ts +31 -0
- package/dist/src/retrieval/hybrid-retriever.js +111 -0
- package/dist/src/retrieval/path-classification.d.ts +6 -0
- package/dist/src/retrieval/path-classification.js +22 -0
- package/dist/src/retrieval/query-matching.d.ts +22 -0
- package/dist/src/retrieval/query-matching.js +166 -0
- package/dist/src/retrieval/query-planner.d.ts +5 -0
- package/dist/src/retrieval/query-planner.js +77 -0
- package/dist/src/retrieval/ranking-signals.d.ts +19 -0
- package/dist/src/retrieval/ranking-signals.js +97 -0
- package/dist/src/retrieval/topology-distance.d.ts +21 -0
- package/dist/src/retrieval/topology-distance.js +116 -0
- package/dist/src/reuse/reuse-detector.d.ts +12 -0
- package/dist/src/reuse/reuse-detector.js +564 -0
- package/dist/src/semantic/deterministic-embedding.d.ts +7 -0
- package/dist/src/semantic/deterministic-embedding.js +31 -0
- package/dist/src/semantic/in-memory-semantic-store.d.ts +11 -0
- package/dist/src/semantic/in-memory-semantic-store.js +65 -0
- package/dist/src/semantic/lance-semantic-store.d.ts +131 -0
- package/dist/src/semantic/lance-semantic-store.js +623 -0
- package/dist/src/semantic/openai-compatible-embedding.d.ts +19 -0
- package/dist/src/semantic/openai-compatible-embedding.js +75 -0
- package/dist/src/service/service-identity.d.ts +13 -0
- package/dist/src/service/service-identity.js +48 -0
- package/dist/src/service/service-manager.d.ts +29 -0
- package/dist/src/service/service-manager.js +231 -0
- package/dist/src/service/service-templates.d.ts +22 -0
- package/dist/src/service/service-templates.js +101 -0
- package/dist/src/subgraph/impact-explainer.d.ts +2 -0
- package/dist/src/subgraph/impact-explainer.js +54 -0
- package/dist/src/subgraph/node-expander.d.ts +13 -0
- package/dist/src/subgraph/node-expander.js +139 -0
- package/dist/src/subgraph/output-preset.d.ts +3 -0
- package/dist/src/subgraph/output-preset.js +102 -0
- package/dist/src/subgraph/subgraph-builder.d.ts +17 -0
- package/dist/src/subgraph/subgraph-builder.js +688 -0
- package/dist/src/topology/export-index.d.ts +7 -0
- package/dist/src/topology/export-index.js +14 -0
- package/dist/src/topology/framework-topology.d.ts +3 -0
- package/dist/src/topology/framework-topology.js +460 -0
- package/dist/src/topology/import-resolver.d.ts +2 -0
- package/dist/src/topology/import-resolver.js +29 -0
- package/dist/src/topology/orm-topology.d.ts +3 -0
- package/dist/src/topology/orm-topology.js +200 -0
- package/dist/src/topology/runtime-topology.d.ts +3 -0
- package/dist/src/topology/runtime-topology.js +204 -0
- package/dist/src/topology/symbol-resolver.d.ts +6 -0
- package/dist/src/topology/symbol-resolver.js +74 -0
- package/dist/src/topology/test-topology.d.ts +2 -0
- package/dist/src/topology/test-topology.js +82 -0
- package/dist/src/utils/hash.d.ts +2 -0
- package/dist/src/utils/hash.js +7 -0
- package/dist/src/utils/path.d.ts +2 -0
- package/dist/src/utils/path.js +7 -0
- package/dist/src/watch/event-journal.d.ts +17 -0
- package/dist/src/watch/event-journal.js +81 -0
- package/dist/src/watch/file-event-coalescer.d.ts +9 -0
- package/dist/src/watch/file-event-coalescer.js +39 -0
- package/dist/src/watch/index-scheduler.d.ts +52 -0
- package/dist/src/watch/index-scheduler.js +190 -0
- package/dist/src/watch/watch-daemon.d.ts +73 -0
- package/dist/src/watch/watch-daemon.js +368 -0
- package/dist/src/watch/watcher-liveness.d.ts +47 -0
- package/dist/src/watch/watcher-liveness.js +168 -0
- package/dist/src/web/server.d.ts +1 -0
- package/dist/src/web/server.js +375 -0
- package/package.json +94 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { promisify } from "node:util";
|
|
3
|
+
import { createRequire } from "node:module";
|
|
4
|
+
const execFileAsync = promisify(execFile);
|
|
5
|
+
// `ragcode update` upgrades the globally-installed CLI in place. We don't bundle an auto-updater;
|
|
6
|
+
// we shell out to the package manager that owns the global install. The published package name is
|
|
7
|
+
// `ragcode-context-engine` (see package.json), which is what npm/pnpm/yarn install globally.
|
|
8
|
+
export const PACKAGE_NAME = "ragcode-context-engine";
|
|
9
|
+
function currentVersion() {
|
|
10
|
+
// The package.json depth differs between source (src/cli/update.ts -> ../../package.json) and the
|
|
11
|
+
// built layout (dist/src/cli/update.js -> ../../../package.json), so try both rather than guessing.
|
|
12
|
+
const require = createRequire(import.meta.url);
|
|
13
|
+
for (const candidate of ["../../package.json", "../../../package.json"]) {
|
|
14
|
+
try {
|
|
15
|
+
const pkg = require(candidate);
|
|
16
|
+
if (pkg.name === PACKAGE_NAME && pkg.version)
|
|
17
|
+
return pkg.version;
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
// try the next candidate
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return "unknown";
|
|
24
|
+
}
|
|
25
|
+
// Auto-detect the package manager from the npm_config_user_agent the parent PM exposes, falling
|
|
26
|
+
// back to npm. This keeps a pnpm-global install from being "updated" by npm into a broken state.
|
|
27
|
+
function detectPackageManager(env = process.env) {
|
|
28
|
+
const agent = env.npm_config_user_agent ?? "";
|
|
29
|
+
if (agent.startsWith("pnpm"))
|
|
30
|
+
return "pnpm";
|
|
31
|
+
if (agent.startsWith("yarn"))
|
|
32
|
+
return "yarn";
|
|
33
|
+
return "npm";
|
|
34
|
+
}
|
|
35
|
+
async function fetchLatestVersion() {
|
|
36
|
+
// `npm view` works even under pnpm/yarn since npm is virtually always present; if it's not,
|
|
37
|
+
// the catch downgrades us to a best-effort install without a pre-check.
|
|
38
|
+
try {
|
|
39
|
+
const { stdout } = await execFileAsync("npm", ["view", PACKAGE_NAME, "version"]);
|
|
40
|
+
const version = stdout.trim();
|
|
41
|
+
return version.length > 0 ? version : undefined;
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function installArgv(pm, spec) {
|
|
48
|
+
switch (pm) {
|
|
49
|
+
case "pnpm":
|
|
50
|
+
return { file: "pnpm", args: ["add", "-g", spec] };
|
|
51
|
+
case "yarn":
|
|
52
|
+
return { file: "yarn", args: ["global", "add", spec] };
|
|
53
|
+
default:
|
|
54
|
+
return { file: "npm", args: ["install", "-g", spec] };
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
export async function runUpdate(options = {}) {
|
|
58
|
+
const current = currentVersion();
|
|
59
|
+
const pm = options.packageManager ?? detectPackageManager();
|
|
60
|
+
const target = options.version ?? "latest";
|
|
61
|
+
const latest = target === "latest" ? await fetchLatestVersion() : target;
|
|
62
|
+
const upToDate = Boolean(latest && latest === current);
|
|
63
|
+
if (options.checkOnly) {
|
|
64
|
+
return {
|
|
65
|
+
ok: true,
|
|
66
|
+
currentVersion: current,
|
|
67
|
+
latestVersion: latest,
|
|
68
|
+
upToDate,
|
|
69
|
+
installed: false,
|
|
70
|
+
message: latest
|
|
71
|
+
? upToDate
|
|
72
|
+
? `RagCode is up to date (${current}).`
|
|
73
|
+
: `Update available: ${current} → ${latest}. Run \`ragcode update\` to install.`
|
|
74
|
+
: `Installed version ${current}. Could not reach the registry to check for updates.`
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
if (upToDate) {
|
|
78
|
+
return {
|
|
79
|
+
ok: true,
|
|
80
|
+
currentVersion: current,
|
|
81
|
+
latestVersion: latest,
|
|
82
|
+
upToDate: true,
|
|
83
|
+
installed: false,
|
|
84
|
+
message: `RagCode is already up to date (${current}).`
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
const spec = `${PACKAGE_NAME}@${target}`;
|
|
88
|
+
const { file, args } = installArgv(pm, spec);
|
|
89
|
+
try {
|
|
90
|
+
await execFileAsync(file, args);
|
|
91
|
+
return {
|
|
92
|
+
ok: true,
|
|
93
|
+
currentVersion: current,
|
|
94
|
+
latestVersion: latest,
|
|
95
|
+
upToDate: false,
|
|
96
|
+
installed: true,
|
|
97
|
+
message: `Updated RagCode via ${pm} (${current} → ${latest ?? target}). Restart any running watchers and MCP clients to pick up the new version.`
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
const err = error;
|
|
102
|
+
return {
|
|
103
|
+
ok: false,
|
|
104
|
+
currentVersion: current,
|
|
105
|
+
latestVersion: latest,
|
|
106
|
+
upToDate: false,
|
|
107
|
+
installed: false,
|
|
108
|
+
message: `Update via ${pm} failed: ${(err.stderr ?? err.message ?? "").trim()}. You can update manually with \`${file} ${args.join(" ")}\`.`
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function loadDotEnv(cwd?: string, env?: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { parseEnv } from "node:util";
|
|
4
|
+
export function loadDotEnv(cwd = process.cwd(), env = process.env) {
|
|
5
|
+
const filePath = path.join(cwd, ".env");
|
|
6
|
+
if (!fs.existsSync(filePath))
|
|
7
|
+
return env;
|
|
8
|
+
const parsed = parseEnv(fs.readFileSync(filePath, "utf8"));
|
|
9
|
+
for (const [key, value] of Object.entries(parsed)) {
|
|
10
|
+
if (env[key] === undefined)
|
|
11
|
+
env[key] = value;
|
|
12
|
+
}
|
|
13
|
+
return env;
|
|
14
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { GraphStore } from "../core/contracts.js";
|
|
2
|
+
export type GraphStoreKind = "memory" | "sqlite";
|
|
3
|
+
export interface GraphRuntimeConfig {
|
|
4
|
+
graphStore: GraphStoreKind;
|
|
5
|
+
sqlitePath: string;
|
|
6
|
+
}
|
|
7
|
+
export interface GraphRuntimeComponents {
|
|
8
|
+
graphStore: GraphStore;
|
|
9
|
+
config: GraphRuntimeConfig;
|
|
10
|
+
}
|
|
11
|
+
export declare function createGraphRuntimeFromEnv(env?: NodeJS.ProcessEnv, cwd?: string): GraphRuntimeComponents;
|
|
12
|
+
export declare function createGraphRuntimeFromConfig(config: GraphRuntimeConfig): GraphRuntimeComponents;
|
|
13
|
+
export declare function readGraphRuntimeConfig(env?: NodeJS.ProcessEnv, cwd?: string): GraphRuntimeConfig;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { InMemoryGraphStore } from "../graph/in-memory-graph-store.js";
|
|
4
|
+
import { SQLiteGraphStore } from "../graph/sqlite-graph-store.js";
|
|
5
|
+
export function createGraphRuntimeFromEnv(env = process.env, cwd = process.cwd()) {
|
|
6
|
+
const config = readGraphRuntimeConfig(env, cwd);
|
|
7
|
+
return createGraphRuntimeFromConfig(config);
|
|
8
|
+
}
|
|
9
|
+
export function createGraphRuntimeFromConfig(config) {
|
|
10
|
+
if (config.graphStore === "memory") {
|
|
11
|
+
return { graphStore: new InMemoryGraphStore(), config };
|
|
12
|
+
}
|
|
13
|
+
fs.mkdirSync(path.dirname(config.sqlitePath), { recursive: true });
|
|
14
|
+
return { graphStore: new SQLiteGraphStore(config.sqlitePath), config };
|
|
15
|
+
}
|
|
16
|
+
export function readGraphRuntimeConfig(env = process.env, cwd = process.cwd()) {
|
|
17
|
+
const graphStore = enumValue(env.RAGCODE_GRAPH_STORE, ["memory", "sqlite"], "memory");
|
|
18
|
+
return {
|
|
19
|
+
graphStore,
|
|
20
|
+
sqlitePath: env.RAGCODE_SQLITE_PATH ?? path.join(cwd, ".ragcode", "graph.sqlite")
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function enumValue(value, allowed, fallback) {
|
|
24
|
+
if (!value)
|
|
25
|
+
return fallback;
|
|
26
|
+
if (allowed.includes(value))
|
|
27
|
+
return value;
|
|
28
|
+
throw new Error(`Invalid graph runtime value "${value}". Expected one of: ${allowed.join(", ")}.`);
|
|
29
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { GraphStore } from "../core/contracts.js";
|
|
2
|
+
import type { EmbeddingProvider, SemanticStore } from "../core/contracts.js";
|
|
3
|
+
import { type GraphRuntimeConfig } from "./graph-runtime.js";
|
|
4
|
+
import { type SemanticRuntimeConfig } from "./semantic-runtime.js";
|
|
5
|
+
export interface RuntimeConfigFile {
|
|
6
|
+
graphStore?: string;
|
|
7
|
+
sqlitePath?: string;
|
|
8
|
+
semanticStore?: string;
|
|
9
|
+
lancedbUri?: string;
|
|
10
|
+
lanceDbUri?: string;
|
|
11
|
+
lancedbTable?: string;
|
|
12
|
+
lanceDbTableName?: string;
|
|
13
|
+
embeddingProvider?: string;
|
|
14
|
+
embeddingBaseUrl?: string;
|
|
15
|
+
embeddingApiKey?: string;
|
|
16
|
+
embeddingModel?: string;
|
|
17
|
+
embeddingDimensions?: number | string;
|
|
18
|
+
embeddingRequestDimensions?: boolean | string;
|
|
19
|
+
embeddingBatchSize?: number | string;
|
|
20
|
+
embeddingConcurrency?: number | string;
|
|
21
|
+
semanticMaxChunks?: number | string;
|
|
22
|
+
}
|
|
23
|
+
export interface RuntimeConfigOverrides extends RuntimeConfigFile {
|
|
24
|
+
repoRoot?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface RuntimeConfig {
|
|
27
|
+
repoRoot: string;
|
|
28
|
+
configPath: string;
|
|
29
|
+
graph: GraphRuntimeConfig;
|
|
30
|
+
semantic: SemanticRuntimeConfig;
|
|
31
|
+
embeddingApiKey?: string;
|
|
32
|
+
sources: Record<string, "override" | "env" | "config" | "default">;
|
|
33
|
+
}
|
|
34
|
+
export interface RuntimeComponents {
|
|
35
|
+
graphStore: GraphStore;
|
|
36
|
+
semanticStore: SemanticStore;
|
|
37
|
+
embeddingProvider: EmbeddingProvider;
|
|
38
|
+
config: RuntimeConfig;
|
|
39
|
+
}
|
|
40
|
+
export interface RedactedRuntimeConfig {
|
|
41
|
+
repoRoot: string;
|
|
42
|
+
configPath: string;
|
|
43
|
+
graphStore: RuntimeConfig["graph"]["graphStore"];
|
|
44
|
+
sqlitePath: string;
|
|
45
|
+
semanticStore: RuntimeConfig["semantic"]["semanticStore"];
|
|
46
|
+
lancedbUri?: string;
|
|
47
|
+
lanceDbTableName: string;
|
|
48
|
+
embeddingProvider: RuntimeConfig["semantic"]["embeddingProvider"];
|
|
49
|
+
embeddingBaseUrl?: string;
|
|
50
|
+
embeddingModel?: string;
|
|
51
|
+
embeddingDimensions?: number;
|
|
52
|
+
embeddingRequestDimensions: boolean;
|
|
53
|
+
embeddingBatchSize: number;
|
|
54
|
+
embeddingConcurrency: number;
|
|
55
|
+
semanticMaxChunks?: number;
|
|
56
|
+
embeddingApiKey: "set" | "unset" | "redacted";
|
|
57
|
+
sources: RuntimeConfig["sources"];
|
|
58
|
+
}
|
|
59
|
+
export declare const DEFAULT_RUNTIME_CONFIG: {
|
|
60
|
+
readonly graphStore: "sqlite";
|
|
61
|
+
readonly sqlitePath: string;
|
|
62
|
+
readonly semanticStore: "lancedb";
|
|
63
|
+
readonly lancedbUri: string;
|
|
64
|
+
readonly lanceDbTableName: "code_chunks";
|
|
65
|
+
readonly embeddingProvider: "deterministic";
|
|
66
|
+
readonly embeddingBaseUrl: "https://api.openai.com/v1";
|
|
67
|
+
readonly embeddingBatchSize: 64;
|
|
68
|
+
readonly embeddingConcurrency: 1;
|
|
69
|
+
readonly embeddingRequestDimensions: false;
|
|
70
|
+
};
|
|
71
|
+
export declare function loadRuntimeConfig(options?: {
|
|
72
|
+
cwd?: string;
|
|
73
|
+
env?: NodeJS.ProcessEnv;
|
|
74
|
+
overrides?: RuntimeConfigOverrides;
|
|
75
|
+
}): RuntimeConfig;
|
|
76
|
+
export declare function createRuntimeComponents(config: RuntimeConfig): RuntimeComponents;
|
|
77
|
+
export declare function createRuntimeComponentsForRepo(options?: {
|
|
78
|
+
cwd?: string;
|
|
79
|
+
env?: NodeJS.ProcessEnv;
|
|
80
|
+
overrides?: RuntimeConfigOverrides;
|
|
81
|
+
}): RuntimeComponents;
|
|
82
|
+
export declare function writeRuntimeConfigFile(repoRoot: string, config: RuntimeConfigFile): string;
|
|
83
|
+
export declare function runtimeConfigToEnv(config: RuntimeConfig, options?: {
|
|
84
|
+
includeSecrets?: boolean;
|
|
85
|
+
}): Record<string, string>;
|
|
86
|
+
export declare function redactRuntimeConfig(config: RuntimeConfig): RedactedRuntimeConfig;
|
|
87
|
+
export declare function readRuntimeConfigFile(configPath: string): RuntimeConfigFile;
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { createGraphRuntimeFromConfig } from "./graph-runtime.js";
|
|
4
|
+
import { createSemanticRuntimeFromConfig } from "./semantic-runtime.js";
|
|
5
|
+
export const DEFAULT_RUNTIME_CONFIG = {
|
|
6
|
+
graphStore: "sqlite",
|
|
7
|
+
sqlitePath: path.join(".ragcode", "graph.sqlite"),
|
|
8
|
+
semanticStore: "lancedb",
|
|
9
|
+
lancedbUri: path.join(".ragcode", "lancedb"),
|
|
10
|
+
lanceDbTableName: "code_chunks",
|
|
11
|
+
embeddingProvider: "deterministic",
|
|
12
|
+
embeddingBaseUrl: "https://api.openai.com/v1",
|
|
13
|
+
embeddingBatchSize: 64,
|
|
14
|
+
embeddingConcurrency: 1,
|
|
15
|
+
embeddingRequestDimensions: false
|
|
16
|
+
};
|
|
17
|
+
const CONFIG_FILE_NAME = path.join(".ragcode", "config.json");
|
|
18
|
+
export function loadRuntimeConfig(options = {}) {
|
|
19
|
+
const env = options.env ?? process.env;
|
|
20
|
+
const repoRoot = path.resolve(options.overrides?.repoRoot ?? env.RAGCODE_REPO_ROOT ?? options.cwd ?? process.cwd());
|
|
21
|
+
const configPath = path.join(repoRoot, CONFIG_FILE_NAME);
|
|
22
|
+
const fileConfig = readRuntimeConfigFile(configPath);
|
|
23
|
+
const sources = {};
|
|
24
|
+
const graphStore = selectString("graphStore", options.overrides?.graphStore, env.RAGCODE_GRAPH_STORE, fileConfig.graphStore, DEFAULT_RUNTIME_CONFIG.graphStore, sources);
|
|
25
|
+
const sqlitePath = resolveRepoPath(repoRoot, selectString("sqlitePath", options.overrides?.sqlitePath, env.RAGCODE_SQLITE_PATH, fileConfig.sqlitePath, DEFAULT_RUNTIME_CONFIG.sqlitePath, sources));
|
|
26
|
+
const semanticStore = selectString("semanticStore", options.overrides?.semanticStore, env.RAGCODE_SEMANTIC_STORE, fileConfig.semanticStore, DEFAULT_RUNTIME_CONFIG.semanticStore, sources);
|
|
27
|
+
const lanceDbUri = resolveRepoPath(repoRoot, selectString("lancedbUri", options.overrides?.lancedbUri ?? options.overrides?.lanceDbUri, env.RAGCODE_LANCEDB_URI, fileConfig.lancedbUri ?? fileConfig.lanceDbUri, DEFAULT_RUNTIME_CONFIG.lancedbUri, sources));
|
|
28
|
+
const lanceDbTableName = selectString("lanceDbTableName", options.overrides?.lanceDbTableName ?? options.overrides?.lancedbTable, env.RAGCODE_LANCEDB_TABLE, fileConfig.lanceDbTableName ?? fileConfig.lancedbTable, DEFAULT_RUNTIME_CONFIG.lanceDbTableName, sources);
|
|
29
|
+
const embeddingProvider = normalizeEmbeddingProvider(selectString("embeddingProvider", options.overrides?.embeddingProvider, env.RAGCODE_EMBEDDING_PROVIDER, fileConfig.embeddingProvider, DEFAULT_RUNTIME_CONFIG.embeddingProvider, sources));
|
|
30
|
+
const embeddingBaseUrl = selectString("embeddingBaseUrl", options.overrides?.embeddingBaseUrl, env.RAGCODE_EMBEDDING_BASE_URL, fileConfig.embeddingBaseUrl, DEFAULT_RUNTIME_CONFIG.embeddingBaseUrl, sources);
|
|
31
|
+
const embeddingApiKey = selectOptionalString("embeddingApiKey", options.overrides?.embeddingApiKey, env.RAGCODE_EMBEDDING_API_KEY ?? env.OPENAI_API_KEY, fileConfig.embeddingApiKey, sources);
|
|
32
|
+
const embeddingModel = selectOptionalString("embeddingModel", options.overrides?.embeddingModel, env.RAGCODE_EMBEDDING_MODEL, fileConfig.embeddingModel, sources)
|
|
33
|
+
?? (embeddingProvider === "openai-compatible" ? "text-embedding-3-small" : undefined);
|
|
34
|
+
const embeddingDimensions = selectOptionalPositiveInteger("embeddingDimensions", options.overrides?.embeddingDimensions, env.RAGCODE_EMBEDDING_DIMENSIONS, fileConfig.embeddingDimensions, sources);
|
|
35
|
+
const embeddingRequestDimensions = selectBoolean("embeddingRequestDimensions", options.overrides?.embeddingRequestDimensions, env.RAGCODE_EMBEDDING_REQUEST_DIMENSIONS, fileConfig.embeddingRequestDimensions, DEFAULT_RUNTIME_CONFIG.embeddingRequestDimensions, sources);
|
|
36
|
+
const embeddingBatchSize = selectPositiveInteger("embeddingBatchSize", options.overrides?.embeddingBatchSize, env.RAGCODE_EMBEDDING_BATCH_SIZE, fileConfig.embeddingBatchSize, DEFAULT_RUNTIME_CONFIG.embeddingBatchSize, sources);
|
|
37
|
+
const embeddingConcurrency = selectPositiveInteger("embeddingConcurrency", options.overrides?.embeddingConcurrency, env.RAGCODE_EMBEDDING_CONCURRENCY, fileConfig.embeddingConcurrency, DEFAULT_RUNTIME_CONFIG.embeddingConcurrency, sources);
|
|
38
|
+
const semanticMaxChunks = selectSemanticMaxChunks("semanticMaxChunks", options.overrides?.semanticMaxChunks, env.RAGCODE_SEMANTIC_MAX_CHUNKS, fileConfig.semanticMaxChunks, embeddingProvider, sources);
|
|
39
|
+
return {
|
|
40
|
+
repoRoot,
|
|
41
|
+
configPath,
|
|
42
|
+
graph: {
|
|
43
|
+
graphStore: enumValue(graphStore, ["memory", "sqlite"], "graphStore"),
|
|
44
|
+
sqlitePath
|
|
45
|
+
},
|
|
46
|
+
semantic: {
|
|
47
|
+
semanticStore: enumValue(semanticStore, ["memory", "lancedb"], "semanticStore"),
|
|
48
|
+
embeddingProvider,
|
|
49
|
+
lanceDbUri,
|
|
50
|
+
lanceDbTableName,
|
|
51
|
+
embeddingBaseUrl,
|
|
52
|
+
embeddingModel,
|
|
53
|
+
embeddingDimensions,
|
|
54
|
+
embeddingRequestDimensions,
|
|
55
|
+
embeddingBatchSize,
|
|
56
|
+
embeddingConcurrency,
|
|
57
|
+
semanticMaxChunks
|
|
58
|
+
},
|
|
59
|
+
embeddingApiKey,
|
|
60
|
+
sources
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
export function createRuntimeComponents(config) {
|
|
64
|
+
const graphRuntime = createGraphRuntimeFromConfig(config.graph);
|
|
65
|
+
const semanticRuntime = createSemanticRuntimeFromConfig(config.semantic, {
|
|
66
|
+
RAGCODE_EMBEDDING_API_KEY: config.embeddingApiKey ?? ""
|
|
67
|
+
});
|
|
68
|
+
return {
|
|
69
|
+
graphStore: graphRuntime.graphStore,
|
|
70
|
+
semanticStore: semanticRuntime.semanticStore,
|
|
71
|
+
embeddingProvider: semanticRuntime.embeddingProvider,
|
|
72
|
+
config
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
export function createRuntimeComponentsForRepo(options = {}) {
|
|
76
|
+
return createRuntimeComponents(loadRuntimeConfig(options));
|
|
77
|
+
}
|
|
78
|
+
export function writeRuntimeConfigFile(repoRoot, config) {
|
|
79
|
+
const configPath = path.join(path.resolve(repoRoot), CONFIG_FILE_NAME);
|
|
80
|
+
fs.mkdirSync(path.dirname(configPath), { recursive: true });
|
|
81
|
+
fs.writeFileSync(configPath, `${JSON.stringify(config, null, 2)}\n`, "utf8");
|
|
82
|
+
return configPath;
|
|
83
|
+
}
|
|
84
|
+
export function runtimeConfigToEnv(config, options = {}) {
|
|
85
|
+
const env = {
|
|
86
|
+
RAGCODE_GRAPH_STORE: config.graph.graphStore,
|
|
87
|
+
RAGCODE_SQLITE_PATH: config.graph.sqlitePath,
|
|
88
|
+
RAGCODE_SEMANTIC_STORE: config.semantic.semanticStore,
|
|
89
|
+
RAGCODE_LANCEDB_URI: config.semantic.lanceDbUri ?? path.join(config.repoRoot, DEFAULT_RUNTIME_CONFIG.lancedbUri),
|
|
90
|
+
RAGCODE_LANCEDB_TABLE: config.semantic.lanceDbTableName,
|
|
91
|
+
RAGCODE_EMBEDDING_PROVIDER: config.semantic.embeddingProvider,
|
|
92
|
+
RAGCODE_EMBEDDING_BASE_URL: config.semantic.embeddingBaseUrl ?? DEFAULT_RUNTIME_CONFIG.embeddingBaseUrl,
|
|
93
|
+
RAGCODE_EMBEDDING_BATCH_SIZE: String(config.semantic.embeddingBatchSize),
|
|
94
|
+
RAGCODE_EMBEDDING_CONCURRENCY: String(config.semantic.embeddingConcurrency)
|
|
95
|
+
};
|
|
96
|
+
if (config.semantic.embeddingModel)
|
|
97
|
+
env.RAGCODE_EMBEDDING_MODEL = config.semantic.embeddingModel;
|
|
98
|
+
if (config.semantic.embeddingDimensions)
|
|
99
|
+
env.RAGCODE_EMBEDDING_DIMENSIONS = String(config.semantic.embeddingDimensions);
|
|
100
|
+
if (config.semantic.embeddingRequestDimensions)
|
|
101
|
+
env.RAGCODE_EMBEDDING_REQUEST_DIMENSIONS = "true";
|
|
102
|
+
if (config.semantic.semanticMaxChunks !== undefined)
|
|
103
|
+
env.RAGCODE_SEMANTIC_MAX_CHUNKS = String(config.semantic.semanticMaxChunks);
|
|
104
|
+
if (config.embeddingApiKey)
|
|
105
|
+
env.RAGCODE_EMBEDDING_API_KEY = options.includeSecrets ? config.embeddingApiKey : "<redacted>";
|
|
106
|
+
return env;
|
|
107
|
+
}
|
|
108
|
+
export function redactRuntimeConfig(config) {
|
|
109
|
+
return {
|
|
110
|
+
repoRoot: config.repoRoot,
|
|
111
|
+
configPath: config.configPath,
|
|
112
|
+
graphStore: config.graph.graphStore,
|
|
113
|
+
sqlitePath: config.graph.sqlitePath,
|
|
114
|
+
semanticStore: config.semantic.semanticStore,
|
|
115
|
+
lancedbUri: config.semantic.lanceDbUri,
|
|
116
|
+
lanceDbTableName: config.semantic.lanceDbTableName,
|
|
117
|
+
embeddingProvider: config.semantic.embeddingProvider,
|
|
118
|
+
embeddingBaseUrl: config.semantic.embeddingBaseUrl,
|
|
119
|
+
embeddingModel: config.semantic.embeddingModel,
|
|
120
|
+
embeddingDimensions: config.semantic.embeddingDimensions,
|
|
121
|
+
embeddingRequestDimensions: config.semantic.embeddingRequestDimensions,
|
|
122
|
+
embeddingBatchSize: config.semantic.embeddingBatchSize,
|
|
123
|
+
embeddingConcurrency: config.semantic.embeddingConcurrency,
|
|
124
|
+
semanticMaxChunks: config.semantic.semanticMaxChunks,
|
|
125
|
+
embeddingApiKey: config.embeddingApiKey ? "set" : "unset",
|
|
126
|
+
sources: config.sources
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
export function readRuntimeConfigFile(configPath) {
|
|
130
|
+
try {
|
|
131
|
+
return JSON.parse(fs.readFileSync(configPath, "utf8"));
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
if (error.code === "ENOENT")
|
|
135
|
+
return {};
|
|
136
|
+
throw error;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
function resolveRepoPath(repoRoot, value) {
|
|
140
|
+
return path.isAbsolute(value) ? value : path.join(repoRoot, value);
|
|
141
|
+
}
|
|
142
|
+
function selectString(field, overrideValue, envValue, configValue, defaultValue, sources) {
|
|
143
|
+
const selected = selectValue(field, overrideValue, envValue, configValue, defaultValue, sources);
|
|
144
|
+
if (typeof selected !== "string" || selected.trim() === "")
|
|
145
|
+
throw new Error(`Invalid runtime config field ${field}: expected a non-empty string.`);
|
|
146
|
+
return selected;
|
|
147
|
+
}
|
|
148
|
+
function selectOptionalString(field, overrideValue, envValue, configValue, sources) {
|
|
149
|
+
const selected = selectValue(field, overrideValue, envValue, configValue, undefined, sources);
|
|
150
|
+
if (selected === undefined || selected === null || selected === "")
|
|
151
|
+
return undefined;
|
|
152
|
+
if (typeof selected !== "string")
|
|
153
|
+
throw new Error(`Invalid runtime config field ${field}: expected a string.`);
|
|
154
|
+
return selected;
|
|
155
|
+
}
|
|
156
|
+
function selectPositiveInteger(field, overrideValue, envValue, configValue, defaultValue, sources) {
|
|
157
|
+
return positiveInteger(field, selectValue(field, overrideValue, envValue, configValue, defaultValue, sources));
|
|
158
|
+
}
|
|
159
|
+
function selectOptionalPositiveInteger(field, overrideValue, envValue, configValue, sources) {
|
|
160
|
+
const selected = selectValue(field, overrideValue, envValue, configValue, undefined, sources);
|
|
161
|
+
if (selected === undefined || selected === null || selected === "")
|
|
162
|
+
return undefined;
|
|
163
|
+
return positiveInteger(field, selected);
|
|
164
|
+
}
|
|
165
|
+
function selectBoolean(field, overrideValue, envValue, configValue, defaultValue, sources) {
|
|
166
|
+
const selected = selectValue(field, overrideValue, envValue, configValue, defaultValue, sources);
|
|
167
|
+
if (typeof selected === "boolean")
|
|
168
|
+
return selected;
|
|
169
|
+
if (selected === "true")
|
|
170
|
+
return true;
|
|
171
|
+
if (selected === "false")
|
|
172
|
+
return false;
|
|
173
|
+
throw new Error(`Invalid runtime config field ${field}: expected boolean.`);
|
|
174
|
+
}
|
|
175
|
+
function selectSemanticMaxChunks(field, overrideValue, envValue, configValue, provider, sources) {
|
|
176
|
+
const selected = selectValue(field, overrideValue, envValue, configValue, undefined, sources);
|
|
177
|
+
if (selected === undefined || selected === null || selected === "")
|
|
178
|
+
return provider === "openai-compatible" ? 512 : undefined;
|
|
179
|
+
if (selected === "0" || (typeof selected === "string" && selected.toLowerCase() === "all"))
|
|
180
|
+
return undefined;
|
|
181
|
+
return positiveInteger(field, selected);
|
|
182
|
+
}
|
|
183
|
+
function selectValue(field, overrideValue, envValue, configValue, defaultValue, sources) {
|
|
184
|
+
if (overrideValue !== undefined) {
|
|
185
|
+
sources[field] = "override";
|
|
186
|
+
return overrideValue;
|
|
187
|
+
}
|
|
188
|
+
if (envValue !== undefined) {
|
|
189
|
+
sources[field] = "env";
|
|
190
|
+
return envValue;
|
|
191
|
+
}
|
|
192
|
+
if (configValue !== undefined) {
|
|
193
|
+
sources[field] = "config";
|
|
194
|
+
return configValue;
|
|
195
|
+
}
|
|
196
|
+
sources[field] = "default";
|
|
197
|
+
return defaultValue;
|
|
198
|
+
}
|
|
199
|
+
function normalizeEmbeddingProvider(value) {
|
|
200
|
+
if (value === "openai")
|
|
201
|
+
return "openai-compatible";
|
|
202
|
+
return enumValue(value, ["deterministic", "openai-compatible"], "embeddingProvider");
|
|
203
|
+
}
|
|
204
|
+
function enumValue(value, allowed, field) {
|
|
205
|
+
if (allowed.includes(value))
|
|
206
|
+
return value;
|
|
207
|
+
throw new Error(`Invalid runtime config field ${field}: expected one of ${allowed.join(", ")}, got ${value}.`);
|
|
208
|
+
}
|
|
209
|
+
function positiveInteger(field, value) {
|
|
210
|
+
const parsed = typeof value === "number" ? value : Number(value);
|
|
211
|
+
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
212
|
+
throw new Error(`Invalid runtime config field ${field}: expected positive integer, got ${String(value)}.`);
|
|
213
|
+
}
|
|
214
|
+
return parsed;
|
|
215
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { EmbeddingProvider, SemanticStore } from "../core/contracts.js";
|
|
2
|
+
export type SemanticStoreKind = "memory" | "lancedb";
|
|
3
|
+
export type EmbeddingProviderKind = "deterministic" | "openai-compatible";
|
|
4
|
+
export interface SemanticRuntimeConfig {
|
|
5
|
+
semanticStore: SemanticStoreKind;
|
|
6
|
+
embeddingProvider: EmbeddingProviderKind;
|
|
7
|
+
lanceDbUri?: string;
|
|
8
|
+
lanceDbTableName: string;
|
|
9
|
+
embeddingBaseUrl?: string;
|
|
10
|
+
embeddingModel?: string;
|
|
11
|
+
embeddingDimensions?: number;
|
|
12
|
+
embeddingRequestDimensions: boolean;
|
|
13
|
+
embeddingBatchSize: number;
|
|
14
|
+
embeddingConcurrency: number;
|
|
15
|
+
semanticMaxChunks?: number;
|
|
16
|
+
}
|
|
17
|
+
export interface SemanticRuntimeComponents {
|
|
18
|
+
semanticStore: SemanticStore;
|
|
19
|
+
embeddingProvider: EmbeddingProvider;
|
|
20
|
+
config: SemanticRuntimeConfig;
|
|
21
|
+
}
|
|
22
|
+
export declare function createSemanticRuntimeFromEnv(env?: NodeJS.ProcessEnv, cwd?: string): SemanticRuntimeComponents;
|
|
23
|
+
export declare function createSemanticRuntimeFromConfig(config: SemanticRuntimeConfig, env?: Partial<Pick<NodeJS.ProcessEnv, "RAGCODE_EMBEDDING_API_KEY">>): SemanticRuntimeComponents;
|
|
24
|
+
export declare function readSemanticRuntimeConfig(env?: NodeJS.ProcessEnv, cwd?: string): SemanticRuntimeConfig;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { DeterministicEmbeddingProvider } from "../semantic/deterministic-embedding.js";
|
|
3
|
+
import { InMemorySemanticStore } from "../semantic/in-memory-semantic-store.js";
|
|
4
|
+
import { LanceSemanticStore } from "../semantic/lance-semantic-store.js";
|
|
5
|
+
import { OpenAICompatibleEmbeddingProvider } from "../semantic/openai-compatible-embedding.js";
|
|
6
|
+
export function createSemanticRuntimeFromEnv(env = process.env, cwd = process.cwd()) {
|
|
7
|
+
const config = readSemanticRuntimeConfig(env, cwd);
|
|
8
|
+
return createSemanticRuntimeFromConfig(config, env);
|
|
9
|
+
}
|
|
10
|
+
export function createSemanticRuntimeFromConfig(config, env = process.env) {
|
|
11
|
+
const embeddingProvider = createEmbeddingProvider(config, env);
|
|
12
|
+
const semanticStore = createSemanticStore(config, embeddingProvider);
|
|
13
|
+
return { semanticStore, embeddingProvider, config };
|
|
14
|
+
}
|
|
15
|
+
export function readSemanticRuntimeConfig(env = process.env, cwd = process.cwd()) {
|
|
16
|
+
const semanticStore = enumValue(env.RAGCODE_SEMANTIC_STORE, ["memory", "lancedb"], "memory");
|
|
17
|
+
const embeddingProvider = enumValue(env.RAGCODE_EMBEDDING_PROVIDER, ["deterministic", "openai-compatible"], "deterministic");
|
|
18
|
+
const embeddingDimensions = optionalPositiveInteger(env.RAGCODE_EMBEDDING_DIMENSIONS);
|
|
19
|
+
return {
|
|
20
|
+
semanticStore,
|
|
21
|
+
embeddingProvider,
|
|
22
|
+
lanceDbUri: env.RAGCODE_LANCEDB_URI ?? path.join(cwd, ".ragcode", "lancedb"),
|
|
23
|
+
lanceDbTableName: env.RAGCODE_LANCEDB_TABLE ?? "code_chunks",
|
|
24
|
+
embeddingBaseUrl: env.RAGCODE_EMBEDDING_BASE_URL ?? "https://api.openai.com/v1",
|
|
25
|
+
embeddingModel: env.RAGCODE_EMBEDDING_MODEL ?? (embeddingProvider === "openai-compatible" ? "text-embedding-3-small" : undefined),
|
|
26
|
+
embeddingDimensions,
|
|
27
|
+
embeddingRequestDimensions: env.RAGCODE_EMBEDDING_REQUEST_DIMENSIONS === "true",
|
|
28
|
+
embeddingBatchSize: optionalPositiveInteger(env.RAGCODE_EMBEDDING_BATCH_SIZE) ?? 64,
|
|
29
|
+
embeddingConcurrency: optionalPositiveInteger(env.RAGCODE_EMBEDDING_CONCURRENCY) ?? 1,
|
|
30
|
+
semanticMaxChunks: semanticMaxChunks(env.RAGCODE_SEMANTIC_MAX_CHUNKS, embeddingProvider)
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function createEmbeddingProvider(config, env) {
|
|
34
|
+
if (config.embeddingProvider === "deterministic") {
|
|
35
|
+
return new DeterministicEmbeddingProvider(config.embeddingDimensions ?? 64);
|
|
36
|
+
}
|
|
37
|
+
return new OpenAICompatibleEmbeddingProvider({
|
|
38
|
+
apiKey: env.RAGCODE_EMBEDDING_API_KEY ?? "",
|
|
39
|
+
model: config.embeddingModel ?? "text-embedding-3-small",
|
|
40
|
+
baseUrl: config.embeddingBaseUrl,
|
|
41
|
+
dimensions: config.embeddingDimensions,
|
|
42
|
+
requestDimensions: config.embeddingRequestDimensions
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
function createSemanticStore(config, provider) {
|
|
46
|
+
if (config.semanticStore === "memory")
|
|
47
|
+
return new InMemorySemanticStore();
|
|
48
|
+
return new LanceSemanticStore(config.lanceDbUri ?? ".ragcode/lancedb", {
|
|
49
|
+
tableName: config.lanceDbTableName,
|
|
50
|
+
vectorDimensions: provider.dimensions,
|
|
51
|
+
embeddingProfile: {
|
|
52
|
+
provider: config.embeddingProvider,
|
|
53
|
+
model: config.embeddingModel,
|
|
54
|
+
baseUrl: config.embeddingBaseUrl,
|
|
55
|
+
requestDimensions: config.embeddingRequestDimensions
|
|
56
|
+
},
|
|
57
|
+
embeddingBatchSize: config.embeddingBatchSize,
|
|
58
|
+
embeddingConcurrency: config.embeddingConcurrency,
|
|
59
|
+
maxChunks: config.semanticMaxChunks,
|
|
60
|
+
onProgress: (progress) => {
|
|
61
|
+
if (process.env.RAGCODE_EMBEDDING_PROGRESS === "false")
|
|
62
|
+
return;
|
|
63
|
+
const percent = Math.round((progress.completedChunks / progress.totalChunks) * 100);
|
|
64
|
+
const elapsedSeconds = Math.max(1, Math.round(progress.elapsedMs / 1000));
|
|
65
|
+
console.error(`[ragcode] embedded ${progress.completedChunks}/${progress.totalChunks} chunks (${percent}%) batch ${progress.batchIndex}/${progress.batchCount} elapsed ${elapsedSeconds}s`);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
function semanticMaxChunks(value, provider) {
|
|
70
|
+
if (value === "0" || value?.toLowerCase() === "all")
|
|
71
|
+
return undefined;
|
|
72
|
+
return optionalPositiveInteger(value) ?? (provider === "openai-compatible" ? 512 : undefined);
|
|
73
|
+
}
|
|
74
|
+
function enumValue(value, allowed, fallback) {
|
|
75
|
+
if (!value)
|
|
76
|
+
return fallback;
|
|
77
|
+
if (allowed.includes(value))
|
|
78
|
+
return value;
|
|
79
|
+
throw new Error(`Invalid semantic runtime value "${value}". Expected one of: ${allowed.join(", ")}.`);
|
|
80
|
+
}
|
|
81
|
+
function optionalPositiveInteger(value) {
|
|
82
|
+
if (!value)
|
|
83
|
+
return undefined;
|
|
84
|
+
const parsed = Number(value);
|
|
85
|
+
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
86
|
+
throw new Error(`Invalid positive integer: ${value}`);
|
|
87
|
+
}
|
|
88
|
+
return parsed;
|
|
89
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ContextPack, ContextRequest, DirtyFile, GraphEdge, SearchHit } from "../core/types.js";
|
|
2
|
+
export interface ContextBuildMetadata {
|
|
3
|
+
projectId: string;
|
|
4
|
+
repoRoot: string;
|
|
5
|
+
indexedAtMs: number;
|
|
6
|
+
skippedFiles: Array<{
|
|
7
|
+
filePath: string;
|
|
8
|
+
reason: string;
|
|
9
|
+
}>;
|
|
10
|
+
indexGeneration?: number;
|
|
11
|
+
staleFiles?: string[];
|
|
12
|
+
pendingFiles?: string[];
|
|
13
|
+
indexingFiles?: string[];
|
|
14
|
+
dirtyFiles?: DirtyFile[];
|
|
15
|
+
burstMode?: boolean;
|
|
16
|
+
droppedEvents?: number;
|
|
17
|
+
}
|
|
18
|
+
export declare class ContextBuilder {
|
|
19
|
+
build(request: ContextRequest, hits: SearchHit[], edges: GraphEdge[] | undefined, metadata: ContextBuildMetadata): ContextPack;
|
|
20
|
+
}
|