83 lines
3.1 KiB
Markdown
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.
|