doum_cli/cli/
switch.rs

1use crate::llm::{Provider, load_presets};
2use crate::system::{load_config, save_config};
3use anyhow::{Context, Result};
4use cliclack::{input, select};
5
6pub async fn handle_switch_command() -> Result<()> {
7    cliclack::intro("🔄 Switch Provider & Model")?;
8
9    // Step 1: Select provider
10    let providers = Provider::all();
11    let provider_items: Vec<_> = providers
12        .iter()
13        .map(|p| (p.as_str(), p.as_display(), ""))
14        .collect();
15
16    let provider_str = select("Select provider")
17        .items(&provider_items)
18        .interact()
19        .context("Provider selection failed")?;
20
21    let provider: Provider = provider_str.parse()?;
22
23    // Step 2: Select model for the chosen provider
24    let models = load_presets(&provider);
25    let mut model_items: Vec<_> = models
26        .iter()
27        .map(|m| (m.id.as_str(), m.name.as_str(), m.description.as_str()))
28        .collect();
29
30    // Add manual option
31    model_items.push(("manual", "Manual", "Enter model name manually"));
32
33    let model_id = select("Select model")
34        .items(&model_items)
35        .interact()
36        .context("Model selection failed")?;
37
38    let model = if model_id == "manual" {
39        input("Enter manual model name")
40            .placeholder("e.g., gpt-5-mini")
41            .interact()
42            .context("Input failed")?
43    } else {
44        model_id.to_string()
45    };
46
47    // Step 3: Update configuration
48    let mut config = load_config()?;
49    config.llm.provider = provider;
50    config.llm.model = model.clone();
51    save_config(&config)?;
52
53    cliclack::outro(format!("✅ Switched to {} - {}", provider_str, model))?;
54    Ok(())
55}