From 6f7664846cace2b4109cd9a207c69deabc700ebc Mon Sep 17 00:00:00 2001 From: Mark Backman Date: Tue, 24 Feb 2026 12:53:55 -0500 Subject: [PATCH 1/2] Add can_generate_metrics to Soniox and AWS Transcribe STT services Commit 859cd7c9 refactored STT TTFB measurement to use the base class start_ttfb_metrics/stop_ttfb_metrics, which are gated behind can_generate_metrics(). Soniox and AWS Transcribe never overrode this method (default returns False), so TTFB was silently never reported. --- changelog/3813.fixed.md | 1 + src/pipecat/services/aws/stt.py | 8 ++++++++ src/pipecat/services/soniox/stt.py | 8 ++++++++ 3 files changed, 17 insertions(+) create mode 100644 changelog/3813.fixed.md diff --git a/changelog/3813.fixed.md b/changelog/3813.fixed.md new file mode 100644 index 000000000..9d9115e77 --- /dev/null +++ b/changelog/3813.fixed.md @@ -0,0 +1 @@ +- Fixed STT TTFB metrics not being reported for `SonioxSTTService` and `AWSTranscribeSTTService` due to missing `can_generate_metrics()` override. diff --git a/src/pipecat/services/aws/stt.py b/src/pipecat/services/aws/stt.py index 09552ecfc..c53e3648c 100644 --- a/src/pipecat/services/aws/stt.py +++ b/src/pipecat/services/aws/stt.py @@ -126,6 +126,14 @@ class AWSTranscribeSTTService(WebsocketSTTService): self._receive_task = None + def can_generate_metrics(self) -> bool: + """Check if this service can generate processing metrics. + + Returns: + True, as AWS Transcribe STT supports metrics generation. + """ + return True + def get_service_encoding(self, encoding: str) -> str: """Convert internal encoding format to AWS Transcribe format. diff --git a/src/pipecat/services/soniox/stt.py b/src/pipecat/services/soniox/stt.py index 1e4b49705..61dbb794f 100644 --- a/src/pipecat/services/soniox/stt.py +++ b/src/pipecat/services/soniox/stt.py @@ -208,6 +208,14 @@ class SonioxSTTService(WebsocketSTTService): self._receive_task = None + def can_generate_metrics(self) -> bool: + """Check if this service can generate processing metrics. + + Returns: + True, as Soniox STT supports metrics generation. + """ + return True + async def start(self, frame: StartFrame): """Start the Soniox STT websocket connection. From 23ad1815156614667e23c7bfd37f540e86619cbc Mon Sep 17 00:00:00 2001 From: Mark Backman Date: Tue, 24 Feb 2026 13:09:29 -0500 Subject: [PATCH 2/2] Fix Soniox processing metrics to measure token-to-transcript time Move start_processing_metrics from run_stt (called per audio chunk, producing noisy 0ms logs) to _receive_messages when the first final token arrives for a new utterance. The existing stop_processing_metrics in send_endpoint_transcript completes the pair, giving a meaningful measurement of time from first recognition to finalized transcript. --- src/pipecat/services/soniox/stt.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pipecat/services/soniox/stt.py b/src/pipecat/services/soniox/stt.py index 61dbb794f..630e11862 100644 --- a/src/pipecat/services/soniox/stt.py +++ b/src/pipecat/services/soniox/stt.py @@ -301,10 +301,8 @@ class SonioxSTTService(WebsocketSTTService): Yields: Frame: None (transcription results come via WebSocket callbacks). """ - await self.start_processing_metrics() if self._websocket and self._websocket.state is State.OPEN: await self._websocket.send(audio) - await self.stop_processing_metrics() yield None @@ -485,6 +483,8 @@ class SonioxSTTService(WebsocketSTTService): # the rest will be sent as interim tokens (even final tokens). await send_endpoint_transcript() else: + if not self._final_transcription_buffer: + await self.start_processing_metrics() self._final_transcription_buffer.append(token) else: non_final_transcription.append(token)