From 64ed0aae1305e99f1d55d9583dbde194018692a2 Mon Sep 17 00:00:00 2001 From: Mark Backman Date: Mon, 13 Apr 2026 17:28:34 -0400 Subject: [PATCH] Reconnect Cartesia STT websocket when settings change at runtime Previously settings updates were ignored with a TODO comment. Now when model/language changes via STTUpdateSettingsFrame the service disconnects and reconnects with the new query parameters. Key changes: - Implement _update_settings to disconnect/reconnect on changes - Check `is not State.OPEN` in run_stt to catch CLOSING state - Send `done` command before closing for clean session shutdown - Capture websocket reference in _disconnect_websocket to prevent a concurrent _connect from having its new connection nulled by a stale finally block --- src/pipecat/services/cartesia/stt.py | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/pipecat/services/cartesia/stt.py b/src/pipecat/services/cartesia/stt.py index 85d43bcd3..e213652c1 100644 --- a/src/pipecat/services/cartesia/stt.py +++ b/src/pipecat/services/cartesia/stt.py @@ -285,8 +285,8 @@ class CartesiaSTTService(WebsocketSTTService): Yields: None - transcription results are handled via WebSocket responses. """ - # If the connection is closed, due to timeout, we need to reconnect when the user starts speaking again - if not self._websocket or self._websocket.state is State.CLOSED: + # If the connection is not open (closed or closing), reconnect + if not self._websocket or self._websocket.state is not State.OPEN: await self._connect() await self._websocket.send(audio) @@ -320,13 +320,12 @@ class CartesiaSTTService(WebsocketSTTService): """ changed = await super()._update_settings(delta) - # TODO: someday we could reconnect here to apply updated settings. - # Code might look something like the below: - # if changed: - # await self._disconnect() - # await self._connect() + if not changed: + return changed - self._warn_unhandled_updated_settings(changed) + if self._websocket: + await self._disconnect() + await self._connect() return changed @@ -351,14 +350,18 @@ class CartesiaSTTService(WebsocketSTTService): await self.push_error(error_msg=f"Unknown error occurred: {e}", exception=e) async def _disconnect_websocket(self): + ws = self._websocket try: - if self._websocket and self._websocket.state is State.OPEN: + if ws and ws.state is State.OPEN: logger.debug("Disconnecting from Cartesia STT") - await self._websocket.close() + await ws.send("done") + await ws.close() except Exception as e: await self.push_error(error_msg=f"Error closing websocket: {e}", exception=e) finally: - self._websocket = None + # Only clear if no concurrent _connect has already replaced it. + if self._websocket is ws: + self._websocket = None await self._call_event_handler("on_disconnected") def _get_websocket(self):