lean-ctx 3.9.19

Context Runtime for AI Agents with CCP. 79 MCP tools, 10 read modes, 95+ compression patterns, cross-session memory (CCP), persistent AI knowledge with temporal facts + contradiction detection, multi-agent context sharing, LITM-aware positioning, AAAK compact format, adaptive compression with Thompson Sampling bandits. Supports 24+ AI tools. Reduces LLM token consumption by up to 99%.
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CostPerAcceptedOutcome {
    pub task_class: String,
    pub total_cost_usd: f64,
    pub accepted_outcomes: u64,
    pub rejected_outcomes: u64,
    pub cost_per_accepted_usd: f64,
    pub etpao: f64,
    pub period_start: String,
    pub period_end: String,
}

impl CostPerAcceptedOutcome {
    #[must_use]
    pub fn calculate(total_cost_usd: f64, accepted: u64, rejected: u64, etpao: f64) -> Self {
        let cost_per_accepted_usd = if accepted == 0 {
            0.0
        } else {
            total_cost_usd / accepted as f64
        };

        Self {
            task_class: String::new(),
            total_cost_usd,
            accepted_outcomes: accepted,
            rejected_outcomes: rejected,
            cost_per_accepted_usd,
            etpao,
            period_start: String::new(),
            period_end: String::new(),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn calculate_cost_per_accepted_outcome() {
        let metric = CostPerAcceptedOutcome::calculate(12.0, 3, 1, 750.0);

        assert_eq!(metric.total_cost_usd, 12.0);
        assert_eq!(metric.accepted_outcomes, 3);
        assert_eq!(metric.rejected_outcomes, 1);
        assert_eq!(metric.cost_per_accepted_usd, 4.0);
        assert_eq!(metric.etpao, 750.0);
    }

    #[test]
    fn zero_accepted_outcomes_has_zero_unit_cost() {
        let metric = CostPerAcceptedOutcome::calculate(12.0, 0, 2, 0.0);

        assert_eq!(metric.cost_per_accepted_usd, 0.0);
        assert!(metric.cost_per_accepted_usd.is_finite());
    }
}