codesearch-mcp 0.2.3-alpha → 0.4.0-alpha
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/CHANGELOG.md +88 -5
- package/LICENSE +661 -21
- package/README.md +76 -40
- package/dist/app.js +17 -38
- package/dist/src/ast/CallExtractor.d.ts +8 -0
- package/dist/src/ast/CallExtractor.js +68 -0
- package/dist/src/ast/GraphqlNameExtractor.d.ts +22 -0
- package/dist/src/ast/GraphqlNameExtractor.js +240 -0
- package/dist/src/ast/ImportEdgeExtractor.d.ts +11 -0
- package/dist/src/ast/ImportEdgeExtractor.js +129 -0
- package/dist/src/ast/IndexedNodeResolver.d.ts +14 -0
- package/dist/src/ast/IndexedNodeResolver.js +217 -0
- package/dist/src/ast/MemberExtractor.d.ts +8 -0
- package/dist/src/ast/MemberExtractor.js +129 -0
- package/dist/src/ast/TopLevelSymbolExtractor.d.ts +5 -0
- package/dist/src/ast/TopLevelSymbolExtractor.js +86 -0
- package/dist/src/ast/graphql-grammar.d.ts +24 -0
- package/dist/src/ast/graphql-grammar.js +93 -0
- package/dist/src/ast/node-helpers.d.ts +11 -0
- package/dist/src/ast/node-helpers.js +55 -0
- package/dist/src/chunking/AstChunker.d.ts +12 -0
- package/dist/src/chunking/AstChunker.js +30 -0
- package/dist/src/chunking/CharacterChunkStrategy.d.ts +8 -0
- package/dist/src/chunking/CharacterChunkStrategy.js +15 -0
- package/dist/src/chunking/DeclarationChunkStrategy.d.ts +15 -0
- package/dist/src/chunking/DeclarationChunkStrategy.js +87 -0
- package/dist/src/chunking/FragmentMerger.d.ts +11 -0
- package/dist/src/chunking/FragmentMerger.js +61 -0
- package/dist/src/chunking/ImportOnlyFilter.d.ts +5 -0
- package/dist/src/chunking/ImportOnlyFilter.js +14 -0
- package/dist/src/chunking/LangchainTextSplitter.d.ts +21 -0
- package/dist/src/chunking/LangchainTextSplitter.js +133 -0
- package/dist/src/chunking/MinSizeSplitPolicy.d.ts +9 -0
- package/dist/src/chunking/MinSizeSplitPolicy.js +18 -0
- package/dist/src/chunking/RunPacker.d.ts +12 -0
- package/dist/src/chunking/RunPacker.js +84 -0
- package/dist/src/chunking/create-chunker.d.ts +3 -0
- package/dist/src/chunking/create-chunker.js +15 -0
- package/dist/src/chunking/interfaces.d.ts +27 -0
- package/dist/src/commands/ConfigCommand.js +1 -9
- package/dist/src/commands/EvalCommand.d.ts +10 -5
- package/dist/src/commands/EvalCommand.js +60 -149
- package/dist/src/commands/IndexCommand.d.ts +10 -4
- package/dist/src/commands/IndexCommand.js +52 -146
- package/dist/src/commands/McpCommand.d.ts +6 -3
- package/dist/src/commands/McpCommand.js +19 -20
- package/dist/src/commands/WebCommand.d.ts +9 -3
- package/dist/src/commands/WebCommand.js +17 -11
- package/dist/src/commands/eval/baseline-comparison.d.ts +6 -0
- package/dist/src/commands/eval/baseline-comparison.js +54 -0
- package/dist/src/commands/eval/eval-args.d.ts +6 -0
- package/dist/src/commands/eval/eval-args.js +71 -0
- package/dist/src/commands/eval/eval-corpora.d.ts +6 -0
- package/dist/src/commands/eval/eval-corpora.js +76 -0
- package/dist/src/commands/eval/eval-metadata.d.ts +17 -0
- package/dist/src/commands/eval/eval-metadata.js +75 -0
- package/dist/src/commands/eval/index-inspector.d.ts +3 -0
- package/dist/src/commands/eval/index-inspector.js +21 -0
- package/dist/src/commands/eval/staged-search.d.ts +3 -0
- package/dist/src/commands/eval/staged-search.js +20 -0
- package/dist/src/commands/eval/suite-loader.d.ts +8 -0
- package/dist/src/commands/eval/suite-loader.js +52 -0
- package/dist/src/commands/index/backend-probe.d.ts +2 -0
- package/dist/src/commands/index/backend-probe.js +15 -0
- package/dist/src/commands/index/embedding-setup.d.ts +3 -0
- package/dist/src/commands/index/embedding-setup.js +16 -0
- package/dist/src/commands/index/index-summary.d.ts +2 -0
- package/dist/src/commands/index/index-summary.js +22 -0
- package/dist/src/commands/index/legacy-ollama-guard.d.ts +3 -0
- package/dist/src/commands/index/legacy-ollama-guard.js +23 -0
- package/dist/src/commands/index/prune-step.d.ts +3 -0
- package/dist/src/commands/index/prune-step.js +22 -0
- package/dist/src/commands/index/scan-targets.d.ts +8 -0
- package/dist/src/commands/index/scan-targets.js +107 -0
- package/dist/src/config-error.d.ts +0 -4
- package/dist/src/config-error.js +0 -4
- package/dist/src/config-store.d.ts +1 -55
- package/dist/src/config-store.js +11 -73
- package/dist/src/config.d.ts +9 -18
- package/dist/src/config.js +36 -35
- package/dist/src/constants.d.ts +17 -28
- package/dist/src/constants.js +35 -29
- package/dist/src/container.d.ts +10 -2
- package/dist/src/container.js +19 -8
- package/dist/src/db/drizzle-types.d.ts +7 -0
- package/dist/src/db/drizzle-types.js +2 -0
- package/dist/src/db/index.d.ts +1 -0
- package/dist/src/db/schema-steps.d.ts +8 -0
- package/dist/src/db/schema-steps.js +105 -0
- package/dist/src/db/schema.d.ts +17 -0
- package/dist/src/db/schema.js +1 -6
- package/dist/src/declarations/DeclarationTree.d.ts +19 -0
- package/dist/src/declarations/DeclarationTree.js +66 -0
- package/dist/src/declarations/DeclarationTreeBuilder.d.ts +22 -0
- package/dist/src/declarations/DeclarationTreeBuilder.js +179 -0
- package/dist/src/declarations/SourceLines.d.ts +37 -0
- package/dist/src/declarations/SourceLines.js +415 -0
- package/dist/src/dependency-traversal.d.ts +0 -6
- package/dist/src/dependency-traversal.js +0 -6
- package/dist/src/enriched-prompt.d.ts +0 -6
- package/dist/src/enriched-prompt.js +0 -6
- package/dist/src/error-record.d.ts +12 -0
- package/dist/src/error-record.js +248 -0
- package/dist/src/eval-corpus.d.ts +16 -0
- package/dist/src/eval-corpus.js +169 -0
- package/dist/src/eval-results.d.ts +6 -3
- package/dist/src/eval-results.js +323 -26
- package/dist/src/eval-vector-index.d.ts +5 -0
- package/dist/src/eval-vector-index.js +60 -0
- package/dist/src/file-utils.d.ts +0 -5
- package/dist/src/file-utils.js +0 -5
- package/dist/src/graph.d.ts +0 -25
- package/dist/src/graph.js +0 -28
- package/dist/src/help.js +9 -1
- package/dist/src/hnsw-settings.d.ts +3 -0
- package/dist/src/hnsw-settings.js +24 -0
- package/dist/src/index-args.d.ts +13 -0
- package/dist/src/index-args.js +48 -0
- package/dist/src/indexing/AnalysisBatcher.d.ts +12 -0
- package/dist/src/indexing/AnalysisBatcher.js +28 -0
- package/dist/src/indexing/ChunkEmbedder.d.ts +24 -0
- package/dist/src/indexing/ChunkEmbedder.js +37 -0
- package/dist/src/indexing/ConsoleScanReporter.d.ts +10 -0
- package/dist/src/indexing/ConsoleScanReporter.js +73 -0
- package/dist/src/indexing/EmbeddingSchemaPreparer.d.ts +14 -0
- package/dist/src/indexing/EmbeddingSchemaPreparer.js +66 -0
- package/dist/src/indexing/FileIngestor.d.ts +22 -0
- package/dist/src/indexing/FileIngestor.js +116 -0
- package/dist/src/indexing/IndexStore.d.ts +24 -0
- package/dist/src/indexing/IndexStore.js +69 -0
- package/dist/src/indexing/StaleFilePruner.d.ts +8 -0
- package/dist/src/indexing/StaleFilePruner.js +55 -0
- package/dist/src/indexing/analysis-rows.d.ts +4 -0
- package/dist/src/indexing/analysis-rows.js +65 -0
- package/dist/src/indexing/project-notices.d.ts +2 -0
- package/dist/src/indexing/project-notices.js +63 -0
- package/dist/src/interfaces/IAstParser.d.ts +4 -40
- package/dist/src/interfaces/ICallGraph.d.ts +28 -0
- package/dist/src/interfaces/ICallGraph.js +2 -0
- package/dist/src/interfaces/IChunkSearch.d.ts +42 -0
- package/dist/src/interfaces/IChunkSearch.js +2 -0
- package/dist/src/interfaces/IChunker.d.ts +3 -12
- package/dist/src/interfaces/ICorpusInspector.d.ts +7 -0
- package/dist/src/interfaces/ICorpusInspector.js +2 -0
- package/dist/src/interfaces/IDatabase.d.ts +8 -24
- package/dist/src/interfaces/IDependencyGraph.d.ts +24 -0
- package/dist/src/interfaces/IDependencyGraph.js +2 -0
- package/dist/src/interfaces/IEmbedder.d.ts +0 -9
- package/dist/src/interfaces/IIndexIdentityGuard.d.ts +3 -0
- package/dist/src/interfaces/IIndexIdentityGuard.js +2 -0
- package/dist/src/interfaces/IIndexedNodeResolver.d.ts +10 -0
- package/dist/src/interfaces/IIndexedNodeResolver.js +2 -0
- package/dist/src/interfaces/ILogger.d.ts +1 -11
- package/dist/src/interfaces/IMcpReadiness.d.ts +12 -0
- package/dist/src/interfaces/IMcpReadiness.js +2 -0
- package/dist/src/interfaces/IMcpToolHandler.d.ts +0 -5
- package/dist/src/interfaces/IMonorepoResolver.d.ts +0 -22
- package/dist/src/interfaces/IProjectCatalog.d.ts +13 -0
- package/dist/src/interfaces/IProjectCatalog.js +2 -0
- package/dist/src/interfaces/IProjectDiscovery.d.ts +0 -17
- package/dist/src/interfaces/IProjectRoots.d.ts +3 -0
- package/dist/src/interfaces/IProjectRoots.js +2 -0
- package/dist/src/interfaces/IRetrievalEvaluator.d.ts +153 -12
- package/dist/src/interfaces/IScanReporter.d.ts +13 -0
- package/dist/src/interfaces/IScanReporter.js +2 -0
- package/dist/src/interfaces/ISymbolLookup.d.ts +49 -0
- package/dist/src/interfaces/ISymbolLookup.js +2 -0
- package/dist/src/interfaces/IToolPaths.d.ts +62 -0
- package/dist/src/interfaces/IToolPaths.js +2 -0
- package/dist/src/interfaces/IWorkspaceFiles.d.ts +28 -0
- package/dist/src/interfaces/IWorkspaceFiles.js +2 -0
- package/dist/src/interfaces/SymbolKind.d.ts +1 -0
- package/dist/src/interfaces/SymbolKind.js +2 -0
- package/dist/src/interfaces/index.d.ts +12 -1
- package/dist/src/interrupt.js +0 -2
- package/dist/src/owner-path.d.ts +9 -10
- package/dist/src/owner-path.js +11 -23
- package/dist/src/project-scope.d.ts +1 -12
- package/dist/src/project-scope.js +5 -12
- package/dist/src/project-selector.d.ts +0 -5
- package/dist/src/project-selector.js +0 -11
- package/dist/src/retrieval-eval.d.ts +15 -6
- package/dist/src/retrieval-eval.js +388 -59
- package/dist/src/search/CallGraph.d.ts +9 -0
- package/dist/src/search/CallGraph.js +84 -0
- package/dist/src/search/ChunkSearch.d.ts +23 -0
- package/dist/src/search/ChunkSearch.js +115 -0
- package/dist/src/search/DependencyGraph.d.ts +19 -0
- package/dist/src/search/DependencyGraph.js +180 -0
- package/dist/src/search/IndexIdentityGuard.d.ts +11 -0
- package/dist/src/search/IndexIdentityGuard.js +37 -0
- package/dist/src/search/ProjectCatalog.d.ts +11 -0
- package/dist/src/search/ProjectCatalog.js +38 -0
- package/dist/src/search/SymbolLookup.d.ts +24 -0
- package/dist/src/search/SymbolLookup.js +97 -0
- package/dist/src/search/chunks/CandidateFetcher.d.ts +19 -0
- package/dist/src/search/chunks/CandidateFetcher.js +40 -0
- package/dist/src/search/chunks/IterativeScanGate.d.ts +10 -0
- package/dist/src/search/chunks/IterativeScanGate.js +42 -0
- package/dist/src/search/chunks/RerankStage.d.ts +15 -0
- package/dist/src/search/chunks/RerankStage.js +42 -0
- package/dist/src/search/chunks/search-metrics.d.ts +18 -0
- package/dist/src/search/chunks/search-metrics.js +32 -0
- package/dist/src/search/chunks/search-plan.d.ts +18 -0
- package/dist/src/search/chunks/search-plan.js +19 -0
- package/dist/src/search/create-search-services.d.ts +26 -0
- package/dist/src/search/create-search-services.js +29 -0
- package/dist/src/search/index-paths.d.ts +1 -0
- package/dist/src/search/index-paths.js +5 -0
- package/dist/src/search/result-shaping.d.ts +4 -0
- package/dist/src/search/result-shaping.js +19 -0
- package/dist/src/search/symbol-sql.d.ts +13 -0
- package/dist/src/search/symbol-sql.js +66 -0
- package/dist/src/search/symbols/SymbolGrepFallback.d.ts +19 -0
- package/dist/src/search/symbols/SymbolGrepFallback.js +106 -0
- package/dist/src/search/symbols/SymbolIndexQuery.d.ts +14 -0
- package/dist/src/search/symbols/SymbolIndexQuery.js +52 -0
- package/dist/src/search/symbols/SymbolTextSearch.d.ts +13 -0
- package/dist/src/search/symbols/SymbolTextSearch.js +84 -0
- package/dist/src/search/symbols/TargetColumnGate.d.ts +7 -0
- package/dist/src/search/symbols/TargetColumnGate.js +23 -0
- package/dist/src/search/symbols/find-symbol-constants.d.ts +4 -0
- package/dist/src/search/symbols/find-symbol-constants.js +8 -0
- package/dist/src/search/symbols/grep-args.d.ts +3 -0
- package/dist/src/search/symbols/grep-args.js +7 -0
- package/dist/src/search/symbols/grep-patterns.d.ts +4 -0
- package/dist/src/search/symbols/grep-patterns.js +60 -0
- package/dist/src/services/AstParserService.d.ts +10 -106
- package/dist/src/services/AstParserService.js +37 -1068
- package/dist/src/services/DatabaseService.d.ts +10 -17
- package/dist/src/services/DatabaseService.js +71 -115
- package/dist/src/services/EmbedderFactory.d.ts +0 -4
- package/dist/src/services/EmbedderFactory.js +0 -5
- package/dist/src/services/IndexerService.d.ts +7 -26
- package/dist/src/services/IndexerService.js +38 -286
- package/dist/src/services/InfinityEmbedder.d.ts +0 -21
- package/dist/src/services/InfinityEmbedder.js +0 -15
- package/dist/src/services/LoggerService.d.ts +7 -5
- package/dist/src/services/LoggerService.js +37 -41
- package/dist/src/services/McpReadiness.d.ts +18 -0
- package/dist/src/services/McpReadiness.js +73 -0
- package/dist/src/services/McpServer.d.ts +50 -19
- package/dist/src/services/McpServer.js +132 -62
- package/dist/src/services/MonorepoAwareDiscoveryService.d.ts +1 -45
- package/dist/src/services/MonorepoAwareDiscoveryService.js +1 -51
- package/dist/src/services/NxMonorepoResolver.d.ts +0 -29
- package/dist/src/services/NxMonorepoResolver.js +5 -56
- package/dist/src/services/OpenAICompatibleEmbedder.d.ts +0 -6
- package/dist/src/services/OpenAICompatibleEmbedder.js +0 -14
- package/dist/src/services/ProjectDiscoveryService.d.ts +0 -4
- package/dist/src/services/ProjectDiscoveryService.js +0 -4
- package/dist/src/services/VoyageEmbedder.d.ts +0 -6
- package/dist/src/services/VoyageEmbedder.js +0 -6
- package/dist/src/services/WebServerService.d.ts +5 -56
- package/dist/src/services/WebServerService.js +25 -63
- package/dist/src/services/http-retry.d.ts +0 -7
- package/dist/src/services/http-retry.js +1 -10
- package/dist/src/services/infinity-provisioning.d.ts +0 -74
- package/dist/src/services/infinity-provisioning.js +5 -88
- package/dist/src/services/legacy-ollama-index.d.ts +0 -16
- package/dist/src/services/legacy-ollama-index.js +0 -23
- package/dist/src/services/reranker.d.ts +0 -9
- package/dist/src/services/reranker.js +46 -12
- package/dist/src/setup.d.ts +24 -24
- package/dist/src/setup.js +205 -103
- package/dist/src/symbol-name.d.ts +1 -12
- package/dist/src/symbol-name.js +16 -25
- package/dist/src/symbol-rows.d.ts +0 -14
- package/dist/src/symbol-rows.js +0 -14
- package/dist/src/tool-call-log.d.ts +2 -0
- package/dist/src/tool-call-log.js +24 -0
- package/dist/src/tools/FindSymbolTool.d.ts +17 -7
- package/dist/src/tools/FindSymbolTool.js +54 -35
- package/dist/src/tools/GetCallersTool.d.ts +16 -8
- package/dist/src/tools/GetCallersTool.js +65 -35
- package/dist/src/tools/GetDependenciesTool.d.ts +16 -8
- package/dist/src/tools/GetDependenciesTool.js +36 -29
- package/dist/src/tools/GetDependentsTool.d.ts +20 -8
- package/dist/src/tools/GetDependentsTool.js +48 -34
- package/dist/src/tools/ListFilesTool.d.ts +16 -8
- package/dist/src/tools/ListFilesTool.js +20 -26
- package/dist/src/tools/ListProjectsTool.d.ts +11 -7
- package/dist/src/tools/ListProjectsTool.js +13 -11
- package/dist/src/tools/McpTool.d.ts +17 -0
- package/dist/src/tools/McpTool.js +28 -0
- package/dist/src/tools/ReadFileRangeTool.d.ts +16 -8
- package/dist/src/tools/ReadFileRangeTool.js +23 -25
- package/dist/src/tools/ReadFileTool.d.ts +15 -8
- package/dist/src/tools/ReadFileTool.js +19 -24
- package/dist/src/tools/SearchCodebaseTool.d.ts +22 -10
- package/dist/src/tools/SearchCodebaseTool.js +71 -50
- package/dist/src/tools/format-helpers.d.ts +9 -9
- package/dist/src/tools/format-helpers.js +146 -28
- package/dist/src/tools/tool-args.d.ts +38 -0
- package/dist/src/tools/tool-args.js +95 -0
- package/dist/src/web/dashboard.d.ts +0 -8
- package/dist/src/web/dashboard.js +7 -10
- package/dist/src/workspace/GrepRunner.d.ts +15 -0
- package/dist/src/workspace/GrepRunner.js +104 -0
- package/dist/src/workspace/ProjectRoots.d.ts +22 -0
- package/dist/src/workspace/ProjectRoots.js +102 -0
- package/dist/src/workspace/ToolPaths.d.ts +31 -0
- package/dist/src/workspace/ToolPaths.js +312 -0
- package/dist/src/workspace/WorkspaceFiles.d.ts +19 -0
- package/dist/src/workspace/WorkspaceFiles.js +285 -0
- package/dist/src/workspace/fs-access.d.ts +9 -0
- package/dist/src/workspace/fs-access.js +47 -0
- package/dist/src/workspace/path-helpers.d.ts +3 -0
- package/dist/src/workspace/path-helpers.js +43 -0
- package/package.json +5 -4
- package/dist/src/interfaces/ISearcher.d.ts +0 -35
- package/dist/src/services/AstChunker.d.ts +0 -42
- package/dist/src/services/AstChunker.js +0 -158
- package/dist/src/services/SearcherService.d.ts +0 -342
- package/dist/src/services/SearcherService.js +0 -1199
- package/docs/web-dashboard.md +0 -206
- /package/dist/src/{interfaces/ISearcher.js → chunking/interfaces.js} +0 -0
package/dist/src/config-store.js
CHANGED
|
@@ -54,11 +54,7 @@ exports.CONFIG_DIR = path.join(os.homedir(), '.config', 'codesearch-mcp');
|
|
|
54
54
|
exports.CONFIG_FILE = path.join(exports.CONFIG_DIR, 'config.json');
|
|
55
55
|
exports.SCHEMA_FILE = path.join(exports.CONFIG_DIR, 'config.schema.json');
|
|
56
56
|
exports.ENV_FILE = path.join(exports.CONFIG_DIR, '.env');
|
|
57
|
-
// Relative $schema reference written into config.json so editors resolve the
|
|
58
|
-
// sibling schema file for autocomplete / inline validation.
|
|
59
57
|
const SCHEMA_REF = './config.schema.json';
|
|
60
|
-
// All fields optional — defaults live in config.ts. The file stays minimal.
|
|
61
|
-
// Descriptions surface as tooltips in schema-aware editors (VS Code, JetBrains).
|
|
62
58
|
const jsonSchema = zod_1.z.object({
|
|
63
59
|
db: zod_1.z.object({
|
|
64
60
|
host: zod_1.z.string().describe('PostgreSQL host').optional(),
|
|
@@ -83,24 +79,23 @@ const jsonSchema = zod_1.z.object({
|
|
|
83
79
|
chunkStrategy: zod_1.z.enum(['ast', 'character']).describe('How TS/JS files are chunked: ast = symbol-aligned boundaries, character = fixed-size recursive splitter (default ast)').optional(),
|
|
84
80
|
}).optional(),
|
|
85
81
|
search: zod_1.z.object({
|
|
86
|
-
similarityThreshold: zod_1.z.number().min(0).max(1).describe('Max cosine distance 0–1
|
|
82
|
+
similarityThreshold: zod_1.z.number().min(0).max(1).describe('Max cosine distance 0–1, lower = stricter. Unset: recommended value for the embedding model').optional(),
|
|
87
83
|
defaultLimit: zod_1.z.number().int().describe('Default result count (default 5)').optional(),
|
|
88
84
|
maxLimit: zod_1.z.number().int().describe('Hard cap on results (default 20)').optional(),
|
|
89
85
|
}).optional(),
|
|
90
86
|
reranker: zod_1.z.object({
|
|
91
|
-
enabled: zod_1.z.boolean().describe('Enable cross-encoder reranking
|
|
92
|
-
provider: zod_1.z.enum(['openai-compatible']).describe('Rerank backend
|
|
93
|
-
baseURL: zod_1.z.string().describe('Rerank server base URL (
|
|
94
|
-
apiKey: zod_1.z.string().describe('API key, or env:VAR_NAME. Empty for local servers.').optional(),
|
|
95
|
-
model: zod_1.z.string().describe('Reranker model name (
|
|
87
|
+
enabled: zod_1.z.boolean().describe('Enable cross-encoder reranking (default true with infinity embedding or when reranker.provider/baseURL/url is set, else false)').optional(),
|
|
88
|
+
provider: zod_1.z.enum(['openai-compatible', 'voyage']).describe('Rerank backend: openai-compatible /rerank servers (Infinity, vLLM) or voyage (Voyage AI, requires reranker.apiKey) (default openai-compatible)').optional(),
|
|
89
|
+
baseURL: zod_1.z.string().describe('Rerank server base URL (default embedding.baseURL for openai-compatible — Infinity serves both; https://api.voyageai.com/v1 for voyage)').optional(),
|
|
90
|
+
apiKey: zod_1.z.string().describe('API key, or env:VAR_NAME. Empty for local servers; required for voyage.').optional(),
|
|
91
|
+
model: zod_1.z.string().describe('Reranker model name (default mixedbread-ai/mxbai-rerank-xsmall-v1 for openai-compatible, rerank-3 for voyage)').optional(),
|
|
96
92
|
url: zod_1.z.string().describe('Full URL of the rerank endpoint (default derived from provider + baseURL)').optional(),
|
|
97
|
-
overfetch: zod_1.z.number().int().min(1).max(20).describe('Candidate multiplier before reranking (limit × N, default 5)').optional(),
|
|
98
|
-
candidateFloor: zod_1.z.number().int().min(1).describe('Minimum candidate pool fed to the reranker regardless of limit; fetchLimit = min(max(limit × overfetch, candidateFloor), 200) (default 80)').optional(),
|
|
93
|
+
overfetch: zod_1.z.number().int().min(1).max(20).describe('Candidate multiplier before reranking (limit × N, default 5); also sizes the pool of a search without reranking whose per-file limit is below limit').optional(),
|
|
94
|
+
candidateFloor: zod_1.z.number().int().min(1).describe('Minimum candidate pool fed to the reranker regardless of limit; fetchLimit = min(max(limit × overfetch, candidateFloor), 200) (default 80); the same pool serves a search without reranking whose per-file limit is below limit').optional(),
|
|
99
95
|
}).optional(),
|
|
100
96
|
logging: zod_1.z.object({
|
|
101
97
|
level: zod_1.z.enum(['debug', 'info', 'warn', 'error']).describe('File log level (default error)').optional(),
|
|
102
98
|
dir: zod_1.z.string().describe('Base log directory; "false" to disable file logging').optional(),
|
|
103
|
-
searchMetrics: zod_1.z.boolean().describe('Emit one structured search-tuning line (info level) per search, independent of level (default false)').optional(),
|
|
104
99
|
}).optional(),
|
|
105
100
|
workspaceRoot: zod_1.z.string().describe('Full path to the directory containing all your projects').optional(),
|
|
106
101
|
});
|
|
@@ -134,22 +129,9 @@ const FIELD_TYPES = {
|
|
|
134
129
|
'reranker.candidateFloor': 'number',
|
|
135
130
|
'logging.level': 'string',
|
|
136
131
|
'logging.dir': 'string',
|
|
137
|
-
'logging.searchMetrics': 'boolean',
|
|
138
132
|
'workspaceRoot': 'string',
|
|
139
133
|
};
|
|
140
134
|
exports.ALL_KEYS = Object.keys(FIELD_TYPES);
|
|
141
|
-
/**
|
|
142
|
-
* Single source of truth for built-in defaults, keyed by raw config.json dotted
|
|
143
|
-
* key. Consumed both by the web dashboard (`GET /api/defaults`) and by
|
|
144
|
-
* `resolvedSchema` in `src/config.ts`, whose `.default(...)` calls reference
|
|
145
|
-
* these values — so the runtime default and the dashboard-displayed default
|
|
146
|
-
* cannot diverge. `as const` keeps the literal types so those `.default()`
|
|
147
|
-
* lookups stay type-safe. Keys omitted here have no static default: required
|
|
148
|
-
* fields (db.host/user/password) and values derived at runtime — db.name →
|
|
149
|
-
* rag_<user>, and the provider-dependent URLs (embedding.baseURL,
|
|
150
|
-
* reranker.baseURL, reranker.url), which are computed in the `Config`
|
|
151
|
-
* constructor per provider rather than through a schema `.default(...)`.
|
|
152
|
-
*/
|
|
153
135
|
exports.CONFIG_DEFAULTS = {
|
|
154
136
|
'db.port': 5433,
|
|
155
137
|
'embedding.provider': 'infinity',
|
|
@@ -161,7 +143,6 @@ exports.CONFIG_DEFAULTS = {
|
|
|
161
143
|
'indexing.embedBatchSize': 5,
|
|
162
144
|
'indexing.astBatchSize': 3000,
|
|
163
145
|
'indexing.chunkStrategy': 'ast',
|
|
164
|
-
'search.similarityThreshold': 0.6,
|
|
165
146
|
'search.defaultLimit': 5,
|
|
166
147
|
'search.maxLimit': 20,
|
|
167
148
|
'reranker.enabled': true,
|
|
@@ -171,7 +152,6 @@ exports.CONFIG_DEFAULTS = {
|
|
|
171
152
|
'reranker.overfetch': 5,
|
|
172
153
|
'reranker.candidateFloor': 80,
|
|
173
154
|
'logging.level': 'error',
|
|
174
|
-
'logging.searchMetrics': false,
|
|
175
155
|
};
|
|
176
156
|
function readConfigJson() {
|
|
177
157
|
if (!fs.existsSync(exports.CONFIG_FILE))
|
|
@@ -181,7 +161,7 @@ function readConfigJson() {
|
|
|
181
161
|
raw = fs.readFileSync(exports.CONFIG_FILE, 'utf-8');
|
|
182
162
|
}
|
|
183
163
|
catch (e) {
|
|
184
|
-
throw new Error(`Cannot read ${exports.CONFIG_FILE}: ${e.message}
|
|
164
|
+
throw new Error(`Cannot read ${exports.CONFIG_FILE}: ${e.message}`, { cause: e });
|
|
185
165
|
}
|
|
186
166
|
let parsed;
|
|
187
167
|
try {
|
|
@@ -189,7 +169,7 @@ function readConfigJson() {
|
|
|
189
169
|
}
|
|
190
170
|
catch (e) {
|
|
191
171
|
throw new Error(`Invalid JSON in ${exports.CONFIG_FILE}: ${e.message}\n` +
|
|
192
|
-
`Fix the file manually or delete it and run: rag-setup
|
|
172
|
+
`Fix the file manually or delete it and run: rag-setup`, { cause: e });
|
|
193
173
|
}
|
|
194
174
|
return parseConfig(parsed, exports.CONFIG_FILE);
|
|
195
175
|
}
|
|
@@ -198,19 +178,9 @@ const OLLAMA_MIGRATION_REMEDY = 'The "ollama" embedding provider has been remove
|
|
|
198
178
|
'and embedding.baseURL to "http://localhost:11434/v1" — via `rag-config edit` (or by ' +
|
|
199
179
|
'editing the config file directly) or by re-running `rag-setup`. After switching, rebuild ' +
|
|
200
180
|
'the index with `rag-index --reindex`.';
|
|
201
|
-
/** Strip a trailing `:tag` (Docker-style) from a model name, if present. */
|
|
202
181
|
function stripModelTag(model) {
|
|
203
182
|
return model.replace(/:[^:]*$/, '');
|
|
204
183
|
}
|
|
205
|
-
/**
|
|
206
|
-
* Detect a raw (pre-migration) config object that still selects the removed
|
|
207
|
-
* `ollama` embedding provider — explicitly, via a legacy top-level `ollama`
|
|
208
|
-
* block, or implicitly (no `provider` set, but `baseURL`/`model` point at
|
|
209
|
-
* Ollama's defaults) — and throw a `ConfigError` with migration guidance
|
|
210
|
-
* instead of letting it validate under a silently reinterpreted provider.
|
|
211
|
-
* Runs before `migrateRawConfig` so a legacy `ollama.*` block is never
|
|
212
|
-
* converted into an `embedding` block first. Pure — never mutates `raw`.
|
|
213
|
-
*/
|
|
214
184
|
function detectFormerOllamaConfig(raw) {
|
|
215
185
|
if (raw == null || typeof raw !== 'object')
|
|
216
186
|
return;
|
|
@@ -227,7 +197,7 @@ function detectFormerOllamaConfig(raw) {
|
|
|
227
197
|
try {
|
|
228
198
|
port = new URL(e.baseURL).port;
|
|
229
199
|
}
|
|
230
|
-
catch {
|
|
200
|
+
catch { }
|
|
231
201
|
if (port === '11434') {
|
|
232
202
|
throw new config_error_1.ConfigError(`Config's embedding.baseURL targets Ollama's default port (11434) with no embedding.provider set. ${OLLAMA_MIGRATION_REMEDY}`);
|
|
233
203
|
}
|
|
@@ -242,21 +212,6 @@ function detectFormerOllamaConfig(raw) {
|
|
|
242
212
|
throw new config_error_1.ConfigError(`Config has a legacy "ollama" configuration block. ${OLLAMA_MIGRATION_REMEDY}`);
|
|
243
213
|
}
|
|
244
214
|
}
|
|
245
|
-
/**
|
|
246
|
-
* Migrate a legacy raw config object to the current shape, in place of a
|
|
247
|
-
* versioned migration system. Pure — returns a new object, never mutates input.
|
|
248
|
-
*
|
|
249
|
-
* - Removed translation keys (`search.autoTranslate`, `search.translateModel`)
|
|
250
|
-
* are dropped so they neither validate-fail nor take effect.
|
|
251
|
-
* - Legacy `reranker.provider: 'ollama'` (a dead value — Ollama has no rerank
|
|
252
|
-
* API) is rewritten to `openai-compatible`, and a stale `/api/rerank` URL is
|
|
253
|
-
* dropped so it re-derives to `/rerank`. Otherwise the tightened enum would
|
|
254
|
-
* fail validation on existing configs and lock the user out.
|
|
255
|
-
*
|
|
256
|
-
* A legacy top-level `ollama` block reaches here only when `detectFormerOllamaConfig`
|
|
257
|
-
* did not already reject it (i.e. an `embedding` block is also present); it is
|
|
258
|
-
* dropped rather than merged. Exported for unit testing.
|
|
259
|
-
*/
|
|
260
215
|
function migrateRawConfig(raw) {
|
|
261
216
|
if (raw == null || typeof raw !== 'object')
|
|
262
217
|
return raw;
|
|
@@ -274,16 +229,6 @@ function migrateRawConfig(raw) {
|
|
|
274
229
|
}
|
|
275
230
|
return obj;
|
|
276
231
|
}
|
|
277
|
-
/**
|
|
278
|
-
* Validate a raw (pre-migration) config object against the Zod schema: first
|
|
279
|
-
* `detectFormerOllamaConfig` (a `ConfigError` on a former-Ollama config takes
|
|
280
|
-
* priority over both migration and the regular Zod enum rejection), then
|
|
281
|
-
* `migrateRawConfig`, then the schema itself. Unknown keys (e.g. the "$schema"
|
|
282
|
-
* editor reference) are stripped. Throws with a caller-friendly message on
|
|
283
|
-
* validation failure. The single entry point for both `readConfigJson` and
|
|
284
|
-
* `PUT /api/config`, so both apply identical rules with an identical message.
|
|
285
|
-
* Pure — no file I/O.
|
|
286
|
-
*/
|
|
287
232
|
function parseConfig(raw, source = exports.CONFIG_FILE) {
|
|
288
233
|
detectFormerOllamaConfig(raw);
|
|
289
234
|
const migrated = migrateRawConfig(raw);
|
|
@@ -295,7 +240,6 @@ function parseConfig(raw, source = exports.CONFIG_FILE) {
|
|
|
295
240
|
}
|
|
296
241
|
return result.data;
|
|
297
242
|
}
|
|
298
|
-
/** Build the JSON Schema object generated from the Zod config schema. Pure. */
|
|
299
243
|
function buildJsonSchema() {
|
|
300
244
|
return {
|
|
301
245
|
$id: 'https://github.com/oleksandr-antoniuk/RAG/config.schema.json',
|
|
@@ -306,15 +250,9 @@ function buildJsonSchema() {
|
|
|
306
250
|
function writeConfigJson(data) {
|
|
307
251
|
fs.mkdirSync(exports.CONFIG_DIR, { recursive: true });
|
|
308
252
|
writeSchemaFile();
|
|
309
|
-
// $schema first so editors pick it up; readConfigJson strips it on validation.
|
|
310
253
|
const withSchema = { $schema: SCHEMA_REF, ...data };
|
|
311
254
|
fs.writeFileSync(exports.CONFIG_FILE, JSON.stringify(withSchema, null, 2) + '\n', { mode: 0o600 });
|
|
312
255
|
}
|
|
313
|
-
/**
|
|
314
|
-
* Generate a JSON Schema from the Zod config schema and write it next to
|
|
315
|
-
* config.json. Editors resolve it via the "$schema" reference and provide
|
|
316
|
-
* key autocomplete, type hints, and inline validation while editing.
|
|
317
|
-
*/
|
|
318
256
|
function writeSchemaFile() {
|
|
319
257
|
fs.mkdirSync(exports.CONFIG_DIR, { recursive: true });
|
|
320
258
|
fs.writeFileSync(exports.SCHEMA_FILE, JSON.stringify(buildJsonSchema(), null, 2) + '\n');
|
package/dist/src/config.d.ts
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
|
+
import { type JsonConfig } from './config-store';
|
|
1
2
|
import { ConfigError } from './config-error';
|
|
2
3
|
export { ConfigError };
|
|
3
|
-
/**
|
|
4
|
-
* Resolve a config value that may reference an environment variable. A value of
|
|
5
|
-
* the form `env:VAR_NAME` resolves to `process.env.VAR_NAME`; any other string
|
|
6
|
-
* (including empty) is returned verbatim. A referenced-but-unset variable throws
|
|
7
|
-
* a clear error naming the variable and the `.env` file. Pure aside from the
|
|
8
|
-
* injected env map. See `src/app.ts` for how `.env` is loaded into the process.
|
|
9
|
-
*/
|
|
10
4
|
export declare function resolveEnvRef(value: string, env?: NodeJS.ProcessEnv): string;
|
|
5
|
+
export declare function rerankContext(raw: JsonConfig): {
|
|
6
|
+
wanted: boolean;
|
|
7
|
+
missingKey: boolean;
|
|
8
|
+
model: string;
|
|
9
|
+
};
|
|
11
10
|
export declare class Config {
|
|
12
11
|
private readonly data;
|
|
13
12
|
get db(): {
|
|
@@ -17,13 +16,6 @@ export declare class Config {
|
|
|
17
16
|
password: string;
|
|
18
17
|
database: string;
|
|
19
18
|
};
|
|
20
|
-
/**
|
|
21
|
-
* Embedding config. `apiKey` is returned **raw** (possibly an `env:VAR` ref) —
|
|
22
|
-
* callers resolve it lazily via `resolveEnvRef` at the moment they build a
|
|
23
|
-
* request, so an unset referenced variable fails only when the key is actually
|
|
24
|
-
* needed (during embed/search) rather than crashing container construction and
|
|
25
|
-
* locking the user out of `rag-web`/`rag-mcp`.
|
|
26
|
-
*/
|
|
27
19
|
get embedding(): {
|
|
28
20
|
provider: "openai-compatible" | "voyage" | "infinity";
|
|
29
21
|
baseURL: string;
|
|
@@ -32,14 +24,14 @@ export declare class Config {
|
|
|
32
24
|
dimensions: number | null;
|
|
33
25
|
batchSize: number;
|
|
34
26
|
};
|
|
35
|
-
/** Reranker config. `apiKey` is raw — resolve lazily with `resolveEnvRef`. */
|
|
36
27
|
get reranker(): {
|
|
37
28
|
enabled: boolean;
|
|
38
|
-
provider: "openai-compatible";
|
|
29
|
+
provider: "openai-compatible" | "voyage";
|
|
39
30
|
baseURL: string;
|
|
40
31
|
apiKey: string;
|
|
41
32
|
model: string;
|
|
42
33
|
url: string;
|
|
34
|
+
missingApiKey: boolean;
|
|
43
35
|
overfetch: number;
|
|
44
36
|
candidateFloor: number;
|
|
45
37
|
};
|
|
@@ -51,13 +43,12 @@ export declare class Config {
|
|
|
51
43
|
chunkStrategy: "ast" | "character";
|
|
52
44
|
};
|
|
53
45
|
get search(): {
|
|
54
|
-
similarityThreshold: number;
|
|
55
46
|
defaultLimit: number;
|
|
56
47
|
maxLimit: number;
|
|
48
|
+
similarityThreshold?: number | undefined;
|
|
57
49
|
};
|
|
58
50
|
get logging(): {
|
|
59
51
|
level: "error" | "debug" | "info" | "warn";
|
|
60
|
-
searchMetrics: boolean;
|
|
61
52
|
dir?: string | undefined;
|
|
62
53
|
};
|
|
63
54
|
get workspaceRoot(): string;
|
package/dist/src/config.js
CHANGED
|
@@ -35,18 +35,13 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.Config = exports.ConfigError = void 0;
|
|
37
37
|
exports.resolveEnvRef = resolveEnvRef;
|
|
38
|
+
exports.rerankContext = rerankContext;
|
|
38
39
|
const os = __importStar(require("os"));
|
|
39
40
|
const zod_1 = require("zod");
|
|
40
41
|
const config_store_1 = require("./config-store");
|
|
42
|
+
const constants_1 = require("./constants");
|
|
41
43
|
const config_error_1 = require("./config-error");
|
|
42
44
|
Object.defineProperty(exports, "ConfigError", { enumerable: true, get: function () { return config_error_1.ConfigError; } });
|
|
43
|
-
/**
|
|
44
|
-
* Resolve a config value that may reference an environment variable. A value of
|
|
45
|
-
* the form `env:VAR_NAME` resolves to `process.env.VAR_NAME`; any other string
|
|
46
|
-
* (including empty) is returned verbatim. A referenced-but-unset variable throws
|
|
47
|
-
* a clear error naming the variable and the `.env` file. Pure aside from the
|
|
48
|
-
* injected env map. See `src/app.ts` for how `.env` is loaded into the process.
|
|
49
|
-
*/
|
|
50
45
|
function resolveEnvRef(value, env = process.env) {
|
|
51
46
|
if (!value.startsWith('env:'))
|
|
52
47
|
return value;
|
|
@@ -66,12 +61,19 @@ const DEFAULT_BASE_URLS = {
|
|
|
66
61
|
function defaultBaseURL(provider) {
|
|
67
62
|
return DEFAULT_BASE_URLS[provider] ?? DEFAULT_BASE_URLS.infinity;
|
|
68
63
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
64
|
+
function rerankContext(raw) {
|
|
65
|
+
const rr = raw.reranker;
|
|
66
|
+
const embProvider = raw.embedding?.provider ?? config_store_1.CONFIG_DEFAULTS['embedding.provider'];
|
|
67
|
+
const isVoyage = (rr?.provider ?? config_store_1.CONFIG_DEFAULTS['reranker.provider']) === 'voyage';
|
|
68
|
+
return {
|
|
69
|
+
wanted: embProvider === 'infinity' || rr?.provider != null || rr?.baseURL != null || rr?.url != null,
|
|
70
|
+
missingKey: isVoyage && !rr?.apiKey,
|
|
71
|
+
model: isVoyage ? constants_1.VOYAGE_RERANK_MODELS[0] : config_store_1.CONFIG_DEFAULTS['reranker.model'],
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
function deriveRerankUrl(provider, baseURL) {
|
|
75
|
+
const trimmed = baseURL.replace(/\/+$/, '');
|
|
76
|
+
const root = provider === 'voyage' ? trimmed : trimmed.replace(/\/(embeddings|v1)$/, '');
|
|
75
77
|
return `${root}/rerank`;
|
|
76
78
|
}
|
|
77
79
|
const resolvedSchema = zod_1.z.object({
|
|
@@ -91,12 +93,13 @@ const resolvedSchema = zod_1.z.object({
|
|
|
91
93
|
batchSize: zod_1.z.number().int().positive().default(config_store_1.CONFIG_DEFAULTS['embedding.batchSize']),
|
|
92
94
|
}),
|
|
93
95
|
reranker: zod_1.z.object({
|
|
94
|
-
enabled: zod_1.z.boolean()
|
|
95
|
-
provider: zod_1.z.enum(['openai-compatible']).default(config_store_1.CONFIG_DEFAULTS['reranker.provider']),
|
|
96
|
+
enabled: zod_1.z.boolean(),
|
|
97
|
+
provider: zod_1.z.enum(['openai-compatible', 'voyage']).default(config_store_1.CONFIG_DEFAULTS['reranker.provider']),
|
|
96
98
|
baseURL: zod_1.z.string().min(1),
|
|
97
99
|
apiKey: zod_1.z.string().default(config_store_1.CONFIG_DEFAULTS['reranker.apiKey']),
|
|
98
|
-
model: zod_1.z.string()
|
|
100
|
+
model: zod_1.z.string(),
|
|
99
101
|
url: zod_1.z.string().min(1),
|
|
102
|
+
missingApiKey: zod_1.z.boolean(),
|
|
100
103
|
overfetch: zod_1.z.number().int().min(1).max(20).default(config_store_1.CONFIG_DEFAULTS['reranker.overfetch']),
|
|
101
104
|
candidateFloor: zod_1.z.number().int().min(1).default(config_store_1.CONFIG_DEFAULTS['reranker.candidateFloor']),
|
|
102
105
|
}),
|
|
@@ -108,29 +111,20 @@ const resolvedSchema = zod_1.z.object({
|
|
|
108
111
|
chunkStrategy: zod_1.z.enum(['ast', 'character']).default(config_store_1.CONFIG_DEFAULTS['indexing.chunkStrategy']),
|
|
109
112
|
}),
|
|
110
113
|
search: zod_1.z.object({
|
|
111
|
-
similarityThreshold: zod_1.z.number().min(0).max(1).
|
|
114
|
+
similarityThreshold: zod_1.z.number().min(0).max(1).optional(),
|
|
112
115
|
defaultLimit: zod_1.z.number().int().positive().default(config_store_1.CONFIG_DEFAULTS['search.defaultLimit']),
|
|
113
116
|
maxLimit: zod_1.z.number().int().positive().default(config_store_1.CONFIG_DEFAULTS['search.maxLimit']),
|
|
114
117
|
}),
|
|
115
118
|
logging: zod_1.z.object({
|
|
116
119
|
level: zod_1.z.enum(['debug', 'info', 'warn', 'error']).default(config_store_1.CONFIG_DEFAULTS['logging.level']),
|
|
117
120
|
dir: zod_1.z.string().optional(),
|
|
118
|
-
searchMetrics: zod_1.z.boolean().default(config_store_1.CONFIG_DEFAULTS['logging.searchMetrics']),
|
|
119
121
|
}),
|
|
120
122
|
workspaceRoot: zod_1.z.string().default(''),
|
|
121
123
|
});
|
|
122
124
|
class Config {
|
|
123
125
|
data;
|
|
124
126
|
get db() { return this.data.db; }
|
|
125
|
-
/**
|
|
126
|
-
* Embedding config. `apiKey` is returned **raw** (possibly an `env:VAR` ref) —
|
|
127
|
-
* callers resolve it lazily via `resolveEnvRef` at the moment they build a
|
|
128
|
-
* request, so an unset referenced variable fails only when the key is actually
|
|
129
|
-
* needed (during embed/search) rather than crashing container construction and
|
|
130
|
-
* locking the user out of `rag-web`/`rag-mcp`.
|
|
131
|
-
*/
|
|
132
127
|
get embedding() { return this.data.embedding; }
|
|
133
|
-
/** Reranker config. `apiKey` is raw — resolve lazily with `resolveEnvRef`. */
|
|
134
128
|
get reranker() { return this.data.reranker; }
|
|
135
129
|
get indexer() { return this.data.indexer; }
|
|
136
130
|
get search() { return this.data.search; }
|
|
@@ -142,8 +136,15 @@ class Config {
|
|
|
142
136
|
throw new config_error_1.ConfigError('Config not found. Run rag-setup.');
|
|
143
137
|
const embProvider = (raw.embedding?.provider ?? config_store_1.CONFIG_DEFAULTS['embedding.provider']);
|
|
144
138
|
const embBaseURL = raw.embedding?.baseURL ?? defaultBaseURL(embProvider);
|
|
145
|
-
const
|
|
146
|
-
const
|
|
139
|
+
const rr = raw.reranker;
|
|
140
|
+
const rerankProvider = (rr?.provider ?? config_store_1.CONFIG_DEFAULTS['reranker.provider']);
|
|
141
|
+
const isVoyageRerank = rerankProvider === 'voyage';
|
|
142
|
+
const rerankBaseURL = rr?.baseURL ?? (isVoyageRerank ? DEFAULT_BASE_URLS.voyage : embBaseURL);
|
|
143
|
+
const rerankUrl = rr?.url ?? deriveRerankUrl(rerankProvider, rerankBaseURL);
|
|
144
|
+
const rerankCtx = rerankContext(raw);
|
|
145
|
+
const rerankModel = rr?.model ?? rerankCtx.model;
|
|
146
|
+
const rerankWanted = rr?.enabled ?? rerankCtx.wanted;
|
|
147
|
+
const missingApiKey = rerankWanted && rerankCtx.missingKey;
|
|
147
148
|
const result = resolvedSchema.safeParse({
|
|
148
149
|
db: {
|
|
149
150
|
host: raw.db?.host,
|
|
@@ -161,14 +162,15 @@ class Config {
|
|
|
161
162
|
batchSize: raw.embedding?.batchSize,
|
|
162
163
|
},
|
|
163
164
|
reranker: {
|
|
164
|
-
enabled:
|
|
165
|
-
provider:
|
|
165
|
+
enabled: rerankWanted && !missingApiKey,
|
|
166
|
+
provider: rr?.provider,
|
|
166
167
|
baseURL: rerankBaseURL,
|
|
167
|
-
apiKey:
|
|
168
|
-
model:
|
|
168
|
+
apiKey: rr?.apiKey,
|
|
169
|
+
model: rerankModel,
|
|
169
170
|
url: rerankUrl,
|
|
170
|
-
|
|
171
|
-
|
|
171
|
+
missingApiKey,
|
|
172
|
+
overfetch: rr?.overfetch,
|
|
173
|
+
candidateFloor: rr?.candidateFloor,
|
|
172
174
|
},
|
|
173
175
|
indexer: {
|
|
174
176
|
chunkSize: raw.indexing?.chunkSize,
|
|
@@ -185,7 +187,6 @@ class Config {
|
|
|
185
187
|
logging: {
|
|
186
188
|
level: raw.logging?.level,
|
|
187
189
|
dir: raw.logging?.dir,
|
|
188
|
-
searchMetrics: raw.logging?.searchMetrics,
|
|
189
190
|
},
|
|
190
191
|
workspaceRoot: raw.workspaceRoot,
|
|
191
192
|
});
|
package/dist/src/constants.d.ts
CHANGED
|
@@ -1,42 +1,31 @@
|
|
|
1
1
|
export type EmbeddingProvider = 'openai-compatible' | 'voyage' | 'infinity';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
* must not exceed this; larger cloud models must reduce via the Matryoshka
|
|
5
|
-
* `dimensions` request parameter (`embedding.dimensions`).
|
|
6
|
-
*/
|
|
2
|
+
export type RerankProvider = 'openai-compatible' | 'voyage';
|
|
3
|
+
export declare const VOYAGE_RERANK_MODELS: readonly ["rerank-3", "rerank-3-lite"];
|
|
7
4
|
export declare const MAX_EMBED_DIM = 2000;
|
|
8
5
|
export interface ModelInfo {
|
|
9
6
|
provider: EmbeddingProvider;
|
|
10
|
-
/** Native / default output width. */
|
|
11
7
|
dimensions: number;
|
|
12
|
-
/** Model supports Matryoshka dimension reduction via a request parameter. */
|
|
13
8
|
dimConfigurable?: boolean;
|
|
14
|
-
/** Max width that can be indexed under the pgvector cap (advisory). */
|
|
15
9
|
maxIndexable?: number;
|
|
16
|
-
/** Max width the model itself can emit (advisory). */
|
|
17
10
|
maxDim?: number;
|
|
11
|
+
defaultThreshold?: number;
|
|
18
12
|
}
|
|
19
|
-
/**
|
|
20
|
-
* Advisory (NOT exhaustive) registry of known embedding models. Used to resolve
|
|
21
|
-
* a model's dimension without a runtime probe and to suggest models in the
|
|
22
|
-
* dashboard. Models absent here still work — their dimension is probed at index
|
|
23
|
-
* time (see `resolveDimension`).
|
|
24
|
-
*/
|
|
25
13
|
export declare const MODEL_REGISTRY: Record<string, ModelInfo>;
|
|
26
14
|
export declare const DEFAULT_EMBED_MODEL = "jinaai/jina-embeddings-v2-base-code";
|
|
27
|
-
/**
|
|
28
|
-
* Former Ollama registry model names, kept only so config validation can
|
|
29
|
-
* recognise an implicit (provider-less) config that still targets Ollama —
|
|
30
|
-
* see `detectFormerOllamaConfig` in `config-store.ts`.
|
|
31
|
-
*/
|
|
32
15
|
export declare const FORMER_OLLAMA_MODELS: readonly ["bge-m3", "nomic-embed-text", "mxbai-embed-large"];
|
|
33
|
-
/** Advisory dimension for a model, or `undefined` when the model is unknown. */
|
|
34
16
|
export declare function registryDimension(model: string): number | undefined;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
17
|
+
export type ThresholdSource = 'call' | 'config' | 'model' | 'fallback';
|
|
18
|
+
export interface ResolvedThreshold {
|
|
19
|
+
value: number;
|
|
20
|
+
source: ThresholdSource;
|
|
21
|
+
}
|
|
22
|
+
export declare const FALLBACK_THRESHOLD = 1;
|
|
23
|
+
export declare function resolveThreshold({ callValue, configValue, model, registry }: {
|
|
24
|
+
callValue?: number;
|
|
25
|
+
configValue?: number;
|
|
26
|
+
model: string;
|
|
27
|
+
registry?: Record<string, ModelInfo>;
|
|
28
|
+
}): ResolvedThreshold;
|
|
29
|
+
export declare function formatThreshold(value: number): string;
|
|
30
|
+
export declare function thresholdMismatchWarning(configValue: number | undefined, model: string, registry?: Record<string, ModelInfo>): string | null;
|
|
42
31
|
export declare function resolveDimension(override: number | null | undefined, model: string, probeFn: () => Promise<number>, registry?: Record<string, ModelInfo>): Promise<number>;
|
package/dist/src/constants.js
CHANGED
|
@@ -1,48 +1,54 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.FORMER_OLLAMA_MODELS = exports.DEFAULT_EMBED_MODEL = exports.MODEL_REGISTRY = exports.MAX_EMBED_DIM = void 0;
|
|
3
|
+
exports.FALLBACK_THRESHOLD = exports.FORMER_OLLAMA_MODELS = exports.DEFAULT_EMBED_MODEL = exports.MODEL_REGISTRY = exports.MAX_EMBED_DIM = exports.VOYAGE_RERANK_MODELS = void 0;
|
|
4
4
|
exports.registryDimension = registryDimension;
|
|
5
|
+
exports.resolveThreshold = resolveThreshold;
|
|
6
|
+
exports.formatThreshold = formatThreshold;
|
|
7
|
+
exports.thresholdMismatchWarning = thresholdMismatchWarning;
|
|
5
8
|
exports.resolveDimension = resolveDimension;
|
|
6
|
-
|
|
7
|
-
* pgvector's HNSW / IVFFlat index hard limit. The effective embedding dimension
|
|
8
|
-
* must not exceed this; larger cloud models must reduce via the Matryoshka
|
|
9
|
-
* `dimensions` request parameter (`embedding.dimensions`).
|
|
10
|
-
*/
|
|
9
|
+
exports.VOYAGE_RERANK_MODELS = ['rerank-3', 'rerank-3-lite'];
|
|
11
10
|
exports.MAX_EMBED_DIM = 2000;
|
|
12
|
-
/**
|
|
13
|
-
* Advisory (NOT exhaustive) registry of known embedding models. Used to resolve
|
|
14
|
-
* a model's dimension without a runtime probe and to suggest models in the
|
|
15
|
-
* dashboard. Models absent here still work — their dimension is probed at index
|
|
16
|
-
* time (see `resolveDimension`).
|
|
17
|
-
*/
|
|
18
11
|
exports.MODEL_REGISTRY = {
|
|
19
12
|
'text-embedding-3-small': { provider: 'openai-compatible', dimensions: 1536, dimConfigurable: true },
|
|
20
13
|
'text-embedding-3-large': { provider: 'openai-compatible', dimensions: 3072, dimConfigurable: true, maxIndexable: 2000 },
|
|
21
14
|
'text-embedding-ada-002': { provider: 'openai-compatible', dimensions: 1536 },
|
|
22
|
-
'voyage-code-
|
|
23
|
-
'voyage-
|
|
24
|
-
'voyage-
|
|
15
|
+
'voyage-code-4': { provider: 'voyage', dimensions: 1024, dimConfigurable: true, maxDim: 2048, defaultThreshold: 0.95 },
|
|
16
|
+
'voyage-4-large': { provider: 'voyage', dimensions: 1024, dimConfigurable: true, maxDim: 2048, defaultThreshold: 0.95 },
|
|
17
|
+
'voyage-4': { provider: 'voyage', dimensions: 1024, dimConfigurable: true, maxDim: 2048, defaultThreshold: 0.95 },
|
|
18
|
+
'voyage-4-lite': { provider: 'voyage', dimensions: 1024, dimConfigurable: true, maxDim: 2048, defaultThreshold: 0.95 },
|
|
25
19
|
'BAAI/bge-m3': { provider: 'infinity', dimensions: 1024 },
|
|
26
|
-
'jinaai/jina-embeddings-v2-base-code': { provider: 'infinity', dimensions: 768 },
|
|
20
|
+
'jinaai/jina-embeddings-v2-base-code': { provider: 'infinity', dimensions: 768, defaultThreshold: 0.6 },
|
|
27
21
|
};
|
|
28
22
|
exports.DEFAULT_EMBED_MODEL = 'jinaai/jina-embeddings-v2-base-code';
|
|
29
|
-
/**
|
|
30
|
-
* Former Ollama registry model names, kept only so config validation can
|
|
31
|
-
* recognise an implicit (provider-less) config that still targets Ollama —
|
|
32
|
-
* see `detectFormerOllamaConfig` in `config-store.ts`.
|
|
33
|
-
*/
|
|
34
23
|
exports.FORMER_OLLAMA_MODELS = ['bge-m3', 'nomic-embed-text', 'mxbai-embed-large'];
|
|
35
|
-
/** Advisory dimension for a model, or `undefined` when the model is unknown. */
|
|
36
24
|
function registryDimension(model) {
|
|
37
25
|
return exports.MODEL_REGISTRY[model]?.dimensions;
|
|
38
26
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
27
|
+
exports.FALLBACK_THRESHOLD = 1.0;
|
|
28
|
+
const THRESHOLD_MISMATCH_TOLERANCE = 0.1;
|
|
29
|
+
const FLOAT_EPSILON = 1e-9;
|
|
30
|
+
function resolveThreshold({ callValue, configValue, model, registry = exports.MODEL_REGISTRY }) {
|
|
31
|
+
if (callValue !== undefined)
|
|
32
|
+
return { value: callValue, source: 'call' };
|
|
33
|
+
if (configValue !== undefined)
|
|
34
|
+
return { value: configValue, source: 'config' };
|
|
35
|
+
const recommended = registry[model]?.defaultThreshold;
|
|
36
|
+
if (recommended !== undefined)
|
|
37
|
+
return { value: recommended, source: 'model' };
|
|
38
|
+
return { value: exports.FALLBACK_THRESHOLD, source: 'fallback' };
|
|
39
|
+
}
|
|
40
|
+
function formatThreshold(value) {
|
|
41
|
+
return Number.isInteger(value) ? value.toFixed(1) : String(value);
|
|
42
|
+
}
|
|
43
|
+
function thresholdMismatchWarning(configValue, model, registry = exports.MODEL_REGISTRY) {
|
|
44
|
+
const recommended = registry[model]?.defaultThreshold;
|
|
45
|
+
if (configValue === undefined || recommended === undefined)
|
|
46
|
+
return null;
|
|
47
|
+
if (Math.abs(configValue - recommended) <= THRESHOLD_MISMATCH_TOLERANCE + FLOAT_EPSILON)
|
|
48
|
+
return null;
|
|
49
|
+
return `search.similarityThreshold is ${formatThreshold(configValue)}, but the recommended value for ${model} is ${formatThreshold(recommended)}. `
|
|
50
|
+
+ 'Searches may miss relevant code or return weak matches. Remove the key to follow the model, or retune it (rag-config edit).';
|
|
51
|
+
}
|
|
46
52
|
async function resolveDimension(override, model, probeFn, registry = exports.MODEL_REGISTRY) {
|
|
47
53
|
let dim;
|
|
48
54
|
if (override != null) {
|
package/dist/src/container.d.ts
CHANGED
|
@@ -1,19 +1,27 @@
|
|
|
1
1
|
import { Config } from './config';
|
|
2
2
|
import { IndexerService } from './services/IndexerService';
|
|
3
|
+
import { type SearchServices } from './search/create-search-services';
|
|
3
4
|
import { McpServer } from './services/McpServer';
|
|
5
|
+
import { LoggerService } from './services/LoggerService';
|
|
4
6
|
import type { IDatabase } from './interfaces';
|
|
5
7
|
import type { IEmbedder } from './interfaces';
|
|
6
|
-
import type { ISearcher } from './interfaces';
|
|
7
8
|
import type { ILogger } from './interfaces';
|
|
8
9
|
import type { IProjectDiscovery } from './interfaces';
|
|
10
|
+
import type { IMcpReadiness } from './interfaces';
|
|
9
11
|
export interface Container {
|
|
10
12
|
config: Config;
|
|
11
13
|
db: IDatabase;
|
|
12
14
|
embedder: IEmbedder;
|
|
13
15
|
indexer: IndexerService;
|
|
14
|
-
|
|
16
|
+
search: SearchServices;
|
|
17
|
+
readiness: IMcpReadiness;
|
|
15
18
|
mcp: McpServer;
|
|
16
19
|
logger: ILogger;
|
|
17
20
|
discovery: IProjectDiscovery;
|
|
18
21
|
}
|
|
22
|
+
export declare function loggerBindingsFor(loggerName?: string): Record<string, unknown> | undefined;
|
|
23
|
+
export declare function createLogger(cfg: {
|
|
24
|
+
level: string;
|
|
25
|
+
dir?: string;
|
|
26
|
+
}, loggerName?: string): LoggerService;
|
|
19
27
|
export declare function createContainer(loggerName?: string): Container;
|
package/dist/src/container.js
CHANGED
|
@@ -1,27 +1,38 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.loggerBindingsFor = loggerBindingsFor;
|
|
4
|
+
exports.createLogger = createLogger;
|
|
3
5
|
exports.createContainer = createContainer;
|
|
6
|
+
const crypto_1 = require("crypto");
|
|
4
7
|
const config_1 = require("./config");
|
|
5
8
|
const DatabaseService_1 = require("./services/DatabaseService");
|
|
6
9
|
const EmbedderFactory_1 = require("./services/EmbedderFactory");
|
|
7
10
|
const AstParserService_1 = require("./services/AstParserService");
|
|
8
|
-
const
|
|
11
|
+
const create_chunker_1 = require("./chunking/create-chunker");
|
|
9
12
|
const IndexerService_1 = require("./services/IndexerService");
|
|
10
|
-
const
|
|
13
|
+
const create_search_services_1 = require("./search/create-search-services");
|
|
11
14
|
const McpServer_1 = require("./services/McpServer");
|
|
15
|
+
const McpReadiness_1 = require("./services/McpReadiness");
|
|
12
16
|
const LoggerService_1 = require("./services/LoggerService");
|
|
13
17
|
const MonorepoAwareDiscoveryService_1 = require("./services/MonorepoAwareDiscoveryService");
|
|
14
18
|
const NxMonorepoResolver_1 = require("./services/NxMonorepoResolver");
|
|
19
|
+
function loggerBindingsFor(loggerName) {
|
|
20
|
+
return loggerName === 'mcp' ? { connectionId: (0, crypto_1.randomUUID)() } : undefined;
|
|
21
|
+
}
|
|
22
|
+
function createLogger(cfg, loggerName) {
|
|
23
|
+
return LoggerService_1.LoggerService.fromConfig(cfg, loggerName, loggerBindingsFor(loggerName));
|
|
24
|
+
}
|
|
15
25
|
function createContainer(loggerName) {
|
|
16
26
|
const config = new config_1.Config();
|
|
17
|
-
const logger =
|
|
18
|
-
const db = new DatabaseService_1.DatabaseService(config);
|
|
27
|
+
const logger = createLogger(config.logging, loggerName);
|
|
28
|
+
const db = new DatabaseService_1.DatabaseService(config, logger);
|
|
19
29
|
const embedder = (0, EmbedderFactory_1.createEmbedder)(config, logger);
|
|
20
30
|
const ast = new AstParserService_1.AstParserService(logger);
|
|
21
|
-
const chunker =
|
|
31
|
+
const chunker = (0, create_chunker_1.createChunker)(config);
|
|
22
32
|
const discovery = new MonorepoAwareDiscoveryService_1.MonorepoAwareDiscoveryService([new NxMonorepoResolver_1.NxMonorepoResolver(logger)], logger);
|
|
23
33
|
const indexer = new IndexerService_1.IndexerService(db, embedder, ast, chunker, config, logger);
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
|
|
34
|
+
const search = (0, create_search_services_1.createSearchServices)(db, embedder, discovery, config, logger);
|
|
35
|
+
const readiness = new McpReadiness_1.McpReadiness(db, search.identity, logger);
|
|
36
|
+
const mcp = new McpServer_1.McpServer(search, readiness, config, logger);
|
|
37
|
+
return { config, db, embedder, indexer, search, readiness, mcp, logger, discovery };
|
|
27
38
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { NodePgDatabase, NodePgTransaction } from 'drizzle-orm/node-postgres';
|
|
2
|
+
import type { ExtractTablesWithRelations } from 'drizzle-orm/relations';
|
|
3
|
+
import * as schema from './schema';
|
|
4
|
+
type Schema = typeof schema;
|
|
5
|
+
export type DrizzleDb = NodePgDatabase<Schema>;
|
|
6
|
+
export type DrizzleTx = NodePgTransaction<Schema, ExtractTablesWithRelations<Schema>>;
|
|
7
|
+
export {};
|
package/dist/src/db/index.d.ts
CHANGED