diff --git a/CHANGELOG.md b/CHANGELOG.md index 9fa6e08dc..9ad44f34b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 `tasks cancelled error` to a debug log. This removes the log from appearing in Pipecat logs upon leaving. +- The `websockets` dependency for a number of packages was updated to support + websockets>=13.1.0 and <15.0.0. This change provides greater compatibility + across Pipecat's packages. + - Updated `MiniMaxHttpTTSService` with a `base_url` arg where you can specify the Global endpoint (default) or Mainland China. diff --git a/pyproject.toml b/pyproject.toml index 8a112fd5f..c9e353e77 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -44,21 +44,21 @@ Website = "https://pipecat.ai" [project.optional-dependencies] anthropic = [ "anthropic~=0.49.0" ] -assemblyai = [ "websockets~=13.1" ] -aws = [ "aioboto3~=15.0.0", "websockets~=13.1" ] +assemblyai = [ "websockets>=13.1,<15.0" ] +aws = [ "aioboto3~=15.0.0", "websockets>=13.1,<15.0" ] aws-nova-sonic = [ "aws_sdk_bedrock_runtime~=0.0.2" ] azure = [ "azure-cognitiveservices-speech~=1.42.0"] -cartesia = [ "cartesia~=2.0.3", "websockets~=13.1" ] +cartesia = [ "cartesia~=2.0.3", "websockets>=13.1,<15.0" ] cerebras = [] deepseek = [] daily = [ "daily-python~=0.19.4" ] deepgram = [ "deepgram-sdk~=4.7.0" ] -elevenlabs = [ "websockets~=13.1" ] +elevenlabs = [ "websockets>=13.1,<15.0" ] fal = [ "fal-client~=0.5.9" ] fireworks = [] -fish = [ "ormsgpack~=1.7.0", "websockets~=13.1" ] -gladia = [ "websockets~=13.1" ] -google = [ "google-cloud-speech~=2.32.0", "google-cloud-texttospeech~=2.26.0", "google-genai~=1.24.0", "websockets~=13.1" ] +fish = [ "ormsgpack~=1.7.0", "websockets>=13.1,<15.0" ] +gladia = [ "websockets>=13.1,<15.0" ] +google = [ "google-cloud-speech~=2.32.0", "google-cloud-texttospeech~=2.26.0", "google-genai~=1.24.0", "websockets>=13.1,<15.0" ] grok = [] groq = [ "groq~=0.23.0" ] gstreamer = [ "pygobject~=3.50.0" ] @@ -66,22 +66,22 @@ krisp = [ "pipecat-ai-krisp~=0.4.0" ] koala = [ "pvkoala~=2.0.3" ] langchain = [ "langchain~=0.3.20", "langchain-community~=0.3.20", "langchain-openai~=0.3.9" ] livekit = [ "livekit~=0.22.0", "livekit-api~=0.8.2", "tenacity>=8.2.3,<10.0.0" ] -lmnt = [ "websockets~=13.1" ] +lmnt = [ "websockets>=13.1,<15.0" ] local = [ "pyaudio~=0.2.14" ] mcp = [ "mcp[cli]~=1.9.4" ] mem0 = [ "mem0ai~=0.1.94" ] mlx-whisper = [ "mlx-whisper~=0.4.2" ] moondream = [ "einops~=0.8.0", "timm~=1.0.13", "transformers>=4.48.0" ] nim = [] -neuphonic = [ "pyneuphonic~=1.5.13", "websockets~=13.1" ] +neuphonic = [ "pyneuphonic~=1.5.13", "websockets>=13.1,<15.0" ] noisereduce = [ "noisereduce~=3.0.3" ] -openai = [ "websockets~=13.1" ] +openai = [ "websockets>=13.1,<15.0" ] openpipe = [ "openpipe~=4.50.0" ] openrouter = [] perplexity = [] -playht = [ "pyht~=0.1.12", "websockets~=13.1" ] +playht = [ "pyht~=0.1.12", "websockets>=13.1,<15.0" ] qwen = [] -rime = [ "websockets~=13.1" ] +rime = [ "websockets>=13.1,<15.0" ] riva = [ "nvidia-riva-client~=2.21.1" ] sambanova = [] sentry = [ "sentry-sdk~=2.23.1" ] @@ -89,7 +89,7 @@ local-smart-turn = [ "coremltools>=8.0", "transformers", "torch==2.5.0", "torcha remote-smart-turn = [] silero = [ "onnxruntime~=1.20.1" ] simli = [ "simli-ai~=0.1.10"] -soniox = [ "websockets~=13.1" ] +soniox = [ "websockets>=13.1,<15.0" ] soundfile = [ "soundfile~=0.13.0" ] speechmatics = [ "speechmatics-rt>=0.3.1" ] tavus=[] @@ -97,7 +97,7 @@ together = [] tracing = [ "opentelemetry-sdk>=1.33.0", "opentelemetry-api>=1.33.0", "opentelemetry-instrumentation>=0.54b0" ] ultravox = [ "transformers>=4.48.0", "vllm~=0.7.3" ] webrtc = [ "aiortc~=1.11.0", "opencv-python~=4.11.0.86" ] -websocket = [ "websockets~=13.1", "fastapi~=0.115.6" ] +websocket = [ "websockets>=13.1,<15.0", "fastapi~=0.115.6" ] whisper = [ "faster-whisper~=1.1.1" ] [tool.setuptools.packages.find] diff --git a/src/pipecat/services/assemblyai/stt.py b/src/pipecat/services/assemblyai/stt.py index 5d8a596ca..6068c6d7e 100644 --- a/src/pipecat/services/assemblyai/stt.py +++ b/src/pipecat/services/assemblyai/stt.py @@ -192,7 +192,7 @@ class AssemblyAISTTService(STTService): } self._websocket = await websockets.connect( ws_url, - extra_headers=headers, + additional_headers=headers, ) self._connected = True self._receive_task = self.create_task(self._receive_task_handler()) diff --git a/src/pipecat/services/aws/stt.py b/src/pipecat/services/aws/stt.py index 22e8c8e63..2e7beb3a3 100644 --- a/src/pipecat/services/aws/stt.py +++ b/src/pipecat/services/aws/stt.py @@ -238,7 +238,7 @@ class AWSTranscribeSTTService(STTService): ) # Add required headers - extra_headers = { + additional_headers = { "Origin": "https://localhost", "Sec-WebSocket-Key": websocket_key, "Sec-WebSocket-Version": "13", @@ -270,7 +270,7 @@ class AWSTranscribeSTTService(STTService): # Connect with the required headers and settings self._ws_client = await websockets.connect( presigned_url, - extra_headers=extra_headers, + additional_headers=additional_headers, subprotocols=["mqtt"], ping_interval=None, ping_timeout=None, diff --git a/src/pipecat/services/cartesia/stt.py b/src/pipecat/services/cartesia/stt.py index 50d42e467..77d7c9f53 100644 --- a/src/pipecat/services/cartesia/stt.py +++ b/src/pipecat/services/cartesia/stt.py @@ -229,7 +229,7 @@ class CartesiaSTTService(STTService): headers = {"Cartesia-Version": "2025-04-16", "X-API-Key": self._api_key} try: - self._connection = await websockets.connect(ws_url, extra_headers=headers) + self._connection = await websockets.connect(ws_url, additional_headers=headers) # Setup the receiver task to handle the incoming messages from the Cartesia server if self._receiver_task is None or self._receiver_task.done(): self._receiver_task = asyncio.create_task(self._receive_messages()) diff --git a/src/pipecat/services/elevenlabs/tts.py b/src/pipecat/services/elevenlabs/tts.py index aa5f2c70c..2ba2bd2cb 100644 --- a/src/pipecat/services/elevenlabs/tts.py +++ b/src/pipecat/services/elevenlabs/tts.py @@ -475,7 +475,7 @@ class ElevenLabsTTSService(AudioContextWordTTSService): # Set max websocket message size to 16MB for large audio responses self._websocket = await websockets.connect( - url, max_size=16 * 1024 * 1024, extra_headers={"xi-api-key": self._api_key} + url, max_size=16 * 1024 * 1024, additional_headers={"xi-api-key": self._api_key} ) except Exception as e: diff --git a/src/pipecat/services/fish/tts.py b/src/pipecat/services/fish/tts.py index 598bac0f3..1f0463f94 100644 --- a/src/pipecat/services/fish/tts.py +++ b/src/pipecat/services/fish/tts.py @@ -216,7 +216,7 @@ class FishAudioTTSService(InterruptibleTTSService): logger.debug("Connecting to Fish Audio") headers = {"Authorization": f"Bearer {self._api_key}"} headers["model"] = self.model_name - self._websocket = await websockets.connect(self._base_url, extra_headers=headers) + self._websocket = await websockets.connect(self._base_url, additional_headers=headers) # Send initial start message with ormsgpack start_message = {"event": "start", "request": {"text": "", **self._settings}} diff --git a/src/pipecat/services/neuphonic/tts.py b/src/pipecat/services/neuphonic/tts.py index 6fb0d6aa7..d7a32aac8 100644 --- a/src/pipecat/services/neuphonic/tts.py +++ b/src/pipecat/services/neuphonic/tts.py @@ -292,7 +292,7 @@ class NeuphonicTTSService(InterruptibleTTSService): headers = {"x-api-key": self._api_key} - self._websocket = await websockets.connect(url, extra_headers=headers) + self._websocket = await websockets.connect(url, additional_headers=headers) except Exception as e: logger.error(f"{self} initialization error: {e}") self._websocket = None diff --git a/src/pipecat/services/openai_realtime_beta/azure.py b/src/pipecat/services/openai_realtime_beta/azure.py index cfa279840..d7727c5d8 100644 --- a/src/pipecat/services/openai_realtime_beta/azure.py +++ b/src/pipecat/services/openai_realtime_beta/azure.py @@ -57,7 +57,7 @@ class AzureRealtimeBetaLLMService(OpenAIRealtimeBetaLLMService): logger.info(f"Connecting to {self.base_url}, api key: {self.api_key}") self._websocket = await websockets.connect( uri=self.base_url, - extra_headers={ + additional_headers={ "api-key": self.api_key, }, ) diff --git a/src/pipecat/services/openai_realtime_beta/openai.py b/src/pipecat/services/openai_realtime_beta/openai.py index eb8925760..b153d1570 100644 --- a/src/pipecat/services/openai_realtime_beta/openai.py +++ b/src/pipecat/services/openai_realtime_beta/openai.py @@ -389,7 +389,7 @@ class OpenAIRealtimeBetaLLMService(LLMService): return self._websocket = await websockets.connect( uri=self.base_url, - extra_headers={ + additional_headers={ "Authorization": f"Bearer {self.api_key}", "OpenAI-Beta": "realtime=v1", }, diff --git a/src/pipecat/services/rime/tts.py b/src/pipecat/services/rime/tts.py index 829f1ac56..1b2e66dab 100644 --- a/src/pipecat/services/rime/tts.py +++ b/src/pipecat/services/rime/tts.py @@ -244,7 +244,7 @@ class RimeTTSService(AudioContextWordTTSService): params = "&".join(f"{k}={v}" for k, v in self._settings.items()) url = f"{self._url}?{params}" headers = {"Authorization": f"Bearer {self._api_key}"} - self._websocket = await websockets.connect(url, extra_headers=headers) + self._websocket = await websockets.connect(url, additional_headers=headers) except Exception as e: logger.error(f"{self} initialization error: {e}") self._websocket = None