Flush Cartesia context on voice/model/language changes

Override _update_settings in CartesiaTTSService to flush the current
audio context and assign a new turn context ID when voice, model, or
language settings change. This prevents Context has closed errors
from Cartesia API, which locks these parameters per context.
This commit is contained in:
Mark Backman
2026-03-31 22:53:24 -04:00
parent e74930b954
commit eb014fffc4

View File

@@ -8,9 +8,10 @@
import base64
import json
import uuid
from dataclasses import dataclass, field
from enum import Enum
from typing import AsyncGenerator, List, Optional
from typing import Any, AsyncGenerator, List, Optional
import aiohttp
from loguru import logger
@@ -590,6 +591,33 @@ class CartesiaTTSService(WebsocketTTSService):
msg = self._build_msg(text="", continue_transcript=False, context_id=flush_id)
await self._websocket.send(msg)
async def _update_settings(self, delta: CartesiaTTSSettings) -> dict[str, Any]:
"""Apply a TTS settings delta, flushing the context if needed.
Voice, model, and language are locked per Cartesia context. If any of
these change, the current context is flushed so the next sentence opens
a fresh one with the updated settings.
Args:
delta: A TTS settings delta.
Returns:
Dict mapping changed field names to their previous values.
"""
changed = await super()._update_settings(delta)
if not changed:
return changed
if changed.keys() & {"voice", "model", "language"}:
if self._turn_context_id and self.audio_context_available(self._turn_context_id):
await self.flush_audio(context_id=self._turn_context_id)
# Assign a new turn context ID so subsequent sentences in this
# turn open a new Cartesia context with the updated settings.
if self._turn_context_id:
self._turn_context_id = str(uuid.uuid4())
return changed
async def _process_messages(self):
async for message in self._get_websocket():
msg = json.loads(message)