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}