kalosm_language_model/claude/
mod.rsuse std::sync::OnceLock;
use thiserror::Error;
mod chat;
pub use chat::*;
#[derive(Debug, Clone)]
pub struct AnthropicCompatibleClient {
reqwest_client: reqwest::Client,
base_url: String,
api_key: Option<String>,
resolved_api_key: OnceLock<String>,
version: String,
}
impl Default for AnthropicCompatibleClient {
fn default() -> Self {
Self::new()
}
}
impl AnthropicCompatibleClient {
pub fn new() -> Self {
Self {
reqwest_client: reqwest::Client::new(),
base_url: "https://api.anthropic.com/v1/".to_string(),
resolved_api_key: OnceLock::new(),
api_key: None,
version: "2023-06-01".to_string(),
}
}
pub fn with_api_key(mut self, api_key: impl ToString) -> Self {
self.api_key = Some(api_key.to_string());
self
}
pub fn with_base_url(mut self, base_url: impl ToString) -> Self {
self.base_url = base_url.to_string();
self
}
pub fn with_anthropic_version(mut self, version: impl ToString) -> Self {
self.version = version.to_string();
self
}
pub fn with_reqwest_client(mut self, client: reqwest::Client) -> Self {
self.reqwest_client = client;
self
}
pub fn resolve_api_key(&self) -> Result<String, NoAnthropicAPIKeyError> {
if let Some(api_key) = self.resolved_api_key.get() {
return Ok(api_key.clone());
}
let anthropic_api_key = match self.api_key.clone() {
Some(api_key) => api_key,
None => std::env::var("ANTHROPIC_API_KEY").map_err(|_| NoAnthropicAPIKeyError)?,
};
self.resolved_api_key
.set(anthropic_api_key.clone())
.unwrap();
Ok(anthropic_api_key)
}
pub(crate) fn base_url(&self) -> &str {
self.base_url.trim_end_matches('/')
}
pub(crate) fn version(&self) -> &str {
&self.version
}
}
#[derive(Debug, Error)]
#[error("No API key was provided in the [AnthropicCompatibleClient] builder or the environment variable `ANTHROPIC_API_KEY` was not set")]
pub struct NoAnthropicAPIKeyError;