grepmax 0.17.17 → 0.17.18
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.
|
@@ -621,16 +621,25 @@ class Searcher {
|
|
|
621
621
|
const FUSED_WEIGHT = Number.isFinite(envBlend) && envBlend >= 0 ? envBlend : 0.5;
|
|
622
622
|
if (queryPooled && topCandidates.length > STAGE2_K) {
|
|
623
623
|
const cosineScores = topCandidates.map((doc) => {
|
|
624
|
-
|
|
624
|
+
const docVec = doc.pooled_colbert_48d;
|
|
625
|
+
// Reject missing or short vectors. Also treat an all-zero vector as
|
|
626
|
+
// "no pooled signal" rather than a genuine cosine of 0 — chunks indexed
|
|
627
|
+
// before the pooled-IPC fix (orchestrator.ts) stored all-zero padding,
|
|
628
|
+
// and on a mixed index those must sort below chunks that carry real
|
|
629
|
+
// pooled vectors, not tie with orthogonal ones.
|
|
630
|
+
if (!docVec || docVec.length < queryPooled.length)
|
|
625
631
|
return -1;
|
|
626
632
|
// Manual cosine sim since we don't have helper here easily
|
|
627
633
|
// Assuming vectors are normalized (which they should be from orchestrator)
|
|
628
634
|
let dot = 0;
|
|
629
|
-
|
|
635
|
+
let nonZero = false;
|
|
630
636
|
for (let i = 0; i < queryPooled.length; i++) {
|
|
631
|
-
|
|
637
|
+
const c = docVec[i] || 0;
|
|
638
|
+
if (c !== 0)
|
|
639
|
+
nonZero = true;
|
|
640
|
+
dot += queryPooled[i] * c;
|
|
632
641
|
}
|
|
633
|
-
return dot;
|
|
642
|
+
return nonZero ? dot : -1;
|
|
634
643
|
});
|
|
635
644
|
// Sort by cosine score and keep top N
|
|
636
645
|
const withScore = topCandidates.map((doc, i) => ({
|
|
@@ -287,7 +287,15 @@ class WorkerOrchestrator {
|
|
|
287
287
|
colbert: new Int8Array(),
|
|
288
288
|
scale: 1,
|
|
289
289
|
};
|
|
290
|
-
return Object.assign(Object.assign({}, chunk), { vector: hybrid.dense, colbert: Buffer.from(hybrid.colbert), colbert_scale: hybrid.scale,
|
|
290
|
+
return Object.assign(Object.assign({}, chunk), { vector: hybrid.dense, colbert: Buffer.from(hybrid.colbert), colbert_scale: hybrid.scale,
|
|
291
|
+
// Convert the pooled Float32Array to a plain number[] so it survives
|
|
292
|
+
// the JSON IPC hop to the parent (process-child.ts → pool.ts). A typed
|
|
293
|
+
// array JSON-serializes to a length-less {"0":..} object, which then
|
|
294
|
+
// Array.from()s to [] on insert and pads to 48 zeros — silently making
|
|
295
|
+
// the stage-1 cosine prefilter a no-op (searcher.ts:732).
|
|
296
|
+
pooled_colbert_48d: hybrid.pooled_colbert_48d
|
|
297
|
+
? Array.from(hybrid.pooled_colbert_48d)
|
|
298
|
+
: undefined, doc_token_ids: hybrid.token_ids });
|
|
291
299
|
});
|
|
292
300
|
onProgress === null || onProgress === void 0 ? void 0 : onProgress();
|
|
293
301
|
(0, logger_1.debug)("orch", `processFile done: ${input.path} ${vectors.length} vectors ${(performance.now() - fileStart).toFixed(0)}ms`);
|
package/package.json
CHANGED