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:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user