use std::{fmt, time::Duration};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ProviderKind {
OpenAiCompatible,
OpenAi,
Anthropic,
}
impl ProviderKind {
pub const fn as_str(self) -> &'static str {
match self {
Self::OpenAiCompatible => "openai_compatible",
Self::OpenAi => "openai",
Self::Anthropic => "anthropic",
}
}
}
#[derive(Clone, PartialEq, Eq)]
pub struct SecretString(String);
impl SecretString {
pub fn new(value: impl Into<String>) -> Self {
Self(value.into())
}
pub fn from_env(name: impl AsRef<str>) -> Result<Self, std::env::VarError> {
std::env::var(name.as_ref()).map(Self)
}
pub fn expose(&self) -> &str {
&self.0
}
pub(crate) fn is_blank(&self) -> bool {
self.0.trim().is_empty()
}
pub(crate) fn contains_whitespace(&self) -> bool {
self.0.chars().any(char::is_whitespace)
}
}
impl fmt::Debug for SecretString {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("SecretString([redacted])")
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ProviderAuth {
Bearer(SecretString),
Header { name: String, value: SecretString },
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum OpenAiCompatibleProtocol {
OpenAiCompatible,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct OpenAiAdapterConfig {
pub api_key: SecretString,
pub base_url: Option<String>,
pub timeout: Option<Duration>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct AnthropicAdapterConfig {
pub api_key: SecretString,
pub base_url: Option<String>,
pub version: Option<String>,
pub timeout: Option<Duration>,
}
#[derive(Clone, PartialEq, Eq)]
pub struct OpenAiCompatibleAdapterConfig {
pub base_url: String,
pub auth: ProviderAuth,
pub protocol: OpenAiCompatibleProtocol,
pub static_headers: Vec<(String, String)>,
pub correlation_header: Option<String>,
pub timeout: Option<Duration>,
}
impl fmt::Debug for OpenAiCompatibleAdapterConfig {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let static_headers = self
.static_headers
.iter()
.map(|(name, _)| (name, "[redacted]"))
.collect::<Vec<_>>();
f.debug_struct("OpenAiCompatibleAdapterConfig")
.field("base_url", &self.base_url)
.field("auth", &self.auth)
.field("protocol", &self.protocol)
.field("static_headers", &static_headers)
.field("correlation_header", &self.correlation_header)
.field("timeout", &self.timeout)
.finish()
}
}