Voice
Openclaw_livekit_agent
SIP-backed voice AI assistant: LiveKit Agent + Sber STT + Silero TTS + any OpenAI-compatible LLM. Inbound/outbound calls over SIP with real-time speech recognition and synthesis.
README
<p align="center">
<img src="https://img.shields.io/badge/python-3.11-blue?logo=python" alt="Python">
<img src="https://img.shields.io/badge/Silero%20TTS-v1.0-green" alt="Silero TTS">
<img src="https://img.shields.io/badge/LiveKit%20Agent-v1.6-purple?logo=livekit" alt="LiveKit">
<img src="https://img.shields.io/badge/Sber%20STT-SaluteSpeech-blueviolet" alt="Sber STT">
<img src="https://img.shields.io/badge/OpenClaw-plugin-orange" alt="OpenClaw Plugin">
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue" alt="License"></a>
</p>
# LiveKit Voice Agent β Voice Channel for OpenClaw AI
**A voice AI assistant that answers calls over SIP and speaks back using Sber Voice (STT/TTS) and any OpenAI-compatible LLM. Works perfectly as a real-time voice channel for [OpenClaw](https://github.com/vstan1986/openclaw) AI agents via OpenClaw's OpenAI-compatible API.**
Callers speak to the assistant over a regular phone line (SIP). The assistant transcribes their speech with Sber STT, generates a response with any OpenAI-compatible LLM (including OpenClaw's built-in API), and speaks it back using Silero TTS β all in real time.
```
Caller βββSIPβββΊ LiveKit SIP Trunk βββWebRTCβββΊ Agent (LiveKit SDK)
β
ββββββββββΌβββββββββ
βΌ βΌ βΌ
Sber STT LLM Silero TTS
β
OpenClaw β OpenAI-compatible
AI Agent β (Ollama, GPT, ...)
```
## β¨ Features
- **π€ OpenClaw AI voice channel** β use any [OpenClaw](https://github.com/vstan1986/openclaw) agent as the LLM brain via its OpenAI-compatible API
- **π SIP telephony** β inbound + outbound calls via LiveKit SIP Trunk
- **ποΈ Sber SaluteSpeech STT** β gRPC streaming speech recognition (Russian language)
- **π£οΈ Silero TTS** β self-hosted neural text-to-speech (HTTP microservice)
- **π§ Any LLM** β OpenAI-compatible API (OpenClaw, Ollama, GPT, Claude, etc.)
- **π No VAD needed** β server-side endpointing via Sber's EOU detection
- **π‘οΈ Confirmation phrases** β instant "one moment" playback while LLM thinks (no silence gaps)
- **π Modular services** β STT, TTS, auth all run as separate microservices
- **π³ Docker Compose** β single `up -d` to start everything
- **β οΈ Resilience** β configurable retry, apology playback on LLM errors, silence timeout β hangup
## π¦ Quick Start
```bash
# 1. Copy and fill in environment
cp .env.example .env
# 2. Start all services
docker compose up -d
```
### Required Environment Variables
| Variable | Description |
|----------|-------------|
| `LIVEKIT_URL` | `ws://<host>:7880` |
| `LIVEKIT_API_KEY` | From `livekit.yaml` |
| `LIVEKIT_API_SECRET` | From `livekit.yaml` |
| `EXTERNAL_IP` | Server public IP |
| `LLM_BASE_URL` | OpenAI-compatible LLM endpoint (e.g. `http://openclaw:8080/v1` for OpenClaw) |
| `LLM_API_KEY` | LLM API key (use `ollama` for Ollama, `openclaw` for OpenClaw) |
| `SBER_CLIENT_ID` | Sber RCE key Client ID |
| `SBER_CLIENT_SECRET` | Sber RCE key secret (base64) |
| `SIP_OUTBOUND_TRUNK_ID` | LiveKit outbound trunk ID (for outbound calls) |
See [`.env.example`](.env.example) for the full list.
## π§ How It Works
### Agent Architecture
The LiveKit agent runs in **two modes**, determined automatically from dispatch metadata:
| Mode | Trigger | Behaviour |
|--------------|----------------------------------------|--------------------------------------|
| **inbound** | metadata has no `phone_number` | Agent waits for an incoming SIP call |
| **outbound** | metadata has `"phone_number": "+7..."` | Agent dials out and starts speaking |
### Call Flow
```
ββββββββββββ ββββββββββββββββ βββββββββββββ ββββββββββββ βββββββββββββ
β Caller β SIP β LiveKit SIP β WS β Agent β gRPC β Sber STT β β LLM β
β ββββββΊβ Trunk ββββββΊβ(LiveKit βββββββΊβ(Salute- β β(OpenClaw /β
β β β β β SDK) β β Speech) β β Ollama / β
β βββββββ βββββββ ββββββββ β β GPT) β
β β SIP β β WS β β HTTP β β β β
ββββββββββββ ββββββββββββββββ β β ββββββββββββ βββββββββββββ
β ββββββββ HTTP ββββββββββ
β β β
βββββββββββββ βββββββββββββ΄ββββββββββββ
β Silero TTS β
β (tts-service) β
βββββββββββββββββββββββββ
```
1. **Call arrives** β SIP provider rings LiveKit SIP Trunk
2. **Agent joins** β LiveKit dispatches the call to the agent
3. **Listening** β agent opens a gRPC stream to Sber STT and listens for speech
4. **User speaks** β audio is streamed to Sber, which detects end-of-utterance (EOU)
5. **Confirmation** β agent instantly plays a short "one moment" phrase via Silero TTS
6. **LLM turn** β transcript is sent to the LLM (OpenClaw, Ollama, GPT, etc.); the response is streamed back
7. **Response spoken** β LLM text is synthesised by Silero TTS and played to the caller
8. **Loop** β agent returns to listening state for the next turn
### Turn-taking (Strict FSM)
Turn handling is strict β no overlap between user and agent speech:
- `allow_interruptions=False` β Sber transcripts received during agent TTS are ignored
- `discard_audio_if_uninterruptible=False` β no audio filtering, Sber decides
- Server-side endpointing via Sber's EOU signal, no client-side VAD
## πΊοΈ Service Map
| Service | Container | Role |
|---------|-----------|------|
| **livekit** | `livekit` | WebRTC SFU (signalling + media), v1.12 |
| **redis** | `redis` | LiveKit coordination |
| **lk-tts** | `tts-service` | Silero TTS HTTP microservice |
| **lk-auth** | `auth-service` | Sber OAuth 2.0 token management |
| **lk-inbound** | `agent` | LiveKit Agent β SIP β LLM orchestration |
## π§ LiveKit SIP Setup
### 1. Inbound trunk β receive calls from SIP provider
```bash
lk sip inbound create inbound-trunk.json
lk sip inbound list # save trunk_id
```
### 2. Outbound trunk β outbound calls
```bash
MANGO_PASSWORD=$MANGO_PASSWORD lk sip outbound create outbound-trunk.json
lk sip outbound list # save trunk_id β SIP_OUTBOUND_TRUNK_ID
```
### 3. Dispatch rule β route inbound call to agent
```bash
lk sip dispatch create dispatch-rule.json
```
### 4. Outbound call (via agent)
```bash
lk dispatch create \
--new-room \
--agent-name sber-voice-assistant \
--metadata '{"phone_number": "+71234567890"}'
```
## π Architecture
```
livekit-agent/
βββ my_agent/ # LiveKit agent package
β βββ session.py # CallSession β turn orchestration
β βββ plugin_stt.py # WebSocket STT plugin (β Sber)
β βββ plugin_tts.py # HTTP TTS plugin (β Silero)
β βββ plugin_tts_transforms.py # Text transforms (digits β words)
β βββ sentence_splitter.py # Aggressive sentence tokenizer for TTS
β βββ http_api.py # FastAPI (/call, /hangup)
β βββ config.py # Centralised configuration
βββ stt_service/ # STT microservice
β βββ server.py # HTTP/WebSocket entrypoint
β βββ sber_stt.py # gRPC streaming client (Sber v2)
β βββ token_manager.py # Sber OAuth 2.0 token management
βββ tts_service/ # TTS microservice
β βββ server.py # HTTP entrypoint
β βββ tts_engine.py # Silero TTS wrapper
β βββ translit.py # Latin β Cyrillic transliteration
βββ tests/ # Pytest suite (52 tests)
```
## π€ Contributing
Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md).
## π Security
See [SECURITY.md](SECURITY.md) for our security policy and vulnerability reporting process.
## π License
This project is licensed under the **MIT License** β see the [LICENSE](LICENSE) file for details.
### Third-Party Licenses
This project uses several open-source components with different licenses.
See [NOTICE.md](NOTICE.md) for full attribution and license information,
including:
- **Apache 2.0** β livekit-agents, livekit-plugins-openai, requests, grpcio, protobuf
- **LGPL** β num2words
- **CC BY-NC-SA 4.0** β Silero TTS model weights (non-commercial use only)
voice
Comments
Sign in to leave a comment