use serde::{Deserialize, Serialize};
use crate::client::http::{HttpClientConfig, http_client_with_config, parse_api_error_response};
pub mod request;
pub mod response;
pub use request::*;
pub use response::*;
pub const AGENT_API_URL: &str = "https://open.bigmodel.cn/api/paas/v4/agents";
pub struct AgentClient {
api_key: String,
base_url: String,
http_config: HttpClientConfig,
client: reqwest::Client,
}
impl AgentClient {
pub fn new(api_key: impl Into<String>) -> Self {
let config = HttpClientConfig::default();
let client = http_client_with_config(&config);
Self {
api_key: api_key.into(),
base_url: AGENT_API_URL.to_string(),
http_config: config,
client,
}
}
pub fn with_base_url(mut self, base_url: impl Into<String>) -> Self {
self.base_url = base_url.into();
self
}
pub fn with_http_config(mut self, config: HttpClientConfig) -> Self {
self.client = http_client_with_config(&config);
self.http_config = config;
self
}
pub async fn create_agent(
&self,
request: AgentCreateRequest,
) -> crate::ZaiResult<AgentCreateResponse> {
self.send_request(&self.base_url, &request).await
}
pub async fn get_agent(&self, agent_id: &str) -> crate::ZaiResult<AgentDetails> {
let url = format!("{}/{}", self.base_url, agent_id);
self.send_get_request(&url).await
}
pub async fn update_agent(
&self,
agent_id: &str,
request: AgentUpdateRequest,
) -> crate::ZaiResult<AgentUpdateResponse> {
let url = format!("{}/{}", self.base_url, agent_id);
self.send_request(&url, &request).await
}
pub async fn delete_agent(&self, agent_id: &str) -> crate::ZaiResult<AgentDeleteResponse> {
let url = format!("{}/{}", self.base_url, agent_id);
let response = self
.client
.delete(&url)
.bearer_auth(&self.api_key)
.send()
.await?;
if response.status().is_success() {
Ok(response.json().await?)
} else {
let status = response.status().as_u16();
let body = response.text().await.unwrap_or_default();
Err(parse_api_error_response(status, body))
}
}
pub async fn chat(
&self,
agent_id: &str,
request: AgentChatRequest,
) -> crate::ZaiResult<AgentChatResponse> {
let url = format!("{}/{}/chat", self.base_url, agent_id);
self.send_request(&url, &request).await
}
pub async fn get_history(
&self,
agent_id: &str,
limit: Option<u32>,
) -> crate::ZaiResult<ConversationHistory> {
let mut url = format!("{}/{}/history", self.base_url, agent_id);
if let Some(l) = limit {
url.push_str(&format!("?limit={}", l));
}
self.send_get_request(&url).await
}
async fn send_request<T: Serialize, R: for<'de> Deserialize<'de>>(
&self,
url: &str,
body: &T,
) -> crate::ZaiResult<R> {
let response = self
.client
.post(url)
.bearer_auth(&self.api_key)
.header("Content-Type", "application/json")
.json(body)
.send()
.await?;
if response.status().is_success() {
Ok(response.json().await?)
} else {
let status = response.status().as_u16();
let body = response.text().await.unwrap_or_default();
Err(parse_api_error_response(status, body))
}
}
async fn send_get_request<R: for<'de> Deserialize<'de>>(
&self,
url: &str,
) -> crate::ZaiResult<R> {
let response = self
.client
.get(url)
.bearer_auth(&self.api_key)
.send()
.await?;
if response.status().is_success() {
Ok(response.json().await?)
} else {
let status = response.status().as_u16();
let body = response.text().await.unwrap_or_default();
Err(parse_api_error_response(status, body))
}
}
}