lean_ctx/core/billing/
metering.rs1use serde::{Deserialize, Serialize};
8
9use crate::core::savings_ledger::{RoiReport, roi_report};
10
11#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
12pub struct Usage {
13 pub schema_version: u32,
14 pub period: String,
15 pub created_at: String,
16 pub agent_id: String,
17 pub metered_events: usize,
18 pub net_saved_tokens: u64,
19 pub saved_usd: f64,
20 pub last_entry_hash: String,
21 pub chain_valid: bool,
22 pub signed: bool,
23}
24
25impl Usage {
26 pub const SCHEMA_VERSION: u32 = 1;
27
28 #[must_use]
29 pub fn from_roi(roi: &RoiReport) -> Self {
30 Self {
31 schema_version: Self::SCHEMA_VERSION,
32 period: roi.period.clone(),
33 created_at: roi.created_at.clone(),
34 agent_id: roi.agent_id.clone(),
35 metered_events: roi.total_events,
36 net_saved_tokens: roi.net_saved_tokens,
37 saved_usd: roi.saved_usd,
38 last_entry_hash: roi.last_entry_hash.clone(),
39 chain_valid: roi.chain_valid,
40 signed: roi.signed,
41 }
42 }
43
44 #[must_use]
45 pub fn is_billable(&self) -> bool {
46 self.chain_valid && self.signed
47 }
48
49 #[must_use]
50 pub fn source_integrity_verified(&self) -> bool {
51 self.chain_valid && self.signed
52 }
53
54 #[must_use]
55 pub fn headline(&self) -> String {
56 format!(
57 "Usage[{}]: {} events, {} net tokens, ${:.4} (OSS — metering stub)",
58 self.period, self.metered_events, self.net_saved_tokens, self.saved_usd,
59 )
60 }
61}
62
63#[must_use]
64pub fn metered_usage(agent_id: &str) -> Usage {
65 Usage::from_roi(&roi_report(agent_id))
66}