use crate::api::anthropic::wire::{BETA_HEADER_NAME, anthropic_beta_for, prepare_request};
use crate::api::types::{CreateMessageRequest, CreateMessageResponse};
use crate::api::utils;
use crate::error::{Result, SofosError};
use reqwest::header::{HeaderMap, HeaderValue};
pub(super) const ANTHROPIC_API_BASE: &str = "https://api.anthropic.com/v1";
#[derive(Clone)]
pub struct AnthropicClient {
pub(super) client: reqwest::Client,
}
const ANTHROPIC_API_VERSION: &str = "2023-06-01";
impl AnthropicClient {
pub fn new(api_key: String) -> Result<Self> {
let mut headers = HeaderMap::new();
headers.insert(
"x-api-key",
HeaderValue::from_str(&api_key)
.map_err(|e| SofosError::Config(format!("Invalid API key format: {}", e)))?,
);
headers.insert(
"anthropic-version",
HeaderValue::from_static(ANTHROPIC_API_VERSION),
);
let client = utils::build_http_client(headers, utils::REQUEST_TIMEOUT)?;
Ok(Self { client })
}
pub async fn check_connectivity(&self) -> Result<()> {
utils::check_api_connectivity(
&self.client,
ANTHROPIC_API_BASE,
"Anthropic",
"https://status.anthropic.com",
)
.await
}
pub async fn create_message(
&self,
request: CreateMessageRequest,
) -> Result<CreateMessageResponse> {
let url = format!("{}/messages", ANTHROPIC_API_BASE);
let request = prepare_request(request);
let beta = anthropic_beta_for(&request.model);
let response = utils::send_once(
"Anthropic",
self.client
.post(&url)
.header(BETA_HEADER_NAME, beta)
.json(&request),
)
.await?;
let result = response.json::<CreateMessageResponse>().await?;
Ok(result)
}
}