feat: remove ModelUse and ModelAdd commands; update command handling and provider configuration
This commit is contained in:
@@ -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,
|
||||||
|
|||||||
@@ -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(),
|
||||||
|
|||||||
@@ -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()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user