agent_sdk_provider/
auth.rs1use std::{env, fmt};
2
3use agent_sdk_core::AgentError;
4
5use crate::error::host_configuration_needed;
6
7#[derive(Clone, Eq, PartialEq)]
8pub struct ProviderApiKey {
14 value: String,
15 source: ProviderSecretSource,
16}
17
18impl ProviderApiKey {
19 pub fn new(value: impl Into<String>) -> Result<Self, AgentError> {
21 let value = value.into();
22 if value.trim().is_empty() {
23 return Err(host_configuration_needed(
24 "provider API key must not be empty",
25 ));
26 }
27 Ok(Self {
28 value,
29 source: ProviderSecretSource::Direct,
30 })
31 }
32
33 pub fn from_env(env_var: impl Into<String>) -> Result<Self, AgentError> {
35 let env_var = env_var.into();
36 let value = env::var(&env_var).map_err(|_| {
37 host_configuration_needed(format!(
38 "missing provider API key environment variable {env_var}"
39 ))
40 })?;
41 if value.trim().is_empty() {
42 return Err(host_configuration_needed(format!(
43 "provider API key environment variable {env_var} is empty"
44 )));
45 }
46 Ok(Self {
47 value,
48 source: ProviderSecretSource::Env(env_var),
49 })
50 }
51
52 pub(crate) fn expose_secret(&self) -> &str {
53 &self.value
54 }
55
56 pub fn source_label(&self) -> &str {
58 match &self.source {
59 ProviderSecretSource::Direct => "direct",
60 ProviderSecretSource::Env(env_var) => env_var.as_str(),
61 }
62 }
63}
64
65impl fmt::Debug for ProviderApiKey {
66 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
67 formatter
68 .debug_struct("ProviderApiKey")
69 .field("source", &self.source)
70 .field("value", &"<redacted>")
71 .finish()
72 }
73}
74
75#[derive(Clone, Eq, PartialEq)]
76enum ProviderSecretSource {
77 Direct,
78 Env(String),
79}
80
81impl fmt::Debug for ProviderSecretSource {
82 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
83 match self {
84 Self::Direct => formatter.write_str("direct"),
85 Self::Env(env_var) => formatter.debug_tuple("env").field(env_var).finish(),
86 }
87 }
88}