llmrix-rust-sdk 1.0.0

Official Rust SDK for the llmrix AI Agent Platform API
Documentation
use std::{sync::Arc, time::Duration};

use crate::{
    error::Result,
    resources::{agents::AgentsResource, chat::ChatResource, conversations::ConversationsResource, cron::CronResource},
    transport::Transport,
};

/// Main entry point for the Llmrix Rust SDK.
///
/// `LlmrixClient` is cheap to clone — all instances share the same underlying
/// connection pool via `Arc<Transport>`.
///
/// # Example
/// ```rust,no_run
/// # use llmrix_rust_sdk::{LlmrixClient, model::ConversationCreateRequest};
/// # #[tokio::main] async fn main() -> llmrix_rust_sdk::error::Result<()> {
/// let client = LlmrixClient::builder()
///     .base_url("http://localhost:8899")
///     .api_key("sk-xxx")
///     .build()?;
///
/// let conv = client.conversations()
///     .create(ConversationCreateRequest { title: "My chat".into(), agent_id: None })
///     .await?;
///
/// client.chat(&conv.id).send("Hello!", |event| {
///     use llmrix_rust_sdk::streaming::event::StreamEvent;
///     if let StreamEvent::MessageChunk(e) = event {
///         print!("{}", e.content);
///     }
///     Ok(())
/// }).await?;
/// # Ok(()) }
/// ```
#[derive(Clone)]
pub struct LlmrixClient {
    transport: Arc<Transport>,
}

impl LlmrixClient {
    /// Returns a builder for configuring and constructing a [`LlmrixClient`].
    pub fn builder() -> ClientBuilder {
        ClientBuilder::default()
    }

    /// Returns the resource for managing conversations and message history.
    pub fn conversations(&self) -> ConversationsResource {
        ConversationsResource { t: Arc::clone(&self.transport) }
    }

    /// Returns the resource for managing scheduled cron tasks.
    pub fn cron(&self) -> CronResource {
        CronResource { t: Arc::clone(&self.transport) }
    }

    /// Returns the resource for managing agents and their mates.
    /// Returns HTTP 503 in native/standalone server mode.
    pub fn agents(&self) -> AgentsResource {
        AgentsResource { t: Arc::clone(&self.transport) }
    }

    /// Returns a [`ChatResource`] scoped to the given conversation ID.
    pub fn chat(&self, conv_id: impl Into<String>) -> ChatResource {
        ChatResource { t: Arc::clone(&self.transport), conv_id: conv_id.into() }
    }
}

// ---------------------------------------------------------------------------
// Builder
// ---------------------------------------------------------------------------

/// Builder for [`LlmrixClient`].
#[derive(Default)]
pub struct ClientBuilder {
    base_url:   Option<String>,
    api_key:    String,
    timeout:    Option<Duration>,
}

impl ClientBuilder {
    /// Base URL of the Llmrix server, e.g. `"http://localhost:8899"`. **Required.**
    pub fn base_url(mut self, url: impl Into<String>) -> Self {
        self.base_url = Some(url.into().trim_end_matches('/').to_string());
        self
    }

    /// API key sent in the `Authorization: Bearer` header.
    /// Omit if the server has no auth configured.
    pub fn api_key(mut self, key: impl Into<String>) -> Self {
        self.api_key = key.into();
        self
    }

    /// HTTP request timeout for non-streaming requests (default: 60 s).
    /// SSE streaming calls use no overall timeout.
    pub fn timeout(mut self, d: Duration) -> Self {
        self.timeout = Some(d);
        self
    }

    /// Construct the [`LlmrixClient`].
    ///
    /// # Errors
    /// Returns an error if `base_url` was not set or if the HTTP client could
    /// not be built (e.g. invalid TLS configuration).
    pub fn build(self) -> Result<LlmrixClient> {
        let base_url = self.base_url
            .expect("LlmrixClient: base_url is required — call .base_url(\"http://...\")");
        let timeout = self.timeout.unwrap_or(Duration::from_secs(60));
        let transport = Transport::new(base_url, self.api_key, timeout)?;
        Ok(LlmrixClient { transport: Arc::new(transport) })
    }
}