@ariaflowagents/livekit-plugin-transport-twilio
v1.0.0
Published
Twilio Media Streams transport adapter for AriaFlow agents. Works with Node.js, Bun, Deno, and any WebSocket-compatible runtime.
Maintainers
Readme
@ariaflow/livekit-plugin-transport-twilio
Twilio Media Streams transport adapter for AriaFlow voice agents. Works with Node.js, Bun, Deno, and any WebSocket-enabled runtime. Cloudflare Workers support is currently unstable.
Features
- ⚠️ Cloudflare Workers Compatible (Unstable) - No Node.js dependencies
- ✅ Twilio Media Streams Support - Native integration with Twilio's API
- ✅ Automatic Codec Conversion - G.711 μ-law ↔ PCM with resampling (8kHz ↔ 24kHz)
- ✅ AriaFlow Native - Works with
createAriaFlowSessionand AriaFlow Runtime - ✅ Session Management - Full lifecycle management with SessionManager
Installation
# Using npm
npm install @ariaflow/livekit-plugin @ariaflow/livekit-plugin-transport-twilio
# Using bun
bun add @ariaflow/livekit-plugin @ariaflow/livekit-plugin-transport-twilioQuick Start
Cloudflare Workers (Unstable)
⚠️ Note: The Cloudflare Workers integration is currently unstable and not officially supported. Use at your own risk.
// wrangler.toml:
// name = "ariaflow-twilio-agent"
// compatibility_date = "2024-01-01"
// compatibility_flags = ["nodejs_compat"]
import { createTwilioWorker } from '@ariaflow/livekit-plugin-transport-twilio/cloudflare';
import { createAriaFlowSession } from '@ariaflow/livekit-plugin';
import { GeminiLiveSTT, GeminiLiveTTS } from '@ariaflow/livekit-plugin/gemini';
const agentConfig = {
agents: [{ id: 'assistant', prompt: 'You are helpful.' }],
defaultAgentId: 'assistant',
};
export default createTwilioWorker({
agent: () => createAriaFlowSession({
runtime: agentConfig,
stt: new GeminiLiveSTT(),
tts: new GeminiLiveTTS(),
greeting: 'Hello! How can I help?',
}),
});Node.js / Deno / Any WebSocket
import { WebSocketServer } from 'ws';
import { TwilioTransportAdapter } from '@ariaflow/livekit-plugin-transport-twilio';
import { createAriaFlowSession } from '@ariaflow/livekit-plugin';
import { SessionManager } from '@ariaflow/livekit-plugin';
import { GeminiLiveSTT, GeminiLiveTTS } from '@ariaflow/livekit-plugin/gemini';
const wss = new WebSocketServer({ port: 8080 });
const sessionManager = new SessionManager();
const agentConfig = {
agents: [{ id: 'assistant', prompt: 'You are helpful.' }],
defaultAgentId: 'assistant',
};
wss.on('connection', (ws) => {
const transport = new TwilioTransportAdapter({
send: (msg) => ws.send(msg),
});
ws.on('message', (data) => {
transport.handleMessage(data.toString());
});
ws.on('close', async () => {
await transport.close();
});
// Wait for 'connected' event before starting session
ws.once('message', async (data) => {
const event = JSON.parse(data.toString());
if (event.event === 'connected') {
const { agent, sessionOptions } = createAriaFlowSession({
runtime: agentConfig,
stt: new GeminiLiveSTT(),
tts: new GeminiLiveTTS(),
});
await sessionManager.startSession(transport, agent, sessionOptions);
}
});
});TwiML Setup
Create a TwiML bin in your Twilio console:
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Say>Connecting to AI assistant...</Say>
<Connect>
<Stream url="wss://your-worker.workers.dev/voice/stream" />
</Connect>
</Response>Audio Specifications
| Direction | Twilio Format | Internal Format | Sample Rate | |-----------|---------------|-----------------|-------------| | Inbound | G.711 μ-law | PCM S16 LE | 8kHz → 24kHz | | Outbound | PCM S16 LE | G.711 μ-law | 24kHz → 8kHz |
The transport handles all codec conversion and resampling automatically.
API Reference
TwilioTransportAdapter
Main transport adapter class.
const transport = new TwilioTransportAdapter({
id: 'optional-custom-id',
send: (message: string) => {
// Send message to WebSocket
ws.send(message);
},
});Properties:
id: string- Unique identifier for this transportaudioInput: TwilioAudioInput- Audio input streamaudioOutput: TwilioAudioOutput- Audio output streamtextOutput: TwilioTextOutput- Text output streamconfig: TransportAdapterConfig- Configuration objectisOpen: boolean- Whether the transport is active
Methods:
handleMessage(message: string)- Process incoming Twilio messageclearAudio()- Clear audio bufferclose()- Close the transport
createTwilioWorker(options) (Unstable)
⚠️ Note: This Cloudflare Workers integration helper is currently unstable and not officially supported.
Cloudflare Workers integration helper.
export default createTwilioWorker({
agent: () => createAriaFlowSession({...}),
});Options:
agent: () => Agent | { agent: Agent; sessionOptions: any }- Agent factorystt?: any- STT instance (for raw LiveKit pattern)llm?: any- LLM instancetts?: any- TTS instancevad?: any- VAD instanceturnDetection?: any- Turn detection config
Environment Compatibility
| Runtime | WebSocket Support | Status |
|---------|------------------|--------|
| Cloudflare Workers | ✅ Native | ⚠️ Unstable |
| Node.js | ✅ via ws package | ✅ Supported |
| Deno | ✅ Native | ✅ Supported |
| Bun | ✅ Native | ✅ Supported |
| Browser | ✅ Native | ✅ Supported (development only) |
Limitations
- Twilio Sample Rate: Twilio uses 8kHz G.711 μ-law. The transport resamples to 24kHz for AriaFlow, but this adds slight latency.
- Codec: Only G.711 μ-law is supported (Twilio's standard).
- Latency: Expect 500-1000ms additional latency compared to direct WebRTC.
- Full Duplex: Twilio Media Streams is full-duplex, but the implementation treats inbound/outbound as separate streams.
Troubleshooting
Audio cutting out
- Check your WebSocket connection is stable
- Verify
sendcallback is working correctly - Check for errors in the console
Poor audio quality
- The 8kHz sample rate is lower than typical 24kHz
- This is a Twilio limitation, not the transport
- Consider using Twilio's programmable voice SDK for higher quality
Connection issues
- Ensure your WebSocket URL is publicly accessible
- Check Twilio can reach your server (no firewall blocking)
- Verify CORS headers if using browser-based testing
Examples
See examples/ directory for:
cloudflare_worker.ts- Complete Cloudflare Worker example (⚠️ Unstable)wrangler.toml- Deployment configuration
License
Apache-2.0
Related Packages
@ariaflow/livekit-plugin- Core AriaFlow LiveKit integration@ariaflow/livekit-plugin/gemini- Gemini STT/TTS plugins@ariaflow/livekit-plugin-transport-ws- WebSocket transport@ariaflow/livekit-plugin-transport-http- HTTP/SSE transport
