uarp-sdk 0.5.7

Async Rust client for the UARP (Snaga) Universal Agent Runtime Platform API
Documentation
// Code generated by @uarp/codegen from spec/openapi.json. DO NOT EDIT.
//!
//! Local agent bridge for Snaga desktop connections

#![allow(unused_imports, clippy::too_many_arguments)]

use reqwest::Method;
use serde::{Deserialize, Serialize};

use crate::client::{Client, Request, NO_BODY, NO_QUERY};
use crate::error::Result;
use crate::generated::models;
use crate::multipart::{field_text, FilePart};
use crate::util::encode_path;

/// Query and header parameters for `bridgePoll`.
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub struct BridgePollParams {
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub agent_id: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub machine_id: Option<String>,
    /// Server-side long-poll timeout override (ms).
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub timeout: Option<i64>,
}

/// Query and header parameters for `getBridgeTaskApproval`.
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub struct GetBridgeTaskApprovalParams {
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub approval_id: Option<String>,
}

/// Local agent bridge for Snaga desktop connections
#[derive(Debug, Clone)]
pub struct BridgeApi {
    pub(crate) client: Client,
}

impl Client {
    /// Local agent bridge for Snaga desktop connections
    pub fn bridge(&self) -> BridgeApi {
        BridgeApi { client: self.clone() }
    }
}

impl BridgeApi {
    /// Delegate task to bridge agent
    ///
    /// `POST /api/v1/bridge/delegate`
    pub async fn bridge_delegate(&self, body: &models::BridgeDelegateRequest) -> Result<models::BridgeDelegateResponse> {
        self.client
            .request_json(Request {
                method: Method::POST,
                path: "/api/v1/bridge/delegate".to_string(),
                query: NO_QUERY,
                body: Some(body),
                headers: Vec::new(),
                idempotent: true,
            })
            .await
    }

    /// Deregister bridge agent
    ///
    /// `POST /api/v1/bridge/deregister`
    pub async fn bridge_deregister(&self, body: &models::BridgeDeregisterRequest) -> Result<models::BridgeDeregisterResponse> {
        self.client
            .request_json(Request {
                method: Method::POST,
                path: "/api/v1/bridge/deregister".to_string(),
                query: NO_QUERY,
                body: Some(body),
                headers: Vec::new(),
                idempotent: true,
            })
            .await
    }

    /// Bridge heartbeat
    ///
    /// Idempotent liveness ping for the bridge connection. **404 on missing connection is
    /// intentional** — drives the client to re-register rather than reusing a stale identity.
    ///
    /// `POST /api/v1/bridge/heartbeat`
    pub async fn bridge_heartbeat(&self, body: &models::BridgeHeartbeatRequest) -> Result<models::BridgeHeartbeatResponse> {
        self.client
            .request_json(Request {
                method: Method::POST,
                path: "/api/v1/bridge/heartbeat".to_string(),
                query: NO_QUERY,
                body: Some(body),
                headers: Vec::new(),
                idempotent: true,
            })
            .await
    }

    /// Long-poll for pending bridge tasks
    ///
    /// Long-poll up to platform-configured `POLL_TIMEOUT_MS`. Returns 200 with tasks if any are
    /// pending, or 204 No Content on timeout (client should re-poll immediately).
    ///
    /// `GET /api/v1/bridge/poll`
    pub async fn bridge_poll(&self, params: &BridgePollParams) -> Result<models::BridgePollResponse> {
        self.client
            .request_json(Request {
                method: Method::GET,
                path: "/api/v1/bridge/poll".to_string(),
                query: Some(params),
                body: NO_BODY,
                headers: Vec::new(),
                idempotent: false,
            })
            .await
    }

    /// Register bridge agent (Snaga CLI handshake)
    ///
    /// Registers a long-lived bridge agent for the calling tenant. Returns 201 on first
    /// registration, 200 on reconnect of an existing machine_id. Tenant-scoped only — no scope
    /// enforcement.
    ///
    /// `POST /api/v1/bridge/register`
    pub async fn bridge_register(&self, body: &models::BridgeRegisterRequest) -> Result<models::BridgeRegisterResponse> {
        self.client
            .request_json(Request {
                method: Method::POST,
                path: "/api/v1/bridge/register".to_string(),
                query: NO_QUERY,
                body: Some(body),
                headers: Vec::new(),
                idempotent: true,
            })
            .await
    }

    /// Get bridge connection status
    ///
    /// `GET /api/v1/bridge/status`
    pub async fn bridge_status(&self) -> Result<models::BridgeStatusResponse> {
        self.client
            .request_json(Request {
                method: Method::GET,
                path: "/api/v1/bridge/status".to_string(),
                query: NO_QUERY,
                body: NO_BODY,
                headers: Vec::new(),
                idempotent: false,
            })
            .await
    }

    /// Bridge WebSocket upgrade endpoint for the Snaga CLI
    ///
    /// WebSocket upgrade. Long-lived bidirectional channel between a `snaga serve` CLI and the
    /// platform. Server delivers tasks, client streams capabilities and tool results. Auth via
    /// `Sec-WebSocket-Protocol: uarp.\<base64(api_key)\>` subprotocol.
    ///
    /// `GET /api/v1/bridge/ws`
    pub async fn bridge_web_socket(&self) -> Result<serde_json::Value> {
        self.client
            .request_json(Request {
                method: Method::GET,
                path: "/api/v1/bridge/ws".to_string(),
                query: NO_QUERY,
                body: NO_BODY,
                headers: Vec::new(),
                idempotent: false,
            })
            .await
    }

    /// Get approval status
    ///
    /// `GET /api/v1/bridge/tasks/{taskId}/approval`
    pub async fn get_bridge_task_approval(&self, task_id: &str, params: &GetBridgeTaskApprovalParams) -> Result<models::GetBridgeTaskApprovalResponse> {
        self.client
            .request_json(Request {
                method: Method::GET,
                path: format!("/api/v1/bridge/tasks/{}/approval", encode_path(task_id)),
                query: Some(params),
                body: NO_BODY,
                headers: Vec::new(),
                idempotent: false,
            })
            .await
    }

    /// List bridge agents
    ///
    /// `GET /api/v1/bridge/agents`
    pub async fn list_bridge_agents(&self) -> Result<Vec<models::BridgeConnection>> {
        self.client
            .request_json(Request {
                method: Method::GET,
                path: "/api/v1/bridge/agents".to_string(),
                query: NO_QUERY,
                body: NO_BODY,
                headers: Vec::new(),
                idempotent: false,
            })
            .await
    }

    /// Push task events
    ///
    /// `POST /api/v1/bridge/tasks/{taskId}/events`
    pub async fn push_bridge_task_events(&self, task_id: &str, body: &Vec<serde_json::Map<String, serde_json::Value>>) -> Result<models::PushBridgeTaskEventsResponse> {
        self.client
            .request_json(Request {
                method: Method::POST,
                path: format!("/api/v1/bridge/tasks/{}/events", encode_path(task_id)),
                query: NO_QUERY,
                body: Some(body),
                headers: Vec::new(),
                idempotent: true,
            })
            .await
    }

    /// Update agent capabilities
    ///
    /// `POST /api/v1/bridge/agents/{agentId}/capability`
    pub async fn update_bridge_agent_capability(&self, agent_id: &str, body: &models::UpdateBridgeAgentCapabilityRequest) -> Result<models::UpdateBridgeAgentCapabilityResponse> {
        self.client
            .request_json(Request {
                method: Method::POST,
                path: format!("/api/v1/bridge/agents/{}/capability", encode_path(agent_id)),
                query: NO_QUERY,
                body: Some(body),
                headers: Vec::new(),
                idempotent: true,
            })
            .await
    }
}