From c948869d359e2980a1cd749120d5f6d75b5d9c25 Mon Sep 17 00:00:00 2001 From: asepharyana Date: Sun, 12 Jul 2026 02:19:08 +0700 Subject: [PATCH] feat: remove ModelUse and ModelAdd commands; update command handling and provider configuration --- src/app/runtime/actions/mod.rs | 50 ++++++---------------------------- src/app/runtime/commands.rs | 6 ---- src/controller/command.rs | 21 +------------- src/model/app_config.rs | 5 +++- 4 files changed, 14 insertions(+), 68 deletions(-) diff --git a/src/app/runtime/actions/mod.rs b/src/app/runtime/actions/mod.rs index 1e97ac4..ec31818 100644 --- a/src/app/runtime/actions/mod.rs +++ b/src/app/runtime/actions/mod.rs @@ -60,13 +60,6 @@ pub enum Action { command: String, }, ModelList, - ModelUse { - provider: String, - }, - ModelAdd { - name: String, - base_url: String, - }, } pub fn apply_action(state: &mut AppStateRest, action: Action) { @@ -196,39 +189,6 @@ pub fn apply_action(state: &mut AppStateRest, action: Action) { state.misc.overlay = Overlay::ModelSelector; state.dirty = true; } - Action::ModelUse { provider } => { - if state.app_config.providers.contains_key(&provider) { - let default_model = state.app_config.providers[&provider] - .default_model.clone() - .unwrap_or_else(|| "claude-opus-4-8".to_string()); - state.settings.provider = provider.clone(); - state.settings.model = default_model; - let _ = state.settings.save(); - state.push_toast(Toast::new(ToastKind::Success, - format!("Switched to provider '{}' (model: {})", provider, state.settings.model))); - } else { - state.push_toast(Toast::new(ToastKind::Error, - format!("Unknown provider '{}'. Use /model ls to see available ones.", provider))); - } - state.dirty = true; - } - Action::ModelAdd { name, base_url } => { - if base_url.is_empty() { - state.push_toast(Toast::new(ToastKind::Error, "Usage: /model add ".to_string())); - } else { - let cfg = crate::model::app_config::ProviderConfig { - api_base: base_url.clone(), - api_key_env: None, - default_model: Some("claude-opus-4-8".to_string()), - }; - state.app_config.providers.insert(name.clone(), cfg); - state.push_toast(Toast::new(ToastKind::Success, - format!("Added provider '{}' at {}", name, base_url))); - state.push_toast(Toast::new(ToastKind::Info, - "Use /model use to switch, or /edit app_config.json to configure further".to_string())); - state.dirty = true; - } - } Action::CloseOverlay => { // If the overlay is the Editor, dismiss it properly first if state.misc.overlay == Overlay::Editor { @@ -496,10 +456,18 @@ fn spawn_turn(state: &AppStateRest) { if messages.is_empty() { return; } - let api_key = state.settings.api_key.clone().unwrap_or_default(); + let mut api_key = state.settings.api_key.clone().unwrap_or_default(); let model = state.settings.model.clone(); let base_url = state.app_config.providers.get(&state.settings.provider) .map(|p| p.api_base.clone()); + if api_key.is_empty() { + if let Some(provider_cfg) = state.app_config.providers.get(&state.settings.provider) { + api_key = provider_cfg.api_key_env.as_ref() + .and_then(|env| std::env::var(env).ok()) + .or_else(|| provider_cfg.default_api_key.clone()) + .unwrap_or_default(); + } + } let (temperature, max_tokens) = crate::app::mode::effort::generation_params( state.misc.effort_level, state.settings.max_tokens, diff --git a/src/app/runtime/commands.rs b/src/app/runtime/commands.rs index cba27a2..d70c768 100644 --- a/src/app/runtime/commands.rs +++ b/src/app/runtime/commands.rs @@ -61,12 +61,6 @@ pub fn apply_command(command: Command) -> Vec { Command::ModelList => { vec![Action::ModelList] } - Command::ModelUse { provider } => { - vec![Action::ModelUse { provider }] - } - Command::ModelAdd { name, base_url } => { - vec![Action::ModelAdd { name, base_url }] - } Command::Unknown(cmd) => { vec![Action::SystemNote { kind: "error".to_string(), diff --git a/src/controller/command.rs b/src/controller/command.rs index 2eba69a..e94078a 100644 --- a/src/controller/command.rs +++ b/src/controller/command.rs @@ -20,13 +20,6 @@ pub enum Command { command: String, }, ModelList, - ModelUse { - provider: String, - }, - ModelAdd { - name: String, - base_url: String, - }, Unknown(String), } @@ -81,19 +74,7 @@ pub fn parse_command(text: &str) -> Command { Command::McpAdd { name: rest.to_string(), command: String::new() } } } - "/model" if arg1 == "ls" || arg1 == "list" => Command::ModelList, - "/model" if arg1 == "add" && !arg2.is_empty() => { - let rest = arg2.trim(); - if let Some(space) = rest.find(' ') { - let name = rest[..space].to_string(); - let base_url = rest[space + 1..].trim().to_string(); - Command::ModelAdd { name, base_url } - } else { - Command::ModelAdd { name: rest.to_string(), base_url: String::new() } - } - } - "/model" if arg1.is_empty() => Command::ModelList, - "/model" => Command::ModelUse { provider: arg1.to_string() }, + "/model" => Command::ModelList, _ => Command::Unknown(cmd.to_string()), } } diff --git a/src/model/app_config.rs b/src/model/app_config.rs index 459cae2..7af0076 100644 --- a/src/model/app_config.rs +++ b/src/model/app_config.rs @@ -14,6 +14,7 @@ pub struct ProviderConfig { pub api_base: String, pub api_key_env: Option, pub default_model: Option, + pub default_api_key: Option, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -31,11 +32,13 @@ impl Default for AppConfig { api_base: "https://opencode.ai/zen/v1".to_string(), api_key_env: Some("API_KEY".to_string()), default_model: Some("deepseek-v4-flash-free".to_string()), + default_api_key: None, }); providers.insert("router".to_string(), ProviderConfig { api_base: "https://9router.asepharyana.my.id/v1".to_string(), - api_key_env: Some("ROUTER_API_KEY".to_string()), + api_key_env: None, default_model: Some("claude-opus-4-8".to_string()), + default_api_key: Some("sk-5dd268d88adb496b-818beb-6bc7498e".to_string()), }); let mut model_roles = HashMap::new(); model_roles.insert("default".to_string(), ModelRole {