Mistral
Text-to-speech with MistralTTSService, Mistral's Voxtral TTS streamed over Server-Sent Events.
Overview
MistralTTSService: posts each sentence to Mistral's speech API with streaming on, converts the float32 PCM chunks to 16-bit, and resamples them from 24 kHz to the pipeline's rate.
Upstream page
Pipecat's documentation for the same service.
Source
packages/mistral/src/tts.ts.
Mistral docs
Voxtral and the audio APIs.
Installation
bun add @pipedog/mistralimport { MistralTTSService } from "@pipedog/mistral/tts";Prerequisites
- A Mistral account and an API key from Mistral.
- Pass the key as
apiKey. The examples read it fromMISTRAL_API_KEY. - A voice ID for
voice: the default isnull.
MistralTTSService
Posts to https://api.mistral.ai/v1/audio/speech.
Configuration
Prop
Type
Settings
Runtime-updatable settings, passed as settings: new MistralTTSService.Settings({...})
(MistralTTSSettings). Any setting you leave out keeps the default below.
| Setting | Type | Default | Description |
|---|---|---|---|
model | string | "voxtral-mini-tts-2603" | Speech model. |
voice | string | null | null | Voice ID, sent as voice_id. |
language | null | null | Not used by this service. |
Usage
import { TTSUpdateSettingsFrame } from "@pipedog/core/frames/frames";
import { MistralTTSService } from "@pipedog/mistral/tts";
const tts = new MistralTTSService({
apiKey: process.env.MISTRAL_API_KEY ?? "",
settings: new MistralTTSService.Settings({ voice: process.env.MISTRAL_VOICE_ID ?? "" }),
});Change settings mid-call with an TTSUpdateSettingsFrame:
// Queue it on the worker, or push it from a processor upstream of the service.
const update = new TTSUpdateSettingsFrame({
delta: new MistralTTSService.Settings({ model: "voxtral-mini-tts-2603" }),
});Notes
- Mistral returns 24 kHz audio, resampled to
sampleRatewhen that differs. - A failed request produces an
ErrorFrameinstead of audio.
Runtime notes
| Runtime | Works | What it needs |
|---|---|---|
| Bun | ✅ yes | Nothing. |
| Node.js | ✅ yes | Nothing. |
| Deno | ✅ yes | Nothing. |
| Cloudflare Workers | ✅ yes | Nothing. |
Generated from pipecat.runtimes and pipecat.compat in packages/mistral/package.json: ✅ means the compat smoke test passes on that runtime.
- Requests go through
fetch, with the Server-Sent Events parsed in the service (upstream uses themistralaiSDK). It works on Bun, Node, Deno and Cloudflare Workers. - The request and events follow Mistral's SDK (
@mistralai/mistralai3.1.0,audioSpeechComplete) and the streaming docs:speech.audio.deltaevents with base64audio_data, thenspeech.audio.done. The float32 layout of"pcm"audio comes from upstream Pipecat's conversion; Mistral's docs don't state it. - Tested against a local fake, not against Mistral itself.
pipedog is an unofficial community TypeScript port of Pipecat. It is not affiliated with or endorsed by Daily or the Pipecat project.
Portions adapted from the Pipecat documentation, Copyright (c) 2024–2025 Daily, BSD-2-Clause (see apps/docs/LICENSE-pipecat-docs).