modelrelay 0.3.4

Rust SDK for the ModelRelay API
Documentation

ModelRelay Rust SDK

Async and blocking clients for the ModelRelay API with optional SSE streaming, tracing, and offline mocks.

Install

[dependencies]
modelrelay = "0.3.4"
# blocking-only:
# modelrelay = { version = "0.3.4", default-features = false, features = ["blocking"] }
# blocking with streaming (no Tokio runtime):
# modelrelay = { version = "0.3.4", default-features = false, features = ["blocking", "streaming"] }
# async without streaming:
# modelrelay = { version = "0.3.4", default-features = false, features = ["client"] }

Features

  • client (default): async reqwest client + Tokio.
  • blocking: blocking reqwest client (no Tokio).
  • streaming (default): SSE streaming for /llm/proxy.
  • tracing: optional spans/events around HTTP + streaming.
  • mock: in-memory mock client + fixtures for offline tests.

Quickstart (async)

use modelrelay::{Client, Config, Model, ProxyOptions, ProxyRequest};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::new(Config {
        api_key: Some(std::env::var("MODELRELAY_API_KEY")?),
        ..Default::default()
    })?;

    let request = ProxyRequest::builder(Model::OpenAIGpt4o)
        .user("Write a short greeting.")
        .max_tokens(64)
        .build()?;

    let completion = client
        .llm()
        .proxy(request, ProxyOptions::default().with_request_id("chat-1"))
        .await?;

    println!("response {}: {}", completion.id, completion.content.join(""));
    Ok(())
}

Error handling

use modelrelay::{Client, Config, Error, ProxyOptions, ProxyRequest};

async fn call() -> Result<(), Error> {
    let client = Client::new(Config {
        api_key: Some("sk_...".into()),
        ..Default::default()
    })?;

    match client.llm().proxy(
        ProxyRequest::builder("openai/gpt-4o-mini").user("hi").build()?,
        ProxyOptions::default(),
    ).await {
        Ok(resp) => println!("reply: {}", resp.content.join("")),
        Err(Error::Validation(err)) => eprintln!("bad request: {}", err),
        Err(Error::Api(err)) => eprintln!("status {} body {:?}", err.status, err.raw_body),
        Err(Error::Transport(err)) => eprintln!("network: {}", err),
        Err(other) => eprintln!("unexpected: {}", other),
    }
    Ok(())
}

More examples

Quickstart (blocking/CLI)

use modelrelay::{BlockingClient, BlockingConfig, ChatRequestBuilder, ChatStreamAdapter};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = BlockingClient::new(BlockingConfig {
        api_key: Some(std::env::var("MODELRELAY_API_KEY")?),
        ..Default::default()
    })?;

    let mut adapter = ChatStreamAdapter::new(
        ChatRequestBuilder::new("openai/gpt-4o-mini")
            .message("user", "Tell me a short fact about Rust.")
            .request_id("cli-chat-1")
            .stream_blocking(&client.llm())?,
    );

    while let Some(delta) = adapter.next_delta()? {
        print!("{delta}");
    }
    Ok(())
}

Configuration highlights

  • Defaults: 5s connect timeout, 60s request timeout (non-streaming), 3 attempts with jittered exponential backoff.
  • Per-request overrides via ProxyOptions (timeout, retry, extra headers/metadata, request IDs).
  • Predefined environments: production/staging/sandbox or custom base URL. Staging base: https://api-stg.modelrelay.ai/api/v1.

Environment variables

  • MODELRELAY_API_KEY — secret key for server-to-server calls.
  • MODELRELAY_PUBLISHABLE_KEY — publishable key for frontend token exchange.
  • MODELRELAY_BASE_URL — override API base URL.