use serde::{Deserialize, Serialize};
use crate::client::{
endpoints::{ApiBase, EndpointConfig, build_query, join_url, paths},
http::{HttpClientConfig, parse_typed_response, send_empty_request, send_json_request},
};
pub mod request;
pub mod response;
pub use request::*;
pub use response::*;
pub const AGENT_API_PATH: &str = paths::AGENTS;
pub struct AgentClient {
api_key: String,
endpoint_config: EndpointConfig,
api_base: ApiBase,
http_config: HttpClientConfig,
}
impl AgentClient {
pub fn new(api_key: impl Into<String>) -> Self {
let config = HttpClientConfig::default();
Self {
api_key: api_key.into(),
endpoint_config: EndpointConfig::default(),
api_base: ApiBase::PaasV4,
http_config: config,
}
}
pub fn with_base_url(mut self, base_url: impl Into<String>) -> Self {
self.api_base = ApiBase::Custom(base_url.into());
self
}
pub fn with_endpoint_config(mut self, endpoint_config: EndpointConfig) -> Self {
self.endpoint_config = endpoint_config;
self
}
pub fn with_http_config(mut self, config: HttpClientConfig) -> Self {
self.http_config = config;
self
}
fn url(&self, path: &str) -> String {
self.endpoint_config.url(&self.api_base, path)
}
pub async fn create_agent(
&self,
request: AgentCreateRequest,
) -> crate::ZaiResult<AgentCreateResponse> {
self.send_request(&self.url(paths::AGENTS), &request).await
}
pub async fn get_agent(&self, agent_id: &str) -> crate::ZaiResult<AgentDetails> {
let url = self.url(&join_url(paths::AGENTS, agent_id));
self.send_get_request(&url).await
}
pub async fn update_agent(
&self,
agent_id: &str,
request: AgentUpdateRequest,
) -> crate::ZaiResult<AgentUpdateResponse> {
let url = self.url(&join_url(paths::AGENTS, agent_id));
self.send_request(&url, &request).await
}
pub async fn delete_agent(&self, agent_id: &str) -> crate::ZaiResult<AgentDeleteResponse> {
let url = self.url(&join_url(paths::AGENTS, agent_id));
let response = send_empty_request(
reqwest::Method::DELETE,
url,
&self.api_key,
std::sync::Arc::new(self.http_config.clone()),
)
.await?;
parse_typed_response::<AgentDeleteResponse>(response).await
}
pub async fn chat(
&self,
agent_id: &str,
request: AgentChatRequest,
) -> crate::ZaiResult<AgentChatResponse> {
let url = self.url(&join_url(&join_url(paths::AGENTS, agent_id), "chat"));
self.send_request(&url, &request).await
}
pub async fn get_history(
&self,
agent_id: &str,
limit: Option<u32>,
) -> crate::ZaiResult<ConversationHistory> {
let base = self.url(&join_url(&join_url(paths::AGENTS, agent_id), "history"));
let url = match limit {
Some(l) => build_query(&base, [("limit", l.to_string())]),
None => base,
};
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 = send_json_request(
reqwest::Method::POST,
url.to_string(),
&self.api_key,
body,
std::sync::Arc::new(self.http_config.clone()),
)
.await?;
parse_typed_response::<R>(response).await
}
async fn send_get_request<R: for<'de> Deserialize<'de>>(
&self,
url: &str,
) -> crate::ZaiResult<R> {
let response = send_empty_request(
reqwest::Method::GET,
url.to_string(),
&self.api_key,
std::sync::Arc::new(self.http_config.clone()),
)
.await?;
parse_typed_response::<R>(response).await
}
}