use agent_registry_contract::{
Agent, AgentId, AgentPage, CreateAgentRequest, ListAgentsRequest, PUBLIC_AGENT_PATH,
PUBLIC_AGENTS_PATH, UpdateAgentRequest,
};
use reqwest::{Client, Url};
use crate::transport::{
CallOptions, ClientOptions, HttpTransport, InfraClientError, ServiceEndpoint,
};
#[derive(Clone, Debug)]
pub struct AgentClient {
transport: HttpTransport,
}
impl AgentClient {
#[doc(hidden)]
pub fn new_for_gateway_upstream(http: Client, base_url: impl Into<String>) -> Self {
Self::new_with_endpoint(
http,
ServiceEndpoint::new(base_url),
ClientOptions::default(),
)
}
pub(crate) fn new_with_endpoint(
http: Client,
endpoint: ServiceEndpoint,
options: ClientOptions,
) -> Self {
let endpoint = endpoint.with_default_credential_audience(agent_registry_contract::AUDIENCE);
Self {
transport: HttpTransport::new_with_options(
http,
agent_registry_contract::SERVICE_NAME,
endpoint,
options,
),
}
}
pub async fn create(&self, request: &CreateAgentRequest) -> Result<Agent, InfraClientError> {
self.transport.post_json(PUBLIC_AGENTS_PATH, request).await
}
pub async fn get(&self, agent_id: &AgentId) -> Result<Agent, InfraClientError> {
self.transport
.get_json(&PUBLIC_AGENT_PATH.replace("{agent_id}", agent_id.as_str()))
.await
}
pub async fn list(&self, request: &ListAgentsRequest) -> Result<AgentPage, InfraClientError> {
let mut url = Url::parse("http://agent-registry.invalid").expect("static URL is valid");
{
let mut query = url.query_pairs_mut();
if let Some(status) = request.status {
query.append_pair(
"status",
match status {
agent_registry_contract::AgentStatus::Active => "active",
agent_registry_contract::AgentStatus::Archived => "archived",
},
);
}
if let Some(agent_id) = &request.related_agent_id {
query.append_pair("relatedAgentId", agent_id.as_str());
}
if let Some(runtime_id) = &request.related_runtime_id {
query.append_pair("relatedRuntimeId", runtime_id);
}
if let Some(user_id) = &request.related_user_id {
query.append_pair("relatedUserId", user_id);
}
if let Some(cursor) = &request.cursor {
query.append_pair("cursor", cursor);
}
if let Some(limit) = request.limit {
query.append_pair("limit", &limit.to_string());
}
}
let path = match url.query() {
Some(query) if !query.is_empty() => format!("{PUBLIC_AGENTS_PATH}?{query}"),
_ => PUBLIC_AGENTS_PATH.to_string(),
};
self.transport.get_json(&path).await
}
pub async fn update(
&self,
agent_id: &AgentId,
request: &UpdateAgentRequest,
) -> Result<Agent, InfraClientError> {
self.transport
.patch_json_with_options(
&PUBLIC_AGENT_PATH.replace("{agent_id}", agent_id.as_str()),
request,
CallOptions::default().idempotent(true),
)
.await
}
}