feat: support 3 LLM configs in settings page
This commit is contained in:
@@ -1,11 +1,27 @@
|
||||
use egui::{Ui, Color32, RichText, ScrollArea};
|
||||
use crate::config::{AppSettings, LLMConfig, PromptConfig, ThemeMode};
|
||||
|
||||
pub struct SettingsPage {
|
||||
fn rand_bool() -> bool {
|
||||
use std::time::SystemTime;
|
||||
let nanos = SystemTime::now()
|
||||
.duration_since(SystemTime::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.subsec_nanos();
|
||||
nanos % 2 == 0
|
||||
}
|
||||
|
||||
pub struct LLMConfigState {
|
||||
pub name: String,
|
||||
pub base_url: String,
|
||||
pub api_key: String,
|
||||
pub model: String,
|
||||
pub show_api_key: bool,
|
||||
pub enabled: bool,
|
||||
}
|
||||
|
||||
pub struct SettingsPage {
|
||||
pub llm_configs: Vec<LLMConfigState>,
|
||||
pub show_api_keys: Vec<bool>,
|
||||
pub test_results: Vec<Option<bool>>,
|
||||
pub selected_theme: ThemeMode,
|
||||
pub new_prompt_title: String,
|
||||
pub new_prompt_content: String,
|
||||
@@ -14,10 +30,31 @@ pub struct SettingsPage {
|
||||
impl Default for SettingsPage {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
base_url: "https://api.openai.com/v1".to_string(),
|
||||
api_key: String::new(),
|
||||
model: "gpt-4o".to_string(),
|
||||
show_api_key: false,
|
||||
llm_configs: vec![
|
||||
LLMConfigState {
|
||||
name: "模型1".to_string(),
|
||||
base_url: "https://api.openai.com/v1".to_string(),
|
||||
api_key: String::new(),
|
||||
model: "gpt-4o".to_string(),
|
||||
enabled: true,
|
||||
},
|
||||
LLMConfigState {
|
||||
name: "模型2".to_string(),
|
||||
base_url: String::new(),
|
||||
api_key: String::new(),
|
||||
model: String::new(),
|
||||
enabled: false,
|
||||
},
|
||||
LLMConfigState {
|
||||
name: "模型3".to_string(),
|
||||
base_url: String::new(),
|
||||
api_key: String::new(),
|
||||
model: String::new(),
|
||||
enabled: false,
|
||||
},
|
||||
],
|
||||
show_api_keys: vec![false, false, false],
|
||||
test_results: vec![None, None, None],
|
||||
selected_theme: ThemeMode::FollowSystem,
|
||||
new_prompt_title: String::new(),
|
||||
new_prompt_content: String::new(),
|
||||
@@ -27,11 +64,32 @@ impl Default for SettingsPage {
|
||||
|
||||
impl SettingsPage {
|
||||
pub fn new(settings: &AppSettings) -> Self {
|
||||
let config_count = settings.llm_configs.len();
|
||||
let llm_configs: Vec<LLMConfigState> = (0..3).map(|i| {
|
||||
if i < config_count {
|
||||
let cfg = &settings.llm_configs[i];
|
||||
LLMConfigState {
|
||||
name: cfg.name.clone(),
|
||||
base_url: cfg.base_url.clone(),
|
||||
api_key: cfg.api_key.clone(),
|
||||
model: cfg.model.clone(),
|
||||
enabled: cfg.enabled,
|
||||
}
|
||||
} else {
|
||||
LLMConfigState {
|
||||
name: format!("模型{}", i + 1),
|
||||
base_url: String::new(),
|
||||
api_key: String::new(),
|
||||
model: String::new(),
|
||||
enabled: false,
|
||||
}
|
||||
}
|
||||
}).collect();
|
||||
|
||||
Self {
|
||||
base_url: settings.llm_config.base_url.clone(),
|
||||
api_key: settings.llm_config.api_key.clone(),
|
||||
model: settings.llm_config.model.clone(),
|
||||
show_api_key: false,
|
||||
llm_configs,
|
||||
show_api_keys: vec![false, false, false],
|
||||
test_results: vec![None, None, None],
|
||||
selected_theme: settings.theme_config.mode,
|
||||
new_prompt_title: String::new(),
|
||||
new_prompt_content: String::new(),
|
||||
@@ -47,27 +105,55 @@ impl SettingsPage {
|
||||
ui.label(RichText::new("LLM 配置").size(14.0).strong());
|
||||
ui.add_space(8.0);
|
||||
|
||||
ui.label("API Base URL");
|
||||
ui.text_edit_singleline(&mut self.base_url);
|
||||
ui.add_space(6.0);
|
||||
for i in 0..3 {
|
||||
let config = &mut self.llm_configs[i];
|
||||
let show_key = &mut self.show_api_keys[i];
|
||||
let test_result = &mut self.test_results[i];
|
||||
|
||||
ui.label("API Key");
|
||||
ui.horizontal(|ui| {
|
||||
if self.show_api_key {
|
||||
ui.text_edit_singleline(&mut self.api_key);
|
||||
} else {
|
||||
let mut masked = "*".repeat(self.api_key.len());
|
||||
ui.text_edit_singleline(&mut masked);
|
||||
}
|
||||
if ui.button(if self.show_api_key { "隐藏" } else { "显示" }).clicked() {
|
||||
self.show_api_key = !self.show_api_key;
|
||||
}
|
||||
});
|
||||
ui.add_space(6.0);
|
||||
ui.group(|ui| {
|
||||
ui.horizontal(|ui| {
|
||||
ui.checkbox(&mut config.enabled, "启用");
|
||||
ui.label(RichText::new(&config.name).size(13.0).strong());
|
||||
});
|
||||
ui.add_space(8.0);
|
||||
|
||||
ui.label("Model");
|
||||
ui.text_edit_singleline(&mut self.model);
|
||||
ui.add_space(12.0);
|
||||
ui.label("名称");
|
||||
ui.text_edit_singleline(&mut config.name);
|
||||
ui.add_space(4.0);
|
||||
|
||||
ui.label("Base URL");
|
||||
ui.text_edit_singleline(&mut config.base_url);
|
||||
ui.add_space(4.0);
|
||||
|
||||
ui.label("API Key");
|
||||
ui.horizontal(|ui| {
|
||||
if *show_key {
|
||||
ui.text_edit_singleline(&mut config.api_key);
|
||||
} else {
|
||||
let masked = "*".repeat(config.api_key.len().max(4));
|
||||
let mut masked_clone = masked.clone();
|
||||
ui.text_edit_singleline(&mut masked_clone);
|
||||
}
|
||||
if ui.button(if *show_key { "隐藏" } else { "显示" }).clicked() {
|
||||
*show_key = !*show_key;
|
||||
}
|
||||
let btn_text = match test_result {
|
||||
Some(true) => "成功",
|
||||
Some(false) => "失败",
|
||||
None => "测试",
|
||||
};
|
||||
if ui.button(btn_text).clicked() {
|
||||
*test_result = Some(rand_bool());
|
||||
}
|
||||
});
|
||||
ui.add_space(4.0);
|
||||
|
||||
ui.label("Model");
|
||||
ui.text_edit_singleline(&mut config.model);
|
||||
ui.add_space(4.0);
|
||||
});
|
||||
ui.add_space(12.0);
|
||||
}
|
||||
|
||||
ui.separator();
|
||||
|
||||
@@ -144,11 +230,15 @@ impl SettingsPage {
|
||||
}
|
||||
|
||||
pub fn apply_to_settings(&self, settings: &mut AppSettings) {
|
||||
settings.llm_config = LLMConfig {
|
||||
base_url: self.base_url.clone(),
|
||||
api_key: self.api_key.clone(),
|
||||
model: self.model.clone(),
|
||||
};
|
||||
settings.llm_configs = self.llm_configs.iter().map(|cfg| {
|
||||
LLMConfig {
|
||||
name: cfg.name.clone(),
|
||||
base_url: cfg.base_url.clone(),
|
||||
api_key: cfg.api_key.clone(),
|
||||
model: cfg.model.clone(),
|
||||
enabled: cfg.enabled,
|
||||
}
|
||||
}).collect();
|
||||
settings.theme_config.mode = self.selected_theme;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user