modern-camera-1918
03/23/2026, 5:43 AMtall-airline-16756
03/23/2026, 5:43 AMtall-airline-16756
03/23/2026, 5:43 AMsession.say() / generate_reply() produce audio (appears in transcript) but the callee hears silence unless they speak first. You’re on self-hosted LiveKit v1.9.12 + SIP bridge, Python agents v1.5.0, Deepgram TTS, and Twilio SIP trunk. You’ve already verified callStatus is active, the SIP bridge subscribes to the agent’s roomio_audio track, TTS generates audio, and audio appears in transcripts.
Quick summary of likely areas to check (what you CAN do next)
• Media flow & SSRC/DTMF timing: If the SIP endpoint has not started receiving RTP from LiveKit (or RTP packets are being dropped) until it receives audio from the callee, the endpoint could be in a receive-only state. Check whether the SIP endpoint expects a specific RTP/RTCP exchange pattern (some trunks disable media until they detect incoming media). You can test by forcing RTP to start earlier (see next steps).
• Early RTP/hold/unmute semantics: Make sure the SIP call is not put in a state that mutes or holds media from the LiveKit side until remote RTP is detected. Verify SDP direction attributes and the negotiated media direction (sendrecv vs sendonly vs recvonly) at call establishment.
• SDP offered/answer differences: Compare the SDP from LiveKit → SIP and SIP → LiveKit on calls where agent speaks first vs where callee speaks first. Look for direction flags (a=sendrecv, a=sendonly, a=recvonly, a=inactive) and codec mismatches. If LiveKit is negotiating recvonly toward the SIP endpoint initially, the callee won’t hear agent audio.
• RTP forwarding from SIP bridge: Confirm the SIP bridge is actually forwarding RTP packets to the SIP trunk when agent audio is generated. Capture RTP on the EC2 interface and/or from the Twilio side to see if packets are leaving LiveKit/SIP bridge when session.say() runs.
• Media SSRC and track mapping: Ensure the roomio_audio track’s SSRC and payload type are mapped correctly in the bridge’s SDP. If payload types differ and no dynamic mapping is applied, RTP may be dropped by the SIP side.
• DTMF / comfort noise / silence suppression: Check whether the SIP trunk or callee endpoint applies silence suppression or VAD and is dropping the TTS audio if it starts with low energy. Try sending an initial short tone or audible playout (e.g., 200 ms of white noise or a short beep) before TTS to see if that wakes the callee’s audio path.
• Twilio SIP trunk specifics: Some trunks or proxies may delay media until they see RTP from the far end. Verify Twilio’s SIP trunk settings for early media and NAT keepalive behavior.
Targeted diagnostic steps (please run when convenient)
1. Capture SDPs:
â—¦ Save the a) SDP from LiveKit->SIP and b) SDP from SIP->LiveKit for a call where agent speaks first and callee hears nothing. Paste the two SDPs here (redact sensitive IPs if needed).
1. Network capture on EC2:
â—¦ Capture UDP/TCP packets on the EC2 interface during an agent-first call and when callee speaks-first (pcap). Look for RTP from LiveKit to Twilio and confirm timestamps align with session.say() audio generation.
1. Verify RTP is sent immediately:
â—¦ While reproducing, run a packet capture filtered for RTP ports used by the bridge to confirm RTP packets are emitted when session.say() runs.
1. Test a “wake” sound:
â—¦ Modify the agent to play a short tone (e.g., 300 Hz sine wave, 200 ms) before the TTS speech. If the callee hears the tone, it likely indicates a receive-only or silence suppression behavior on the SIP/trunk side.
1. Check negotiated directions:
â—¦ From the SDPs, confirm LiveKit advertises sendrecv and the SIP side does not answer recvonly toward LiveKit.
1. Try forcing a small RTP stream:
â—¦ If possible, send a short RTP keepalive or periodic audio packets to Twilio immediately after call connect and before session.say() to ensure media path is open.
Information I need from you to narrow this down (please provide any that you can)
• A sanitized copy of the two SDPs (LiveKit→SIP and SIP→LiveKit) for a failing agent-first call.
• A short pcap or confirmation whether RTP packets leave the SIP bridge when session.say() is invoked.
• Any SIP/trunk settings on Twilio that could affect early media, silence suppression, or RTP gating.
• Whether the callee endpoint is a SIP phone, PSTN via Twilio, or mobile — and whether behavior differs by callee type.
• The SIP bridge logs around call setup and when session.say() is executed (timestamps help).
Why I’m asking for these: the symptoms point strongly to media-negotiation or RTP-forwarding timing rather than TTS or LiveKit SDK logic, since you see transcripts and bridge subscriptions but no audio at the callee. The SDPs, RTP traces, and trunk settings will reveal whether the SIP side is refusing audio until it detects incoming media or if SSRC/codecs are mismatched.
Short-term workaround ideas to try now
• Prepend a short audible tone or a brief 200–500 ms audio burst before the actual greeting to force the callee’s media path open.
• If you can control Twilio settings, enable any “early media” or disable silence suppression features for the trunk to see if that allows agent-first audio.
• Try a test using a different SIP endpoint (pure SIP UA) to see if the problem is Twilio-specific.
If you share the SDP and/or a short pcap and any Twilio trunk settings, I’ll analyze them and give concrete next steps (we can check exact SDP attributes, payload types, and expected RTP mappings).
, with interactive elementsmodern-camera-1918
03/23/2026, 5:59 AMtall-airline-16756
03/23/2026, 5:59 AMsession.say() runs.
â—¦ If no RTP is emitted until the callee speaks, that confirms the bridge is deferring forwarding.
• Add bridge debug logs around RTP forwarding to see the exact condition that toggles forwarding (e.g., inbound RTP detection, RTCP, or SDP event).
3) Bridge code change (self-hosted, more involved but definitive)
• Modify the SIP bridge logic to begin forwarding RTP immediately after the agent track is subscribed and the call is active — i.e., do not require prior inbound RTP detection.
• Areas to inspect/patch:
◦ The “RTP gating” or “wait for inbound RTP” logic in the SIP bridge implementation (this is what PR #165 and related discussion reference).
â—¦ Ensure the bridge will still respect sendrecv SDP semantics and handle RTP/RTCP correctly (SSRC/payload-type mapping).
• If you’re comfortable editing the bridge, I can point you to the likely code paths to change (where the bridge waits for inbound RTP before creating/forwarding RTP sockets). If you prefer, paste the bridge logs and I’ll point to specific files/conditions to inspect.
• This change is only viable for self-hosted deployments and will require careful testing with various trunks to avoid regressions.
4) Longer-term: upstream fix or feature
• The underlying issue appears to be a SIP bridge media-policy limitation. If the bridge were changed to not defer forwarding, agent-first speech would work for all self-hosted users.
• You’ve already filed a GitHub issue — continue that thread and reference your SDPs and RTP captures. If a PR exists (PR #165 style), ask if it can be backported to your v1.9.12 stack or provide guidance on applying the patch.
What I can help with next
• If you want to try the bridge patch route, tell me whether you can share the SIP bridge logs and the bridge repo version/commit. I’ll point to the specific code paths to change and suggested patch logic.
• If you prefer the diagnostics route, share a short pcap (RTP) or the bridge debug logs for a failing agent-first call and I’ll confirm whether RTP is leaving the bridge.
• If you want to test a stronger wake tone and need a quick snippet to generate a 1 kHz 300 ms tone via your agent, tell me your agent language and I’ll provide code.
If you tell me which path you want to take (workaround, diagnostics, or bridge patch), I’ll give targeted next steps and exact commands/snippets.
Sources: examples/voice_agents | livekit/livekit_composite | DeepWiki | sip | livekit/livekit_composite | DeepWiki | Agents telephony integration | LiveKit Documentation | Outbound Calling Script | LiveKit Documentation | examples/dtmf | livekit/livekit_composite | DeepWiki, with interactive elementsmodern-camera-1918
03/23/2026, 6:10 AMtall-airline-16756
03/23/2026, 6:11 AMmodern-camera-1918
03/23/2026, 6:19 AM