"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.HallucinationDetector = void 0;
const DEFAULT_CONFIG = {
    enabled: true,
    sensitivity: 'medium',
    patterns: [
        "I can't verify",
        "I don't have access to",
        "I cannot confirm",
        "I'm not sure",
        "I don't know",
        "I cannot provide",
        "I'm unable to",
        "I don't have information about"
    ]
};
class HallucinationDetector {
    constructor(config) {
        this.config = { ...DEFAULT_CONFIG, ...config };
    }
    detect(input, output) {
        if (!this.config.enabled) {
            return null;
        }
        const outputText = this.extractText(output);
        if (!outputText) {
            return null;
        }
        const patterns = this.config.patterns;
        const detectedPatterns = [];
        const details = {};
        const lowerText = outputText.toLowerCase();
        for (const pattern of patterns) {
            if (lowerText.includes(pattern.toLowerCase())) {
                detectedPatterns.push(pattern);
            }
        }
        const contradictions = this.checkForContradictions(outputText);
        if (contradictions.length > 0) {
            detectedPatterns.push(...contradictions);
            details['contradictions'] = contradictions;
        }
        const contextDrift = this.checkForContextDrift(input, outputText);
        if (contextDrift.detected) {
            details['contextDrift'] = contextDrift;
        }
        const factualIssues = this.checkForFactualInconsistencies(outputText);
        if (factualIssues.length > 0) {
            details['factualIssues'] = factualIssues;
        }
        if (detectedPatterns.length === 0 && !contextDrift.detected && factualIssues.length === 0) {
            return null;
        }
        const severity = this.calculateSeverity(detectedPatterns, contextDrift, factualIssues);
        const confidence = this.calculateConfidence(detectedPatterns, contextDrift, factualIssues);
        return {
            detected: true,
            severity,
            patterns: detectedPatterns,
            confidence,
            details
        };
    }
    checkForContradictions(text) {
        const contradictions = [];
        const lowerText = text.toLowerCase();
        const contradictionPatterns = [
            /but.*however/i,
            /although.*but/i,
            /yes.*no/i,
            /true.*false/i,
            /correct.*incorrect/i
        ];
        for (const pattern of contradictionPatterns) {
            if (pattern.test(text)) {
                contradictions.push('Self-contradictory statement');
                break;
            }
        }
        return contradictions;
    }
    checkForContextDrift(input, outputText) {
        const inputText = this.extractText(input);
        if (!inputText) {
            return { detected: false, details: {} };
        }
        const inputWords = inputText.toLowerCase().split(/\s+/).filter(w => w.length > 4);
        const outputWords = outputText.toLowerCase().split(/\s+/).filter(w => w.length > 4);
        const keyTerms = inputWords.slice(0, 5);
        const matchingTerms = keyTerms.filter(term => outputWords.includes(term));
        const matchRatio = keyTerms.length > 0 ? matchingTerms.length / keyTerms.length : 0;
        if (matchRatio < 0.2 && keyTerms.length > 0) {
            return {
                detected: true,
                details: {
                    matchRatio,
                    keyTerms,
                    matchingTerms
                }
            };
        }
        return { detected: false, details: {} };
    }
    checkForFactualInconsistencies(text) {
        const issues = [];
        const lowerText = text.toLowerCase();
        const futureDatePattern = /\b(20[3-9][0-9]|2[1-9][0-9]{2})\b/;
        if (futureDatePattern.test(text)) {
            const matches = text.match(futureDatePattern);
            const currentYear = new Date().getFullYear();
            for (const match of matches || []) {
                const year = parseInt(match);
                if (year > currentYear + 1) {
                    issues.push(`Impossible future date: ${match}`);
                }
            }
        }
        const impossibleNumbers = [
            /\b\d{10,}\s*(?:people|users|customers)/i,
            /\b(?:infinite|unlimited|endless)\s*(?:amount|number|quantity)/i
        ];
        for (const pattern of impossibleNumbers) {
            if (pattern.test(text)) {
                issues.push('Potentially unrealistic claim');
                break;
            }
        }
        return issues;
    }
    calculateSeverity(patterns, contextDrift, factualIssues) {
        let score = 0;
        score += patterns.length;
        if (contextDrift.detected) {
            score += 2;
        }
        score += factualIssues.length;
        if (score >= 4)
            return 'high';
        if (score >= 2)
            return 'medium';
        return 'low';
    }
    calculateConfidence(patterns, contextDrift, factualIssues) {
        let confidence = 0.4;
        confidence += Math.min(patterns.length * 0.1, 0.3);
        if (contextDrift.detected) {
            confidence += 0.2;
        }
        confidence += Math.min(factualIssues.length * 0.1, 0.2);
        return Math.min(confidence, 1.0);
    }
    extractText(input) {
        if (typeof input === 'string') {
            return input;
        }
        if (typeof input === 'object' && input !== null) {
            if (input.text)
                return String(input.text);
            if (input.content)
                return String(input.content);
            if (input.message)
                return String(input.message);
            if (input.prompt)
                return String(input.prompt);
            if (input.output)
                return String(input.output);
            try {
                return JSON.stringify(input);
            }
            catch {
                return null;
            }
        }
        return String(input);
    }
    updateConfig(config) {
        this.config = { ...this.config, ...config };
    }
    getConfig() {
        return { ...this.config };
    }
}
exports.HallucinationDetector = HallucinationDetector;
//# sourceMappingURL=hallucination-detector.js.map