/**
 * Context Engine
 *
 * Manages context window with compression and retrieval.
 */
import { TokenOptimizer } from './token-optimizer.js';
export class ContextEngine {
    maxTokens;
    tokenOptimizer;
    workingContext = [];
    compressedCache = new Map();
    constructor(maxTokens = 128000) {
        this.maxTokens = maxTokens;
        this.tokenOptimizer = new TokenOptimizer(maxTokens);
    }
    /**
     * Add content to context
     */
    add(content) {
        const tokens = this.tokenize(content);
        // Check if we need to compress
        if (this.getTokenCount() + tokens.length > this.maxTokens * 0.8) {
            this.compress();
        }
        this.workingContext.push(content);
    }
    /**
     * Get relevant context for query
     */
    getContext(query) {
        // Simple retrieval - in production use embeddings
        const relevant = this.workingContext
            .filter(c => this.similarity(query, c) > 0.3)
            .slice(-50);
        return relevant;
    }
    /**
     * Compress working context
     */
    compress() {
        if (this.workingContext.length === 0)
            return;
        // Keep most recent and most relevant
        const toCompress = this.workingContext.slice(0, -10);
        const recent = this.workingContext.slice(-10);
        // Create compressed version (simple concatenation for now)
        const compressed = toCompress.join(' | ');
        const key = this.hashString(compressed);
        this.compressedCache.set(key, toCompress);
        this.workingContext = recent;
    }
    /**
     * Get total token count
     */
    getTokenCount() {
        return this.workingContext.reduce((sum, c) => sum + c.length / 4, 0);
    }
    /**
     * Simple tokenization
     */
    tokenize(content) {
        return content.split(/\s+/);
    }
    /**
     * Simple similarity (in production use embeddings)
     */
    similarity(a, b) {
        const wordsA = new Set(a.toLowerCase().split(/\s+/));
        const wordsB = new Set(b.toLowerCase().split(/\s+/));
        const intersection = [...wordsA].filter(x => wordsB.has(x));
        const union = new Set([...wordsA, ...wordsB]);
        return intersection.length / union.size;
    }
    /**
     * Simple hash
     */
    hashString(str) {
        let hash = 0;
        for (let i = 0; i < str.length; i++) {
            hash = ((hash << 5) - hash) + str.charCodeAt(i);
            hash |= 0;
        }
        return hash.toString(36);
    }
    /**
     * Clear context
     */
    clear() {
        this.workingContext = [];
    }
    /**
     * Get all context
     */
    getAll() {
        return [...this.workingContext];
    }
}
export const createContextEngine = (maxTokens) => new ContextEngine(maxTokens);
