provider-sarvam
v0.1.1Sarvam AI provider worker; implements provider::sarvam::stream for the Sarvam chat models plus provider::sarvam::transcribe (Saaras) and provider::sarvam::speak (Bulbul) behind llm-router.
Install
iii trigger compose::add worker=provider-sarvam@nextRun in your project with the iii engine running. Exact versions are immutable and digest-pinned.
provider-sarvam
Sarvam AI behind llm-router, as one worker for every Sarvam model family:
- Chat:
provider::sarvam::streamrunssarvam-105b,sarvam-30bandsarvam-mon Sarvam's OpenAI-compatible Chat Completions API (SSE streaming, tool calling,reasoning_effort), sorouter::chatand the harness use them like any other provider's models. - Speech to text:
provider::sarvam::transcriberuns Saaras (saaras:v3default,saaras:v4,saarika:v2.5) behindrouter::transcribe: 22 Indian languages and English, detected when no hint is given, word timings folded into sentence segments. - Text to speech:
provider::sarvam::speakruns Bulbul (bulbul:v3default,bulbul:v2) behindrouter::speak: 11 languages, 35+ speakers, mp3, wav, pcm16 or opus back. provider::sarvam::count_tokensestimates prompt tokens locally with tiktoken (Sarvam publishes no tokenizer for the 105B and 30B models).
The voice worker reaches the speech half with stt.backend: router /
tts.backend: router and a sarvam::… model.
Install
iii trigger compose::add worker=provider-sarvamPut the key where the router reads it: SARVAM_API_KEY in the router's
environment, or paste it into the sarvam block of the llm-router entry in
the console's Settings. The catalog fills the moment a key lands.
Behavior
- Auth: the same key goes out as
Authorization: Bearer(what the chat endpoint documents) and asapi-subscription-key(what every other endpoint takes), so a gateway in front of either shape is satisfied. - Endpoints: chat at the configured
api_url(defaulthttps://api.sarvam.ai/v1/chat/completions); the speech endpoints at that URL's origin (/speech-to-text,/text-to-speech), so a residency host override moves all three. - Reasoning: every Sarvam chat model reasons by default; the router's
thinking_levelfolds ontoreasoning_effortlow | medium | high.response_formatmaps tojson_objectwithout schema validation and the catalog says so (supports_structured_output: false). - Languages: hints such as
hi,hi-INoren-USbecome Sarvam'sxx-INcodes; Odia's ISO codeorbecomesod-IN. Unknown hints let Saaras detect the language and make Bulbul speak English. - Speakers:
shubhis the Bulbul v3 default (anushkafor v2). Pass any speaker name Sarvam lists; v2 voices do not work on v3 and vice versa. - Limits: Bulbul takes up to 2500 characters per request; the REST speech-to-text endpoint is for recordings, not hour-long files (use Sarvam's batch API for those).
Surfaces
| Function | Request | Response |
|---|---|---|
provider::sarvam::stream |
router chat stream contract | AssistantMessageEvent frames |
provider::sarvam::transcribe |
{model?, audio_base64, mime?, language?} |
{model, text, segments[{text, start_secs, end_secs}], language, duration_secs} |
provider::sarvam::speak |
{model?, text, voice?, format?, language?, speed?} |
{model, audio_base64, mime, voice} |
provider::sarvam::count_tokens |
{model, system_prompt?, tools?, messages} |
{model, tokens, estimator} |
provider::sarvam::refresh_models |
{} |
{ok, count} |
Errors carry stable prefixes: provider/not_configured,
provider/auth_expired, provider/quota_exceeded, provider/rate_limited,
provider/invalid_input, provider/upstream_transient; chat failures use
the shared ErrorKind taxonomy on their error frames.
Configuration
Nothing in this worker's own config file. The credential, api_url and
max_tokens resolve per request through router::provider::resolve.
Tests
cargo test # unit tests + wire-schema goldens (+ engine-backed suite when `iii` is on PATH)
UPDATE_GOLDENS=1 cargo test # regenerate tests/golden after a surface changeRunning
cargo run -- --url ws://127.0.0.1:49134