1use crate::llm::{AnthropicSecret, OpenAISecret};
2use crate::system::SecretManager;
3use anyhow::Result;
4use std::collections::HashMap;
5
6pub struct SecretField {
7 pub name: String,
8 pub label: String,
9 pub required: bool,
10 pub is_password: bool,
11}
12
13pub struct SecretConfigData {
14 pub provider: String,
15 pub fields: Vec<SecretField>,
16}
17
18pub struct SecretService;
19
20impl SecretService {
21 pub fn get_provider_config(provider: &str) -> Result<SecretConfigData> {
23 match provider {
24 "openai" => Ok(SecretConfigData {
25 provider: "openai".to_string(),
26 fields: vec![
27 SecretField {
28 name: "api_key".to_string(),
29 label: "OpenAI API Key (required)".to_string(),
30 required: true,
31 is_password: true,
32 },
33 SecretField {
34 name: "organization".to_string(),
35 label: "Organization ID (optional, press Enter to skip)".to_string(),
36 required: false,
37 is_password: false,
38 },
39 SecretField {
40 name: "project".to_string(),
41 label: "Project ID (optional, press Enter to skip)".to_string(),
42 required: false,
43 is_password: false,
44 },
45 ],
46 }),
47 "anthropic" => Ok(SecretConfigData {
48 provider: "anthropic".to_string(),
49 fields: vec![SecretField {
50 name: "api_key".to_string(),
51 label: "Anthropic API Key (required)".to_string(),
52 required: true,
53 is_password: true,
54 }],
55 }),
56 _ => anyhow::bail!("Unknown provider: {}", provider),
57 }
58 }
59
60 pub fn save_secrets(provider: &str, values: HashMap<String, String>) -> Result<()> {
62 match provider {
63 "openai" => {
64 let secret = OpenAISecret {
65 api_key: values
66 .get("api_key")
67 .ok_or_else(|| anyhow::anyhow!("API key is required"))?
68 .clone(),
69 organization: values
70 .get("organization")
71 .cloned()
72 .filter(|s| !s.is_empty()),
73 project: values.get("project").cloned().filter(|s| !s.is_empty()),
74 };
75 SecretManager::save("openai", &secret)
76 }
77 "anthropic" => {
78 let secret = AnthropicSecret {
79 api_key: values
80 .get("api_key")
81 .ok_or_else(|| anyhow::anyhow!("API key is required"))?
82 .clone(),
83 };
84 SecretManager::save("anthropic", &secret)
85 }
86 _ => anyhow::bail!("Unknown provider: {}", provider),
87 }
88 }
89
90 pub fn list_providers() -> Vec<String> {
92 vec!["openai".to_string(), "anthropic".to_string()]
93 }
94}