""" Utility functions for agentic forensic controller. """ from typing import Dict def convert_to_evidence_dict(features: Dict, prediction_score: float, prediction_label: int, thresholds: Dict) -> Dict: """ Convert raw features and prediction to evidence dict format. Args: features: Raw feature dictionary prediction_score: Prediction score (0-1) prediction_label: 0 for REAL, 1 for FAKE thresholds: Threshold dictionary for each feature Returns: Evidence dict with forensic_cues and feature_contributions """ pred_label = 'FAKE' if prediction_label == 1 else 'REAL' # Build forensic cues forensic_cues = {} # Noiseprint mismatch if 'noiseprint_mismatch' in features: mismatch = features['noiseprint_mismatch'] threshold = thresholds.get('noiseprint_mismatch', 2.5) forensic_cues['noiseprint_mismatch'] = { 'value': mismatch, 'threshold': threshold, 'supports': 'fake' if mismatch > threshold else 'real' } # Residual energy if 'residual_energy_p95' in features: energy = features['residual_energy_p95'] threshold = thresholds.get('residual_energy_p95', 0.08) forensic_cues['residual_energy_p95'] = { 'value': energy, 'threshold': threshold, 'supports': 'fake' if energy > threshold else 'real' } # FFT peakiness if 'fft_peakiness' in features: peakiness = features['fft_peakiness'] threshold = thresholds.get('fft_peakiness', 3.0) forensic_cues['fft_peakiness'] = { 'value': peakiness, 'threshold': threshold, 'supports': 'fake' if peakiness > threshold else 'real' } # Feature contributions (simplified - could be more sophisticated) feature_contributions = {} for feat_name, feat_value in features.items(): if feat_name in thresholds: threshold = thresholds[feat_name] # Contribution is how far from threshold (normalized) contribution = abs(feat_value - threshold) / max(threshold, 1.0) feature_contributions[feat_name] = contribution return { 'forensic_cues': forensic_cues, 'feature_contributions': feature_contributions, 'prediction': { 'label': pred_label, 'score': prediction_score } }