agent-infra-sdk 0.1.1

Gateway-backed Rust SDK for Agent Infra APIs
Documentation
//! Typed Agent Registry client.

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 {
    /// Internal Gateway upstream constructor.
    #[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
    }
}