09 / Feature modules
Piper text-to-speech (synaplan-tts)
On this page 9
Module id: piper_tts · Kind: sidecar · Configured by: SYNAPLAN_TTS_URL · Capability: text_to_speech · Provider: piper
Spoken answers without a cloud: synaplan-tts is a small HTTP service around Piper with five voices baked into the image — English, German, Spanish, French, Turkish. The UI language picks the voice; the audio never leaves your infrastructure. Starts with the standard stack.
The companion page Text-to-Speech covers voices, the image and adding your own models. This page is the module view.
What it adds#
- The speaker control on chat answers, using a local voice.
- The
text_to_speechcapability the assistant can use in multi-task plans ("read this back to me"). - A voice per UI language — German UI → kerstin, Spanish → davefx, and so on — with no separate picker to configure.
Without it#
The speaker control does not appear and the capability inventory reports text-to-speech as unavailable — unless you use a cloud voice instead: ELEVENLABS_API_KEY, or a catalog TTS model from Gemini, Mistral Voxtral or xAI. Those live inside the main app and do not need this module. Speech input (Whisper transcription) ships with the core and is unaffected either way.
How to enable#
Option A — with the stack (default)#
make up # dev / evaluation stack: tts starts with it
docker compose stop tts # hide spoken answers again
The standard compose files (dev and deploy/compose.yaml) start the published
ghcr.io/metadist/synaplan-tts image and default SYNAPLAN_TTS_URL to
http://tts:10200, so the backend finds it without further configuration.
Production keeps the service internal-only (no host port); the development stack
additionally publishes it on 127.0.0.1:10200. The minimal stack keeps the opt-in profile:
docker compose -f docker-compose-minimal.yml --profile tts up -d # minimal stack
Option B — standalone container, same or another host#
docker run -d --name synaplan-tts \
-p 127.0.0.1:10200:10200 \
ghcr.io/metadist/synaplan-tts:latest
Then point the backend at it and restart backend + worker:
SYNAPLAN_TTS_URL=http://host.docker.internal:10200 # same host
SYNAPLAN_TTS_URL=http://192.168.1.50:10200 # a LAN box or GPU host serving several Synaplan nodes
Production deploy/compose.yaml already includes the service, so this option is
only for a speaker that lives outside the stack (another host, a GPU box).
Check it works#
- Operate → Feature Status → Piper text-to-speech shows Available / Synaplan TTS is running. The probe is
GET /healthon the service. Synaplan TTS is not reachable means the URL is set but nothing answered; SYNAPLAN_TTS_URL is unset means the module is off. - Send a chat message and click the speaker icon on the answer.
- Directly from inside the backend container (works on both stacks; production has no host port):
docker compose exec -T backend php -r 'echo file_get_contents("http://tts:10200/health"), "\n";'
On the development stack curl http://127.0.0.1:10200/health on the host works too.
Configuration reference#
| Variable | Default | Meaning |
|---|---|---|
SYNAPLAN_TTS_URL |
Compose default http://tts:10200 (the stack service) |
Base URL of synaplan-tts. Empty = module off. |
Extra voices: mount .onnx + .onnx.json Piper models into the service's extra-voices volume — see the synaplan-tts README. Cloud alternatives (ELEVENLABS_API_KEY, catalog TTS models) are provider settings, not part of this module.
Troubleshooting#
not reachablealthoughcurlon the host works. The backend resolves the URL from inside its container.localhostthere is the backend; usehost.docker.internal(Compose adds the mapping) or the host's LAN address.- No speaker icon. The control only renders when the service answers; check Feature Status first, then the browser console for the
/api/v1/tts/streamcall. - Wrong voice. The backend sends the frontend locale; if it detects a different reply language, that language's voice wins. There is no manual voice picker by design.
Related#
- Text-to-Speech — voices, image details, adding models, cloud alternatives
- Feature modules — states, gates, the CLI