llm_manager/tui/app/
profiles.rs1use super::types::App;
2
3impl App {
4 pub fn apply_profile(&mut self, profile: &crate::config::Profile) {
6 self.settings = profile.apply(self.settings.clone());
7 self.resolve_system_prompt();
8 self.settings_state.settings_render_cache = None;
9 self.add_log(
10 format!("Applied profile: {}", profile.name),
11 crate::config::LogLevel::Info,
12 );
13 }
14
15 pub fn resolve_system_prompt(&mut self) {
17 if let Some(content) = self
18 .config
19 .get_preset_content(&self.settings.system_prompt_preset_name)
20 {
21 self.settings.system_prompt = content;
22 }
23 }
24
25 pub fn save_current_as_profile(&mut self, name: &str) {
27 let profile = crate::config::Profile {
28 name: name.to_string(),
29 description: format!("User-defined profile: {}", name),
30 settings: crate::config::ModelOverride::from_settings(&self.settings),
31 };
32 self.config.profiles.save(&profile);
33 if let Err(e) = self.config.save() {
34 self.add_log(
35 format!("Failed to save profile: {}", e),
36 crate::config::LogLevel::Error,
37 );
38 } else {
39 self.add_log(
40 format!("Saved profile: {}", name),
41 crate::config::LogLevel::Info,
42 );
43 }
44 }
45
46 pub fn save_model_settings(&mut self) {
48 if let Some(model) = self.selected_model() {
49 let name = model.name.clone();
50 let override_cfg = crate::config::ModelOverride::from_settings(&self.settings);
51 self.config.model_overrides.save(&name, &override_cfg);
52 if let Err(e) = self.config.save() {
53 self.add_log(
54 format!("Failed to save settings for {}: {}", name, e),
55 crate::config::LogLevel::Error,
56 );
57 } else {
58 self.add_log(
59 format!("Saved settings for {}", name),
60 crate::config::LogLevel::Info,
61 );
62 self.model_settings_cache = self.settings.clone();
64 }
65 } else {
66 self.add_log(
67 "No model selected to save settings for",
68 crate::config::LogLevel::Warning,
69 );
70 }
71 self.settings_state.settings_render_cache = None;
72 }
73
74 pub fn is_settings_dirty(&self) -> bool {
76 self.settings.is_dirty(&self.model_settings_cache)
77 }
78
79 pub fn settings_fingerprint(&self) -> u64 {
81 use std::collections::hash_map::DefaultHasher;
82 use std::hash::{Hash, Hasher};
83 let mut h = DefaultHasher::new();
84 self.settings.context_length.hash(&mut h);
85 self.settings.system_prompt_preset_name.hash(&mut h);
86 self.settings.mlock.hash(&mut h);
87 self.settings.gpu_layers_mode.hash(&mut h);
88 self.settings.flash_attn.hash(&mut h);
89 self.settings.fit.hash(&mut h);
90 self.settings.kv_cache_offload.hash(&mut h);
91 self.settings.cache_type_k.hash(&mut h);
92 self.settings.cache_type_v.hash(&mut h);
93 self.settings.expert_count.hash(&mut h);
94 self.settings.batch_size.hash(&mut h);
95 self.settings.uniform_cache.hash(&mut h);
96 self.settings.max_concurrent_predictions.hash(&mut h);
97 self.settings.seed.hash(&mut h);
98 self.settings.temperature.to_bits().hash(&mut h);
99 self.settings.top_k.hash(&mut h);
100 self.settings.top_p.to_bits().hash(&mut h);
101 self.settings.min_p.to_bits().hash(&mut h);
102 self.settings.max_tokens.hash(&mut h);
103 self.settings.repeat_penalty.to_bits().hash(&mut h);
104 self.settings.repeat_last_n.hash(&mut h);
105 self.settings
106 .presence_penalty
107 .map(|v| v.to_bits())
108 .hash(&mut h);
109 self.settings
110 .frequency_penalty
111 .map(|v| v.to_bits())
112 .hash(&mut h);
113 self.settings.keep.hash(&mut h);
114 self.settings.mmap.hash(&mut h);
115 self.settings.numa.hash(&mut h);
116 self.settings.threads.hash(&mut h);
117 self.settings.threads_batch.hash(&mut h);
118 self.settings.get_active_backend_version().hash(&mut h);
119 self.settings_state.settings_edit_buffer.hash(&mut h);
120 self.settings_state.expert_mode.hash(&mut h);
121 h.finish()
122 }
123
124 pub fn delete_profile(&mut self, selected_idx: usize) -> bool {
127 let builtin = crate::config::builtin_profiles();
128 let all_profiles = self.config.profiles.all();
129
130 if selected_idx >= all_profiles.len() {
132 self.add_log("Invalid profile selection", crate::config::LogLevel::Info);
133 return false;
134 }
135
136 if selected_idx < builtin.len() {
138 self.add_log(
139 "Cannot delete built-in profiles",
140 crate::config::LogLevel::Info,
141 );
142 return false;
143 }
144
145 let profile = all_profiles[selected_idx].clone();
146 let profile_name = profile.name.clone();
147
148 self.config.profiles.delete(&profile_name);
149
150 if let Err(e) = self.config.save() {
151 self.add_log(
152 format!("Failed to delete profile: {}", e),
153 crate::config::LogLevel::Error,
154 );
155 return false;
156 }
157
158 self.add_log(
159 format!("Deleted profile: {}", profile_name),
160 crate::config::LogLevel::Info,
161 );
162 true
163 }
164
165 pub fn get_api_port_str(&self) -> String {
166 let port = self.settings.api_endpoint_port;
167 let mut cache = super::types::API_PORT_CACHE
168 .lock()
169 .unwrap_or_else(|e| e.into_inner());
170 if cache.0 == port && !cache.1.is_empty() {
171 return cache.1.clone();
172 }
173 cache.0 = port;
174 cache.1 = port.to_string();
175 cache.1.clone()
176 }
177}