1use crate::core::{get_provider_config, save_secrets};
2use crate::llm::{Provider, load_presets, verify_config};
3use anyhow::{Context, Result};
4use cliclack::{input, password, select, spinner};
5use std::collections::HashMap;
6
7pub async fn handle_secret_command() -> Result<()> {
8 cliclack::intro("🔐 Configure LLM Provider Secret")?;
9
10 let providers = Provider::all();
12 let provider_items: Vec<_> = providers
13 .iter()
14 .map(|p| (p.as_str(), p.as_str(), ""))
15 .collect();
16
17 let provider_str = select("Select provider to configure")
18 .items(&provider_items)
19 .interact()
20 .context("Selection failed")?;
21
22 let provider: Provider = provider_str.parse()?;
23
24 let config = get_provider_config(&provider)?;
26 let mut values = HashMap::new();
27 for field in &config.fields {
28 let value = if field.is_password {
29 password(&field.label)
30 .interact()
31 .context("Password input failed")?
32 } else {
33 let input_value: String = input(&field.label)
35 .placeholder("Press Enter to skip")
36 .required(false)
37 .interact()
38 .context("Input failed")?;
39 input_value
40 };
41 values.insert(field.name.clone(), value.trim().to_string());
42 }
43
44 save_secrets(&provider, values)?;
46
47 let first_model = load_presets(&provider)
49 .first()
50 .map(|m| m.id.clone())
51 .unwrap_or_else(|| "gpt-4".to_string());
52
53 let sp = spinner();
55 sp.start("Verifying API key...");
56
57 match verify_config(provider.as_str(), &first_model).await {
58 Ok(true) => {
59 sp.stop(format!(
60 "✅ {} secrets saved and verified successfully",
61 provider_str.to_uppercase()
62 ));
63 cliclack::outro("Configuration complete!")?;
64 Ok(())
65 }
66 Ok(false) => {
67 sp.stop("⚠️ API key verification failed");
68 cliclack::outro("Secrets saved but verification failed. Please check your API key.")?;
69 Ok(())
70 }
71 Err(e) => {
72 sp.stop("❌ Verification error");
73 cliclack::outro(format!("Error: {}", e))?;
74 Err(e)
75 }
76 }
77}