vemora 0.1.0-alpha.8
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.
Potentially problematic release.
This version of vemora might be problematic. Click here for more details.
- package/README.md +716 -0
- package/dist/cli.d.ts +16 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +589 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/ask.d.ts +14 -0
- package/dist/commands/ask.d.ts.map +1 -0
- package/dist/commands/ask.js +136 -0
- package/dist/commands/ask.js.map +1 -0
- package/dist/commands/audit.d.ts +17 -0
- package/dist/commands/audit.d.ts.map +1 -0
- package/dist/commands/audit.js +408 -0
- package/dist/commands/audit.js.map +1 -0
- package/dist/commands/brief.d.ts +14 -0
- package/dist/commands/brief.d.ts.map +1 -0
- package/dist/commands/brief.js +73 -0
- package/dist/commands/brief.js.map +1 -0
- package/dist/commands/chat.d.ts +7 -0
- package/dist/commands/chat.d.ts.map +1 -0
- package/dist/commands/chat.js +161 -0
- package/dist/commands/chat.js.map +1 -0
- package/dist/commands/context.d.ts +61 -0
- package/dist/commands/context.d.ts.map +1 -0
- package/dist/commands/context.js +778 -0
- package/dist/commands/context.js.map +1 -0
- package/dist/commands/deps.d.ts +20 -0
- package/dist/commands/deps.d.ts.map +1 -0
- package/dist/commands/deps.js +138 -0
- package/dist/commands/deps.js.map +1 -0
- package/dist/commands/focus.d.ts +6 -0
- package/dist/commands/focus.d.ts.map +1 -0
- package/dist/commands/focus.js +302 -0
- package/dist/commands/focus.js.map +1 -0
- package/dist/commands/index.d.ts +10 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +366 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/init-agent.d.ts +23 -0
- package/dist/commands/init-agent.d.ts.map +1 -0
- package/dist/commands/init-agent.js +447 -0
- package/dist/commands/init-agent.js.map +1 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +122 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/knowledge.d.ts +8 -0
- package/dist/commands/knowledge.d.ts.map +1 -0
- package/dist/commands/knowledge.js +98 -0
- package/dist/commands/knowledge.js.map +1 -0
- package/dist/commands/plan.d.ts +16 -0
- package/dist/commands/plan.d.ts.map +1 -0
- package/dist/commands/plan.js +535 -0
- package/dist/commands/plan.js.map +1 -0
- package/dist/commands/query.d.ts +39 -0
- package/dist/commands/query.d.ts.map +1 -0
- package/dist/commands/query.js +389 -0
- package/dist/commands/query.js.map +1 -0
- package/dist/commands/remember.d.ts +11 -0
- package/dist/commands/remember.d.ts.map +1 -0
- package/dist/commands/remember.js +174 -0
- package/dist/commands/remember.js.map +1 -0
- package/dist/commands/report.d.ts +10 -0
- package/dist/commands/report.d.ts.map +1 -0
- package/dist/commands/report.js +180 -0
- package/dist/commands/report.js.map +1 -0
- package/dist/commands/status.d.ts +2 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +127 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/summarize.d.ts +14 -0
- package/dist/commands/summarize.d.ts.map +1 -0
- package/dist/commands/summarize.js +205 -0
- package/dist/commands/summarize.js.map +1 -0
- package/dist/commands/triage.d.ts +33 -0
- package/dist/commands/triage.d.ts.map +1 -0
- package/dist/commands/triage.js +419 -0
- package/dist/commands/triage.js.map +1 -0
- package/dist/commands/usages.d.ts +14 -0
- package/dist/commands/usages.d.ts.map +1 -0
- package/dist/commands/usages.js +236 -0
- package/dist/commands/usages.js.map +1 -0
- package/dist/core/config.d.ts +35 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +140 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/types.d.ts +251 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +4 -0
- package/dist/core/types.js.map +1 -0
- package/dist/embeddings/factory.d.ts +9 -0
- package/dist/embeddings/factory.d.ts.map +1 -0
- package/dist/embeddings/factory.js +26 -0
- package/dist/embeddings/factory.js.map +1 -0
- package/dist/embeddings/noop.d.ts +17 -0
- package/dist/embeddings/noop.d.ts.map +1 -0
- package/dist/embeddings/noop.js +22 -0
- package/dist/embeddings/noop.js.map +1 -0
- package/dist/embeddings/ollama.d.ts +16 -0
- package/dist/embeddings/ollama.d.ts.map +1 -0
- package/dist/embeddings/ollama.js +41 -0
- package/dist/embeddings/ollama.js.map +1 -0
- package/dist/embeddings/openai.d.ts +10 -0
- package/dist/embeddings/openai.d.ts.map +1 -0
- package/dist/embeddings/openai.js +67 -0
- package/dist/embeddings/openai.js.map +1 -0
- package/dist/embeddings/provider.d.ts +19 -0
- package/dist/embeddings/provider.d.ts.map +1 -0
- package/dist/embeddings/provider.js +3 -0
- package/dist/embeddings/provider.js.map +1 -0
- package/dist/indexer/callgraph.d.ts +16 -0
- package/dist/indexer/callgraph.d.ts.map +1 -0
- package/dist/indexer/callgraph.js +154 -0
- package/dist/indexer/callgraph.js.map +1 -0
- package/dist/indexer/chunkBySlidingWindow.d.ts +6 -0
- package/dist/indexer/chunkBySlidingWindow.d.ts.map +1 -0
- package/dist/indexer/chunkBySlidingWindow.js +30 -0
- package/dist/indexer/chunkBySlidingWindow.js.map +1 -0
- package/dist/indexer/chunkBySymbols.d.ts +7 -0
- package/dist/indexer/chunkBySymbols.d.ts.map +1 -0
- package/dist/indexer/chunkBySymbols.js +57 -0
- package/dist/indexer/chunkBySymbols.js.map +1 -0
- package/dist/indexer/chunker.d.ts +15 -0
- package/dist/indexer/chunker.d.ts.map +1 -0
- package/dist/indexer/chunker.js +26 -0
- package/dist/indexer/chunker.js.map +1 -0
- package/dist/indexer/classHeader.d.ts +7 -0
- package/dist/indexer/classHeader.d.ts.map +1 -0
- package/dist/indexer/classHeader.js +37 -0
- package/dist/indexer/classHeader.js.map +1 -0
- package/dist/indexer/deps.d.ts +66 -0
- package/dist/indexer/deps.d.ts.map +1 -0
- package/dist/indexer/deps.js +409 -0
- package/dist/indexer/deps.js.map +1 -0
- package/dist/indexer/hasher.d.ts +17 -0
- package/dist/indexer/hasher.d.ts.map +1 -0
- package/dist/indexer/hasher.js +38 -0
- package/dist/indexer/hasher.js.map +1 -0
- package/dist/indexer/parser.d.ts +18 -0
- package/dist/indexer/parser.d.ts.map +1 -0
- package/dist/indexer/parser.js +355 -0
- package/dist/indexer/parser.js.map +1 -0
- package/dist/indexer/scanner.d.ts +18 -0
- package/dist/indexer/scanner.d.ts.map +1 -0
- package/dist/indexer/scanner.js +37 -0
- package/dist/indexer/scanner.js.map +1 -0
- package/dist/indexer/strategy.d.ts +11 -0
- package/dist/indexer/strategy.d.ts.map +1 -0
- package/dist/indexer/strategy.js +15 -0
- package/dist/indexer/strategy.js.map +1 -0
- package/dist/indexer/tests.d.ts +15 -0
- package/dist/indexer/tests.d.ts.map +1 -0
- package/dist/indexer/tests.js +68 -0
- package/dist/indexer/tests.js.map +1 -0
- package/dist/indexer/todos.d.ts +9 -0
- package/dist/indexer/todos.d.ts.map +1 -0
- package/dist/indexer/todos.js +29 -0
- package/dist/indexer/todos.js.map +1 -0
- package/dist/llm/anthropic.d.ts +8 -0
- package/dist/llm/anthropic.d.ts.map +1 -0
- package/dist/llm/anthropic.js +76 -0
- package/dist/llm/anthropic.js.map +1 -0
- package/dist/llm/factory.d.ts +7 -0
- package/dist/llm/factory.d.ts.map +1 -0
- package/dist/llm/factory.js +39 -0
- package/dist/llm/factory.js.map +1 -0
- package/dist/llm/ollama.d.ts +8 -0
- package/dist/llm/ollama.d.ts.map +1 -0
- package/dist/llm/ollama.js +83 -0
- package/dist/llm/ollama.js.map +1 -0
- package/dist/llm/openai.d.ts +8 -0
- package/dist/llm/openai.d.ts.map +1 -0
- package/dist/llm/openai.js +68 -0
- package/dist/llm/openai.js.map +1 -0
- package/dist/llm/provider.d.ts +29 -0
- package/dist/llm/provider.d.ts.map +1 -0
- package/dist/llm/provider.js +3 -0
- package/dist/llm/provider.js.map +1 -0
- package/dist/search/bm25.d.ts +3 -0
- package/dist/search/bm25.d.ts.map +1 -0
- package/dist/search/bm25.js +102 -0
- package/dist/search/bm25.js.map +1 -0
- package/dist/search/formatter.d.ts +43 -0
- package/dist/search/formatter.d.ts.map +1 -0
- package/dist/search/formatter.js +208 -0
- package/dist/search/formatter.js.map +1 -0
- package/dist/search/hybrid.d.ts +10 -0
- package/dist/search/hybrid.d.ts.map +1 -0
- package/dist/search/hybrid.js +53 -0
- package/dist/search/hybrid.js.map +1 -0
- package/dist/search/merge.d.ts +33 -0
- package/dist/search/merge.d.ts.map +1 -0
- package/dist/search/merge.js +158 -0
- package/dist/search/merge.js.map +1 -0
- package/dist/search/mmr.d.ts +23 -0
- package/dist/search/mmr.d.ts.map +1 -0
- package/dist/search/mmr.js +95 -0
- package/dist/search/mmr.js.map +1 -0
- package/dist/search/rerank.d.ts +15 -0
- package/dist/search/rerank.d.ts.map +1 -0
- package/dist/search/rerank.js +76 -0
- package/dist/search/rerank.js.map +1 -0
- package/dist/search/signature.d.ts +42 -0
- package/dist/search/signature.d.ts.map +1 -0
- package/dist/search/signature.js +112 -0
- package/dist/search/signature.js.map +1 -0
- package/dist/search/vector.d.ts +41 -0
- package/dist/search/vector.d.ts.map +1 -0
- package/dist/search/vector.js +185 -0
- package/dist/search/vector.js.map +1 -0
- package/dist/storage/cache.d.ts +30 -0
- package/dist/storage/cache.d.ts.map +1 -0
- package/dist/storage/cache.js +160 -0
- package/dist/storage/cache.js.map +1 -0
- package/dist/storage/knowledge.d.ts +17 -0
- package/dist/storage/knowledge.d.ts.map +1 -0
- package/dist/storage/knowledge.js +58 -0
- package/dist/storage/knowledge.js.map +1 -0
- package/dist/storage/repository.d.ts +27 -0
- package/dist/storage/repository.d.ts.map +1 -0
- package/dist/storage/repository.js +95 -0
- package/dist/storage/repository.js.map +1 -0
- package/dist/storage/session.d.ts +38 -0
- package/dist/storage/session.d.ts.map +1 -0
- package/dist/storage/session.js +100 -0
- package/dist/storage/session.js.map +1 -0
- package/dist/storage/summaries.d.ts +19 -0
- package/dist/storage/summaries.d.ts.map +1 -0
- package/dist/storage/summaries.js +66 -0
- package/dist/storage/summaries.js.map +1 -0
- package/dist/storage/usage.d.ts +35 -0
- package/dist/storage/usage.d.ts.map +1 -0
- package/dist/storage/usage.js +55 -0
- package/dist/storage/usage.js.map +1 -0
- package/dist/utils/git.d.ts +15 -0
- package/dist/utils/git.d.ts.map +1 -0
- package/dist/utils/git.js +38 -0
- package/dist/utils/git.js.map +1 -0
- package/dist/utils/tokenizer.d.ts +24 -0
- package/dist/utils/tokenizer.d.ts.map +1 -0
- package/dist/utils/tokenizer.js +52 -0
- package/dist/utils/tokenizer.js.map +1 -0
- package/package.json +71 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rerank.d.ts","sourceRoot":"","sources":["../../src/search/rerank.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAqClD;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,YAAY,EAAE,EACvB,IAAI,GAAE,MAAW,GAChB,OAAO,CAAC,YAAY,EAAE,CAAC,CAuCzB"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.rerankResults = rerankResults;
|
|
4
|
+
// biome-ignore lint/suspicious/noExplicitAny: @xenova/transformers has no exported TS types
|
|
5
|
+
let model = null;
|
|
6
|
+
// biome-ignore lint/suspicious/noExplicitAny: @xenova/transformers has no exported TS types
|
|
7
|
+
let tokenizer = null;
|
|
8
|
+
/**
|
|
9
|
+
* Initializes the reranker model and tokenizer if not already loaded.
|
|
10
|
+
* Model: Xenova/ms-marco-MiniLM-L-6-v2
|
|
11
|
+
*
|
|
12
|
+
* Requires the optional peer dependency `@xenova/transformers`:
|
|
13
|
+
* npm install @xenova/transformers
|
|
14
|
+
*/
|
|
15
|
+
async function initReranker() {
|
|
16
|
+
if (!model) {
|
|
17
|
+
// biome-ignore lint/suspicious/noExplicitAny: dynamic optional dependency
|
|
18
|
+
let transformers;
|
|
19
|
+
try {
|
|
20
|
+
transformers = require("@xenova/transformers");
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
throw new Error("The --rerank flag requires @xenova/transformers.\n" +
|
|
24
|
+
"Install it with: npm install @xenova/transformers");
|
|
25
|
+
}
|
|
26
|
+
const { AutoModelForSequenceClassification, AutoTokenizer } = transformers;
|
|
27
|
+
model = await AutoModelForSequenceClassification.from_pretrained("Xenova/ms-marco-MiniLM-L-6-v2", { quantized: false });
|
|
28
|
+
tokenizer = await AutoTokenizer.from_pretrained("Xenova/ms-marco-MiniLM-L-6-v2");
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Re-scores search results using a Cross-Encoder model.
|
|
33
|
+
*
|
|
34
|
+
* A cross-encoder processes the (query, chunk) pair together,
|
|
35
|
+
* capturing deep semantic interactions that cosine similarity
|
|
36
|
+
* (bi-encoder) might miss.
|
|
37
|
+
*
|
|
38
|
+
* @param query The user's natural language query
|
|
39
|
+
* @param results Initial search results (from vector or keyword search)
|
|
40
|
+
* @param topK Number of results to return after reranking
|
|
41
|
+
* @returns Re-scored and sorted search results
|
|
42
|
+
*/
|
|
43
|
+
async function rerankResults(query, results, topK = 10) {
|
|
44
|
+
if (results.length === 0)
|
|
45
|
+
return [];
|
|
46
|
+
await initReranker();
|
|
47
|
+
const reranked = [];
|
|
48
|
+
// We only rerank the first 25 results to keep it fast
|
|
49
|
+
const candidates = results.slice(0, 25);
|
|
50
|
+
for (const res of candidates) {
|
|
51
|
+
try {
|
|
52
|
+
// Tokenize the pair
|
|
53
|
+
const inputs = await tokenizer(query, {
|
|
54
|
+
text_pair: res.chunk.content,
|
|
55
|
+
truncation: true,
|
|
56
|
+
padding: true,
|
|
57
|
+
});
|
|
58
|
+
// Get the raw logits
|
|
59
|
+
const { logits } = await model(inputs);
|
|
60
|
+
// For this model, the logit at index 0 is the relevance score
|
|
61
|
+
const score = logits.data[0];
|
|
62
|
+
reranked.push({
|
|
63
|
+
...res,
|
|
64
|
+
score: score,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
console.warn(`Failed to rerank chunk ${res.chunk.id}:`, err);
|
|
69
|
+
reranked.push(res);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// Sort by the new cross-encoder logit (higher is more relevant)
|
|
73
|
+
reranked.sort((a, b) => b.score - a.score);
|
|
74
|
+
return reranked.slice(0, topK);
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=rerank.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rerank.js","sourceRoot":"","sources":["../../src/search/rerank.ts"],"names":[],"mappings":";;AAiDA,sCA2CC;AA1FD,4FAA4F;AAC5F,IAAI,KAAK,GAAQ,IAAI,CAAC;AACtB,4FAA4F;AAC5F,IAAI,SAAS,GAAQ,IAAI,CAAC;AAE1B;;;;;;GAMG;AACH,KAAK,UAAU,YAAY;IACzB,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,0EAA0E;QAC1E,IAAI,YAAiB,CAAC;QACtB,IAAI,CAAC;YACH,YAAY,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;QACjD,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,KAAK,CACb,oDAAoD;gBAClD,mDAAmD,CACtD,CAAC;QACJ,CAAC;QACD,MAAM,EAAE,kCAAkC,EAAE,aAAa,EAAE,GAAG,YAAY,CAAC;QAC3E,KAAK,GAAG,MAAM,kCAAkC,CAAC,eAAe,CAC9D,+BAA+B,EAC/B,EAAE,SAAS,EAAE,KAAK,EAAE,CACrB,CAAC;QACF,SAAS,GAAG,MAAM,aAAa,CAAC,eAAe,CAC7C,+BAA+B,CAChC,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;;;;;;GAWG;AACI,KAAK,UAAU,aAAa,CACjC,KAAa,EACb,OAAuB,EACvB,OAAe,EAAE;IAEjB,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEpC,MAAM,YAAY,EAAE,CAAC;IAErB,MAAM,QAAQ,GAAmB,EAAE,CAAC;IAEpC,sDAAsD;IACtD,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAExC,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,oBAAoB;YACpB,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,KAAK,EAAE;gBACpC,SAAS,EAAE,GAAG,CAAC,KAAK,CAAC,OAAO;gBAC5B,UAAU,EAAE,IAAI;gBAChB,OAAO,EAAE,IAAI;aACd,CAAC,CAAC;YAEH,qBAAqB;YACrB,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC;YAEvC,8DAA8D;YAC9D,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAE7B,QAAQ,CAAC,IAAI,CAAC;gBACZ,GAAG,GAAG;gBACN,KAAK,EAAE,KAAK;aACb,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC,0BAA0B,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;YAC7D,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IAED,gEAAgE;IAChE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IAE3C,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Signature extraction for code chunks.
|
|
3
|
+
*
|
|
4
|
+
* Given the raw content of a chunk, returns the declaration signature —
|
|
5
|
+
* the part that describes *what* exists without the implementation body.
|
|
6
|
+
* This is used in the query output for medium-relevance results.
|
|
7
|
+
*
|
|
8
|
+
* Design philosophy:
|
|
9
|
+
* - Interfaces and type aliases ARE their signature → show them in full (compact)
|
|
10
|
+
* - Functions and classes → extract up to the opening brace, replace body with { … }
|
|
11
|
+
* - Arrow functions with expression bodies → show up to =>
|
|
12
|
+
* - Everything else → show first meaningful lines
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Extracts the declaration signature from a chunk's content.
|
|
16
|
+
*
|
|
17
|
+
* Examples:
|
|
18
|
+
*
|
|
19
|
+
* Input: "export async function connect(\n host: string,\n): Promise<void> {\n ..."
|
|
20
|
+
* Output: "export async function connect(\n host: string,\n): Promise<void> { … }"
|
|
21
|
+
*
|
|
22
|
+
* Input: "export interface ImapConfig {\n host: string;\n}"
|
|
23
|
+
* Output: (same — interfaces are returned as-is, they are compact)
|
|
24
|
+
*
|
|
25
|
+
* Input: "export const send = async (msg: Email): Promise<void> =>\n smtp.send(msg);"
|
|
26
|
+
* Output: "export const send = async (msg: Email): Promise<void> => …"
|
|
27
|
+
*/
|
|
28
|
+
export declare function extractSignature(content: string): string;
|
|
29
|
+
export type DisplayTier = "high" | "med" | "low";
|
|
30
|
+
/**
|
|
31
|
+
* Determines how much of a chunk to show based on its rank in results.
|
|
32
|
+
*
|
|
33
|
+
* high (rank 1-3) → full code block (capped at MAX_HIGH_LINES automatically)
|
|
34
|
+
* med (rank 4-7) → signature only (declaration without body)
|
|
35
|
+
* low (rank 8+) → file + symbol + score only (no code)
|
|
36
|
+
*
|
|
37
|
+
* The --show-code flag overrides all tiers to show full code.
|
|
38
|
+
*/
|
|
39
|
+
export declare function getDisplayTier(rank: number): DisplayTier;
|
|
40
|
+
/** Lines shown automatically for high-tier results (without --show-code) */
|
|
41
|
+
export declare const HIGH_CODE_LINES = 30;
|
|
42
|
+
//# sourceMappingURL=signature.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signature.d.ts","sourceRoot":"","sources":["../../src/search/signature.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAMH;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAmExD;AAID,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,CAAC;AAEjD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAIxD;AAED,4EAA4E;AAC5E,eAAO,MAAM,eAAe,KAAK,CAAC"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Signature extraction for code chunks.
|
|
4
|
+
*
|
|
5
|
+
* Given the raw content of a chunk, returns the declaration signature —
|
|
6
|
+
* the part that describes *what* exists without the implementation body.
|
|
7
|
+
* This is used in the query output for medium-relevance results.
|
|
8
|
+
*
|
|
9
|
+
* Design philosophy:
|
|
10
|
+
* - Interfaces and type aliases ARE their signature → show them in full (compact)
|
|
11
|
+
* - Functions and classes → extract up to the opening brace, replace body with { … }
|
|
12
|
+
* - Arrow functions with expression bodies → show up to =>
|
|
13
|
+
* - Everything else → show first meaningful lines
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.HIGH_CODE_LINES = void 0;
|
|
17
|
+
exports.extractSignature = extractSignature;
|
|
18
|
+
exports.getDisplayTier = getDisplayTier;
|
|
19
|
+
const MAX_SIG_LINES = 10;
|
|
20
|
+
// ─── Public API ───────────────────────────────────────────────────────────────
|
|
21
|
+
/**
|
|
22
|
+
* Extracts the declaration signature from a chunk's content.
|
|
23
|
+
*
|
|
24
|
+
* Examples:
|
|
25
|
+
*
|
|
26
|
+
* Input: "export async function connect(\n host: string,\n): Promise<void> {\n ..."
|
|
27
|
+
* Output: "export async function connect(\n host: string,\n): Promise<void> { … }"
|
|
28
|
+
*
|
|
29
|
+
* Input: "export interface ImapConfig {\n host: string;\n}"
|
|
30
|
+
* Output: (same — interfaces are returned as-is, they are compact)
|
|
31
|
+
*
|
|
32
|
+
* Input: "export const send = async (msg: Email): Promise<void> =>\n smtp.send(msg);"
|
|
33
|
+
* Output: "export const send = async (msg: Email): Promise<void> => …"
|
|
34
|
+
*/
|
|
35
|
+
function extractSignature(content) {
|
|
36
|
+
const lines = content.split("\n");
|
|
37
|
+
const firstMeaningful = lines.find((l) => l.trim().length > 0) ?? "";
|
|
38
|
+
// ── Interfaces and type aliases ──────────────────────────────────────────
|
|
39
|
+
// These are inherently compact — the full declaration IS the signature.
|
|
40
|
+
// Show up to 20 lines (rare for them to be longer).
|
|
41
|
+
if (/^\s*(export\s+)?(type\s+\w|interface\s+\w)/.test(firstMeaningful)) {
|
|
42
|
+
const slice = lines.slice(0, 20);
|
|
43
|
+
if (lines.length > 20)
|
|
44
|
+
slice.push(" …");
|
|
45
|
+
return slice.join("\n").trim();
|
|
46
|
+
}
|
|
47
|
+
// ── File header / import blocks ──────────────────────────────────────────
|
|
48
|
+
// Chunks that are just import statements — show first 5 lines.
|
|
49
|
+
if (/^\s*import\s/.test(firstMeaningful)) {
|
|
50
|
+
const slice = lines.slice(0, 5);
|
|
51
|
+
if (lines.length > 5)
|
|
52
|
+
slice.push(` … (${lines.length - 5} more lines)`);
|
|
53
|
+
return slice.join("\n").trim();
|
|
54
|
+
}
|
|
55
|
+
// ── Function / class / method declarations ───────────────────────────────
|
|
56
|
+
const result = [];
|
|
57
|
+
for (let i = 0; i < lines.length; i++) {
|
|
58
|
+
const line = lines[i];
|
|
59
|
+
const trimmed = line.trimEnd();
|
|
60
|
+
// Line ends with opening brace → body starts here.
|
|
61
|
+
// Captures patterns like:
|
|
62
|
+
// ): Promise<void> {
|
|
63
|
+
// export class Foo extends Bar {
|
|
64
|
+
// } catch (e) { (skip mid-function braces — result.length guard)
|
|
65
|
+
if (/\{\s*(\/\/[^\n]*)?\s*$/.test(trimmed)) {
|
|
66
|
+
// Strip the brace (and any trailing comment) and append { … }
|
|
67
|
+
const withoutBrace = trimmed
|
|
68
|
+
.replace(/\s*\{\s*(\/\/[^\n]*)?\s*$/, "")
|
|
69
|
+
.trimEnd();
|
|
70
|
+
result.push((withoutBrace !== ""
|
|
71
|
+
? withoutBrace
|
|
72
|
+
: trimmed.replace(/\{.*$/, "").trim()) + " { … }");
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
// Arrow function with expression body:
|
|
76
|
+
// const f = (x: number) =>
|
|
77
|
+
// x * 2
|
|
78
|
+
if (trimmed.endsWith("=>") && !trimmed.endsWith("=>>")) {
|
|
79
|
+
result.push(trimmed + " …");
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
result.push(line);
|
|
83
|
+
// Single-line declarations ending with `;` (e.g. `declare function f(): void;`)
|
|
84
|
+
if (result.length === 1 && trimmed.endsWith(";"))
|
|
85
|
+
break;
|
|
86
|
+
// Safety cap
|
|
87
|
+
if (result.length >= MAX_SIG_LINES) {
|
|
88
|
+
result.push(" …");
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return result.join("\n").trim();
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Determines how much of a chunk to show based on its rank in results.
|
|
96
|
+
*
|
|
97
|
+
* high (rank 1-3) → full code block (capped at MAX_HIGH_LINES automatically)
|
|
98
|
+
* med (rank 4-7) → signature only (declaration without body)
|
|
99
|
+
* low (rank 8+) → file + symbol + score only (no code)
|
|
100
|
+
*
|
|
101
|
+
* The --show-code flag overrides all tiers to show full code.
|
|
102
|
+
*/
|
|
103
|
+
function getDisplayTier(rank) {
|
|
104
|
+
if (rank <= 3)
|
|
105
|
+
return "high";
|
|
106
|
+
if (rank <= 7)
|
|
107
|
+
return "med";
|
|
108
|
+
return "low";
|
|
109
|
+
}
|
|
110
|
+
/** Lines shown automatically for high-tier results (without --show-code) */
|
|
111
|
+
exports.HIGH_CODE_LINES = 30;
|
|
112
|
+
//# sourceMappingURL=signature.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signature.js","sourceRoot":"","sources":["../../src/search/signature.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Chunk, EmbeddingCache, SearchResult, SymbolIndex } from "../core/types";
|
|
2
|
+
/**
|
|
3
|
+
* Computes cosine similarity between two vectors.
|
|
4
|
+
* Returns a value in [-1, 1]. For normalized embeddings (OpenAI, Ollama)
|
|
5
|
+
* this is effectively in [0, 1] for semantically related pairs.
|
|
6
|
+
*/
|
|
7
|
+
export declare function cosineSimilarity(a: number[], b: number[]): number;
|
|
8
|
+
/**
|
|
9
|
+
* Fast cosine similarity between a number[] and a Float32Array slice.
|
|
10
|
+
*/
|
|
11
|
+
export declare function cosineSimilarityBinary(query: number[], vectors: Float32Array, offset: number, dims: number): number;
|
|
12
|
+
/**
|
|
13
|
+
* Performs an exhaustive nearest-neighbor search over all cached embeddings.
|
|
14
|
+
*
|
|
15
|
+
* Uses HNSW (O(log N)) when the index is available in the cache.
|
|
16
|
+
* Falls back to exhaustive O(n * d) cosine search on the contiguous
|
|
17
|
+
* Float32Array buffer if the HNSW index is missing or fails to load.
|
|
18
|
+
*/
|
|
19
|
+
export declare function vectorSearch(queryEmbedding: number[], chunks: Chunk[], cache: EmbeddingCache, symbols: SymbolIndex, topK?: number): SearchResult[];
|
|
20
|
+
/**
|
|
21
|
+
* Direct symbol lookup — bypasses embedding when the query matches a known
|
|
22
|
+
* symbol name. Returns chunks for matched symbols scored by match quality.
|
|
23
|
+
*
|
|
24
|
+
* Match tiers (in order of precedence):
|
|
25
|
+
* 1.0 — exact match: query === symbolName (case-insensitive)
|
|
26
|
+
* 0.95 — single-word match: one word in query === symbolName
|
|
27
|
+
* 0.80 — prefix match: symbolName starts with a query word (or vice versa)
|
|
28
|
+
*
|
|
29
|
+
* Returns [] if no symbol matches (caller should fall through to vector/BM25).
|
|
30
|
+
* Only activates for narrow queries (≤5 matches) to avoid false positives on
|
|
31
|
+
* generic names like "connect" or "init".
|
|
32
|
+
*/
|
|
33
|
+
export declare function symbolLookup(query: string, chunks: Chunk[], symbols: SymbolIndex): SearchResult[];
|
|
34
|
+
/**
|
|
35
|
+
* TF-based keyword search — used as fallback when embeddings are not available.
|
|
36
|
+
*
|
|
37
|
+
* Scores each chunk by term frequency normalized by content length.
|
|
38
|
+
* Not as powerful as semantic search but requires no embedding service.
|
|
39
|
+
*/
|
|
40
|
+
export declare function keywordSearch(query: string, chunks: Chunk[], symbols: SymbolIndex, topK?: number): SearchResult[];
|
|
41
|
+
//# sourceMappingURL=vector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vector.d.ts","sourceRoot":"","sources":["../../src/search/vector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,KAAK,EACL,cAAc,EACd,YAAY,EACZ,WAAW,EACZ,MAAM,eAAe,CAAC;AAIvB;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAejE;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,MAAM,EAAE,EACf,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,GACX,MAAM,CAcR;AAID;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,cAAc,EAAE,MAAM,EAAE,EACxB,MAAM,EAAE,KAAK,EAAE,EACf,KAAK,EAAE,cAAc,EACrB,OAAO,EAAE,WAAW,EACpB,IAAI,SAAK,GACR,YAAY,EAAE,CA4DhB;AAID;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,KAAK,EAAE,EACf,OAAO,EAAE,WAAW,GACnB,YAAY,EAAE,CA+BhB;AAID;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,KAAK,EAAE,EACf,OAAO,EAAE,WAAW,EACpB,IAAI,SAAK,GACR,YAAY,EAAE,CAyChB"}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.cosineSimilarity = cosineSimilarity;
|
|
4
|
+
exports.cosineSimilarityBinary = cosineSimilarityBinary;
|
|
5
|
+
exports.vectorSearch = vectorSearch;
|
|
6
|
+
exports.symbolLookup = symbolLookup;
|
|
7
|
+
exports.keywordSearch = keywordSearch;
|
|
8
|
+
// ─── Cosine Similarity ────────────────────────────────────────────────────────
|
|
9
|
+
/**
|
|
10
|
+
* Computes cosine similarity between two vectors.
|
|
11
|
+
* Returns a value in [-1, 1]. For normalized embeddings (OpenAI, Ollama)
|
|
12
|
+
* this is effectively in [0, 1] for semantically related pairs.
|
|
13
|
+
*/
|
|
14
|
+
function cosineSimilarity(a, b) {
|
|
15
|
+
if (a.length === 0 || a.length !== b.length)
|
|
16
|
+
return 0;
|
|
17
|
+
let dot = 0;
|
|
18
|
+
let normA = 0;
|
|
19
|
+
let normB = 0;
|
|
20
|
+
for (let i = 0; i < a.length; i++) {
|
|
21
|
+
dot += a[i] * b[i];
|
|
22
|
+
normA += a[i] * a[i];
|
|
23
|
+
normB += b[i] * b[i];
|
|
24
|
+
}
|
|
25
|
+
const denom = Math.sqrt(normA) * Math.sqrt(normB);
|
|
26
|
+
return denom === 0 ? 0 : dot / denom;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Fast cosine similarity between a number[] and a Float32Array slice.
|
|
30
|
+
*/
|
|
31
|
+
function cosineSimilarityBinary(query, vectors, offset, dims) {
|
|
32
|
+
let dot = 0;
|
|
33
|
+
let normA = 0;
|
|
34
|
+
let normB = 0;
|
|
35
|
+
for (let i = 0; i < dims; i++) {
|
|
36
|
+
const valB = vectors[offset + i];
|
|
37
|
+
dot += query[i] * valB;
|
|
38
|
+
normA += query[i] * query[i];
|
|
39
|
+
normB += valB * valB;
|
|
40
|
+
}
|
|
41
|
+
const denom = Math.sqrt(normA) * Math.sqrt(normB);
|
|
42
|
+
return denom === 0 ? 0 : dot / denom;
|
|
43
|
+
}
|
|
44
|
+
// ─── Vector Search ────────────────────────────────────────────────────────────
|
|
45
|
+
/**
|
|
46
|
+
* Performs an exhaustive nearest-neighbor search over all cached embeddings.
|
|
47
|
+
*
|
|
48
|
+
* Uses HNSW (O(log N)) when the index is available in the cache.
|
|
49
|
+
* Falls back to exhaustive O(n * d) cosine search on the contiguous
|
|
50
|
+
* Float32Array buffer if the HNSW index is missing or fails to load.
|
|
51
|
+
*/
|
|
52
|
+
function vectorSearch(queryEmbedding, chunks, cache, symbols, topK = 10) {
|
|
53
|
+
if (queryEmbedding.length === 0)
|
|
54
|
+
return [];
|
|
55
|
+
const scored = [];
|
|
56
|
+
const { vectors, chunkIds, dimensions, hnswIndex } = cache;
|
|
57
|
+
if (!vectors || !chunkIds) {
|
|
58
|
+
return [];
|
|
59
|
+
}
|
|
60
|
+
if (hnswIndex) {
|
|
61
|
+
try {
|
|
62
|
+
const { HNSW } = require("hnsw");
|
|
63
|
+
const index = HNSW.fromJSON(hnswIndex);
|
|
64
|
+
// Increased efSearch for better accuracy
|
|
65
|
+
const hnswResults = index.searchKNN(queryEmbedding, Math.max(topK * 2, 20), { efSearch: 64 });
|
|
66
|
+
const chunkById = new Map(chunks.map(c => [c.id, c]));
|
|
67
|
+
const chunkResults = [];
|
|
68
|
+
for (const res of hnswResults) {
|
|
69
|
+
const chunkId = chunkIds[res.id];
|
|
70
|
+
const chunk = chunkById.get(chunkId);
|
|
71
|
+
if (chunk) {
|
|
72
|
+
const symbol = chunk.symbol ? symbols[chunk.symbol] : undefined;
|
|
73
|
+
chunkResults.push({ chunk, score: res.score, symbol });
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
chunkResults.sort((a, b) => b.score - a.score);
|
|
77
|
+
return chunkResults.slice(0, topK);
|
|
78
|
+
}
|
|
79
|
+
catch (e) {
|
|
80
|
+
console.warn("HNSW search failed, falling back to exhaustive search:", e);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// Fallback: Optimized path: binary search over contiguous buffer
|
|
84
|
+
// Map chunkId to index for fast lookup
|
|
85
|
+
const idToIndex = new Map();
|
|
86
|
+
chunkIds.forEach((id, i) => idToIndex.set(id, i));
|
|
87
|
+
for (const chunk of chunks) {
|
|
88
|
+
const idx = idToIndex.get(chunk.id);
|
|
89
|
+
if (idx === undefined)
|
|
90
|
+
continue;
|
|
91
|
+
const score = cosineSimilarityBinary(queryEmbedding, vectors, idx * dimensions, dimensions);
|
|
92
|
+
const symbol = chunk.symbol ? symbols[chunk.symbol] : undefined;
|
|
93
|
+
scored.push({ chunk, score, symbol });
|
|
94
|
+
}
|
|
95
|
+
scored.sort((a, b) => b.score - a.score);
|
|
96
|
+
return scored.slice(0, topK);
|
|
97
|
+
}
|
|
98
|
+
// ─── Symbol Lookup ────────────────────────────────────────────────────────────
|
|
99
|
+
/**
|
|
100
|
+
* Direct symbol lookup — bypasses embedding when the query matches a known
|
|
101
|
+
* symbol name. Returns chunks for matched symbols scored by match quality.
|
|
102
|
+
*
|
|
103
|
+
* Match tiers (in order of precedence):
|
|
104
|
+
* 1.0 — exact match: query === symbolName (case-insensitive)
|
|
105
|
+
* 0.95 — single-word match: one word in query === symbolName
|
|
106
|
+
* 0.80 — prefix match: symbolName starts with a query word (or vice versa)
|
|
107
|
+
*
|
|
108
|
+
* Returns [] if no symbol matches (caller should fall through to vector/BM25).
|
|
109
|
+
* Only activates for narrow queries (≤5 matches) to avoid false positives on
|
|
110
|
+
* generic names like "connect" or "init".
|
|
111
|
+
*/
|
|
112
|
+
function symbolLookup(query, chunks, symbols) {
|
|
113
|
+
const q = query.trim().toLowerCase();
|
|
114
|
+
const words = q.split(/[\s\W]+/).filter((w) => w.length >= 2);
|
|
115
|
+
const candidates = [];
|
|
116
|
+
for (const name of Object.keys(symbols)) {
|
|
117
|
+
const lower = name.toLowerCase();
|
|
118
|
+
if (lower === q) {
|
|
119
|
+
candidates.push({ name, score: 1.0 });
|
|
120
|
+
}
|
|
121
|
+
else if (words.some((w) => lower === w)) {
|
|
122
|
+
candidates.push({ name, score: 0.95 });
|
|
123
|
+
}
|
|
124
|
+
else if (words.some((w) => lower.startsWith(w) || w.startsWith(lower))) {
|
|
125
|
+
candidates.push({ name, score: 0.8 });
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
if (candidates.length === 0 || candidates.length > 5)
|
|
129
|
+
return [];
|
|
130
|
+
candidates.sort((a, b) => b.score - a.score);
|
|
131
|
+
const results = [];
|
|
132
|
+
for (const { name, score } of candidates) {
|
|
133
|
+
const sym = symbols[name];
|
|
134
|
+
const chunk = chunks.find((c) => c.symbol === name && c.file === sym.file);
|
|
135
|
+
if (chunk) {
|
|
136
|
+
results.push({ chunk, score, symbol: sym });
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return results;
|
|
140
|
+
}
|
|
141
|
+
// ─── Keyword Search ───────────────────────────────────────────────────────────
|
|
142
|
+
/**
|
|
143
|
+
* TF-based keyword search — used as fallback when embeddings are not available.
|
|
144
|
+
*
|
|
145
|
+
* Scores each chunk by term frequency normalized by content length.
|
|
146
|
+
* Not as powerful as semantic search but requires no embedding service.
|
|
147
|
+
*/
|
|
148
|
+
function keywordSearch(query, chunks, symbols, topK = 10) {
|
|
149
|
+
// Split query into meaningful terms (skip stop words shorter than 3 chars)
|
|
150
|
+
const terms = query
|
|
151
|
+
.toLowerCase()
|
|
152
|
+
.split(/[\s\W]+/)
|
|
153
|
+
.filter((t) => t.length >= 3);
|
|
154
|
+
if (terms.length === 0)
|
|
155
|
+
return [];
|
|
156
|
+
const scored = chunks.map((chunk) => {
|
|
157
|
+
const content = chunk.content.toLowerCase();
|
|
158
|
+
let score = 0;
|
|
159
|
+
for (const term of terms) {
|
|
160
|
+
// Count occurrences
|
|
161
|
+
let pos = 0;
|
|
162
|
+
let count = 0;
|
|
163
|
+
while ((pos = content.indexOf(term, pos)) !== -1) {
|
|
164
|
+
count++;
|
|
165
|
+
pos += term.length;
|
|
166
|
+
}
|
|
167
|
+
if (count > 0) {
|
|
168
|
+
// TF normalized by content length (log-scaled to dampen large files)
|
|
169
|
+
score += count / Math.log(content.length + 2);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
// Bonus: symbol name matches the query terms
|
|
173
|
+
if (chunk.symbol) {
|
|
174
|
+
const symLower = chunk.symbol.toLowerCase();
|
|
175
|
+
if (terms.some((t) => symLower.includes(t))) {
|
|
176
|
+
score *= 2;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
const symbol = chunk.symbol ? symbols[chunk.symbol] : undefined;
|
|
180
|
+
return { chunk, score, symbol };
|
|
181
|
+
});
|
|
182
|
+
scored.sort((a, b) => b.score - a.score);
|
|
183
|
+
return scored.filter((r) => r.score > 0).slice(0, topK);
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=vector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vector.js","sourceRoot":"","sources":["../../src/search/vector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { EmbeddingCache } from "../core/types";
|
|
2
|
+
/**
|
|
3
|
+
* Manages the local per-developer embedding cache.
|
|
4
|
+
*
|
|
5
|
+
* Stored in ~/.vemora-cache/<projectId>/ — never in the repo.
|
|
6
|
+
* Each developer builds their own cache after running `vemora index`.
|
|
7
|
+
*
|
|
8
|
+
* Design choice: dual-file storage per project.
|
|
9
|
+
* Metadata and chunk IDs are stored in JSON (inspectable).
|
|
10
|
+
* Vectors are stored as a contiguous Float32Array binary buffer (fast I/O).
|
|
11
|
+
* The HNSW index is serialized to a separate JSON file for O(log N) search.
|
|
12
|
+
*/
|
|
13
|
+
export declare class EmbeddingCacheStorage {
|
|
14
|
+
private cacheDir;
|
|
15
|
+
private cachePath;
|
|
16
|
+
private binPath;
|
|
17
|
+
private hnswPath;
|
|
18
|
+
constructor(projectId: string);
|
|
19
|
+
load(): EmbeddingCache | null;
|
|
20
|
+
save(cache: EmbeddingCache): void;
|
|
21
|
+
private writeAtomic;
|
|
22
|
+
update(newEmbeddings: Record<string, number[]>, cache: EmbeddingCache): EmbeddingCache;
|
|
23
|
+
prune(validChunkIds: Set<string>, cache: EmbeddingCache): EmbeddingCache;
|
|
24
|
+
/**
|
|
25
|
+
* Helper to always get a Map, regardless of storage format
|
|
26
|
+
*/
|
|
27
|
+
private getEmbeddingsMap;
|
|
28
|
+
getCacheDir(): string;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/storage/cache.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAKpD;;;;;;;;;;GAUG;AACH,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAS;gBAEb,SAAS,EAAE,MAAM;IAO7B,IAAI,IAAI,cAAc,GAAG,IAAI;IAoD7B,IAAI,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI;IA0CjC,OAAO,CAAC,WAAW;IAMnB,MAAM,CACJ,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EACvC,KAAK,EAAE,cAAc,GACpB,cAAc;IAYjB,KAAK,CAAC,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,cAAc,GAAG,cAAc;IAwBxE;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAaxB,WAAW,IAAI,MAAM;CAGtB"}
|