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