Invoking superclass method when audio context is interrupted or completed.

This commit is contained in:
filipi87
2026-03-26 10:14:21 -03:00
parent 2ff4b3f4a3
commit f7ec6befe1
10 changed files with 16 additions and 3 deletions

View File

@@ -435,6 +435,7 @@ class AsyncAITTSService(WebsocketTTSService):
async def on_audio_context_interrupted(self, context_id: str): async def on_audio_context_interrupted(self, context_id: str):
"""Close the Async AI context when the bot is interrupted.""" """Close the Async AI context when the bot is interrupted."""
await self._close_context(context_id) await self._close_context(context_id)
await super().on_audio_context_interrupted(context_id)
async def on_audio_context_completed(self, context_id: str): async def on_audio_context_completed(self, context_id: str):
"""Close the Async AI context after all audio has been played. """Close the Async AI context after all audio has been played.
@@ -444,6 +445,7 @@ class AsyncAITTSService(WebsocketTTSService):
``close_context: True`` to free server-side resources. ``close_context: True`` to free server-side resources.
""" """
await self._close_context(context_id) await self._close_context(context_id)
await super().on_audio_context_completed(context_id)
@traced_tts @traced_tts
async def run_tts(self, text: str, context_id: str) -> AsyncGenerator[Frame, None]: async def run_tts(self, text: str, context_id: str) -> AsyncGenerator[Frame, None]:

View File

@@ -574,6 +574,7 @@ class CartesiaTTSService(WebsocketTTSService):
if context_id: if context_id:
cancel_msg = json.dumps({"context_id": context_id, "cancel": True}) cancel_msg = json.dumps({"context_id": context_id, "cancel": True})
await self._get_websocket().send(cancel_msg) await self._get_websocket().send(cancel_msg)
await super().on_audio_context_interrupted(context_id)
async def on_audio_context_completed(self, context_id: str): async def on_audio_context_completed(self, context_id: str):
"""Close the Cartesia context after all audio has been played. """Close the Cartesia context after all audio has been played.
@@ -582,7 +583,7 @@ class CartesiaTTSService(WebsocketTTSService):
done once it has sent its ``done`` message, which is handled in done once it has sent its ``done`` message, which is handled in
``_process_messages``. ``_process_messages``.
""" """
pass await super().on_audio_context_completed(context_id)
async def flush_audio(self, context_id: Optional[str] = None): async def flush_audio(self, context_id: Optional[str] = None):
"""Flush any pending audio and finalize the current context. """Flush any pending audio and finalize the current context.

View File

@@ -309,6 +309,7 @@ class DeepgramSageMakerTTSService(TTSService):
await self._client.send_json({"type": "Clear"}) await self._client.send_json({"type": "Clear"})
except Exception as e: except Exception as e:
logger.error(f"{self} error sending Clear message: {e}") logger.error(f"{self} error sending Clear message: {e}")
await super().on_audio_context_interrupted(context_id)
async def flush_audio(self, context_id: Optional[str] = None): async def flush_audio(self, context_id: Optional[str] = None):
"""Flush any pending audio synthesis by sending Flush command. """Flush any pending audio synthesis by sending Flush command.

View File

@@ -277,6 +277,7 @@ class DeepgramTTSService(WebsocketTTSService):
await self._websocket.send(json.dumps({"type": "Clear"})) await self._websocket.send(json.dumps({"type": "Clear"}))
except Exception as e: except Exception as e:
logger.error(f"{self} error sending Clear message: {e}") logger.error(f"{self} error sending Clear message: {e}")
await super().on_audio_context_interrupted(context_id)
async def _receive_messages(self): async def _receive_messages(self):
"""Receive and process messages from Deepgram WebSocket.""" """Receive and process messages from Deepgram WebSocket."""

View File

@@ -731,6 +731,7 @@ class ElevenLabsTTSService(WebsocketTTSService):
async def on_audio_context_interrupted(self, context_id: str): async def on_audio_context_interrupted(self, context_id: str):
"""Close the ElevenLabs context when the bot is interrupted.""" """Close the ElevenLabs context when the bot is interrupted."""
await self._close_context(context_id) await self._close_context(context_id)
await super().on_audio_context_interrupted(context_id)
async def on_audio_context_completed(self, context_id: str): async def on_audio_context_completed(self, context_id: str):
"""Close the ElevenLabs context after all audio has been played. """Close the ElevenLabs context after all audio has been played.
@@ -740,6 +741,7 @@ class ElevenLabsTTSService(WebsocketTTSService):
``close_context: True`` to free server-side resources. ``close_context: True`` to free server-side resources.
""" """
await self._close_context(context_id) await self._close_context(context_id)
await super().on_audio_context_completed(context_id)
async def _receive_messages(self): async def _receive_messages(self):
"""Handle incoming WebSocket messages from ElevenLabs.""" """Handle incoming WebSocket messages from ElevenLabs."""

View File

@@ -363,6 +363,7 @@ class FishAudioTTSService(InterruptibleTTSService):
async def on_audio_context_interrupted(self, context_id: str): async def on_audio_context_interrupted(self, context_id: str):
"""Stop all metrics when audio context is interrupted.""" """Stop all metrics when audio context is interrupted."""
await self.stop_all_metrics() await self.stop_all_metrics()
await super().on_audio_context_interrupted(context_id)
async def _receive_messages(self): async def _receive_messages(self):
async for message in self._get_websocket(): async for message in self._get_websocket():

View File

@@ -301,6 +301,7 @@ class GradiumTTSService(WebsocketTTSService):
audio context no longer exists. audio context no longer exists.
""" """
await self.stop_all_metrics() await self.stop_all_metrics()
await super().on_audio_context_interrupted(context_id)
async def on_audio_context_completed(self, context_id: str): async def on_audio_context_completed(self, context_id: str):
"""Called after an audio context has finished playing all of its audio. """Called after an audio context has finished playing all of its audio.
@@ -309,7 +310,7 @@ class GradiumTTSService(WebsocketTTSService):
``end_of_stream`` message (handled in ``_receive_messages``), after ``end_of_stream`` message (handled in ``_receive_messages``), after
which the server-side context is already closed. which the server-side context is already closed.
""" """
pass await super().on_audio_context_completed(context_id)
async def _receive_messages(self): async def _receive_messages(self):
"""Process incoming websocket messages, demultiplexing by client_req_id.""" """Process incoming websocket messages, demultiplexing by client_req_id."""

View File

@@ -800,6 +800,7 @@ class InworldTTSService(WebsocketTTSService):
async def on_audio_context_interrupted(self, context_id: str): async def on_audio_context_interrupted(self, context_id: str):
"""Callback invoked when an audio context has been interrupted.""" """Callback invoked when an audio context has been interrupted."""
await self._close_context(context_id) await self._close_context(context_id)
await super().on_audio_context_interrupted(context_id)
def _get_websocket(self): def _get_websocket(self):
"""Get the websocket for the Inworld WebSocket TTS service. """Get the websocket for the Inworld WebSocket TTS service.

View File

@@ -258,6 +258,7 @@ class ResembleAITTSService(WebsocketTTSService):
async def on_audio_context_interrupted(self, context_id: str): async def on_audio_context_interrupted(self, context_id: str):
"""Stop metrics when the bot is interrupted.""" """Stop metrics when the bot is interrupted."""
await self.stop_all_metrics() await self.stop_all_metrics()
await super().on_audio_context_interrupted(context_id)
async def on_audio_context_completed(self, context_id: str): async def on_audio_context_completed(self, context_id: str):
"""Stop metrics after the Resemble AI context finishes playing. """Stop metrics after the Resemble AI context finishes playing.
@@ -266,7 +267,7 @@ class ResembleAITTSService(WebsocketTTSService):
``audio_end`` message (handled in ``_process_messages``), after which ``audio_end`` message (handled in ``_process_messages``), after which
the server-side context is already closed. the server-side context is already closed.
""" """
pass await super().on_audio_context_completed(context_id)
async def flush_audio(self, context_id: Optional[str] = None): async def flush_audio(self, context_id: Optional[str] = None):
"""Flush any pending audio and finalize the current context.""" """Flush any pending audio and finalize the current context."""

View File

@@ -516,6 +516,7 @@ class RimeTTSService(WebsocketTTSService):
async def on_audio_context_interrupted(self, context_id: str): async def on_audio_context_interrupted(self, context_id: str):
"""Clear the Rime speech queue and stop metrics when the bot is interrupted.""" """Clear the Rime speech queue and stop metrics when the bot is interrupted."""
await self._close_context(context_id) await self._close_context(context_id)
await super().on_audio_context_interrupted(context_id)
async def on_audio_context_completed(self, context_id: str): async def on_audio_context_completed(self, context_id: str):
"""Clear server-side state and stop metrics after the Rime context finishes playing. """Clear server-side state and stop metrics after the Rime context finishes playing.
@@ -525,6 +526,7 @@ class RimeTTSService(WebsocketTTSService):
any residual server-side state once all audio has been delivered. any residual server-side state once all audio has been delivered.
""" """
await self._close_context(context_id) await self._close_context(context_id)
await super().on_audio_context_completed(context_id)
def _calculate_word_times(self, words: list, starts: list, ends: list) -> list: def _calculate_word_times(self, words: list, starts: list, ends: list) -> list:
"""Calculate word timing pairs with proper spacing and punctuation. """Calculate word timing pairs with proper spacing and punctuation.