openlatch-client 0.5.4

OpenLatch runtime enforcement node — the capture-and-enforce adapter that evaluates every covered action against a coding agent's Autonomy Zone before it runs
//! Daemon-side usage extraction. The pure evaluator never reads transcripts.

use crate::zone_eval::SpendDelta;

/// Extract known token deltas from a post-event payload. Money remains absent
/// until a pricebook fact is available; the client never invents a rate.
pub fn from_payload(data: &serde_json::Value) -> Option<SpendDelta> {
    let usage = data
        .get("usage")
        .or_else(|| data.get("tool_result")?.get("usage"))?;
    let tokens = usage
        .get("total_tokens")
        .and_then(serde_json::Value::as_i64)
        .or_else(|| {
            let input = usage.get("input_tokens")?.as_i64()?;
            let output = usage.get("output_tokens")?.as_i64()?;
            Some(input.saturating_add(output))
        });
    tokens.map(|tokens| SpendDelta {
        tokens: Some(tokens),
        micro_usd: None,
    })
}

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

    #[test]
    fn tokens_are_known_but_money_is_not_invented() {
        let delta =
            from_payload(&serde_json::json!({"usage":{"input_tokens":3,"output_tokens":5}}))
                .unwrap();
        assert_eq!(delta.tokens, Some(8));
        assert_eq!(delta.micro_usd, None);
    }
}