"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TokenCompressor = void 0;
/**
 * Token compressor for reducing token usage
 * Implements various compression techniques
 */
class TokenCompressor {
    /**
     * Compress conversation history by removing redundant information
     * and summarizing older exchanges
     */
    compressConversation(messages) {
        if (messages.length <= 2) {
            return messages; // Keep system and latest user message
        }
        // Always keep the system message if present
        const systemMsg = messages.find(msg => msg.role === "system");
        const otherMsgs = messages.filter(msg => msg.role !== "system");
        // Keep the last 2 exchanges (user + assistant) in full
        const recentCount = Math.min(4, otherMsgs.length); // Aim for ~2 exchanges
        const recentMsgs = otherMsgs.slice(-recentCount);
        const olderMsgs = otherMsgs.slice(0, -recentCount);
        // Compress older messages by summarizing
        const compressedOlder = this.summarizeMessages(olderMsgs);
        // Reconstruct: [system] + [compressed older] + [recent full]
        const result = [];
        if (systemMsg)
            result.push(systemMsg);
        if (compressedOlder.length > 0)
            result.push(...compressedOlder);
        result.push(...recentMsgs);
        return result;
    }
    /**
     * Summarize multiple messages into a concise representation
     */
    summarizeMessages(messages) {
        if (messages.length === 0)
            return [];
        // Combine all content
        const combined = messages.map(msg => `${msg.role}: ${msg.content}`).join(" | ");
        // Simple summarization: take first 100 chars and last 100 chars
        // In a real implementation, this would use an actual summarization model
        if (combined.length <= 200) {
            return [{ role: "summary", content: combined }];
        }
        const firstPart = combined.substring(0, 100);
        const lastPart = combined.substring(combined.length - 100);
        const summary = `${firstPart}...${lastPart}`;
        return [{ role: "summary", content: summary }];
    }
    /**
     * Compress code by extracting only relevant parts
     * For example, when editing a file, only send the relevant function/class
     */
    compressCode(content, contextHint) {
        const originalTokens = this.estimateTokens(content);
        // If no context hint, return original
        if (!contextHint) {
            return { compressed: content, savedTokens: 0 };
        }
        // Simple approach: look for lines containing the context hint
        const lines = content.split('\n');
        const relevantLines = lines.filter(line => line.toLowerCase().includes(contextHint.toLowerCase()));
        // Always include some context lines around matches
        const expandedLines = new Set();
        relevantLines.forEach((line, index) => {
            const lineIndex = lines.indexOf(line);
            // Add the line and 2 lines before/after for context
            for (let i = Math.max(0, lineIndex - 2); i <= Math.min(lines.length - 1, lineIndex + 2); i++) {
                expandedLines.add(i);
            }
        });
        const compressedLines = Array.from(expandedLines)
            .sort((a, b) => a - b)
            .map(i => lines[i])
            .join('\n');
        // If compression didn't reduce much, return original
        if (compressedLines.length >= content.length * 0.8) {
            return { compressed: content, savedTokens: 0 };
        }
        const compressedTokens = this.estimateTokens(compressedLines);
        const savedTokens = originalTokens - compressedTokens;
        return {
            compressed: compressedLines,
            savedTokens: Math.max(0, savedTokens)
        };
    }
    /**
     * Estimate token count for text
     * Rough approximation: 4 characters per token for English text
     */
    estimateTokens(text) {
        if (!text)
            return 0;
        return Math.ceil(text.length / 4);
    }
}
exports.TokenCompressor = TokenCompressor;
//# sourceMappingURL=compressor.js.map