feat(keyring): 集成系统密钥环安全存储 API key
This commit is contained in:
@@ -57,48 +57,50 @@ impl Default for LlmClientConfig {
|
||||
}
|
||||
|
||||
impl LlmClient {
|
||||
/// Create LLM client from configuration
|
||||
pub async fn from_config(config: &crate::config::LlmConfig) -> Result<Self> {
|
||||
/// Create LLM client from configuration manager
|
||||
pub async fn from_config(manager: &crate::config::manager::ConfigManager) -> Result<Self> {
|
||||
let config = manager.config();
|
||||
let client_config = LlmClientConfig {
|
||||
max_tokens: config.max_tokens,
|
||||
temperature: config.temperature,
|
||||
timeout: Duration::from_secs(config.timeout),
|
||||
max_tokens: config.llm.max_tokens,
|
||||
temperature: config.llm.temperature,
|
||||
timeout: Duration::from_secs(config.llm.timeout),
|
||||
};
|
||||
|
||||
let provider: Box<dyn LlmProvider> = match config.provider.as_str() {
|
||||
let provider = config.llm.provider.as_str();
|
||||
let model = config.llm.model.as_str();
|
||||
let base_url = manager.llm_base_url();
|
||||
let api_key = manager.get_api_key();
|
||||
|
||||
let provider: Box<dyn LlmProvider> = match provider {
|
||||
"ollama" => {
|
||||
Box::new(OllamaClient::new(&config.ollama.url, &config.ollama.model))
|
||||
Box::new(OllamaClient::new(&base_url, model))
|
||||
}
|
||||
"openai" => {
|
||||
let api_key = config.openai.api_key.as_ref()
|
||||
let key = api_key.as_ref()
|
||||
.ok_or_else(|| anyhow::anyhow!("OpenAI API key not configured"))?;
|
||||
Box::new(OpenAiClient::new(
|
||||
&config.openai.base_url,
|
||||
api_key,
|
||||
&config.openai.model,
|
||||
)?)
|
||||
Box::new(OpenAiClient::new(&base_url, key, model)?)
|
||||
}
|
||||
"anthropic" => {
|
||||
let api_key = config.anthropic.api_key.as_ref()
|
||||
let key = api_key.as_ref()
|
||||
.ok_or_else(|| anyhow::anyhow!("Anthropic API key not configured"))?;
|
||||
Box::new(AnthropicClient::new(api_key, &config.anthropic.model)?)
|
||||
Box::new(AnthropicClient::new(key, model)?)
|
||||
}
|
||||
"kimi" => {
|
||||
let api_key = config.kimi.api_key.as_ref()
|
||||
let key = api_key.as_ref()
|
||||
.ok_or_else(|| anyhow::anyhow!("Kimi API key not configured"))?;
|
||||
Box::new(KimiClient::with_base_url(api_key, &config.kimi.model, &config.kimi.base_url)?)
|
||||
Box::new(KimiClient::with_base_url(key, model, &base_url)?)
|
||||
}
|
||||
"deepseek" => {
|
||||
let api_key = config.deepseek.api_key.as_ref()
|
||||
let key = api_key.as_ref()
|
||||
.ok_or_else(|| anyhow::anyhow!("DeepSeek API key not configured"))?;
|
||||
Box::new(DeepSeekClient::with_base_url(api_key, &config.deepseek.model, &config.deepseek.base_url)?)
|
||||
Box::new(DeepSeekClient::with_base_url(key, model, &base_url)?)
|
||||
}
|
||||
"openrouter" => {
|
||||
let api_key = config.openrouter.api_key.as_ref()
|
||||
let key = api_key.as_ref()
|
||||
.ok_or_else(|| anyhow::anyhow!("OpenRouter API key not configured"))?;
|
||||
Box::new(OpenRouterClient::with_base_url(api_key, &config.openrouter.model, &config.openrouter.base_url)?)
|
||||
Box::new(OpenRouterClient::with_base_url(key, model, &base_url)?)
|
||||
}
|
||||
_ => bail!("Unknown LLM provider: {}", config.provider),
|
||||
_ => bail!("Unknown LLM provider: {}", provider),
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
@@ -1012,3 +1014,10 @@ Gruppieren Sie Commits nach:
|
||||
|
||||
Formatieren Sie in Markdown mit geeigneten Überschriften und Aufzählungspunkten.
|
||||
"#;
|
||||
|
||||
/// Test LLM connection
|
||||
pub async fn test_connection(manager: &crate::config::manager::ConfigManager) -> Result<String> {
|
||||
let client = LlmClient::from_config(manager).await?;
|
||||
let response = client.provider.generate("Say 'Hello, World!'").await?;
|
||||
Ok(response)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user