Skip to content

v0.1.0 — Within Earshot (first public release)

Choose a tag to compare

@xpertvoip xpertvoip released this 05 Aug 08:25
· 71 commits to main since this release

mod_earshot 0.1.0 — first public release

A FreeSWITCH module that bridges live call audio to your AI voice agent over one WebSocket — full-duplex, with the agent's voice played back reliably on the same leg. A drop-in mod_audio_stream alternative whose playback actually works, with seven protocol adapters, module-side turn-taking, agent-driven call control, PCI masking, multi-stream fan-out, and typed ESL events.

The transport, full-duplex audio path, and playout are validated end-to-end on real SIP calls with real audio — live OpenAI Realtime and Deepgram Voice Agent sessions (Deepgram from a hardware SIP phone), plus a shared-pool concurrency + soak load test.

Highlights

  • Playback that works — the WRITE_REPLACE agent→caller path validated with real audio, full duplex, on one leg. This is the wedge the incumbent module never delivered.
  • 7 protocol adapters — native, twilio, openai (Realtime), deepgram (Voice Agent), elevenlabs, gemini (Live), pipecat. Swap vendors with one word (proto=).
  • Turn-taking for any agent — module-side VAD → speech_started/speech_stopped, a ready-gate (no "answered into silence"), and speech-triggered barge-in.
  • Agent drives the call — opt-in, whitelisted control channel (transfer / hangup / DTMF / play / record / hold / bridge / setvar), every action audited via earshot::command.
  • PCI/PII masking — mute caller audio + redact DTMF to the agent during card entry, while digits still reach a secure collector.
  • Multi-stream fan-out — agent + live transcription + supervisor on one call.
  • Scales with sessions, not threads — all streams share a small pool of libwebsockets service contexts (~1 MB/session vs ~17 MB thread-per-stream), so a small box holds thousands of sessions where thread-per-stream hit a wall near ~420. Validated to 150 concurrent + a 12-minute flat-memory soak, mass-teardown/RST-storm without a crash, and a ThreadSanitizer-clean fuzz run.
  • Observable — typed earshot:: custom events over the FreeSWITCH event socket (ESL) + latency KPIs (time-to-first-audio, per-turn response, WebSocket RTT), keyed to a two-key trace (SIP Call-ID + channel UUID).
  • Drop-in migration — uuid_audio_stream / audio_stream compat runs existing mod_audio_stream dialplans unchanged.

Adapter validation (stated per vendor, not blanket)

native · openai · deepgram — live-validated on a real call · pipecat — against Pipecat's official protobuf schema · twilio — WebSocket echo round-trip · elevenlabs · gemini — implemented, not yet live-validated (see the adapter status table in the README).

Install

Needs FreeSWITCH dev headers + libwebsockets-dev:

cmake -S . -B build && cmake --build build
sudo cmake --install build        # -> /usr/lib/freeswitch/mod/mod_earshot.so
fs_cli -x "load mod_earshot"

Quickstart recipes in QUICKSTART.md, full option/verb/event reference in docs/API.md.

License: MIT · Full changelog: CHANGELOG.md