"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MultiAIOrchestrator = exports.MockAIAdapter = exports.OpenAIAdapter = exports.ContextWindow = exports.VectorSearch = void 0;
class VectorSearch {
    docs = [];
    tfidf = new Map();
    index(id, text) {
        this.docs.push({ id, text });
        this.rebuild();
    }
    indexBatch(entries) {
        this.docs.push(...entries);
        this.rebuild();
    }
    search(query, limit = 5) {
        if (this.tfidf.size === 0)
            return [];
        const qVec = this.tfidfVector(query);
        const scores = this.docs.map((d) => {
            const dVec = this.tfidf.get(d.id);
            if (!dVec)
                return { id: d.id, score: 0 };
            const score = this.cosineSimilarity(qVec, dVec);
            return { id: d.id, score };
        });
        return scores.sort((a, b) => b.score - a.score).slice(0, limit).filter((s) => s.score > 0.01);
    }
    clear() { this.docs = []; this.tfidf.clear(); }
    rebuild() {
        const termCount = new Map();
        const docTerms = new Map();
        for (const d of this.docs) {
            const terms = this.tokenize(d.text);
            const termFreq = new Map();
            for (const t of terms) {
                termFreq.set(t, (termFreq.get(t) || 0) + 1);
                termCount.set(t, (termCount.get(t) || 0) + 1);
            }
            docTerms.set(d.id, termFreq);
        }
        const N = this.docs.length;
        this.tfidf.clear();
        for (const [id, tf] of docTerms) {
            const vec = new Map();
            for (const [term, freq] of tf) {
                const idf = Math.log((N + 1) / ((termCount.get(term) || 0) + 1)) + 1;
                vec.set(term, (freq / tf.size) * idf);
            }
            this.tfidf.set(id, vec);
        }
    }
    tfidfVector(text) {
        const terms = this.tokenize(text);
        const freq = new Map();
        for (const t of terms)
            freq.set(t, (freq.get(t) || 0) + 1);
        const vec = new Map();
        const N = this.docs.length;
        for (const [term, f] of freq) {
            const df = this.docs.filter((d) => d.text.includes(term)).length;
            const idf = Math.log((N + 1) / (df + 1)) + 1;
            vec.set(term, (f / terms.length) * idf);
        }
        return vec;
    }
    cosineSimilarity(a, b) {
        let dot = 0, magA = 0, magB = 0;
        for (const [k, v] of a) {
            dot += v * (b.get(k) || 0);
            magA += v * v;
        }
        for (const [, v] of b)
            magB += v * v;
        const denom = Math.sqrt(magA) * Math.sqrt(magB);
        return denom === 0 ? 0 : dot / denom;
    }
    tokenize(text) {
        return text.toLowerCase().replace(/[^a-z0-9\s]/g, ' ').split(/\s+/).filter(Boolean);
    }
}
exports.VectorSearch = VectorSearch;
class ContextWindow {
    entries = [];
    maxTokens;
    constructor(maxTokens = 32000) { this.maxTokens = maxTokens; }
    add(role, content) {
        const tokens = Math.ceil(content.length / 4);
        this.entries.push({ role, content, tokens, timestamp: Date.now() });
        this.prune();
        return tokens;
    }
    getWindow() {
        return this.entries.map((e) => ({ role: e.role, content: e.content }));
    }
    summarize() {
        return this.entries.slice(-10).map((e) => `[${e.role}] ${e.content.slice(0, 100)}...`);
    }
    clear() { this.entries = []; }
    prune() {
        let total = this.entries.reduce((s, e) => s + e.tokens, 0);
        while (total > this.maxTokens && this.entries.length > 1) {
            const removed = this.entries.shift();
            total -= removed.tokens;
        }
    }
}
exports.ContextWindow = ContextWindow;
class OpenAIAdapter {
    name = 'GPT-4o';
    provider = 'openai';
    async generate(prompt, context) {
        return `[AI: Would call OpenAI API with ${prompt.slice(0, 30)}... using context ${context.length} chars]`;
    }
    estimateCost(prompt) {
        return (prompt.length / 4) * 0.00001;
    }
}
exports.OpenAIAdapter = OpenAIAdapter;
class MockAIAdapter {
    name = 'MockAI';
    provider = 'local';
    async generate(prompt, context) {
        const promptHash = prompt.length.toString();
        return `Past patterns suggest: optimize imports, use const, prefer early returns (based on ${context.length} chars of context, prompt hash: ${promptHash})`;
    }
    estimateCost(prompt) {
        return (prompt.length / 4) * 0.000001;
    }
}
exports.MockAIAdapter = MockAIAdapter;
class MultiAIOrchestrator {
    adapters = new Map();
    defaultAdapter = 'mock';
    constructor() {
        this.register(new MockAIAdapter());
        this.register(new OpenAIAdapter());
    }
    register(adapter) { this.adapters.set(adapter.name.toLowerCase(), adapter); }
    async generate(prompt, context, preferred) {
        const key = preferred?.toLowerCase() || this.defaultAdapter;
        const adapter = this.adapters.get(key) || this.adapters.get(this.defaultAdapter);
        return adapter.generate(prompt, context);
    }
    estimateCost(prompt, preferred) {
        const key = preferred?.toLowerCase() || this.defaultAdapter;
        return (this.adapters.get(key) || this.adapters.get(this.defaultAdapter)).estimateCost(prompt);
    }
    listAdapters() { return Array.from(this.adapters.keys()); }
}
exports.MultiAIOrchestrator = MultiAIOrchestrator;
//# sourceMappingURL=memory-store.js.map