Skip to main content

wisp/conversation/
turn.rs

1use agent_client_protocol::schema::v2::{CompactionId, CompactionStatus, CompactionUpdate};
2use std::collections::HashSet;
3
4/// Context-window usage as the status line displays it.
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6pub struct ContextUsageDisplay {
7    pub used_tokens: u32,
8    pub limit_tokens: u32,
9}
10
11impl ContextUsageDisplay {
12    pub fn used_ratio(self) -> f64 {
13        if self.limit_tokens == 0 {
14            return 0.0;
15        }
16        (f64::from(self.used_tokens) / f64::from(self.limit_tokens)).clamp(0.0, 1.0)
17    }
18}
19
20#[derive(Debug, Default)]
21pub struct TurnState {
22    active_compactions: HashSet<CompactionId>,
23    context_usage: Option<ContextUsageDisplay>,
24    spinner_tick: usize,
25}
26
27impl TurnState {
28    pub fn is_compaction_active(&self) -> bool {
29        !self.active_compactions.is_empty()
30    }
31
32    pub fn apply_compaction(&mut self, update: &CompactionUpdate) {
33        match update.status {
34            CompactionStatus::InProgress => { self.active_compactions.insert(update.compaction_id.clone()); }
35            CompactionStatus::Completed | CompactionStatus::Failed | CompactionStatus::Cancelled => {
36                self.active_compactions.remove(&update.compaction_id);
37            }
38            _ => {}
39        }
40    }
41
42    pub fn clear_compactions(&mut self) {
43        self.active_compactions.clear();
44    }
45
46    pub fn set_context_usage(&mut self, context_usage: Option<ContextUsageDisplay>) {
47        self.context_usage = context_usage;
48    }
49
50    pub fn context_usage(&self) -> Option<ContextUsageDisplay> {
51        self.context_usage
52    }
53
54    pub fn spinner_tick(&self) -> usize {
55        self.spinner_tick
56    }
57
58    pub fn advance_spinner(&mut self) {
59        self.spinner_tick = self.spinner_tick.wrapping_add(1);
60    }
61
62    pub fn reset(&mut self) {
63        let spinner_tick = self.spinner_tick;
64        *self = Self { spinner_tick, ..Self::default() };
65    }
66}