Cloudflare's Voice Agents Can Now Tell You Exactly Where a Call Got Stuck!
Hi, it's me, Shiichan! Today I've got an update for Cloudflare's voice agent package.
Cloudflare ChangelogWhat was announced?
According to Cloudflare's Changelog, @cloudflare/voice v0.4.0 now lets you inspect, for every single conversation turn of a Voice Agent, where time was spent and how that turn ended. @cloudflare/voice is the package for building real-time voice agents on top of Cloudflare Agents: it streams microphone audio to an Agent over WebSocket, transcribes the speech, runs your model through onTurn(), converts the response to speech, and streams audio back to the caller.
A turn moves through roughly these stages:
- The user speaks
- Speech-to-text
- The model generates a response
- Text-to-speech
- Audio is streamed back
The story so far
The package previously shipped four aggregate metrics, but they only covered successful, non-empty speech turns. That meant failed, aborted, empty, or text-only turns had no visibility into how they actually ended — making it hard to tell where a broken conversation had gone wrong.
What changes
Now, every speech or text turn produces a typed VoiceTurnMetrics summary, covering successful turns as well as failed, aborted, and empty ones. You can finally see why a turn ended the way it did and where the time went. For anyone running Voice Agents in production, this makes tracking down latency bottlenecks and isolating error causes much easier.
Dive Deep
Each VoiceTurnMetrics summary includes:
- A
turnIdfor correlating events from the same turn - A terminal
outcomedescribing how the turn ended (see below) - Timings for key processing stages
The terminal outcome is one of:
completed— finished successfullyno_output— ended with no outputoutput_limit— hit an output limitcontent_filtered— stopped by content filteringmodel_error— an error from the modeltts_error— an error from text-to-speechaborted— the turn was aborted
Timings cover these key stages:
- Speech-to-final-transcript
- Model-to-first-text
- TTS-to-first-audio
- Total turn duration
These timings can overlap, so they are not simply additive, and timings for stages a given turn never reached are omitted. Here's how you subscribe to them:
client.addEventListener("turnmetrics", (turn) => {
console.log(turn.outcome, turn.turnTotalMs);
});
The latest VoiceTurnMetrics summary is available through VoiceClient, useVoiceAgent(), or useVoiceInput(). Note that useVoiceInput() only includes the speech and transcription timings it can measure directly.
On top of that, passing diagnostics: { browserConsole: true } to withVoice() forwards server-side lifecycle events to the browser console alongside local microphone, connection, and playback events.
To use this, you'll need @cloudflare/voice@^0.4.0 along with agents@^0.22.0 or later.
Wrap-up
@cloudflare/voicev0.4.0 addsVoiceTurnMetricsper turn, with aturnId, a terminaloutcome, and per-stage timings- Outcomes are one of
completed,no_output,output_limit,content_filtered,model_error,tts_error, oraborted - Timings cover speech-to-final-transcript, model-to-first-text, TTS-to-first-audio, and total turn duration — they can overlap, so don't just add them up
- Get the latest metrics via
VoiceClient,useVoiceAgent(), oruseVoiceInput(), and combine them withbrowserConsolediagnostics - Requires
agents@^0.22.0+. Great for anyone running voice agents on Cloudflare Agents who wants to pin down why a call failed or where the latency went!