1use crate::cli::ui::{prompt_password_input, prompt_text_input};
2use crate::llm::AnthropicSecret;
3use crate::llm::OpenAISecret;
4use crate::system::DoumError::Config;
5use crate::system::error::DoumResult;
6use dialoguer::Select;
7use rust_embed::RustEmbed;
8use serde::Deserialize;
9
10#[derive(RustEmbed)]
11#[folder = "static/presets/"]
12struct ModelPresets;
13
14#[derive(Debug, Deserialize, Clone)]
15pub struct ModelInfo {
16 pub id: String,
17 pub name: String,
18 pub description: String,
19}
20
21#[derive(Debug, Deserialize)]
22struct ModelList {
23 models: Vec<ModelInfo>,
24}
25
26pub fn load_presets(provider: &str) -> Vec<ModelInfo> {
28 let filename = format!("{}.toml", provider);
29
30 if let Some(content) = ModelPresets::get(&filename)
31 && let Ok(data) = std::str::from_utf8(content.data.as_ref())
32 && let Ok(list) = toml::from_str::<ModelList>(data)
33 {
34 return list.models;
35 }
36
37 vec![]
38}
39
40pub fn handle_secret_command(provider: Option<String>) -> DoumResult<()> {
41 let provider = match provider {
42 Some(p) => p,
43 None => select_provider()?,
44 };
45
46 configure_provider_secret(&provider)
47}
48
49fn select_provider() -> DoumResult<String> {
50 let providers = vec!["openai", "anthropic"];
51 let selection = Select::new()
52 .with_prompt("Select provider to configure")
53 .items(&providers)
54 .default(0)
55 .interact()?;
56
57 Ok(providers[selection].to_string())
58}
59
60fn configure_provider_secret(provider: &str) -> DoumResult<()> {
61 match provider {
62 "openai" => configure_openai_secret(),
63 "anthropic" => configure_anthropic_secret(),
64 _ => Err(Config(format!("Unknown provider: {}", provider))),
65 }
66}
67
68fn configure_openai_secret() -> DoumResult<()> {
69 println!("\nš Configure OpenAI Secrets\n");
70
71 let api_key = prompt_password_input("OpenAI API Key (required)")?;
72
73 let organization = prompt_text_input("Organization ID (optional, press Enter to skip)", None)?;
74
75 let project = prompt_text_input("Project ID (optional, press Enter to skip)", None)?;
76
77 let secret = OpenAISecret {
78 api_key,
79 organization: if organization.is_empty() {
80 None
81 } else {
82 Some(organization)
83 },
84 project: if project.is_empty() {
85 None
86 } else {
87 Some(project)
88 },
89 };
90
91 secret.save()?;
92 println!("\nā
OpenAI secrets saved successfully");
93 Ok(())
94}
95
96fn configure_anthropic_secret() -> DoumResult<()> {
97 println!("\nš Configure Anthropic Secrets\n");
98
99 let api_key = prompt_password_input("Anthropic API Key (required)")?;
100
101 let secret = AnthropicSecret { api_key };
102
103 secret.save()?;
104 println!("\nā
Anthropic secrets saved successfully");
105 Ok(())
106}