vios_app 0.1.1

Small JSON vaults: Argon2id + AES-GCM, with optional AAD binding.
Documentation
//! Whisper Fusion Engine™ — Tone + Vision Emotional Congruence Scoring

use crate::vision::whisper_vision::{FacialEmotion, VisionEmotionResult};
use crate::whisper::tone_classifier::{ToneResult, EmotionTone};

/// Result of fusion between tone and face emotion
#[derive(Debug, Clone)]
pub struct FusionResult {
    pub facial_emotion: FacialEmotion,
    pub tone_emotion: EmotionTone,
    pub congruence_score: f32,
    pub explanation: String,
    pub timestamp: String,
}

/// Compare tone and facial emotion for alignment
pub fn calculate_congruence(
    face_result: &VisionEmotionResult,
    tone_result: &ToneResult,
) -> FusionResult {
    let congruent = is_emotion_congruent(&face_result.emotion, &tone_result.primary_emotion);

    let score = if congruent { 1.0 } else { 0.25 };

    let explanation = if congruent {
        format!(
            "✅ Facial emotion '{:?}' matches tone '{:?}'",
            face_result.emotion, tone_result.primary_emotion
        )
    } else {
        format!(
            "⚠️ Facial emotion '{:?}' differs from tone '{:?}'",
            face_result.emotion, tone_result.primary_emotion
        )
    };

    FusionResult {
        facial_emotion: face_result.emotion.clone(),
        tone_emotion: tone_result.primary_emotion.clone(),
        congruence_score: score,
        explanation,
    }
}

/// Naive matching for congruence logic — upgradeable to matrix later
fn is_emotion_congruent(face: &FacialEmotion, tone: &EmotionTone) -> bool {
    match (face, tone) {
        (FacialEmotion::Happy, EmotionTone::Joy) => true,
        (FacialEmotion::Sad, EmotionTone::Sadness) => true,
        (FacialEmotion::Angry, EmotionTone::Anger) => true,
        (FacialEmotion::Neutral, EmotionTone::Neutral) => true,
        (FacialEmotion::Fearful, EmotionTone::Fear) => true,
        (FacialEmotion::Disgusted, EmotionTone::Disgust) => true,
        (FacialEmotion::Surprised, EmotionTone::Surprise) => true,
        _ => false,
    }
}