feat: implement model management commands and overlays for enhanced user interaction

This commit is contained in:
asepharyana
2026-07-12 02:06:46 +07:00
parent 9f272d5973
commit 662e269f2c
8 changed files with 403 additions and 26 deletions
+46
View File
@@ -60,6 +60,14 @@ pub enum Action {
name: String,
command: String,
},
ModelList,
ModelUse {
provider: String,
},
ModelAdd {
name: String,
base_url: String,
},
}
pub fn apply_action(state: &mut AppStateRest, action: Action) {
@@ -184,6 +192,44 @@ pub fn apply_action(state: &mut AppStateRest, action: Action) {
}
}
}
Action::ModelList => {
state.misc.selected_index = 0;
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 <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 => {
// If the overlay is the Editor, dismiss it properly first
if state.misc.overlay == Overlay::Editor {