File size: 916 Bytes
eb46abf | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | import type { EmbeddedChunk, ScoredChunk } from "../types";
/**
* Cosine similarity between two vectors.
*/
export function cosineSimilarity(a: Float32Array, b: Float32Array): number {
let dot = 0;
let normA = 0;
let normB = 0;
for (let i = 0; i < a.length; i++) {
dot += a[i] * b[i];
normA += a[i] * a[i];
normB += b[i] * b[i];
}
return dot / (Math.sqrt(normA) * Math.sqrt(normB));
}
/**
* Search embedded chunks by cosine similarity to query embedding.
* Returns the top-K results sorted by descending similarity score.
*/
export function vectorSearch(
queryEmbedding: Float32Array,
chunks: EmbeddedChunk[],
topK: number = 20,
): ScoredChunk[] {
const scored = chunks.map((chunk) => ({
chunk,
score: cosineSimilarity(queryEmbedding, chunk.embedding),
source: "vector" as const,
}));
scored.sort((a, b) => b.score - a.score);
return scored.slice(0, topK);
}
|