systemprompt_cli/commands/cloud/profile/
api_keys.rs1use anyhow::{Result, bail};
7use systemprompt_logging::CliService;
8
9use crate::interactive::Prompter;
10
11#[derive(Debug)]
12pub struct ApiKeys {
13 pub gemini: Option<String>,
14 pub anthropic: Option<String>,
15 pub openai: Option<String>,
16}
17
18impl ApiKeys {
19 pub fn from_options(
20 gemini: Option<String>,
21 anthropic: Option<String>,
22 openai: Option<String>,
23 ) -> Result<Self> {
24 if gemini.is_none() && anthropic.is_none() && openai.is_none() {
25 bail!(
26 "At least one AI provider API key is required.\nProvide: --anthropic-key, \
27 --openai-key, or --gemini-key"
28 );
29 }
30 Ok(Self {
31 gemini,
32 anthropic,
33 openai,
34 })
35 }
36
37 pub const fn selected_provider(&self) -> &'static str {
38 if self.anthropic.is_some() {
39 "anthropic"
40 } else if self.openai.is_some() {
41 "openai"
42 } else if self.gemini.is_some() {
43 "gemini"
44 } else {
45 "anthropic"
46 }
47 }
48}
49
50pub fn collect_api_keys(prompter: &dyn Prompter) -> Result<ApiKeys> {
51 CliService::info("At least one AI provider API key is required.");
52
53 let providers = vec![
54 "Google AI (Gemini) - https://aistudio.google.com/app/apikey".to_owned(),
55 "Anthropic (Claude) - https://console.anthropic.com/api-keys".to_owned(),
56 "OpenAI (GPT) - https://platform.openai.com/api-keys".to_owned(),
57 ];
58
59 let selection = prompter.select("Select your AI provider", &providers)?;
60
61 match selection {
62 0 => {
63 let key = prompter.password("Gemini API Key")?;
64 if key.is_empty() {
65 bail!("API key is required");
66 }
67 Ok(ApiKeys {
68 gemini: Some(key),
69 anthropic: None,
70 openai: None,
71 })
72 },
73 1 => {
74 let key = prompter.password("Anthropic API Key")?;
75 if key.is_empty() {
76 bail!("API key is required");
77 }
78 Ok(ApiKeys {
79 gemini: None,
80 anthropic: Some(key),
81 openai: None,
82 })
83 },
84 2 => {
85 let key = prompter.password("OpenAI API Key")?;
86 if key.is_empty() {
87 bail!("API key is required");
88 }
89 Ok(ApiKeys {
90 gemini: None,
91 anthropic: None,
92 openai: Some(key),
93 })
94 },
95 _ => bail!("Invalid selection"),
96 }
97}