Project Files
src / search / multimodalSearch.ts
import { MultimodalEmbeddingStore, cosineSimilarity, type StoredMultimodalEmbedding } from "../embeddings/index.js";
export type MultimodalQueryMode = "text" | "image" | "mixed";
export interface MultimodalSearchHit {
entry: StoredMultimodalEmbedding;
similarity: number;
score: number;
}
export function searchMultimodalEmbeddings(
queryEmbedding: number[],
store: MultimodalEmbeddingStore,
model: string,
dimension: number,
options: { maxResults: number; minScore: number; maxScoreExclusive?: number }
): MultimodalSearchHit[] {
const entries = store.getAllEmbeddings(model, dimension);
const hits: MultimodalSearchHit[] = [];
for (const entry of entries) {
if (entry.embedding.length !== queryEmbedding.length) continue;
const similarity = cosineSimilarity(queryEmbedding, entry.embedding);
const score = Math.round(Math.max(0, Math.min(1, similarity)) * 100);
if (score >= options.minScore) {
if (options.maxScoreExclusive !== undefined && score >= options.maxScoreExclusive) continue;
hits.push({ entry, similarity, score });
}
}
hits.sort((a, b) => b.score - a.score || b.similarity - a.similarity);
return hits.slice(0, options.maxResults);
}