ModelRelay Rust SDK
[]
= "0.44.0"
Top 3 Features
1. Structured Outputs with Auto-Retry
Define a Rust struct, and the SDK generates the JSON schema, validates responses, and automatically retries on malformed output:
use ;
use JsonSchema;
use Deserialize;
async
2. Streaming Structured JSON with Field Completion
Stream typed JSON and know exactly when each field is complete for progressive UI rendering:
use StreamExt;
use JsonSchema;
use Deserialize;
// Stream with field completion tracking
let mut stream = new
.model
.user
.
.stream
.await?;
while let Some = stream.next.await
// Or just collect the final result
let article: Article = new
.model
.user
.
.stream
.await?
.collect
.await?;
3. Tool Use with Type-Safe Argument Parsing
Register tools with typed argument validation:
use ;
use JsonSchema;
use Deserialize;
// Register handler with automatic argument parsing
let registry = new
.register;
// Generate tool schema from the type
let weather_tool = function;
// Send request with tools
let response = new
.model
.user
.tools
.tool_choice
.send
.await?;
// Execute tool calls
let tool_calls: = response
.output
.iter
.flat_map
.collect;
if !tool_calls.is_empty
Quick Start
Basic Response
use ;
let client = with_key.build?;
let response = new
.model
.system
.user
.send
.await?;
let mut text = Stringnew;
for item in &response.output
println!;
Streaming
use StreamExt;
// Simple: iterate text deltas directly
let mut deltas = new
.model
.user
.stream_deltas
.await?;
while let Some = deltas.next.await
// Or use the raw stream for more control
let mut stream = new
.model
.user
.stream
.await?;
while let Some = stream.next.await
Customer-Attributed Requests
For metered billing, set customer_id(...) - the customer's tier determines the model and model(...) can be omitted:
use ResponseBuilder;
// Basic response - model determined by customer's tier
let response = new
.customer_id
.user
.send
.await?;
// Structured output
let result = new
.customer_id
.user
.
.max_retries
.send
.await?;
// Streaming text deltas
let mut deltas = new
.customer_id
.user
.stream_deltas
.await?;
while let Some = deltas.next.await
Blocking API (No Tokio)
use ;
let client = new?;
// Non-streaming
let response = new
.model
.user
.send_blocking?;
// Streaming text deltas
let deltas = new
.model
.user
.stream_deltas_blocking?;
for text in deltas
API Matrix
ResponseBuilder supports all modes (use customer_id(...) for customer-attributed calls):
| Mode | Non-Streaming | Streaming | Text Deltas | Structured | Structured Streaming |
|---|---|---|---|---|---|
| Async | .send() |
.stream() |
.stream_deltas() |
.structured::<T>().send() |
.structured::<T>().stream() |
| Blocking | .send_blocking() |
.stream_blocking() |
.stream_deltas_blocking() |
.structured::<T>().send_blocking() |
.structured::<T>().stream_blocking() |
Features
| Feature | Default | Description |
|---|---|---|
client |
Yes | Async client with Tokio |
streaming |
Yes | NDJSON streaming support |
blocking |
No | Sync client without Tokio |
tracing |
No | OpenTelemetry spans/events |
mock |
No | In-memory client for tests |
Error Handling
API errors include typed helpers for common cases:
use ;
let result = new
.model
.user
.send
.await;
match result