This guide uses
tuner-stt-observer. It assumes you have a TunerSession set up. See the Quickstart for the session lifecycle and credentials.tuner-stt-observer hooks into your STT provider’s native event system to capture the user side of the conversation. It never proxies or modifies your audio stream. It listens to the same events your application already receives.
Supported adapters
Need a provider that isn’t listed? Extend
BaseSTTAdapter. See Custom providers below.
Install
Deepgram
DeepgramAdapter registers on Deepgram’s Open, Transcript, and UtteranceEnd events. speech_final transcript fragments are buffered internally and flushed as a single joined utterance when UtteranceEnd fires. You get one complete user turn per utterance.
Attach it to the Deepgram connection you already have:
Speechmatics
SpeechmaticsAdapter registers on ADD_TRANSCRIPT and END_OF_UTTERANCE. Speechmatics-rt stacks event handlers rather than replacing them, so the adapter coexists safely with any handlers you register yourself.
session_start_ns anchors them to wall-clock time so the adapter can measure STT latency. Without it, the latency field is omitted. If the value is captured slightly too early, the adapter corrects it automatically.
Custom providers
For providers other than Deepgram and Speechmatics, extendBaseSTTAdapter from tuner_stt_observer. Its docstring documents the full contract (_record_user_turn(), _record_stt_usage(), timestamp conversion) with a worked example.
What gets captured
Troubleshooting
Calls have no user turns (Deepgram)
Calls have no user turns (Deepgram)
- Your
LiveOptionsmust setutterance_end_ms(e.g."1000") andvad_events=True. Without them, Deepgram never emitsUtteranceEndand the utterance buffer never flushes.
User turns arrive as fragments
User turns arrive as fragments
- Fragments are joined per utterance. If you’re seeing one turn per fragment, the utterance-end event is never firing. On Deepgram, check
utterance_end_ms; on Speechmatics, confirm your session emitsEND_OF_UTTERANCE.
Next steps
Quickstart
The session lifecycle, credentials, and every observer wired together.
Text-to-Speech
Capture the agent side: synthesis latency and word-accurate interruption.
LangChain / LangGraph
Node transitions, tool calls, and LLM latency in your call timeline.
Create Call API
The underlying API every observer feeds into at flush time.