Files
ai-operator/docs/media-gateway.md
T

83 lines
3.1 KiB
Markdown

# Media Gateway
## Purpose
The Media Gateway connects the Go AI Operator to Asterisk audio through `chan_websocket` media channels.
## Why chan_websocket
Asterisk 20.16.0 on this server has `chan_websocket` and `res_http_websocket` loaded, and HTTP status exposes `/media/...` as Media over Websocket. This avoids RTP socket handling for the MVP media path.
## Asterisk 20.16.0 Compatibility
- Plain-text media control messages are used by default.
- JSON control parsing is implemented for future compatibility.
- No dependency on `transport_data=f(json)`.
- Codec for TZ-04 is `slin16`.
- Media WebSocket subprotocol is `media`.
## Runtime Flow
```text
Caller calls 7199@from-softphones
-> Stasis(ai-operator,test)
-> Go ARI Call Manager receives StasisStart
-> Answer caller
-> Create mixing bridge
-> Add caller channel
-> Create externalMedia WebSocket channel
-> Get MEDIA_WEBSOCKET_CONNECTION_ID
-> Go connects to ws://127.0.0.1:8088/media/{connection_id}
-> Add media channel to bridge
-> Pump caller slin16 audio to VoiceProvider
-> Pump VoiceProvider assistant audio deltas back to Asterisk
-> Cleanup
```
Production Kazakhtelecom routes remain unchanged. AudioSocket `7100` remains the rollback route.
## CLI Usage
Media self-test without real call:
```sh
./bin/ai-operator media-self-test --env /etc/ai-operator/ai-operator.env --duration 3s
```
Controlled test route media mode:
```sh
./bin/ai-operator run --env /etc/ai-operator/ai-operator.env --ari-events --call-control --media --voice-provider openai_realtime --media-test-mode stats --test-call-hangup-after 180s
```
## Media Test Modes
- `stats`: collect media stats and do not synthesize test audio. Real VoiceProvider audio is still forwarded to the caller.
- `silence`: send short slin16 silence.
- `tone`: send a short low-volume sine tone for controlled testing only.
- `echo`: reserved for controlled testing, not a default mode.
## Safety
- Production route is disabled.
- No audio recording by default.
- Raw audio frames are not saved to disk by default.
- OpenAI is not called.
- Cleanup is designed to be idempotent.
## Troubleshooting
- No `MEDIA_START`: verify externalMedia channel creation and `/media/{connection_id}` URL.
- Missing `MEDIA_WEBSOCKET_CONNECTION_ID`: retry variable fetch; channel may not be fully initialized yet.
- WebSocket 404/401: verify ARI/HTTP localhost binding and credentials.
- XOFF stuck: outbound audio pauses until `MEDIA_XON` or context timeout.
- Leaked bridge/channel: run `core show channels` and `bridge show all`, then clean up aiop-prefixed resources.
## Voice Provider Integration
Media Gateway audio is forwarded to a VoiceProvider in test route mode. Caller audio is resampled from Asterisk `slin16` 16 kHz PCM16 to provider 24 kHz PCM16. Assistant audio deltas are resampled back to 16 kHz PCM16 and sent to Asterisk over the media WebSocket. Default provider is `fake`; OpenAI requires explicit `--voice-provider openai_realtime` and an API key.
## TZ-06 Dialogue Safety
Media Gateway remains transport-only. It does not decide business state. Dialogue state and tool permissions are handled by the Dialogue Orchestrator.