Skip to main content

mermaid_cli/tui/state/
generation.rs

1/// Generation state machine
2///
3/// Tracks the application lifecycle during model interactions.
4
5use std::time::Instant;
6
7/// Generation status for the status line
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub enum GenerationStatus {
10    /// Not currently generating
11    Idle,
12    /// Message sent upstream, waiting for model to start responding
13    Sending,
14    /// Model is loading/initializing (before first token)
15    Initializing,
16    /// Waiting for first token from model (thinking/reasoning)
17    Thinking,
18    /// Actively receiving and displaying tokens
19    Streaming,
20}
21
22impl GenerationStatus {
23    pub fn display_text(&self) -> &str {
24        match self {
25            GenerationStatus::Idle => "Idle",
26            GenerationStatus::Sending => "Sending",
27            GenerationStatus::Initializing => "Initializing",
28            GenerationStatus::Thinking => "Thinking",
29            GenerationStatus::Streaming => "Streaming",
30        }
31    }
32}
33
34/// Comprehensive state machine for the application lifecycle
35/// Impossible states become impossible to represent
36#[derive(Debug, Clone)]
37pub enum AppState {
38    /// Idle - not doing anything, ready for input
39    Idle,
40
41    /// Currently generating a response from the model
42    Generating {
43        status: GenerationStatus,
44        start_time: Instant,
45        tokens_received: usize,
46        abort_handle: Option<tokio::task::AbortHandle>,
47    },
48}
49
50impl AppState {
51    /// Get generation status if we're generating
52    pub fn generation_status(&self) -> Option<GenerationStatus> {
53        match self {
54            AppState::Generating { status, .. } => Some(*status),
55            _ => None,
56        }
57    }
58
59    /// Check if we're currently generating
60    pub fn is_generating(&self) -> bool {
61        matches!(self, AppState::Generating { .. })
62    }
63
64    /// Check if we're idle
65    pub fn is_idle(&self) -> bool {
66        matches!(self, AppState::Idle)
67    }
68
69    /// Get generation start time if we're generating
70    pub fn generation_start_time(&self) -> Option<Instant> {
71        match self {
72            AppState::Generating { start_time, .. } => Some(*start_time),
73            _ => None,
74        }
75    }
76
77    /// Get tokens received if we're generating
78    pub fn tokens_received(&self) -> Option<usize> {
79        match self {
80            AppState::Generating { tokens_received, .. } => Some(*tokens_received),
81            _ => None,
82        }
83    }
84
85    /// Get abort handle if we're generating
86    pub fn abort_handle(&self) -> Option<&tokio::task::AbortHandle> {
87        match self {
88            AppState::Generating { abort_handle, .. } => abort_handle.as_ref(),
89            _ => None,
90        }
91    }
92}