Voice service operations
The Voice service runs the actual voice-AI processing: TelSys (Asterisk 22.9.0) provides PBX and media handling, TelPhi (Node 24) orchestrates AI conversations via realtime and modular speech providers, and AudioProc does optional VAD / noise reduction. SIP calls arrive from TelPro and are processed here. Multiple Voice instances run in parallel for horizontal scaling.
- Overview
- Runbook
- Configuration
- Troubleshooting
Containers
| Container | Base | Port(s) | Purpose |
|---|---|---|---|
voiceai-telsys | Asterisk 22.9.0 (built from source on debian:bookworm-slim) | 5080 SIP · 8088 ARI · 10000–11999 RTP | Asterisk PBX / media |
voiceai-telphi | Node 24-alpine | 12001 media WS | AI conversation engine |
voiceai-audioproc | python:3.11-slim (CPU) or nvidia/cuda:12.4.1-runtime-ubuntu22.04 (GPU) | 8790 WS | Audio preprocessing (optional) |
log-to-span | alpine:3.19 + Go binary | — | Converts TelSys structured logs to OTLP spans |
voiceai-otel-collector | otel/opentelemetry-collector-contrib:0.150.1 | — | Telemetry collector |
Asterisk upgraded to 22.9.0 with missing slin RTP codec entries fixed. chan_websocket enables WebSocket-oriented voice infrastructure. TelPhi media-session handling improved; WebRTC start-call no longer requires two clicks.
Call flow
- TelPro routes an INVITE to TelSys (
VAIPROXIESPIPED:SIPPORTTELPRO). - TelSys answers and bridges to TelPhi via Asterisk ExternalMedia over the TelPhi media WebSocket (
TELPHI_MEDIA_PORT, default12001). - TelPhi opens a realtime session against the configured AI provider (OpenAI Realtime, Pythia, Vodafone TOBi, Azure STT/TTS) — outbound traffic goes through Squid.
- AudioProc (when
AUDIOPROC_ENABLED=true) preprocesses inbound audio frames.
Scaling
Set the initial Voice instance count in your provisioning tool. The Ops Scaler can adjust this dynamically based on active call count. Instances are named ${environment}-voice-01, -02, etc.
When the Scaler creates a new Voice instance, it appears in the Kamailio dispatcher set in Redis (voiceai:dispatcher:*) and starts receiving calls automatically.
Deploy and update
cd /opt/services/voice
./init.sh
./update.sh --ecr-tag v0.9.11
./update.sh --restart-only
init.sh copies the log-to-span binary into the right path, fetches config from S3, loads env vars from SSM / SM, logs into ECR, and starts Compose. Standard flags apply.
RTP port allocation
| Component | Range |
|---|---|
| TelSys (carrier-facing) | 10000–11999 |
| TelPhi | media WebSocket only (no separate RTP range) |
| Janus (on TelPro) | 10000–12000 |
| RTPEngine (on TelPro) | 20000–40000 |
Adjust the carrier-facing range via RTPSTART / RTPEND in SSM if your upstream carrier needs a different window.
Recording
When RECORDING_ENABLED=true, TelPhi writes recordings to the S3 bucket RECORDING_BUCKET using AWS credentials available to the container. Recording is post-processed by Tasker on the Ops service.
TelSys (Asterisk)
| Name | Source | Scope | Default | Description |
|---|---|---|---|---|
VAIPROXIESPIPED | SSM | all | — | Kamailio SIP proxy (TelPro private IP). |
SIP_PORT_INTERNAL | SSM | all | — | Internal SIP port (from TelPro). |
SIPPORTTELPRO | SSM | all | — | TelPro SIP port TelSys dials out to. |
RTPSTART | SSM | all | 10000 | Carrier-facing RTP start. |
RTPEND | SSM | all | 11999 | Carrier-facing RTP end. |
TelPhi (Voice AI)
| Name | Source | Scope | Default | Description |
|---|---|---|---|---|
DATABASE_URL | Secrets Manager | all | — | PostgreSQL connection. |
DATABASE_POOL_SIZE | SSM | all | 50 | Connection pool size. |
REDIS_HOST | SSM | all | — | Redis server. |
REDIS_PASSWORD | Secrets Manager | all | — | Redis auth. |
TELPHI_MEDIA_PORT | SSM | all | 12001 | TCP port for ExternalMedia WS. |
TELPHI_MEDIA_PATH | SSM | all | /media | URL path Asterisk dials. |
TELPHI_MEDIA_SCHEME | SSM | all | ws | ws or wss. |
RECORDING_ENABLED | SSM | all | false | Enable S3 call recording. |
RECORDING_BUCKET | SSM | all | recordings | S3 recordings bucket. |
AUDIOPROC_ENABLED | SSM | all | false | Toggle AudioProc preprocessor. |
TTS_MEDIA_CACHE_BASE_URL | SSM | all | — | HTTPS base URL for Media service. |
TTS_MEDIA_CACHE_UPLOAD_TOKEN | Secrets Manager | all | — | Bearer for media writes. |
TTS_MEDIA_CACHE_CA_BUNDLE | SSM | all | — | CA bundle for private media TLS. |
HTTP_PROXY | SSM | all | — | Squid proxy for outbound HTTP (OpenAI, etc.). |
HTTPS_PROXY | SSM | all | — | Squid proxy for outbound HTTPS. |
VONAGE_SMS_API_KEY | Secrets Manager | all | — | Vonage SMS API key (when SMS feature enabled). |
Call processing
| Symptom | Likely cause | Check |
|---|---|---|
| Calls ring but no AI response | TelPhi not connected to Asterisk ARI | TelPhi logs for ARI connection errors. |
| TelSys won't start (90s timeout) | Asterisk config error | docker compose logs voiceai-telsys. |
| TelPhi can't reach OpenAI | Proxy misconfigured or Squid down | Verify HTTP_PROXY / HTTPS_PROXY; check Squid. |
| Call drops after ~30s | Realtime API timeout / WS drop | TelPhi logs for WebSocket close; proxy stability. |
| No SIP from TelPro | VAIPROXIESPIPED wrong | Verify matches TelPro private IP. |
| Caller hears no AI audio | TelSys can't reach TelPhi media WS | Tail TelPhi for media_session connect; check chan_websocket errors in TelSys. |
Transfer to human
| Symptom | Cause | Check |
|---|---|---|
| Transfer not initiating | transfer() tool not on agent, AI never calls it | Agent tools in TelWeb; TelPhi logs for tool invocations. |
| Outbound leg rings, no answer | Target unreachable / no egress trunk | TelPhi logs for SIP response codes; egress trunk linked to the base number. |
| Mini AI session silent | ExternalMedia bridge / RTP wiring failed | Look for Mini session audio wired. |
See also
- TelPro operations — SIP / WebRTC entry point.
- Database operations — Redis keys used for routing.
- Monitoring in SigNoz — trace IDs, call-ID correlation, logs, and dashboards.