Skip to main content

llmleaf_client/
lib.rs

1//! # llmleaf-client
2//!
3//! Official async Rust SDK for the [llmleaf](https://github.com/codefionn/llmleaf) LLM
4//! proxy. It speaks llmleaf's OpenAI/OpenRouter-shaped JSON over HTTP — the wire is JSON,
5//! never protobuf-binary — and covers every endpoint in `clients/SPEC.md`:
6//!
7//! * chat completions, non-streaming ([`Client::chat`]) and streaming
8//!   ([`Client::chat_stream`], an `impl Stream` of [`ChatCompletionChunk`]s that stops on
9//!   the `[DONE]` sentinel);
10//! * the OpenAI Responses dialect, non-streaming ([`Client::responses`]) and streaming
11//!   ([`Client::responses_stream`], an `impl Stream` of [`ResponsesStreamEvent`]s that ends
12//!   on the terminal `response.completed`/`incomplete`/`failed` event — there is no
13//!   `[DONE]` sentinel);
14//! * embeddings ([`Client::embeddings`], with base64 → float decoding);
15//! * model catalog ([`Client::list_models`]);
16//! * text-to-speech ([`Client::speech`] → `(bytes, content_type)`) and the voice catalog
17//!   ([`Client::voices`]);
18//! * speech-to-text ([`Client::transcribe`], multipart with the `file` part);
19//! * batches ([`Client::create_batch`], [`Client::get_batch`], [`Client::cancel_batch`],
20//!   [`Client::batch_results`] → an NDJSON stream of [`BatchResultLine`]s).
21//!
22//! ## Codegen
23//!
24//! `build.rs` compiles `proto/llmleaf/v1/llmleaf.proto` with `prost-build` (real codegen,
25//! run every build); the generated messages are exposed under [`pb`]. The public types
26//! (re-exported at the crate root, e.g. [`ChatRequest`]) are hand-written serde structs
27//! that produce the exact OpenAI JSON wire — prost compiles the proto while serde drives
28//! the wire.
29//!
30//! ## Quickstart
31//!
32//! ```no_run
33//! use llmleaf_client::{Client, ChatRequest, ChatMessage};
34//!
35//! # async fn run() -> Result<(), llmleaf_client::Error> {
36//! let client = Client::new("https://gateway.example.com", "sk-...")?;
37//! let resp = client
38//!     .chat(ChatRequest::new(
39//!         "gpt-4o-mini",
40//!         vec![ChatMessage::user("hi")],
41//!     ))
42//!     .await?;
43//! println!("{}", resp.first_text().unwrap_or_default());
44//! # Ok(())
45//! # }
46//! ```
47
48// Public types mirror `proto/llmleaf/v1/llmleaf.proto` field-for-field; the proto and
49// `clients/SPEC.md` are the authoritative documentation for individual fields, so we warn
50// on undocumented top-level items but not on every mirrored struct field.
51#![warn(missing_docs)]
52#![allow(clippy::doc_markdown)]
53
54pub mod pb;
55
56mod client;
57mod error;
58mod stream;
59mod wire;
60
61// The wire-mirror structs document themselves at the type level; their fields map
62// one-to-one onto the proto/SPEC keys, so we don't repeat that prose per field.
63#[allow(missing_docs)]
64mod types;
65
66pub use client::{Client, ClientBuilder};
67pub use error::{Error, Result};
68pub use types::*;