use crate::error::{LlmError, Result};
#[derive(Debug, Clone)]
pub struct OpenAIConfig {
pub api_key: String,
pub base_url: String,
pub model: String,
pub organization: Option<String>,
pub timeout_secs: Option<u64>,
}
impl OpenAIConfig {
pub const DEFAULT_BASE_URL: &'static str = "https://api.openai.com/v1";
pub const DEFAULT_MODEL: &'static str = "gpt-4o";
#[must_use]
pub fn new(api_key: impl Into<String>) -> Self {
Self {
api_key: api_key.into(),
base_url: Self::DEFAULT_BASE_URL.to_owned(),
model: Self::DEFAULT_MODEL.to_owned(),
organization: None,
timeout_secs: Some(120),
}
}
pub fn from_env() -> Result<Self> {
let api_key = std::env::var("OPENAI_API_KEY")
.map_err(|_| LlmError::auth("openai", "OPENAI_API_KEY environment variable not set"))?;
let base_url =
std::env::var("OPENAI_BASE_URL").unwrap_or_else(|_| Self::DEFAULT_BASE_URL.to_owned());
let model =
std::env::var("OPENAI_MODEL").unwrap_or_else(|_| Self::DEFAULT_MODEL.to_owned());
let organization = std::env::var("OPENAI_ORGANIZATION").ok();
Ok(Self {
api_key,
base_url,
model,
organization,
timeout_secs: Some(120),
})
}
#[must_use]
pub fn base_url(mut self, url: impl Into<String>) -> Self {
self.base_url = url.into();
self
}
#[must_use]
pub fn model(mut self, model: impl Into<String>) -> Self {
self.model = model.into();
self
}
#[must_use]
pub fn organization(mut self, org: impl Into<String>) -> Self {
self.organization = Some(org.into());
self
}
#[must_use]
pub const fn timeout(mut self, secs: u64) -> Self {
self.timeout_secs = Some(secs);
self
}
#[must_use]
pub fn azure(endpoint: impl Into<String>, api_key: impl Into<String>) -> Self {
Self {
api_key: api_key.into(),
base_url: endpoint.into(),
model: "gpt-4o".to_owned(),
organization: None,
timeout_secs: Some(120),
}
}
}
impl Default for OpenAIConfig {
fn default() -> Self {
Self {
api_key: String::new(),
base_url: Self::DEFAULT_BASE_URL.to_owned(),
model: Self::DEFAULT_MODEL.to_owned(),
organization: None,
timeout_secs: Some(120),
}
}
}