sync: migrate ai-operator to Gitea (2026-08-10)
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user