vtcode_core/metrics/
sdk_metrics.rs1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Serialize, Deserialize)]
4pub struct SdkMetrics {
5 pub total_generations: u64,
6 pub total_generation_time_ms: u64,
7 pub cache_hits: u64,
8 pub tools_total_generated: u64,
9 pub max_tools_per_generation: u64,
10 #[serde(default)]
14 pub total_tool_definition_tokens: u64,
15}
16
17impl SdkMetrics {
18 pub fn new() -> Self {
19 Self {
20 total_generations: 0,
21 total_generation_time_ms: 0,
22 cache_hits: 0,
23 tools_total_generated: 0,
24 max_tools_per_generation: 0,
25 total_tool_definition_tokens: 0,
26 }
27 }
28
29 pub fn record_generation(&mut self, generation_time_ms: u64, tools_count: u64) {
30 self.total_generations += 1;
31 self.total_generation_time_ms += generation_time_ms;
32 self.tools_total_generated += tools_count;
33 if tools_count > self.max_tools_per_generation {
34 self.max_tools_per_generation = tools_count;
35 }
36 }
37
38 pub fn record_cache_hit(&mut self) {
39 self.cache_hits += 1;
40 }
41
42 pub fn record_tool_definition_tokens(&mut self, tokens: u64) {
44 self.total_tool_definition_tokens = self.total_tool_definition_tokens.saturating_add(tokens);
45 }
46
47 pub fn avg_generation_time_ms(&self) -> u64 {
48 self.total_generation_time_ms.checked_div(self.total_generations).unwrap_or(0)
49 }
50
51 pub fn avg_tools_per_generation(&self) -> u64 {
52 self.tools_total_generated.checked_div(self.total_generations).unwrap_or(0)
53 }
54
55 pub fn cache_hit_rate(&self) -> f64 {
56 if self.total_generations > 0 {
57 self.cache_hits as f64 / self.total_generations as f64
58 } else {
59 0.0
60 }
61 }
62
63 pub fn avg_tool_definition_tokens_per_generation(&self) -> u64 {
65 self.total_tool_definition_tokens
66 .checked_div(self.total_generations)
67 .unwrap_or(0)
68 }
69}
70
71impl Default for SdkMetrics {
72 fn default() -> Self {
73 Self::new()
74 }
75}
76
77#[cfg(test)]
78mod tests {
79 use super::*;
80
81 #[test]
82 fn test_record_generation() {
83 let mut metrics = SdkMetrics::new();
84 metrics.record_generation(50, 10);
85
86 assert_eq!(metrics.total_generations, 1);
87 assert_eq!(metrics.total_generation_time_ms, 50);
88 assert_eq!(metrics.tools_total_generated, 10);
89 }
90
91 #[test]
92 fn test_avg_generation_time() {
93 let mut metrics = SdkMetrics::new();
94 metrics.record_generation(50, 10);
95 metrics.record_generation(60, 12);
96 metrics.record_generation(40, 8);
97
98 assert_eq!(metrics.avg_generation_time_ms(), 50);
99 }
100
101 #[test]
102 fn test_max_tools() {
103 let mut metrics = SdkMetrics::new();
104 metrics.record_generation(50, 10);
105 metrics.record_generation(60, 25);
106 metrics.record_generation(40, 8);
107
108 assert_eq!(metrics.max_tools_per_generation, 25);
109 }
110
111 #[test]
112 fn test_cache_hit_rate() {
113 let mut metrics = SdkMetrics::new();
114 metrics.record_generation(50, 10);
115 metrics.record_generation(60, 12);
116 metrics.record_cache_hit();
117 metrics.record_cache_hit();
118
119 assert_eq!(metrics.total_generations, 2);
120 assert_eq!(metrics.cache_hits, 2);
121 assert!(metrics.cache_hit_rate() > 0.0);
122 }
123}