chat-openrouter
OpenRouter provider for chat-rs. OpenRouter exposes two OpenAI-compatible wires; the builder picks one and hands off to the matching wire crate:
- Responses API (Beta) (default) →
chat-responses,build()returns aResponsesClient. - Chat Completions (opt in via
.with_completions()) →chat-completions,build()returns aChatCompletionsClient.
OpenRouter is a unified gateway in front of hundreds of models from many vendors. The model slug selects which one, and is vendor-prefixed (e.g. anthropic/claude-sonnet-4, openai/gpt-4o, google/gemini-2.5-pro).
Install
[]
= "0.4.0"
= "0.1.0"
= { = "1", = ["macros", "rt-multi-thread"] }
Or via the umbrella crate: chat-rs = { version = "0.5.0", features = ["openrouter"] }.
Usage
use OpenRouterBuilder;
use ;
// Default: Responses API.
let client = new
.with_model
.build;
// Opt in to Chat Completions instead.
let client = new
.with_completions
.with_model
.build;
let mut chat = new.with_model.build;
let mut msgs = from_user;
let response = chat.complete.await?;
Set OPENROUTER_API_KEY in your environment or call .with_api_key() on the builder.
Capabilities
- Completions — text generation with tool calling and structured output, on either wire
- Streaming — token-by-token output over SSE (requires the
streamfeature); both wire clients implement it - Reasoning —
.with_reasoning_effort("high")for reasoning-capable models (Responses wire only)
Notes
- Two wires. OpenRouter speaks both the OpenAI Responses API (Beta) and Chat Completions. The builder picks one upstream —
.with_completions()switches from the default Responses wire — and returns the underlying wire client directly (ResponsesClientorChatCompletionsClient); there is no wrapper type. Both already implement the chat-rs provider traits. - Stateless. The OpenRouter Responses API persists no server-side state and has no
previous_response_idround-trip. The builder always disables response-id reuse and sends the full conversation each turn. - No WebSocket. OpenRouter has no WebSocket/realtime endpoint; streaming is SSE over HTTP. The builder is still generic over
Transport, so a custom transport can be supplied via.with_transport(...).
Custom Endpoint / Transport
Override the base URL with .with_base_url(...) or supply a custom transport with .with_transport(...).
Feature Flags
Streaming is gated on the stream feature:
= { = "0.1.0", = ["stream"] }