Skip to main content

hematite/agent/
economics.rs

1// ── Session Economics Tracking ───────────────────────────────────────────────
2
3use serde::Serialize;
4
5/// Tracks token usage and tool calls for a session.
6pub struct SessionEconomics {
7    /// Input tokens accumulated across all calls.
8    pub input_tokens: usize,
9    /// Output tokens accumulated across all calls.
10    pub output_tokens: usize,
11    /// List of tool calls with name and success/fail status.
12    pub tools_used: Vec<ToolRecord>,
13}
14
15impl SessionEconomics {
16    /// Create a new empty economics tracker.
17    pub fn new() -> Self {
18        Self {
19            input_tokens: 0,
20            output_tokens: 0,
21            tools_used: Vec::new(),
22        }
23    }
24
25    /// Record a tool call.
26    pub fn record_tool(&mut self, name: &str, success: bool) {
27        self.tools_used.push(ToolRecord {
28            name: name.to_string(),
29            success,
30        });
31    }
32}
33
34impl Default for SessionEconomics {
35    fn default() -> Self {
36        Self {
37            input_tokens: 0,
38            output_tokens: 0,
39            tools_used: Vec::new(),
40        }
41    }
42}
43
44/// A record of a tool call.
45#[derive(Serialize, Clone, Debug)]
46pub struct ToolRecord {
47    pub name: String,
48    pub success: bool,
49}
50
51// ── Pricing constants ─────────────────────────────────────────────────────────
52
53/// Input token price: $0.002 per 1K tokens.
54pub const INPUT_PRICE_PER_1K: f64 = 0.002;
55
56/// Output token price: $0.006 per 1K tokens.
57pub const OUTPUT_PRICE_PER_1K: f64 = 0.006;
58
59// ── Report generation ────────────────────────────────────────────────────────
60
61impl SessionEconomics {
62    /// Calculate simulated cost based on token usage.
63    pub fn simulated_cost(&self) -> f64 {
64        let input_cost = (self.input_tokens as f64 / 1000.0) * INPUT_PRICE_PER_1K;
65        let output_cost = (self.output_tokens as f64 / 1000.0) * OUTPUT_PRICE_PER_1K;
66        input_cost + output_cost
67    }
68
69    /// Generate a JSON report of the session economics.
70    pub fn to_json(&self) -> String {
71        use serde_json::json;
72        json!({
73            "session_economics": {
74                "input_tokens": self.input_tokens,
75                "output_tokens": self.output_tokens,
76                "total_tokens": self.input_tokens + self.output_tokens,
77                "tools_used": self.tools_used.iter().map(|t| {
78                    json!({
79                        "name": t.name,
80                        "success": t.success
81                    })
82                }).collect::<Vec<_>>(),
83                "simulated_cost_usd": self.simulated_cost()
84            }
85        })
86        .to_string()
87    }
88}