1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
use crate::providers::LlmInstance;
use crate::{LlmResponse, LlmResult};
use std::time::{Duration, Instant};
use std::sync::Arc;
/// An LLM provider instance with associated metrics
pub struct InstanceTracker {
pub instance: Arc<dyn LlmInstance + Send + Sync>,
pub last_used: Instant,
pub response_times: Vec<Duration>,
pub request_count: usize,
pub error_count: usize,
}
impl InstanceTracker {
/// Create a new LLM instance
///
/// # Parameters
/// * `id` - Unique identifier for this instance
/// * `provider` - Reference to the provider implementation
pub fn new(instance: Arc<dyn LlmInstance + Send + Sync>) -> Self {
Self {
instance: instance,
last_used: Instant::now(),
response_times: Vec::new(),
request_count: 0,
error_count: 0,
}
}
/// Record the result of a request for metrics tracking
///
/// # Parameters
/// * `duration` - How long the request took
/// * `result` - The result of the request (success or error)
pub fn record_result(&mut self, duration: Duration, result: &LlmResult<LlmResponse>) {
self.last_used = Instant::now();
self.request_count += 1;
match result {
Ok(_) => {
self.response_times.push(duration);
if self.response_times.len() > 10 {
self.response_times.remove(0);
} }
Err(e) => {
self.error_count += 1;
}
}
}
/// Calculate the average response time from recent requests
///
/// # Returns
/// * Average duration, or zero if no requests recorded
pub fn avg_response_time(&self) -> Duration {
if self.response_times.is_empty() {
return Duration::from_millis(0);
}
let total: Duration = self.response_times.iter().sum();
total / self.response_times.len().max(1) as u32 // Avoid division by zero
}
/// Calculate the error rate as a percentage
///
/// # Returns
/// * Error rate from 0.0 to 100.0, or 0.0 if no requests
pub fn get_error_rate(&self) -> f64 {
if self.request_count > 0 {
(self.error_count as f64 / self.request_count as f64) * 100.0
} else {
0.0
}
}
/// Check if this instance is currently enabled
///
/// # Returns
/// * Whether this instance is enabled or not
pub fn is_enabled(&self) -> bool {
self.instance.is_enabled()
}
/// Check if this instance supports a specific task
///
/// # Returns
/// * Whether this instance supports this task or not
pub fn supports_task(&self, task_name: &str) -> bool {
self.instance.get_supported_tasks().contains_key(task_name)
}
}