codetether_agent/telemetry/context.rs
1//! Context-window usage ratios.
2//!
3//! The TUI uses this to render the "context %" badge next to the model name.
4
5use serde::{Deserialize, Serialize};
6
7/// How much of a model's context window has been consumed.
8///
9/// # Examples
10///
11/// ```rust
12/// use codetether_agent::telemetry::ContextLimit;
13///
14/// let cl = ContextLimit::new(50_000, 200_000);
15/// assert_eq!(cl.remaining_tokens, 150_000);
16/// assert!((cl.percentage() - 25.0).abs() < 1e-6);
17/// ```
18#[derive(Debug, Clone, Serialize, Deserialize)]
19pub struct ContextLimit {
20 /// Model's total context window in tokens.
21 pub max_tokens: u64,
22 /// Tokens currently in use.
23 pub used_tokens: u64,
24 /// `max_tokens - used_tokens`, saturating at zero.
25 pub remaining_tokens: u64,
26 /// `used_tokens / max_tokens * 100`.
27 pub percentage_used: f64,
28 /// Alias for [`Self::percentage_used`] retained for API compatibility.
29 pub percentage: f64,
30}
31
32impl ContextLimit {
33 /// Construct from raw counts. `max_tokens == 0` is handled by reporting
34 /// `0.0` percentage rather than dividing by zero.
35 pub fn new(used_tokens: u64, max_tokens: u64) -> Self {
36 let remaining = max_tokens.saturating_sub(used_tokens);
37 let percentage = if max_tokens > 0 {
38 (used_tokens as f64 / max_tokens as f64) * 100.0
39 } else {
40 0.0
41 };
42 Self {
43 max_tokens,
44 used_tokens,
45 remaining_tokens: remaining,
46 percentage_used: percentage,
47 percentage,
48 }
49 }
50
51 /// Accessor kept for API compatibility; returns [`Self::percentage_used`].
52 pub fn percentage(&self) -> f64 {
53 self.percentage_used
54 }
55}