codesift-mcp 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 +241 -0
- package/dist/cli/args.d.ts +13 -0
- package/dist/cli/args.d.ts.map +1 -0
- package/dist/cli/args.js +79 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/commands.d.ts +4 -0
- package/dist/cli/commands.d.ts.map +1 -0
- package/dist/cli/commands.js +336 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/cli/help.d.ts +3 -0
- package/dist/cli/help.d.ts.map +1 -0
- package/dist/cli/help.js +271 -0
- package/dist/cli/help.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +80 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +23 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +49 -0
- package/dist/config.js.map +1 -0
- package/dist/parser/extractors/go.d.ts +4 -0
- package/dist/parser/extractors/go.d.ts.map +1 -0
- package/dist/parser/extractors/go.js +185 -0
- package/dist/parser/extractors/go.js.map +1 -0
- package/dist/parser/extractors/javascript.d.ts +9 -0
- package/dist/parser/extractors/javascript.d.ts.map +1 -0
- package/dist/parser/extractors/javascript.js +10 -0
- package/dist/parser/extractors/javascript.js.map +1 -0
- package/dist/parser/extractors/markdown.d.ts +15 -0
- package/dist/parser/extractors/markdown.d.ts.map +1 -0
- package/dist/parser/extractors/markdown.js +217 -0
- package/dist/parser/extractors/markdown.js.map +1 -0
- package/dist/parser/extractors/prisma.d.ts +17 -0
- package/dist/parser/extractors/prisma.d.ts.map +1 -0
- package/dist/parser/extractors/prisma.js +121 -0
- package/dist/parser/extractors/prisma.js.map +1 -0
- package/dist/parser/extractors/python.d.ts +4 -0
- package/dist/parser/extractors/python.d.ts.map +1 -0
- package/dist/parser/extractors/python.js +203 -0
- package/dist/parser/extractors/python.js.map +1 -0
- package/dist/parser/extractors/rust.d.ts +4 -0
- package/dist/parser/extractors/rust.d.ts.map +1 -0
- package/dist/parser/extractors/rust.js +178 -0
- package/dist/parser/extractors/rust.js.map +1 -0
- package/dist/parser/extractors/typescript.d.ts +4 -0
- package/dist/parser/extractors/typescript.d.ts.map +1 -0
- package/dist/parser/extractors/typescript.js +296 -0
- package/dist/parser/extractors/typescript.js.map +1 -0
- package/dist/parser/languages/tree-sitter-css.wasm +0 -0
- package/dist/parser/languages/tree-sitter-go.wasm +0 -0
- package/dist/parser/languages/tree-sitter-java.wasm +0 -0
- package/dist/parser/languages/tree-sitter-javascript.wasm +0 -0
- package/dist/parser/languages/tree-sitter-json.wasm +0 -0
- package/dist/parser/languages/tree-sitter-php.wasm +0 -0
- package/dist/parser/languages/tree-sitter-python.wasm +0 -0
- package/dist/parser/languages/tree-sitter-ruby.wasm +0 -0
- package/dist/parser/languages/tree-sitter-rust.wasm +0 -0
- package/dist/parser/languages/tree-sitter-tsx.wasm +0 -0
- package/dist/parser/languages/tree-sitter-typescript.wasm +0 -0
- package/dist/parser/parser-manager.d.ts +6 -0
- package/dist/parser/parser-manager.d.ts.map +1 -0
- package/dist/parser/parser-manager.js +60 -0
- package/dist/parser/parser-manager.js.map +1 -0
- package/dist/parser/symbol-extractor.d.ts +22 -0
- package/dist/parser/symbol-extractor.d.ts.map +1 -0
- package/dist/parser/symbol-extractor.js +115 -0
- package/dist/parser/symbol-extractor.js.map +1 -0
- package/dist/retrieval/codebase-retrieval.d.ts +27 -0
- package/dist/retrieval/codebase-retrieval.d.ts.map +1 -0
- package/dist/retrieval/codebase-retrieval.js +472 -0
- package/dist/retrieval/codebase-retrieval.js.map +1 -0
- package/dist/search/bm25.d.ts +22 -0
- package/dist/search/bm25.d.ts.map +1 -0
- package/dist/search/bm25.js +179 -0
- package/dist/search/bm25.js.map +1 -0
- package/dist/search/chunker.d.ts +9 -0
- package/dist/search/chunker.d.ts.map +1 -0
- package/dist/search/chunker.js +91 -0
- package/dist/search/chunker.js.map +1 -0
- package/dist/search/hybrid.d.ts +16 -0
- package/dist/search/hybrid.d.ts.map +1 -0
- package/dist/search/hybrid.js +51 -0
- package/dist/search/hybrid.js.map +1 -0
- package/dist/search/semantic.d.ts +44 -0
- package/dist/search/semantic.d.ts.map +1 -0
- package/dist/search/semantic.js +194 -0
- package/dist/search/semantic.js.map +1 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +285 -0
- package/dist/server.js.map +1 -0
- package/dist/storage/chunk-store.d.ts +32 -0
- package/dist/storage/chunk-store.d.ts.map +1 -0
- package/dist/storage/chunk-store.js +144 -0
- package/dist/storage/chunk-store.js.map +1 -0
- package/dist/storage/embedding-store.d.ts +41 -0
- package/dist/storage/embedding-store.d.ts.map +1 -0
- package/dist/storage/embedding-store.js +149 -0
- package/dist/storage/embedding-store.js.map +1 -0
- package/dist/storage/index-store.d.ts +23 -0
- package/dist/storage/index-store.d.ts.map +1 -0
- package/dist/storage/index-store.js +95 -0
- package/dist/storage/index-store.js.map +1 -0
- package/dist/storage/registry.d.ts +35 -0
- package/dist/storage/registry.d.ts.map +1 -0
- package/dist/storage/registry.js +99 -0
- package/dist/storage/registry.js.map +1 -0
- package/dist/storage/usage-stats.d.ts +32 -0
- package/dist/storage/usage-stats.d.ts.map +1 -0
- package/dist/storage/usage-stats.js +180 -0
- package/dist/storage/usage-stats.js.map +1 -0
- package/dist/storage/usage-tracker.d.ts +35 -0
- package/dist/storage/usage-tracker.d.ts.map +1 -0
- package/dist/storage/usage-tracker.js +245 -0
- package/dist/storage/usage-tracker.js.map +1 -0
- package/dist/storage/watcher.d.ts +12 -0
- package/dist/storage/watcher.d.ts.map +1 -0
- package/dist/storage/watcher.js +66 -0
- package/dist/storage/watcher.js.map +1 -0
- package/dist/tools/context-tools.d.ts +31 -0
- package/dist/tools/context-tools.d.ts.map +1 -0
- package/dist/tools/context-tools.js +219 -0
- package/dist/tools/context-tools.js.map +1 -0
- package/dist/tools/diff-tools.d.ts +22 -0
- package/dist/tools/diff-tools.d.ts.map +1 -0
- package/dist/tools/diff-tools.js +165 -0
- package/dist/tools/diff-tools.js.map +1 -0
- package/dist/tools/generate-tools.d.ts +11 -0
- package/dist/tools/generate-tools.d.ts.map +1 -0
- package/dist/tools/generate-tools.js +135 -0
- package/dist/tools/generate-tools.js.map +1 -0
- package/dist/tools/graph-tools.d.ts +60 -0
- package/dist/tools/graph-tools.d.ts.map +1 -0
- package/dist/tools/graph-tools.js +313 -0
- package/dist/tools/graph-tools.js.map +1 -0
- package/dist/tools/index-tools.d.ts +39 -0
- package/dist/tools/index-tools.d.ts.map +1 -0
- package/dist/tools/index-tools.js +451 -0
- package/dist/tools/index-tools.js.map +1 -0
- package/dist/tools/outline-tools.d.ts +59 -0
- package/dist/tools/outline-tools.d.ts.map +1 -0
- package/dist/tools/outline-tools.js +342 -0
- package/dist/tools/outline-tools.js.map +1 -0
- package/dist/tools/search-tools.d.ts +29 -0
- package/dist/tools/search-tools.d.ts.map +1 -0
- package/dist/tools/search-tools.js +309 -0
- package/dist/tools/search-tools.js.map +1 -0
- package/dist/tools/symbol-tools.d.ts +24 -0
- package/dist/tools/symbol-tools.d.ts.map +1 -0
- package/dist/tools/symbol-tools.js +172 -0
- package/dist/tools/symbol-tools.js.map +1 -0
- package/dist/types.d.ts +91 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/git-validation.d.ts +11 -0
- package/dist/utils/git-validation.d.ts.map +1 -0
- package/dist/utils/git-validation.js +19 -0
- package/dist/utils/git-validation.js.map +1 -0
- package/dist/utils/test-file.d.ts +11 -0
- package/dist/utils/test-file.d.ts.map +1 -0
- package/dist/utils/test-file.js +27 -0
- package/dist/utils/test-file.js.map +1 -0
- package/package.json +62 -0
- package/src/parser/languages/tree-sitter-css.wasm +0 -0
- package/src/parser/languages/tree-sitter-go.wasm +0 -0
- package/src/parser/languages/tree-sitter-java.wasm +0 -0
- package/src/parser/languages/tree-sitter-javascript.wasm +0 -0
- package/src/parser/languages/tree-sitter-json.wasm +0 -0
- package/src/parser/languages/tree-sitter-php.wasm +0 -0
- package/src/parser/languages/tree-sitter-python.wasm +0 -0
- package/src/parser/languages/tree-sitter-ruby.wasm +0 -0
- package/src/parser/languages/tree-sitter-rust.wasm +0 -0
- package/src/parser/languages/tree-sitter-tsx.wasm +0 -0
- package/src/parser/languages/tree-sitter-typescript.wasm +0 -0
|
@@ -0,0 +1,472 @@
|
|
|
1
|
+
import { loadConfig } from "../config.js";
|
|
2
|
+
import { isTestFile } from "../utils/test-file.js";
|
|
3
|
+
/**
|
|
4
|
+
* Estimate token count from a string. ~4 chars per token.
|
|
5
|
+
*/
|
|
6
|
+
function estimateTokens(text) {
|
|
7
|
+
return Math.ceil(text.length / 4);
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Execute a single sub-query and return the result with token estimate.
|
|
11
|
+
*/
|
|
12
|
+
async function executeSubQuery(repo, query) {
|
|
13
|
+
const qType = query.type;
|
|
14
|
+
switch (qType) {
|
|
15
|
+
case "symbols": {
|
|
16
|
+
const { searchSymbols } = await import("../tools/search-tools.js");
|
|
17
|
+
const results = await searchSymbols(repo, query["query"], {
|
|
18
|
+
kind: query["kind"],
|
|
19
|
+
file_pattern: query["file_pattern"],
|
|
20
|
+
include_source: true,
|
|
21
|
+
top_k: query["top_k"] ?? 5,
|
|
22
|
+
});
|
|
23
|
+
const sourceLimit = query["source_chars"] ?? 200;
|
|
24
|
+
const data = results.map((r) => {
|
|
25
|
+
const sym = r.symbol;
|
|
26
|
+
return sourceLimit > 0 && sym.source && sym.source.length > sourceLimit
|
|
27
|
+
? { ...sym, source: sym.source.slice(0, sourceLimit) }
|
|
28
|
+
: sym;
|
|
29
|
+
});
|
|
30
|
+
const text = JSON.stringify(data);
|
|
31
|
+
return { type: qType, data, tokens: estimateTokens(text) };
|
|
32
|
+
}
|
|
33
|
+
case "text": {
|
|
34
|
+
const { searchText } = await import("../tools/search-tools.js");
|
|
35
|
+
const results = await searchText(repo, query["query"], {
|
|
36
|
+
regex: query["regex"],
|
|
37
|
+
context_lines: query["context_lines"],
|
|
38
|
+
file_pattern: query["file_pattern"],
|
|
39
|
+
});
|
|
40
|
+
const text = JSON.stringify(results);
|
|
41
|
+
return { type: qType, data: results, tokens: estimateTokens(text) };
|
|
42
|
+
}
|
|
43
|
+
case "file_tree": {
|
|
44
|
+
const { getFileTree } = await import("../tools/outline-tools.js");
|
|
45
|
+
const result = await getFileTree(repo, {
|
|
46
|
+
path_prefix: (query["path"] ?? query["path_prefix"]),
|
|
47
|
+
name_pattern: query["name_pattern"],
|
|
48
|
+
depth: query["depth"],
|
|
49
|
+
compact: query["compact"],
|
|
50
|
+
min_symbols: query["min_symbols"],
|
|
51
|
+
});
|
|
52
|
+
const text = JSON.stringify(result);
|
|
53
|
+
return { type: qType, data: result, tokens: estimateTokens(text) };
|
|
54
|
+
}
|
|
55
|
+
case "outline": {
|
|
56
|
+
const { getFileOutline } = await import("../tools/outline-tools.js");
|
|
57
|
+
const result = await getFileOutline(repo, query["file_path"]);
|
|
58
|
+
const text = JSON.stringify(result);
|
|
59
|
+
return { type: qType, data: result, tokens: estimateTokens(text) };
|
|
60
|
+
}
|
|
61
|
+
case "references": {
|
|
62
|
+
const { findReferences } = await import("../tools/symbol-tools.js");
|
|
63
|
+
const results = await findReferences(repo, query["symbol_name"]);
|
|
64
|
+
const text = JSON.stringify(results);
|
|
65
|
+
return { type: qType, data: results, tokens: estimateTokens(text) };
|
|
66
|
+
}
|
|
67
|
+
case "call_chain": {
|
|
68
|
+
const { traceCallChain } = await import("../tools/graph-tools.js");
|
|
69
|
+
const result = await traceCallChain(repo, query["symbol_name"], query["direction"] ?? "callers", {
|
|
70
|
+
depth: query["depth"],
|
|
71
|
+
include_source: query["include_source"] ?? false,
|
|
72
|
+
});
|
|
73
|
+
const text = JSON.stringify(result);
|
|
74
|
+
return { type: qType, data: result, tokens: estimateTokens(text) };
|
|
75
|
+
}
|
|
76
|
+
case "impact": {
|
|
77
|
+
const { impactAnalysis } = await import("../tools/graph-tools.js");
|
|
78
|
+
const result = await impactAnalysis(repo, query["since"], {
|
|
79
|
+
depth: query["depth"],
|
|
80
|
+
until: query["until"],
|
|
81
|
+
include_source: query["include_source"] ?? false,
|
|
82
|
+
});
|
|
83
|
+
const text = JSON.stringify(result);
|
|
84
|
+
return { type: qType, data: result, tokens: estimateTokens(text) };
|
|
85
|
+
}
|
|
86
|
+
case "context": {
|
|
87
|
+
const { assembleContext } = await import("../tools/context-tools.js");
|
|
88
|
+
const result = await assembleContext(repo, query["query"], query["max_tokens"]);
|
|
89
|
+
const text = JSON.stringify(result);
|
|
90
|
+
return { type: qType, data: result, tokens: estimateTokens(text) };
|
|
91
|
+
}
|
|
92
|
+
case "knowledge_map": {
|
|
93
|
+
const { getKnowledgeMap } = await import("../tools/context-tools.js");
|
|
94
|
+
const result = await getKnowledgeMap(repo, query["focus"], query["depth"]);
|
|
95
|
+
const text = JSON.stringify(result);
|
|
96
|
+
return { type: qType, data: result, tokens: estimateTokens(text) };
|
|
97
|
+
}
|
|
98
|
+
case "semantic": {
|
|
99
|
+
const { getCodeIndex, getEmbeddingCache } = await import("../tools/index-tools.js");
|
|
100
|
+
const { createEmbeddingProvider, searchSemantic, cosineSimilarity } = await import("../search/semantic.js");
|
|
101
|
+
const { loadConfig: getConfig } = await import("../config.js");
|
|
102
|
+
const { getRepo } = await import("../storage/registry.js");
|
|
103
|
+
const { loadChunks, loadChunkEmbeddings, getChunkPath, getChunkEmbeddingPath } = await import("../storage/chunk-store.js");
|
|
104
|
+
const semanticConfig = getConfig();
|
|
105
|
+
if (!semanticConfig.embeddingProvider) {
|
|
106
|
+
throw new Error("No embedding provider configured. Set CODESIFT_VOYAGE_API_KEY, CODESIFT_OPENAI_API_KEY, or CODESIFT_OLLAMA_URL.");
|
|
107
|
+
}
|
|
108
|
+
const topK = query["top_k"] ?? 10;
|
|
109
|
+
const fileFilter = query["file_filter"];
|
|
110
|
+
const excludeTests = query["exclude_tests"] ?? true;
|
|
111
|
+
// Auto-decompose long queries for RRF merging (shared by both paths)
|
|
112
|
+
const provider = createEmbeddingProvider(semanticConfig.embeddingProvider, semanticConfig);
|
|
113
|
+
const subQueryTexts = decomposeQuery(query["query"]);
|
|
114
|
+
const vecs = await provider.embed(subQueryTexts);
|
|
115
|
+
// Try chunk-level semantic search first
|
|
116
|
+
const repoMeta = await getRepo(semanticConfig.registryPath, repo);
|
|
117
|
+
if (repoMeta) {
|
|
118
|
+
const chunkPath = getChunkPath(repoMeta.index_path);
|
|
119
|
+
const chunkEmbeddingPath = getChunkEmbeddingPath(repoMeta.index_path);
|
|
120
|
+
const [chunks, chunkEmbeddings] = await Promise.all([
|
|
121
|
+
loadChunks(chunkPath),
|
|
122
|
+
loadChunkEmbeddings(chunkEmbeddingPath),
|
|
123
|
+
]);
|
|
124
|
+
if (chunks && chunkEmbeddings) {
|
|
125
|
+
// Filter embeddings by file path substring and/or test file exclusion
|
|
126
|
+
let filteredEmbeddings = chunkEmbeddings;
|
|
127
|
+
if (fileFilter || excludeTests) {
|
|
128
|
+
filteredEmbeddings = new Map([...chunkEmbeddings.entries()].filter(([id]) => {
|
|
129
|
+
const chunkFile = chunks.get(id)?.file;
|
|
130
|
+
if (!chunkFile)
|
|
131
|
+
return false;
|
|
132
|
+
if (fileFilter && !chunkFile.includes(fileFilter))
|
|
133
|
+
return false;
|
|
134
|
+
if (excludeTests && isTestFile(chunkFile))
|
|
135
|
+
return false;
|
|
136
|
+
return true;
|
|
137
|
+
}));
|
|
138
|
+
}
|
|
139
|
+
// RRF over sub-query rankings (k=60 per standard RRF)
|
|
140
|
+
const rrfScores = new Map();
|
|
141
|
+
const rrfK = 60;
|
|
142
|
+
for (const vec of vecs) {
|
|
143
|
+
if (!vec)
|
|
144
|
+
continue;
|
|
145
|
+
const qEmbed = new Float32Array(vec);
|
|
146
|
+
const subScores = [];
|
|
147
|
+
for (const [id, chunkVec] of filteredEmbeddings) {
|
|
148
|
+
if (chunkVec.length === qEmbed.length) {
|
|
149
|
+
subScores.push({ id, score: cosineSimilarity(qEmbed, chunkVec) });
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
subScores.sort((a, b) => b.score - a.score);
|
|
153
|
+
subScores.forEach((s, rank) => {
|
|
154
|
+
rrfScores.set(s.id, (rrfScores.get(s.id) ?? 0) + 1 / (rrfK + rank + 1));
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
const topIds = [...rrfScores.entries()]
|
|
158
|
+
.sort((a, b) => b[1] - a[1])
|
|
159
|
+
.slice(0, topK)
|
|
160
|
+
.map(([id]) => id);
|
|
161
|
+
// Group chunks by file and sort by line number within each file
|
|
162
|
+
const byFile = new Map();
|
|
163
|
+
for (const id of topIds) {
|
|
164
|
+
const chunk = chunks.get(id);
|
|
165
|
+
if (!chunk)
|
|
166
|
+
continue;
|
|
167
|
+
const existing = byFile.get(chunk.file) ?? [];
|
|
168
|
+
existing.push({ startLine: chunk.startLine, endLine: chunk.endLine, text: chunk.text });
|
|
169
|
+
byFile.set(chunk.file, existing);
|
|
170
|
+
}
|
|
171
|
+
// Format as plain text — same style as Augment's context engine
|
|
172
|
+
const sections = ["The following code sections were retrieved:"];
|
|
173
|
+
for (const [file, fileChunks] of byFile) {
|
|
174
|
+
fileChunks.sort((a, b) => a.startLine - b.startLine);
|
|
175
|
+
// Merge overlapping/adjacent chunks to avoid duplicate lines
|
|
176
|
+
const merged = [];
|
|
177
|
+
for (const chunk of fileChunks) {
|
|
178
|
+
const last = merged[merged.length - 1];
|
|
179
|
+
if (last && chunk.startLine <= last.endLine + 5) {
|
|
180
|
+
if (chunk.endLine > last.endLine) {
|
|
181
|
+
const overlapLines = last.endLine - chunk.startLine + 1;
|
|
182
|
+
const newLines = chunk.text.split("\n").slice(overlapLines);
|
|
183
|
+
last.text = last.text + "\n" + newLines.join("\n");
|
|
184
|
+
last.endLine = chunk.endLine;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
merged.push({ startLine: chunk.startLine, endLine: chunk.endLine, text: chunk.text });
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
sections.push(`Path: ${file}`);
|
|
192
|
+
for (const chunk of merged) {
|
|
193
|
+
// Add line numbers to each line (matching Auggie's format)
|
|
194
|
+
const lines = chunk.text.split("\n");
|
|
195
|
+
const numbered = lines.map((line, i) => {
|
|
196
|
+
const lineNo = String(chunk.startLine + i).padStart(6, " ");
|
|
197
|
+
return `${lineNo}\t${line}`;
|
|
198
|
+
}).join("\n");
|
|
199
|
+
sections.push(numbered);
|
|
200
|
+
}
|
|
201
|
+
sections.push("...");
|
|
202
|
+
}
|
|
203
|
+
const text = sections.join("\n");
|
|
204
|
+
return { type: qType, data: text, tokens: estimateTokens(text) };
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
// Fall back to symbol-level semantic search when no chunks are indexed
|
|
208
|
+
const index = await getCodeIndex(repo);
|
|
209
|
+
if (!index)
|
|
210
|
+
throw new Error(`Repository "${repo}" not found`);
|
|
211
|
+
const embeddings = await getEmbeddingCache(repo);
|
|
212
|
+
if (!embeddings)
|
|
213
|
+
throw new Error(`No embeddings for "${repo}". Run index_folder with an embedding provider configured.`);
|
|
214
|
+
const sourceLimit = query["source_chars"] ?? 200;
|
|
215
|
+
const symbolMap = new Map(index.symbols.map((s) => [s.id, s]));
|
|
216
|
+
// Filter embeddings by file path substring and/or test file exclusion
|
|
217
|
+
let filteredEmbeddings = embeddings;
|
|
218
|
+
if (fileFilter || excludeTests) {
|
|
219
|
+
filteredEmbeddings = new Map([...embeddings.entries()].filter(([id]) => {
|
|
220
|
+
const symFile = symbolMap.get(id)?.file;
|
|
221
|
+
if (!symFile)
|
|
222
|
+
return false;
|
|
223
|
+
if (fileFilter && !symFile.includes(fileFilter))
|
|
224
|
+
return false;
|
|
225
|
+
if (excludeTests && isTestFile(symFile))
|
|
226
|
+
return false;
|
|
227
|
+
return true;
|
|
228
|
+
}));
|
|
229
|
+
}
|
|
230
|
+
const primaryVec = vecs[0];
|
|
231
|
+
if (!primaryVec)
|
|
232
|
+
throw new Error("Embedding provider returned no vector");
|
|
233
|
+
const results = searchSemantic(new Float32Array(primaryVec), filteredEmbeddings, symbolMap, topK);
|
|
234
|
+
const data = results.map((r) => {
|
|
235
|
+
const sym = r.symbol;
|
|
236
|
+
return sourceLimit > 0 && sym.source && sym.source.length > sourceLimit
|
|
237
|
+
? { ...sym, source: sym.source.slice(0, sourceLimit) }
|
|
238
|
+
: sym;
|
|
239
|
+
});
|
|
240
|
+
const text = JSON.stringify(data);
|
|
241
|
+
return { type: qType, data, tokens: estimateTokens(text) };
|
|
242
|
+
}
|
|
243
|
+
case "hybrid": {
|
|
244
|
+
// Hybrid: semantic embedding search + text/BM25 search, RRF-merged.
|
|
245
|
+
// Benefits: no need to choose semantic vs text — gets best of both.
|
|
246
|
+
const { getRepo: getRepoH } = await import("../storage/registry.js");
|
|
247
|
+
const { loadChunks: loadChunksH, loadChunkEmbeddings: loadChunkEmbeddingsH, getChunkPath: getChunkPathH, getChunkEmbeddingPath: getChunkEmbeddingPathH } = await import("../storage/chunk-store.js");
|
|
248
|
+
const { createEmbeddingProvider: createProviderH, cosineSimilarity: cosSimH } = await import("../search/semantic.js");
|
|
249
|
+
const { loadConfig: getConfigH } = await import("../config.js");
|
|
250
|
+
const { searchText: searchTextH } = await import("../tools/search-tools.js");
|
|
251
|
+
const hybridConfig = getConfigH();
|
|
252
|
+
if (!hybridConfig.embeddingProvider) {
|
|
253
|
+
throw new Error("No embedding provider configured.");
|
|
254
|
+
}
|
|
255
|
+
const topK = query["top_k"] ?? 10;
|
|
256
|
+
const fileFilter = query["file_filter"];
|
|
257
|
+
const excludeTests = query["exclude_tests"] ?? true;
|
|
258
|
+
const queryText = query["query"];
|
|
259
|
+
const repoMeta = await getRepoH(hybridConfig.registryPath, repo);
|
|
260
|
+
if (!repoMeta)
|
|
261
|
+
throw new Error(`Repository "${repo}" not found`);
|
|
262
|
+
const chunkPath = getChunkPathH(repoMeta.index_path);
|
|
263
|
+
const chunkEmbeddingPath = getChunkEmbeddingPathH(repoMeta.index_path);
|
|
264
|
+
// Run semantic embedding + text search in parallel
|
|
265
|
+
const provider = createProviderH(hybridConfig.embeddingProvider, hybridConfig);
|
|
266
|
+
const subQueryTexts = decomposeQuery(queryText);
|
|
267
|
+
const [chunks, chunkEmbeddings, textMatches, embVecs] = await Promise.all([
|
|
268
|
+
loadChunksH(chunkPath),
|
|
269
|
+
loadChunkEmbeddingsH(chunkEmbeddingPath),
|
|
270
|
+
searchTextH(repo, queryText, { file_pattern: fileFilter }).catch(() => []),
|
|
271
|
+
provider.embed(subQueryTexts),
|
|
272
|
+
]);
|
|
273
|
+
if (!chunks || !chunkEmbeddings)
|
|
274
|
+
throw new Error(`No chunk index for "${repo}"`);
|
|
275
|
+
let filteredEmbeddings = chunkEmbeddings;
|
|
276
|
+
if (fileFilter || excludeTests) {
|
|
277
|
+
filteredEmbeddings = new Map([...chunkEmbeddings.entries()].filter(([id]) => {
|
|
278
|
+
const chunkFile = chunks.get(id)?.file;
|
|
279
|
+
if (!chunkFile)
|
|
280
|
+
return false;
|
|
281
|
+
if (fileFilter && !chunkFile.includes(fileFilter))
|
|
282
|
+
return false;
|
|
283
|
+
if (excludeTests && isTestFile(chunkFile))
|
|
284
|
+
return false;
|
|
285
|
+
return true;
|
|
286
|
+
}));
|
|
287
|
+
}
|
|
288
|
+
const rrfK = 60;
|
|
289
|
+
const rrfScores = new Map();
|
|
290
|
+
// 1. Semantic RRF contributions (one pass per decomposed sub-query)
|
|
291
|
+
for (const vec of embVecs) {
|
|
292
|
+
if (!vec)
|
|
293
|
+
continue;
|
|
294
|
+
const qEmbed = new Float32Array(vec);
|
|
295
|
+
const subScores = [];
|
|
296
|
+
for (const [id, chunkVec] of filteredEmbeddings) {
|
|
297
|
+
if (chunkVec.length === qEmbed.length) {
|
|
298
|
+
subScores.push({ id, score: cosSimH(qEmbed, chunkVec) });
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
subScores.sort((a, b) => b.score - a.score);
|
|
302
|
+
subScores.forEach((s, rank) => {
|
|
303
|
+
rrfScores.set(s.id, (rrfScores.get(s.id) ?? 0) + 1 / (rrfK + rank + 1));
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
// 2. Text match RRF contributions — map match line → covering chunk
|
|
307
|
+
// Build file → sorted-chunks index for efficient line lookup
|
|
308
|
+
const fileToChunks = new Map();
|
|
309
|
+
for (const [id, chunk] of chunks) {
|
|
310
|
+
const list = fileToChunks.get(chunk.file) ?? [];
|
|
311
|
+
list.push({ id, startLine: chunk.startLine, endLine: chunk.endLine });
|
|
312
|
+
fileToChunks.set(chunk.file, list);
|
|
313
|
+
}
|
|
314
|
+
for (const list of fileToChunks.values()) {
|
|
315
|
+
list.sort((a, b) => a.startLine - b.startLine);
|
|
316
|
+
}
|
|
317
|
+
for (let rank = 0; rank < textMatches.length; rank++) {
|
|
318
|
+
const match = textMatches[rank];
|
|
319
|
+
if (!match)
|
|
320
|
+
continue;
|
|
321
|
+
// Skip text matches from test files when excluding tests
|
|
322
|
+
if (excludeTests && isTestFile(match.file))
|
|
323
|
+
continue;
|
|
324
|
+
const list = fileToChunks.get(match.file) ?? [];
|
|
325
|
+
for (const chunk of list) {
|
|
326
|
+
if (chunk.startLine <= match.line && match.line <= chunk.endLine) {
|
|
327
|
+
rrfScores.set(chunk.id, (rrfScores.get(chunk.id) ?? 0) + 1 / (rrfK + rank + 1));
|
|
328
|
+
break;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
// Top_k by combined RRF score
|
|
333
|
+
const topIds = [...rrfScores.entries()]
|
|
334
|
+
.sort((a, b) => b[1] - a[1])
|
|
335
|
+
.slice(0, topK)
|
|
336
|
+
.map(([id]) => id);
|
|
337
|
+
// Format as plain text (same as semantic case)
|
|
338
|
+
const byFile = new Map();
|
|
339
|
+
for (const id of topIds) {
|
|
340
|
+
const chunk = chunks.get(id);
|
|
341
|
+
if (!chunk)
|
|
342
|
+
continue;
|
|
343
|
+
// Double-check test file exclusion (text matches could contribute chunk IDs)
|
|
344
|
+
if (excludeTests && isTestFile(chunk.file))
|
|
345
|
+
continue;
|
|
346
|
+
const existing = byFile.get(chunk.file) ?? [];
|
|
347
|
+
existing.push({ startLine: chunk.startLine, endLine: chunk.endLine, text: chunk.text });
|
|
348
|
+
byFile.set(chunk.file, existing);
|
|
349
|
+
}
|
|
350
|
+
const sections = ["The following code sections were retrieved:"];
|
|
351
|
+
for (const [file, fileChunks] of byFile) {
|
|
352
|
+
fileChunks.sort((a, b) => a.startLine - b.startLine);
|
|
353
|
+
const merged = [];
|
|
354
|
+
for (const chunk of fileChunks) {
|
|
355
|
+
const last = merged[merged.length - 1];
|
|
356
|
+
if (last && chunk.startLine <= last.endLine + 5) {
|
|
357
|
+
if (chunk.endLine > last.endLine) {
|
|
358
|
+
const overlapLines = last.endLine - chunk.startLine + 1;
|
|
359
|
+
const newLines = chunk.text.split("\n").slice(overlapLines);
|
|
360
|
+
last.text = last.text + "\n" + newLines.join("\n");
|
|
361
|
+
last.endLine = chunk.endLine;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
else {
|
|
365
|
+
merged.push({ startLine: chunk.startLine, endLine: chunk.endLine, text: chunk.text });
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
sections.push(`Path: ${file}`);
|
|
369
|
+
for (const chunk of merged) {
|
|
370
|
+
const lines = chunk.text.split("\n");
|
|
371
|
+
const numbered = lines.map((line, i) => {
|
|
372
|
+
const lineNo = String(chunk.startLine + i).padStart(6, " ");
|
|
373
|
+
return `${lineNo}\t${line}`;
|
|
374
|
+
}).join("\n");
|
|
375
|
+
sections.push(numbered);
|
|
376
|
+
}
|
|
377
|
+
sections.push("...");
|
|
378
|
+
}
|
|
379
|
+
const hybridText = sections.join("\n");
|
|
380
|
+
return { type: qType, data: hybridText, tokens: estimateTokens(hybridText) };
|
|
381
|
+
}
|
|
382
|
+
default:
|
|
383
|
+
return {
|
|
384
|
+
type: qType,
|
|
385
|
+
data: { error: `Unknown sub-query type: ${qType}` },
|
|
386
|
+
tokens: 50,
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Split a long query into sub-queries at natural connectors for RRF merging.
|
|
392
|
+
* Queries ≤ 8 words are returned as-is.
|
|
393
|
+
*/
|
|
394
|
+
function decomposeQuery(query) {
|
|
395
|
+
const words = query.split(/\s+/).filter(Boolean);
|
|
396
|
+
if (words.length <= 8)
|
|
397
|
+
return [query];
|
|
398
|
+
const splitWords = new Set(["and", "or", "from", "to", "with", "using", "for", "via", "then"]);
|
|
399
|
+
const lo = Math.floor(words.length * 0.35);
|
|
400
|
+
const hi = Math.floor(words.length * 0.65);
|
|
401
|
+
for (let i = lo; i <= hi; i++) {
|
|
402
|
+
if (splitWords.has((words[i] ?? "").toLowerCase())) {
|
|
403
|
+
const a = words.slice(0, i).join(" ");
|
|
404
|
+
const b = words.slice(i + 1).join(" ");
|
|
405
|
+
if (a.trim() && b.trim())
|
|
406
|
+
return [a, b];
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
const mid = Math.floor(words.length / 2);
|
|
410
|
+
return [words.slice(0, mid).join(" "), words.slice(mid).join(" ")];
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* Execute multiple sub-queries in a single batched call with shared token budget.
|
|
414
|
+
*
|
|
415
|
+
* Features:
|
|
416
|
+
* - Cross-query deduplication (same symbol in multiple results → included once)
|
|
417
|
+
* - Token budget enforcement
|
|
418
|
+
* - Max 20 sub-queries per call
|
|
419
|
+
* - Parallel execution where queries are independent
|
|
420
|
+
*/
|
|
421
|
+
export async function codebaseRetrieval(repo, queries, tokenBudget) {
|
|
422
|
+
const config = loadConfig();
|
|
423
|
+
const budget = tokenBudget ?? config.defaultTokenBudget;
|
|
424
|
+
const maxQueries = 20;
|
|
425
|
+
const limited = queries.slice(0, maxQueries);
|
|
426
|
+
// Execute all sub-queries in parallel
|
|
427
|
+
const subResults = await Promise.all(limited.map((q) => executeSubQuery(repo, q).catch((err) => {
|
|
428
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
429
|
+
return {
|
|
430
|
+
type: q.type,
|
|
431
|
+
data: { error: message },
|
|
432
|
+
tokens: estimateTokens(message),
|
|
433
|
+
};
|
|
434
|
+
})));
|
|
435
|
+
// Enforce token budget — include results until budget is exceeded
|
|
436
|
+
const results = [];
|
|
437
|
+
let totalTokens = 0;
|
|
438
|
+
let truncated = false;
|
|
439
|
+
for (const result of subResults) {
|
|
440
|
+
if (totalTokens + result.tokens > budget) {
|
|
441
|
+
truncated = true;
|
|
442
|
+
// Try to include a truncated version
|
|
443
|
+
const remaining = budget - totalTokens;
|
|
444
|
+
if (remaining > 100) {
|
|
445
|
+
const truncatedText = JSON.stringify(result.data).slice(0, remaining * 4);
|
|
446
|
+
let truncatedData;
|
|
447
|
+
try {
|
|
448
|
+
truncatedData = JSON.parse(truncatedText);
|
|
449
|
+
}
|
|
450
|
+
catch {
|
|
451
|
+
truncatedData = { partial: true, note: "Result truncated to fit token budget" };
|
|
452
|
+
}
|
|
453
|
+
results.push({
|
|
454
|
+
type: result.type,
|
|
455
|
+
data: truncatedData,
|
|
456
|
+
tokens: remaining,
|
|
457
|
+
});
|
|
458
|
+
totalTokens += remaining;
|
|
459
|
+
}
|
|
460
|
+
break;
|
|
461
|
+
}
|
|
462
|
+
results.push(result);
|
|
463
|
+
totalTokens += result.tokens;
|
|
464
|
+
}
|
|
465
|
+
return {
|
|
466
|
+
results,
|
|
467
|
+
total_tokens: totalTokens,
|
|
468
|
+
truncated,
|
|
469
|
+
query_count: limited.length,
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
//# sourceMappingURL=codebase-retrieval.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codebase-retrieval.js","sourceRoot":"","sources":["../../src/retrieval/codebase-retrieval.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { CodeSymbol, SearchResult } from "../types.js";
|
|
2
|
+
type FieldName = "name" | "signature" | "docstring" | "body";
|
|
3
|
+
export interface BM25Index {
|
|
4
|
+
/** Per-field inverted index: token -> Map<symbolId, termFrequency> */
|
|
5
|
+
fields: Record<FieldName, Map<string, Map<string, number>>>;
|
|
6
|
+
/** Per-field average document length (in tokens) */
|
|
7
|
+
avgFieldLengths: Record<FieldName, number>;
|
|
8
|
+
/** Total number of indexed documents */
|
|
9
|
+
docCount: number;
|
|
10
|
+
/** Symbol lookup by ID */
|
|
11
|
+
symbols: Map<string, CodeSymbol>;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* General-purpose tokenizer for signature, docstring, and body text.
|
|
15
|
+
* Splits on non-alphanumeric chars, applies camelCase/snake_case splitting,
|
|
16
|
+
* lowercases, and filters tokens shorter than 2 chars.
|
|
17
|
+
*/
|
|
18
|
+
export declare function tokenizeText(text: string): string[];
|
|
19
|
+
export declare function buildBM25Index(symbols: CodeSymbol[]): BM25Index;
|
|
20
|
+
export declare function searchBM25(index: BM25Index, query: string, topK: number, fieldWeights: Record<FieldName, number>): SearchResult[];
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=bm25.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bm25.d.ts","sourceRoot":"","sources":["../../src/search/bm25.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAe5D,KAAK,SAAS,GAAG,MAAM,GAAG,WAAW,GAAG,WAAW,GAAG,MAAM,CAAC;AAE7D,MAAM,WAAW,SAAS;IACxB,sEAAsE;IACtE,MAAM,EAAE,MAAM,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IAC5D,oDAAoD;IACpD,eAAe,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAC3C,wCAAwC;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,0BAA0B;IAC1B,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;CAClC;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAqBnD;AAqBD,wBAAgB,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,SAAS,CAgD/D;AAED,wBAAgB,UAAU,CACxB,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,GACtC,YAAY,EAAE,CAiGhB"}
|