sweet-search 0.0.1 → 2.3.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 +190 -0
- package/NOTICE +23 -0
- package/core/cli.js +51 -0
- package/core/config.js +27 -0
- package/core/embedding/embedding-cache.js +467 -0
- package/core/embedding/embedding-local-model.js +845 -0
- package/core/embedding/embedding-remote.js +492 -0
- package/core/embedding/embedding-service.js +712 -0
- package/core/embedding/embedding-telemetry.js +219 -0
- package/core/embedding/index.js +40 -0
- package/core/graph/community-detector.js +294 -0
- package/core/graph/graph-expansion.js +839 -0
- package/core/graph/graph-extractor.js +2304 -0
- package/core/graph/graph-search.js +2148 -0
- package/core/graph/hcgs-generator.js +666 -0
- package/core/graph/index.js +16 -0
- package/core/graph/leiden-algorithm.js +547 -0
- package/core/graph/relationship-resolver.js +366 -0
- package/core/graph/repo-map.js +408 -0
- package/core/graph/summary-manager.js +549 -0
- package/core/indexing/artifact-builder.js +1054 -0
- package/core/indexing/ast-chunker.js +709 -0
- package/core/indexing/chunking/chunk-builder.js +170 -0
- package/core/indexing/chunking/markdown-chunker.js +503 -0
- package/core/indexing/chunking/plaintext-chunker.js +104 -0
- package/core/indexing/dedup/dedup-phase.js +159 -0
- package/core/indexing/dedup/exemplar-selector.js +65 -0
- package/core/indexing/document-chunker.js +56 -0
- package/core/indexing/incremental-parser.js +390 -0
- package/core/indexing/incremental-tracker.js +761 -0
- package/core/indexing/index-codebase-v21.js +472 -0
- package/core/indexing/index-maintainer.mjs +1674 -0
- package/core/indexing/index.js +90 -0
- package/core/indexing/indexer-ann.js +1077 -0
- package/core/indexing/indexer-build.js +742 -0
- package/core/indexing/indexer-phases.js +800 -0
- package/core/indexing/indexer-pool.js +764 -0
- package/core/indexing/indexer-sparse-gram.js +98 -0
- package/core/indexing/indexer-utils.js +536 -0
- package/core/indexing/indexer-worker.js +148 -0
- package/core/indexing/li-skip-policy.js +225 -0
- package/core/indexing/merkle-tracker.js +244 -0
- package/core/indexing/model-pool.js +166 -0
- package/core/infrastructure/code-graph-repository.js +120 -0
- package/core/infrastructure/codebase-repository.js +131 -0
- package/core/infrastructure/config/dedup.js +54 -0
- package/core/infrastructure/config/embedding.js +298 -0
- package/core/infrastructure/config/graph.js +80 -0
- package/core/infrastructure/config/index.js +82 -0
- package/core/infrastructure/config/indexing.js +8 -0
- package/core/infrastructure/config/platform.js +254 -0
- package/core/infrastructure/config/ranking.js +221 -0
- package/core/infrastructure/config/search.js +396 -0
- package/core/infrastructure/config/translation.js +89 -0
- package/core/infrastructure/config/vector-store.js +114 -0
- package/core/infrastructure/constants.js +86 -0
- package/core/infrastructure/coreml-cascade.js +909 -0
- package/core/infrastructure/coreml-cascade.json +46 -0
- package/core/infrastructure/coreml-provider.js +81 -0
- package/core/infrastructure/db-utils.js +69 -0
- package/core/infrastructure/dedup-hashing.js +83 -0
- package/core/infrastructure/hardware-capability.js +332 -0
- package/core/infrastructure/index.js +104 -0
- package/core/infrastructure/language-patterns/maps.js +121 -0
- package/core/infrastructure/language-patterns/registry-core.js +323 -0
- package/core/infrastructure/language-patterns/registry-data-query.js +155 -0
- package/core/infrastructure/language-patterns/registry-object-oriented.js +285 -0
- package/core/infrastructure/language-patterns/registry-tooling.js +240 -0
- package/core/infrastructure/language-patterns/registry-web-style.js +143 -0
- package/core/infrastructure/language-patterns/registry.js +19 -0
- package/core/infrastructure/language-patterns.js +141 -0
- package/core/infrastructure/llm-provider.js +733 -0
- package/core/infrastructure/manifest.json +46 -0
- package/core/infrastructure/maxsim.wasm +0 -0
- package/core/infrastructure/model-fetcher.js +423 -0
- package/core/infrastructure/model-registry.js +214 -0
- package/core/infrastructure/native-inference.js +587 -0
- package/core/infrastructure/native-resolver.js +187 -0
- package/core/infrastructure/native-sparse-gram.js +257 -0
- package/core/infrastructure/native-tokenizer.js +160 -0
- package/core/infrastructure/onnx-mutex.js +45 -0
- package/core/infrastructure/onnx-session-utils.js +261 -0
- package/core/infrastructure/ort-pipeline.js +111 -0
- package/core/infrastructure/project-detector.js +102 -0
- package/core/infrastructure/quantization.js +410 -0
- package/core/infrastructure/simd-distance.js +502 -0
- package/core/infrastructure/simd-distance.wasm +0 -0
- package/core/infrastructure/tree-sitter-provider.js +665 -0
- package/core/infrastructure/webgpu-maxsim.js +222 -0
- package/core/query/index.js +35 -0
- package/core/query/intent-detector.js +201 -0
- package/core/query/intent-router.js +156 -0
- package/core/query/query-router-catboost.js +222 -0
- package/core/query/query-router-ml.js +266 -0
- package/core/query/query-router.js +213 -0
- package/core/ranking/cascaded-scorer.js +379 -0
- package/core/ranking/flashrank.js +810 -0
- package/core/ranking/index.js +49 -0
- package/core/ranking/late-interaction-index.js +2383 -0
- package/core/ranking/late-interaction-model.js +812 -0
- package/core/ranking/local-reranker.js +374 -0
- package/core/ranking/mmr.js +379 -0
- package/core/ranking/quality-scorer.js +363 -0
- package/core/search/context-expander.js +1167 -0
- package/core/search/dedup/sibling-expander.js +327 -0
- package/core/search/index.js +16 -0
- package/core/search/search-boost.js +259 -0
- package/core/search/search-cli.js +544 -0
- package/core/search/search-format.js +282 -0
- package/core/search/search-fusion.js +327 -0
- package/core/search/search-hybrid.js +204 -0
- package/core/search/search-pattern-chunks.js +337 -0
- package/core/search/search-pattern-planner.js +439 -0
- package/core/search/search-pattern-prefilter.js +412 -0
- package/core/search/search-pattern-ripgrep.js +663 -0
- package/core/search/search-pattern.js +463 -0
- package/core/search/search-postprocess.js +452 -0
- package/core/search/search-semantic.js +706 -0
- package/core/search/search-server.js +554 -0
- package/core/search/session-daemon-prewarm.mjs +164 -0
- package/core/search/session-warmup.js +595 -0
- package/core/search/sweet-search.js +632 -0
- package/core/search/warmup-metrics.js +532 -0
- package/core/start-server.js +6 -0
- package/core/training/query-router/features/extractor.js +762 -0
- package/core/training/query-router/features/multilingual-patterns.js +431 -0
- package/core/training/query-router/features/text-segmenter.js +303 -0
- package/core/training/query-router/features/unicode-utils.js +383 -0
- package/core/training/query-router/output/v45_router_d4.js +11521 -0
- package/core/training/query-router/output/v46_router_d4.js +11498 -0
- package/core/vector-store/binary-heap.js +227 -0
- package/core/vector-store/binary-hnsw-index.js +1004 -0
- package/core/vector-store/float-vector-store.js +234 -0
- package/core/vector-store/hnsw-index.js +580 -0
- package/core/vector-store/index.js +39 -0
- package/core/vector-store/seismic-index.js +498 -0
- package/core/vocabulary/index.js +84 -0
- package/core/vocabulary/vocab-constants.js +20 -0
- package/core/vocabulary/vocab-miner-extractors.js +375 -0
- package/core/vocabulary/vocab-miner-nl.js +404 -0
- package/core/vocabulary/vocab-miner-utils.js +146 -0
- package/core/vocabulary/vocab-miner.js +574 -0
- package/core/vocabulary/vocab-prewarm-cli.js +110 -0
- package/core/vocabulary/vocab-ranker.js +492 -0
- package/core/vocabulary/vocab-warmer.js +523 -0
- package/core/vocabulary/vocab-warmup-orchestrator.js +425 -0
- package/core/vocabulary/vocabulary-utils.js +704 -0
- package/crates/wasm-router/pkg/package.json +13 -0
- package/crates/wasm-router/pkg/query_router_wasm.d.ts +36 -0
- package/crates/wasm-router/pkg/query_router_wasm.js +271 -0
- package/crates/wasm-router/pkg/query_router_wasm_bg.wasm +0 -0
- package/crates/wasm-router/pkg/query_router_wasm_bg.wasm.d.ts +19 -0
- package/mcp/config-gen.js +121 -0
- package/mcp/server.js +335 -0
- package/mcp/tool-handlers.js +476 -0
- package/package.json +131 -9
- package/scripts/benchmark-harness.js +794 -0
- package/scripts/init.js +1058 -0
- package/scripts/smoke-test.js +435 -0
- package/scripts/uninstall.js +478 -0
- package/scripts/verify-runtime.js +176 -0
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Float Vector Store — Direct-access binary storage for Stage 2.5 rescoring.
|
|
3
|
+
*
|
|
4
|
+
* Replaces SQLite on the float-rescore hot path. Vectors are stored contiguously
|
|
5
|
+
* in a flat binary file and preloaded into memory at startup. Lookup is O(1) by
|
|
6
|
+
* integer index or by ID via an ID→index map.
|
|
7
|
+
*
|
|
8
|
+
* File format (.float-vectors.bin):
|
|
9
|
+
* Header (20 bytes):
|
|
10
|
+
* magic: 4 bytes "FVEC"
|
|
11
|
+
* version: uint32 1
|
|
12
|
+
* dimension: uint32 number of float32 elements per vector
|
|
13
|
+
* count: uint32 number of vectors
|
|
14
|
+
* reserved: uint32 0
|
|
15
|
+
* Data:
|
|
16
|
+
* count × dimension × 4 bytes (float32, little-endian, contiguous)
|
|
17
|
+
*
|
|
18
|
+
* ID mapping (.float-vectors.ids.json):
|
|
19
|
+
* Array of string IDs in index order. id[i] corresponds to vector at offset
|
|
20
|
+
* i * dimension * 4 in the data section.
|
|
21
|
+
*
|
|
22
|
+
* At query time:
|
|
23
|
+
* 1. Resolve chunk ID → index via idToIndex Map
|
|
24
|
+
* 2. Slice Float32Array at index * dimension
|
|
25
|
+
* 3. Batch dot product for Stage 2.5 candidates
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
import { readFile, writeFile } from 'fs/promises';
|
|
29
|
+
import { existsSync } from 'fs';
|
|
30
|
+
import path from 'path';
|
|
31
|
+
import { float32BatchDot } from '../infrastructure/simd-distance.js';
|
|
32
|
+
|
|
33
|
+
const MAGIC = 0x43455646; // "FVEC" in little-endian
|
|
34
|
+
const VERSION = 1;
|
|
35
|
+
const HEADER_SIZE = 20;
|
|
36
|
+
|
|
37
|
+
export class FloatVectorStore {
|
|
38
|
+
constructor() {
|
|
39
|
+
this.buffer = null; // Raw ArrayBuffer
|
|
40
|
+
this.data = null; // Float32Array view over data section
|
|
41
|
+
this.dimension = 0;
|
|
42
|
+
this.count = 0;
|
|
43
|
+
this.idToIndex = new Map();
|
|
44
|
+
this.loaded = false;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Build the store from an array of { id, vector } entries.
|
|
49
|
+
* Vectors should be Float32Array or number[] of consistent dimension.
|
|
50
|
+
*
|
|
51
|
+
* @param {Array<{id: string, vector: Float32Array|number[]}>} entries
|
|
52
|
+
* @param {number} dimension
|
|
53
|
+
*/
|
|
54
|
+
build(entries, dimension) {
|
|
55
|
+
this.dimension = dimension;
|
|
56
|
+
this.count = entries.length;
|
|
57
|
+
this.idToIndex = new Map();
|
|
58
|
+
|
|
59
|
+
// Allocate contiguous buffer: header + data
|
|
60
|
+
const dataBytes = this.count * this.dimension * 4;
|
|
61
|
+
this.buffer = new ArrayBuffer(HEADER_SIZE + dataBytes);
|
|
62
|
+
|
|
63
|
+
// Write header
|
|
64
|
+
const header = new DataView(this.buffer, 0, HEADER_SIZE);
|
|
65
|
+
header.setUint32(0, MAGIC, true);
|
|
66
|
+
header.setUint32(4, VERSION, true);
|
|
67
|
+
header.setUint32(8, this.dimension, true);
|
|
68
|
+
header.setUint32(12, this.count, true);
|
|
69
|
+
header.setUint32(16, 0, true); // reserved
|
|
70
|
+
|
|
71
|
+
// Write data + build ID map (bulk set per vector)
|
|
72
|
+
this.data = new Float32Array(this.buffer, HEADER_SIZE);
|
|
73
|
+
for (let i = 0; i < entries.length; i++) {
|
|
74
|
+
const { id, vector } = entries[i];
|
|
75
|
+
this.idToIndex.set(id, i);
|
|
76
|
+
this.data.set(vector, i * this.dimension);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
this.loaded = true;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Save to disk: binary file + ID map JSON.
|
|
84
|
+
* @param {string} binPath - Path for binary file (e.g., foo.float-vectors.bin)
|
|
85
|
+
*/
|
|
86
|
+
async save(binPath) {
|
|
87
|
+
if (!this.loaded) throw new Error('FloatVectorStore: nothing to save');
|
|
88
|
+
|
|
89
|
+
// Write binary file
|
|
90
|
+
await writeFile(binPath, Buffer.from(this.buffer));
|
|
91
|
+
|
|
92
|
+
// Write ID map
|
|
93
|
+
const idsPath = binPath.replace(/\.bin$/, '.ids.json');
|
|
94
|
+
const ids = new Array(this.count);
|
|
95
|
+
for (const [id, idx] of this.idToIndex) ids[idx] = id;
|
|
96
|
+
await writeFile(idsPath, JSON.stringify(ids));
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Load from disk. Reads entire binary file into memory.
|
|
101
|
+
* @param {string} binPath - Path to binary file
|
|
102
|
+
* @returns {boolean} true if loaded successfully
|
|
103
|
+
*/
|
|
104
|
+
async load(binPath) {
|
|
105
|
+
if (!existsSync(binPath)) return false;
|
|
106
|
+
|
|
107
|
+
const idsPath = binPath.replace(/\.bin$/, '.ids.json');
|
|
108
|
+
if (!existsSync(idsPath)) return false;
|
|
109
|
+
|
|
110
|
+
// Read binary
|
|
111
|
+
const fileBuffer = await readFile(binPath);
|
|
112
|
+
this.buffer = fileBuffer.buffer.slice(
|
|
113
|
+
fileBuffer.byteOffset,
|
|
114
|
+
fileBuffer.byteOffset + fileBuffer.byteLength
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
// Parse header
|
|
118
|
+
const header = new DataView(this.buffer, 0, HEADER_SIZE);
|
|
119
|
+
const magic = header.getUint32(0, true);
|
|
120
|
+
if (magic !== MAGIC) throw new Error(`FloatVectorStore: bad magic 0x${magic.toString(16)}`);
|
|
121
|
+
|
|
122
|
+
const version = header.getUint32(4, true);
|
|
123
|
+
if (version !== VERSION) throw new Error(`FloatVectorStore: unsupported version ${version}`);
|
|
124
|
+
|
|
125
|
+
this.dimension = header.getUint32(8, true);
|
|
126
|
+
this.count = header.getUint32(12, true);
|
|
127
|
+
|
|
128
|
+
// Map data section
|
|
129
|
+
this.data = new Float32Array(this.buffer, HEADER_SIZE, this.count * this.dimension);
|
|
130
|
+
|
|
131
|
+
// Read ID map
|
|
132
|
+
const idsJson = await readFile(idsPath, 'utf-8');
|
|
133
|
+
const ids = JSON.parse(idsJson);
|
|
134
|
+
this.idToIndex = new Map();
|
|
135
|
+
for (let i = 0; i < ids.length; i++) {
|
|
136
|
+
this.idToIndex.set(ids[i], i);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
this.loaded = true;
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Get a float vector by string ID.
|
|
145
|
+
* @param {string} id
|
|
146
|
+
* @returns {Float32Array|null}
|
|
147
|
+
*/
|
|
148
|
+
get(id) {
|
|
149
|
+
const idx = this.idToIndex.get(id);
|
|
150
|
+
if (idx === undefined) return null;
|
|
151
|
+
const offset = idx * this.dimension;
|
|
152
|
+
// Return a copy, not a view — prevents callers from corrupting the shared buffer.
|
|
153
|
+
return this.data.slice(offset, offset + this.dimension);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Batch-get float vectors for multiple IDs.
|
|
158
|
+
* @param {string[]} ids
|
|
159
|
+
* @returns {Map<string, Float32Array>}
|
|
160
|
+
*/
|
|
161
|
+
batchGet(ids) {
|
|
162
|
+
const result = new Map();
|
|
163
|
+
for (const id of ids) {
|
|
164
|
+
const vec = this.get(id);
|
|
165
|
+
if (vec) result.set(id, vec);
|
|
166
|
+
}
|
|
167
|
+
return result;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Batch dot product of a query against candidates identified by IDs.
|
|
172
|
+
* For L2-normalized vectors (from truncateForHNSW), dot = cosine.
|
|
173
|
+
*
|
|
174
|
+
* Uses subarray views internally (no per-candidate copy) since the
|
|
175
|
+
* vectors are only passed to float32BatchDot and never returned.
|
|
176
|
+
*
|
|
177
|
+
* @param {Float32Array} query - L2-normalized query vector
|
|
178
|
+
* @param {string[]} ids - Candidate chunk IDs
|
|
179
|
+
* @returns {{ scores: Map<string, number>, missing: number }}
|
|
180
|
+
*/
|
|
181
|
+
batchScore(query, ids) {
|
|
182
|
+
const candidates = [];
|
|
183
|
+
const validIds = [];
|
|
184
|
+
let missing = 0;
|
|
185
|
+
|
|
186
|
+
for (const id of ids) {
|
|
187
|
+
const idx = this.idToIndex.get(id);
|
|
188
|
+
if (idx !== undefined) {
|
|
189
|
+
const offset = idx * this.dimension;
|
|
190
|
+
candidates.push(this.data.subarray(offset, offset + this.dimension));
|
|
191
|
+
validIds.push(id);
|
|
192
|
+
} else {
|
|
193
|
+
missing++;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (candidates.length === 0) {
|
|
198
|
+
return { scores: new Map(), missing };
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// For L2-normalized vectors (from truncateForHNSW), dot product = cosine.
|
|
202
|
+
const dotScores = float32BatchDot(query, candidates);
|
|
203
|
+
const scores = new Map();
|
|
204
|
+
for (let i = 0; i < validIds.length; i++) {
|
|
205
|
+
scores.set(validIds[i], dotScores[i]);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
return { scores, missing };
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/** Memory size in MB */
|
|
212
|
+
get memorySizeMB() {
|
|
213
|
+
if (!this.buffer) return 0;
|
|
214
|
+
return (this.buffer.byteLength / (1024 * 1024)).toFixed(2);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
getStats() {
|
|
218
|
+
return {
|
|
219
|
+
loaded: this.loaded,
|
|
220
|
+
count: this.count,
|
|
221
|
+
dimension: this.dimension,
|
|
222
|
+
memorySizeMB: this.memorySizeMB,
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Derive the float vector store path from the binary HNSW index path.
|
|
229
|
+
* e.g., .sweet-search/codebase-binary-hnsw.idx → .sweet-search/codebase-float-vectors.bin
|
|
230
|
+
*/
|
|
231
|
+
export function getFloatStorePath(binaryHnswPath) {
|
|
232
|
+
const dir = path.dirname(binaryHnswPath);
|
|
233
|
+
return path.join(dir, 'codebase-float-vectors.bin');
|
|
234
|
+
}
|