mermaid_cli/models/
config.rs1use crate::constants::{DEFAULT_MAX_TOKENS, DEFAULT_TEMPERATURE};
7use crate::prompts;
8use serde::{Deserialize, Serialize};
9use std::collections::HashMap;
10
11#[derive(Debug, Clone, Serialize, Deserialize)]
13pub struct ModelConfig {
14 pub model: String,
17
18 #[serde(default = "default_temperature")]
20 pub temperature: f32,
21
22 #[serde(default = "default_max_tokens")]
24 pub max_tokens: usize,
25
26 pub system_prompt: Option<String>,
28
29 #[serde(default = "default_thinking_enabled")]
32 pub thinking_enabled: Option<bool>,
33
34 #[serde(skip)]
37 pub is_subagent: bool,
38
39 #[serde(default)]
42 pub backend_options: HashMap<String, HashMap<String, String>>,
43
44 #[serde(skip)]
47 pub mcp_tools: Vec<serde_json::Value>,
48}
49
50impl Default for ModelConfig {
51 fn default() -> Self {
52 Self {
53 model: "ollama/tinyllama".to_string(),
54 temperature: default_temperature(),
55 max_tokens: default_max_tokens(),
56 system_prompt: Some(prompts::get_system_prompt()),
57 thinking_enabled: Some(true),
58 is_subagent: false,
59 backend_options: HashMap::new(),
60 mcp_tools: Vec::new(),
61 }
62 }
63}
64
65impl ModelConfig {
66 pub fn get_backend_option(&self, backend: &str, key: &str) -> Option<&String> {
68 self.backend_options.get(backend)?.get(key)
69 }
70
71 pub fn get_backend_option_i32(&self, backend: &str, key: &str) -> Option<i32> {
73 self.get_backend_option(backend, key)?.parse::<i32>().ok()
74 }
75
76 pub fn get_backend_option_bool(&self, backend: &str, key: &str) -> Option<bool> {
78 self.get_backend_option(backend, key)?.parse::<bool>().ok()
79 }
80
81 pub fn set_backend_option(&mut self, backend: String, key: String, value: String) {
83 self.backend_options
84 .entry(backend)
85 .or_default()
86 .insert(key, value);
87 }
88
89 pub fn from_app_config(config: &crate::app::Config, model_id: &str) -> Self {
94 let mut mc = Self {
95 model: model_id.to_string(),
96 temperature: config.default_model.temperature,
97 max_tokens: config.default_model.max_tokens,
98 ..Self::default()
99 };
100 if let Some(v) = config.ollama.num_gpu {
101 mc.set_backend_option("ollama".into(), "num_gpu".into(), v.to_string());
102 }
103 if let Some(v) = config.ollama.num_ctx {
104 mc.set_backend_option("ollama".into(), "num_ctx".into(), v.to_string());
105 }
106 if let Some(v) = config.ollama.num_thread {
107 mc.set_backend_option("ollama".into(), "num_thread".into(), v.to_string());
108 }
109 if let Some(v) = config.ollama.numa {
110 mc.set_backend_option("ollama".into(), "numa".into(), v.to_string());
111 }
112 mc
113 }
114
115 pub fn ollama_options(&self) -> OllamaOptions {
117 OllamaOptions {
118 num_gpu: self.get_backend_option_i32("ollama", "num_gpu"),
119 num_thread: self.get_backend_option_i32("ollama", "num_thread"),
120 num_ctx: self.get_backend_option_i32("ollama", "num_ctx"),
121 numa: self.get_backend_option_bool("ollama", "numa"),
122 }
123 }
124}
125
126#[derive(Debug, Clone, Default)]
128pub struct OllamaOptions {
129 pub num_gpu: Option<i32>,
130 pub num_thread: Option<i32>,
131 pub num_ctx: Option<i32>,
132 pub numa: Option<bool>,
133}
134
135#[derive(Debug, Clone, Serialize, Deserialize)]
137pub struct BackendConfig {
138 #[serde(default = "default_ollama_url")]
140 pub ollama_url: String,
141
142 #[serde(default = "default_timeout")]
144 pub timeout_secs: u64,
145
146 #[serde(default = "default_max_idle")]
148 pub max_idle_per_host: usize,
149}
150
151impl Default for BackendConfig {
152 fn default() -> Self {
153 Self {
154 ollama_url: default_ollama_url(),
155 timeout_secs: default_timeout(),
156 max_idle_per_host: default_max_idle(),
157 }
158 }
159}
160
161fn default_temperature() -> f32 {
163 DEFAULT_TEMPERATURE
164}
165
166fn default_max_tokens() -> usize {
167 DEFAULT_MAX_TOKENS
168}
169
170fn default_ollama_url() -> String {
171 std::env::var("OLLAMA_HOST").unwrap_or_else(|_| "http://localhost:11434".to_string())
172}
173
174fn default_timeout() -> u64 {
175 10
176}
177
178fn default_max_idle() -> usize {
179 10
180}
181
182fn default_thinking_enabled() -> Option<bool> {
183 Some(true)
184}