feat: remove ModelUse and ModelAdd commands; update command handling and provider configuration

This commit is contained in:
asepharyana
2026-07-12 02:19:08 +07:00
parent 32155f8ea8
commit c948869d35
4 changed files with 14 additions and 68 deletions
+9 -41
View File
@@ -60,13 +60,6 @@ pub enum Action {
command: String, command: String,
}, },
ModelList, ModelList,
ModelUse {
provider: String,
},
ModelAdd {
name: String,
base_url: String,
},
} }
pub fn apply_action(state: &mut AppStateRest, action: Action) { 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.misc.overlay = Overlay::ModelSelector;
state.dirty = true; 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 <name> <base_url>".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 <name> to switch, or /edit app_config.json to configure further".to_string()));
state.dirty = true;
}
}
Action::CloseOverlay => { Action::CloseOverlay => {
// If the overlay is the Editor, dismiss it properly first // If the overlay is the Editor, dismiss it properly first
if state.misc.overlay == Overlay::Editor { if state.misc.overlay == Overlay::Editor {
@@ -496,10 +456,18 @@ fn spawn_turn(state: &AppStateRest) {
if messages.is_empty() { if messages.is_empty() {
return; 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 model = state.settings.model.clone();
let base_url = state.app_config.providers.get(&state.settings.provider) let base_url = state.app_config.providers.get(&state.settings.provider)
.map(|p| p.api_base.clone()); .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( let (temperature, max_tokens) = crate::app::mode::effort::generation_params(
state.misc.effort_level, state.misc.effort_level,
state.settings.max_tokens, state.settings.max_tokens,
-6
View File
@@ -61,12 +61,6 @@ pub fn apply_command(command: Command) -> Vec<Action> {
Command::ModelList => { Command::ModelList => {
vec![Action::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) => { Command::Unknown(cmd) => {
vec![Action::SystemNote { vec![Action::SystemNote {
kind: "error".to_string(), kind: "error".to_string(),
+1 -20
View File
@@ -20,13 +20,6 @@ pub enum Command {
command: String, command: String,
}, },
ModelList, ModelList,
ModelUse {
provider: String,
},
ModelAdd {
name: String,
base_url: String,
},
Unknown(String), Unknown(String),
} }
@@ -81,19 +74,7 @@ pub fn parse_command(text: &str) -> Command {
Command::McpAdd { name: rest.to_string(), command: String::new() } Command::McpAdd { name: rest.to_string(), command: String::new() }
} }
} }
"/model" if arg1 == "ls" || arg1 == "list" => Command::ModelList, "/model" => 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() },
_ => Command::Unknown(cmd.to_string()), _ => Command::Unknown(cmd.to_string()),
} }
} }
+4 -1
View File
@@ -14,6 +14,7 @@ pub struct ProviderConfig {
pub api_base: String, pub api_base: String,
pub api_key_env: Option<String>, pub api_key_env: Option<String>,
pub default_model: Option<String>, pub default_model: Option<String>,
pub default_api_key: Option<String>,
} }
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
@@ -31,11 +32,13 @@ impl Default for AppConfig {
api_base: "https://opencode.ai/zen/v1".to_string(), api_base: "https://opencode.ai/zen/v1".to_string(),
api_key_env: Some("API_KEY".to_string()), api_key_env: Some("API_KEY".to_string()),
default_model: Some("deepseek-v4-flash-free".to_string()), default_model: Some("deepseek-v4-flash-free".to_string()),
default_api_key: None,
}); });
providers.insert("router".to_string(), ProviderConfig { providers.insert("router".to_string(), ProviderConfig {
api_base: "https://9router.asepharyana.my.id/v1".to_string(), 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_model: Some("claude-opus-4-8".to_string()),
default_api_key: Some("sk-5dd268d88adb496b-818beb-6bc7498e".to_string()),
}); });
let mut model_roles = HashMap::new(); let mut model_roles = HashMap::new();
model_roles.insert("default".to_string(), ModelRole { model_roles.insert("default".to_string(), ModelRole {