Skip to main content

noxy_sdk/
lib.rs

1//! SDK for **AI agent runtimes** integrating with the [Noxy](https://noxy.network) **Decision Layer**:
2//! send encrypted, **actionable** decision payloads (tool proposals, approvals, next-step hints) to
3//! registered agent devices over gRPC.
4//!
5//! The wire API is **`agent.proto`** (`noxy.agent.AgentService`): `RouteDecision`, `GetDecisionOutcome`,
6//! `GetQuota`, `GetIdentityDevices`.
7
8pub mod config;
9pub mod decision_outcome;
10pub mod kyber_provider;
11pub mod retries;
12pub mod transport;
13pub mod types;
14
15mod client;
16mod crypto;
17mod services;
18
19pub use client::NoxyAgentClient;
20pub use config::NoxyConfig;
21pub use decision_outcome::{
22    is_terminal_human_outcome, SendDecisionAndWaitNoDecisionIdError, SendDecisionAndWaitOptions,
23    WaitForDecisionOutcomeOptions, WaitForDecisionOutcomeTimeoutError,
24};
25pub use types::{
26    NoxyDeliveryOutcome, NoxyDeliveryStatus, NoxyGetDecisionOutcomeResponse, NoxyGetQuotaResponse,
27    NoxyHumanDecisionOutcome, NoxyIdentityDevice, NoxyQuotaStatus,
28};
29
30/// Initialize the Noxy Decision Layer client (async: establishes the gRPC connection).
31pub async fn init_noxy_agent_client(
32    config: NoxyConfig,
33) -> Result<NoxyAgentClient, Box<dyn std::error::Error + Send + Sync>> {
34    let endpoint = normalize_endpoint(&config.endpoint);
35    let channel = tonic::transport::Endpoint::from_shared(format!("https://{}", endpoint))?
36        .tls_config(tonic::transport::ClientTlsConfig::new().with_enabled_roots())?
37        .connect()
38        .await?;
39    let kyber_provider = kyber_provider::KyberProvider::new();
40    let client = NoxyAgentClient::new(config, channel, kyber_provider);
41    Ok(client)
42}
43
44fn normalize_endpoint(endpoint: &str) -> String {
45    endpoint
46        .trim_start_matches("https://")
47        .trim_start_matches("http://")
48        .trim_end_matches('/')
49        .to_string()
50}