Skip to main content

mermaid_cli/tui/state/
model.rs

1/// Model state management
2///
3/// Handles LLM configuration and identity.
4
5use std::sync::Arc;
6use tokio::sync::RwLock;
7
8use crate::models::Model;
9
10/// Model state - LLM configuration and identity
11pub struct ModelState {
12    pub model: Arc<RwLock<Box<dyn Model>>>,
13    pub model_id: String,
14    pub model_name: String,
15    /// Thinking mode state:
16    /// - Some(true) = model supports thinking, currently enabled
17    /// - Some(false) = model supports thinking, currently disabled
18    /// - None = model does not support thinking (or unknown)
19    pub thinking_enabled: Option<bool>,
20    /// Vision support state:
21    /// - Some(true) = model supports vision
22    /// - Some(false) = model does not support vision (detected from error)
23    /// - None = unknown (optimistic default)
24    pub vision_supported: Option<bool>,
25}
26
27impl ModelState {
28    pub fn new(model: Box<dyn Model>, model_id: String) -> Self {
29        let model_name = model.name().to_string();
30        Self {
31            model: Arc::new(RwLock::new(model)),
32            model_id,
33            model_name,
34            // Default: thinking enabled (will be disabled if model doesn't support it)
35            thinking_enabled: Some(true),
36            // Default: vision unknown (optimistic — try until error)
37            vision_supported: None,
38        }
39    }
40
41    /// Get a reference to the model for reading
42    pub fn model_ref(&self) -> &Arc<RwLock<Box<dyn Model>>> {
43        &self.model
44    }
45
46    /// Toggle thinking mode (only if model supports it)
47    /// Returns the new state, or None if model doesn't support thinking
48    pub fn toggle_thinking(&mut self) -> Option<bool> {
49        match self.thinking_enabled {
50            Some(enabled) => {
51                self.thinking_enabled = Some(!enabled);
52                self.thinking_enabled
53            }
54            None => None, // Model doesn't support thinking, can't toggle
55        }
56    }
57
58    /// Mark model as not supporting thinking
59    /// Called when we get "does not support thinking" error from Ollama
60    pub fn disable_thinking_support(&mut self) {
61        self.thinking_enabled = None;
62    }
63
64    /// Check if thinking is currently active
65    pub fn is_thinking_active(&self) -> bool {
66        self.thinking_enabled == Some(true)
67    }
68}