llmrix-rust-sdk 1.0.0

Official Rust SDK for the llmrix AI Agent Platform API
Documentation
use std::sync::Arc;
use crate::{
    error::{LlmrixError, Result},
    model::{ChatRequest, HitlDecideRequest, HitlDecision},
    streaming::event::StreamEvent,
    transport::*,
};

/// Streaming chat, stop, and HITL-decision operations scoped to one conversation.
/// Obtain via [`LlmrixClient::chat`].
pub struct ChatResource {
    pub(crate) t:       Arc<Transport>,
    pub(crate) conv_id: String,
}

impl ChatResource {
    /// Send a plain-text message and stream the agent's response.
    ///
    /// `handler` is called synchronously for each received [`StreamEvent`].
    /// Return `Err` from the handler to abort streaming early.
    ///
    /// ```rust,no_run
    /// # use llmrix_rust_sdk::{LlmrixClient, streaming::event::StreamEvent};
    /// # #[tokio::main] async fn main() -> llmrix_rust_sdk::error::Result<()> {
    /// # let client = LlmrixClient::builder().base_url("http://localhost").build().unwrap();
    /// # let conv_id = "test-id";
    /// client.chat(conv_id).send("Hello!", |event| {
    ///     if let StreamEvent::MessageChunk(e) = event {
    ///         print!("{}", e.content);
    ///     }
    ///     Ok(())
    /// }).await?;
    /// # Ok(()) }
    /// ```
    pub async fn send<F>(&self, message: &str, handler: F) -> Result<()>
    where
        F: FnMut(&StreamEvent) -> Result<()>,
    {
        self.send_request(ChatRequest { message: message.to_string(), ..Default::default() }, handler)
            .await
    }

    /// Send a fully-specified [`ChatRequest`] and stream the response.
    /// Use this overload to supply `agent_id`, `metadata`, or HITL decisions inline.
    pub async fn send_request<F>(&self, req: ChatRequest, handler: F) -> Result<()>
    where
        F: FnMut(&StreamEvent) -> Result<()>,
    {
        self.t.stream(&path_chat(&self.conv_id), &req, handler).await
    }

    /// Request the server to cancel the currently running chat turn.
    /// The in-flight `send` call will receive a `Cancelled` event before the stream closes.
    pub async fn stop(&self) -> Result<()> {
        self.t.post_no_body(&path_chat_stop(&self.conv_id)).await
    }

    /// Submit HITL decisions to resume a paused agent run.
    /// Call this after receiving a `HitlInterrupt` event.
    pub async fn decide(&self, decisions: Vec<HitlDecision>) -> Result<()> {
        if decisions.is_empty() {
            return Err(LlmrixError::Other("decisions must not be empty".into()));
        }
        self.t
            .post_void(&path_chat_decide(&self.conv_id), &HitlDecideRequest { decisions })
            .await
    }
}