use crate::core::{HttpClient, Protocol};
use crate::protocols::AnthropicProtocol;
use crate::error::LlmConnectorError;
use std::collections::HashMap;
#[derive(Clone, Debug)]
pub struct LongCatAnthropicProtocol {
inner: AnthropicProtocol,
api_key: String,
}
impl LongCatAnthropicProtocol {
pub fn new(api_key: &str) -> Self {
Self {
inner: AnthropicProtocol::new(api_key),
api_key: api_key.to_string(),
}
}
}
#[async_trait::async_trait]
impl Protocol for LongCatAnthropicProtocol {
type Request = <AnthropicProtocol as Protocol>::Request;
type Response = <AnthropicProtocol as Protocol>::Response;
fn name(&self) -> &str {
"longcat-anthropic"
}
fn chat_endpoint(&self, base_url: &str) -> String {
self.inner.chat_endpoint(base_url)
}
fn build_request(&self, request: &crate::types::ChatRequest) -> Result<Self::Request, LlmConnectorError> {
self.inner.build_request(request)
}
fn parse_response(&self, response: &str) -> Result<crate::types::ChatResponse, LlmConnectorError> {
self.inner.parse_response(response)
}
fn map_error(&self, status: u16, message: &str) -> LlmConnectorError {
self.inner.map_error(status, message)
}
fn auth_headers(&self) -> Vec<(String, String)> {
vec![
("Authorization".to_string(), format!("Bearer {}", self.api_key)),
("anthropic-version".to_string(), "2023-06-01".to_string()),
]
}
#[cfg(feature = "streaming")]
async fn parse_stream_response(&self, response: reqwest::Response) -> Result<crate::types::ChatStream, LlmConnectorError> {
self.inner.parse_stream_response(response).await
}
}
pub type LongCatAnthropicProvider = crate::core::GenericProvider<LongCatAnthropicProtocol>;
pub fn longcat_anthropic(api_key: &str) -> Result<LongCatAnthropicProvider, LlmConnectorError> {
longcat_anthropic_with_config(api_key, None, None, None)
}
pub fn longcat_anthropic_with_config(
api_key: &str,
base_url: Option<&str>,
timeout_secs: Option<u64>,
proxy: Option<&str>,
) -> Result<LongCatAnthropicProvider, LlmConnectorError> {
let protocol = LongCatAnthropicProtocol::new(api_key);
let client = HttpClient::with_config(
base_url.unwrap_or("https://api.longcat.chat/anthropic"),
timeout_secs,
proxy,
)?;
let auth_headers: HashMap<String, String> = protocol.auth_headers().into_iter().collect();
let client = client.with_headers(auth_headers);
Ok(crate::core::GenericProvider::new(protocol, client))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_longcat_anthropic() {
let provider = longcat_anthropic("ak_test");
assert!(provider.is_ok());
}
#[test]
fn test_longcat_anthropic_with_config() {
let provider = longcat_anthropic_with_config(
"ak_test",
Some("https://custom.url"),
Some(60),
None
);
assert!(provider.is_ok());
}
#[test]
fn test_longcat_anthropic_protocol_auth_headers() {
let protocol = LongCatAnthropicProtocol::new("ak_test123");
let headers = protocol.auth_headers();
assert!(headers.iter().any(|(k, v)| k == "Authorization" && v == "Bearer ak_test123"));
assert!(headers.iter().any(|(k, v)| k == "anthropic-version" && v == "2023-06-01"));
assert!(!headers.iter().any(|(k, _)| k == "x-api-key"));
}
}