From ddf6a418543b02884bea0b73468a1442447de337 Mon Sep 17 00:00:00 2001 From: Mark Backman Date: Tue, 24 Mar 2026 16:11:35 -0400 Subject: [PATCH 1/3] Add on_end_of_turn event handler to AssemblyAI STT Fires after the final transcript is pushed in both Pipecat and AssemblyAI turn detection modes, giving users a reliable hook that arrives after all transcript frames. Matches the existing Deepgram Flux on_end_of_turn pattern. --- src/pipecat/services/assemblyai/stt.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/pipecat/services/assemblyai/stt.py b/src/pipecat/services/assemblyai/stt.py index fa723a771..8b273188f 100644 --- a/src/pipecat/services/assemblyai/stt.py +++ b/src/pipecat/services/assemblyai/stt.py @@ -129,6 +129,16 @@ class AssemblyAISTTService(WebsocketSTTService): Provides real-time speech transcription using AssemblyAI's WebSocket API. Supports both interim and final transcriptions with configurable parameters for audio processing and connection management. + + Event handlers available (in addition to WebsocketSTTService events): + + - on_end_of_turn(service, transcript): Called when AssemblyAI detects end of turn. + + Example:: + + @service.event_handler("on_end_of_turn") + async def on_end_of_turn(service, transcript): + ... """ Settings = AssemblyAISTTSettings @@ -303,6 +313,8 @@ class AssemblyAISTTService(WebsocketSTTService): self._user_speaking = False + self._register_event_handler("on_end_of_turn") + def _configure_pipecat_turn_mode(self, settings: Settings, is_u3_pro: bool): """Configure settings for Pipecat turn detection mode. @@ -741,6 +753,7 @@ class AssemblyAISTTService(WebsocketSTTService): ) await self._trace_transcription(transcript_text, True, language) await self.stop_processing_metrics() + await self._call_event_handler("on_end_of_turn", transcript_text) else: await self.push_frame( InterimTranscriptionFrame( @@ -774,6 +787,7 @@ class AssemblyAISTTService(WebsocketSTTService): # above, so ordering is preserved) and upstream. await self.broadcast_frame(UserStoppedSpeakingFrame) self._user_speaking = False + await self._call_event_handler("on_end_of_turn", transcript_text) else: await self.push_frame( InterimTranscriptionFrame( From 6c30371295109740d19a344a15fa188c3aca384c Mon Sep 17 00:00:00 2001 From: Mark Backman Date: Tue, 24 Mar 2026 16:12:25 -0400 Subject: [PATCH 2/3] Fix Deepgram Flux event handler docstring to match implementation Update documented event signatures to include transcript argument where the code actually passes it. Remove stale on_speech_started and on_utterance_end entries that were never registered. --- src/pipecat/services/deepgram/flux/stt.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/pipecat/services/deepgram/flux/stt.py b/src/pipecat/services/deepgram/flux/stt.py index 64d4e87b9..c75a092a0 100644 --- a/src/pipecat/services/deepgram/flux/stt.py +++ b/src/pipecat/services/deepgram/flux/stt.py @@ -102,16 +102,15 @@ class DeepgramFluxSTTService(WebsocketSTTService): Event handlers available (in addition to WebsocketSTTService events): - - on_speech_started(service): Deepgram detected start of speech - - on_utterance_end(service): Deepgram detected end of utterance - - on_end_of_turn(service): Deepgram detected end of turn (EOT) - - on_eager_end_of_turn(service): Deepgram predicted end of turn (EagerEOT) + - on_start_of_turn(service, transcript): Deepgram detected start of speech + - on_end_of_turn(service, transcript): Deepgram detected end of turn (EOT) + - on_eager_end_of_turn(service, transcript): Deepgram predicted end of turn (EagerEOT) - on_turn_resumed(service): User resumed speaking after EagerEOT Example:: @stt.event_handler("on_end_of_turn") - async def on_end_of_turn(service): + async def on_end_of_turn(service, transcript): ... """ From b66c89210044afc6286da378e791b31240d6c591 Mon Sep 17 00:00:00 2001 From: Mark Backman Date: Tue, 24 Mar 2026 16:15:00 -0400 Subject: [PATCH 3/3] Add changelog for #4128 --- changelog/4128.added.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog/4128.added.md diff --git a/changelog/4128.added.md b/changelog/4128.added.md new file mode 100644 index 000000000..7cbeed91b --- /dev/null +++ b/changelog/4128.added.md @@ -0,0 +1 @@ +- Added `on_end_of_turn` event handler to `AssemblyAISTTService`. This fires after the final transcript is pushed, providing a reliable hook for end-of-turn logic that doesn't race with `TranscriptionFrame`. Works in both Pipecat and AssemblyAI turn detection modes.