Keep the call at 8 kHz, and sit before the fork.
A LiveKit SIP path gives you narrowband caller audio and exactly one enhancement option at the trunk — the bundled one. This plugin runs inside your agent process, which is the one place you can choose differently, keep the call at its native rate, and measure what the path is actually delivering.
pip install anecho-livekit-pluginBefore you add any processing, check what your audio path is already doing. Frame accounting is worth checking: if your first processor receives fewer seconds than the caller sent, something upstream is dropping audio and no enhancer can put it back.
What we will not tell you is how much that costs you in accuracy, because we tried to and our own control refuted it. An earlier version of this page repeated a community report attributing a large fixed loss of every caller’s audio to the default frame-processor pattern, together with an operator’s transcription recovery credited to fixing it. We measured the round trip: at telephony’s exact 2:1 ratio it is close to the identity, and with no model in the path resampler quality moves word error rate by a fraction of a point. Frame accounting is real; the accuracy claim we attached to it is not ours to make.
from anecho_livekit_plugin import audit_input_path
# Compares what the caller sent against what your first processor received.
report = await audit_input_path(track, seconds=20)
print(report.frames_in, report.frames_out, report.dropped_ratio)
# dropped_ratio > 0.01 means the path is losing audio before any model runs.import os
from livekit.agents import AgentSession
from livekit.plugins import deepgram, openai, cartesia
from anecho_livekit_plugin import AnechoAudio
session = AgentSession(
audio_processor=AnechoAudio(
api_key=os.environ["ANECHO_API_KEY"],
model="clearline-s", # Clearline: native narrowband
sample_rate=8000, # stays 8 kHz through the whole chain
echo_suppression=True, # residual echo left over by the carrier's AEC
split_pipeline=True, # enhanced -> turn detection, raw -> stt
),
stt=deepgram.STT(),
llm=openai.LLM(model="gpt-4o-mini"),
tts=cartesia.TTS(),
)
await session.start(room=ctx.room, agent=MyAgent())AnechoAudio registers itself as the room’s audio processor and publishes two internal tracks. The turn detector subscribes to the enhanced one; the STT node subscribes to the raw one. Nothing else in your agent changes.
WebRTC participants arrive wideband. Use chamber and let the plugin pick the rate off the track.
anecho = AnechoAudio(
model="chamber-s",
sample_rate=None, # follow the track
split_pipeline=True,
)Pooled across every condition, our published results say enhancement raised word error rate on all ten engines we tested. That is a statement about our test set and one recogniser, not about your traffic. The plugin will transcribe both channels on a sampled slice so you can settle it on your own data.
anecho = AnechoAudio(
model="clearline-s",
split_pipeline=True,
shadow_stt=True,
shadow_rate=0.02, # 2% of calls, not all of them
)
@anecho.on("shadow_result")
def _(ev):
log.info("wer_raw=%.4f wer_enh=%.4f delta=%+.4f",
ev.wer_raw, ev.wer_enhanced, ev.wer_enhanced - ev.wer_raw)