hematite/agent/
economics.rs1use serde::Serialize;
4
5pub struct SessionEconomics {
7 pub input_tokens: usize,
9 pub output_tokens: usize,
11 pub tools_used: Vec<ToolRecord>,
13}
14
15impl SessionEconomics {
16 pub fn new() -> Self {
18 Self {
19 input_tokens: 0,
20 output_tokens: 0,
21 tools_used: Vec::new(),
22 }
23 }
24
25 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#[derive(Serialize, Clone, Debug)]
46pub struct ToolRecord {
47 pub name: String,
48 pub success: bool,
49}
50
51pub const INPUT_PRICE_PER_1K: f64 = 0.002;
55
56pub const OUTPUT_PRICE_PER_1K: f64 = 0.006;
58
59impl SessionEconomics {
62 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 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}