import { DEFAULT_EMBEDDING_MODEL } from "../../constants.js";
import { EMBEDDING_FORMAT_VERSION, } from "./types.js";
export function cosineSimilarity(a, b) {
    let dot = 0;
    let magA = 0;
    let magB = 0;
    for (let i = 0; i < a.length; i++) {
        dot += a[i] * b[i];
        magA += a[i] * a[i];
        magB += b[i] * b[i];
    }
    const denom = Math.sqrt(magA) * Math.sqrt(magB);
    if (denom === 0)
        return 0;
    return dot / denom;
}
export class EmbeddingManager {
    entries = [];
    model = DEFAULT_EMBEDDING_MODEL;
    setModel(model) {
        this.model = model;
    }
    getModel() {
        return this.model;
    }
    setEntries(entries) {
        this.entries = entries;
    }
    addEntry(id, vector) {
        this.entries = this.entries.filter((e) => e.id !== id);
        this.entries.push({ id, vector });
    }
    removeEntry(id) {
        this.entries = this.entries.filter((e) => e.id !== id);
    }
    findSimilar(queryVector, topK, minThreshold = 0.0) {
        const scored = this.entries
            .map((entry) => ({
            id: entry.id,
            score: cosineSimilarity(queryVector, entry.vector),
        }))
            .filter((r) => r.score >= minThreshold);
        scored.sort((a, b) => b.score - a.score);
        return scored.slice(0, topK);
    }
    toIndex() {
        return {
            formatVersion: EMBEDDING_FORMAT_VERSION,
            model: this.model,
            entries: this.entries,
        };
    }
    static fromIndex(index) {
        const manager = new EmbeddingManager();
        manager.model = index.model;
        manager.entries = index.entries;
        return manager;
    }
}
