Change extra_headers to additional_headers, update websocket version support

This commit is contained in:
Mark Backman
2025-07-22 15:25:03 -04:00
parent 994e82c1ef
commit 7955080da2
11 changed files with 28 additions and 24 deletions

View File

@@ -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 `tasks cancelled error` to a debug log. This removes the log from appearing
in Pipecat logs upon leaving. 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 - Updated `MiniMaxHttpTTSService` with a `base_url` arg where you can specify
the Global endpoint (default) or Mainland China. the Global endpoint (default) or Mainland China.

View File

@@ -44,21 +44,21 @@ Website = "https://pipecat.ai"
[project.optional-dependencies] [project.optional-dependencies]
anthropic = [ "anthropic~=0.49.0" ] anthropic = [ "anthropic~=0.49.0" ]
assemblyai = [ "websockets~=13.1" ] assemblyai = [ "websockets>=13.1,<15.0" ]
aws = [ "aioboto3~=15.0.0", "websockets~=13.1" ] aws = [ "aioboto3~=15.0.0", "websockets>=13.1,<15.0" ]
aws-nova-sonic = [ "aws_sdk_bedrock_runtime~=0.0.2" ] aws-nova-sonic = [ "aws_sdk_bedrock_runtime~=0.0.2" ]
azure = [ "azure-cognitiveservices-speech~=1.42.0"] 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 = [] cerebras = []
deepseek = [] deepseek = []
daily = [ "daily-python~=0.19.4" ] daily = [ "daily-python~=0.19.4" ]
deepgram = [ "deepgram-sdk~=4.7.0" ] deepgram = [ "deepgram-sdk~=4.7.0" ]
elevenlabs = [ "websockets~=13.1" ] elevenlabs = [ "websockets>=13.1,<15.0" ]
fal = [ "fal-client~=0.5.9" ] fal = [ "fal-client~=0.5.9" ]
fireworks = [] fireworks = []
fish = [ "ormsgpack~=1.7.0", "websockets~=13.1" ] fish = [ "ormsgpack~=1.7.0", "websockets>=13.1,<15.0" ]
gladia = [ "websockets~=13.1" ] 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" ] google = [ "google-cloud-speech~=2.32.0", "google-cloud-texttospeech~=2.26.0", "google-genai~=1.24.0", "websockets>=13.1,<15.0" ]
grok = [] grok = []
groq = [ "groq~=0.23.0" ] groq = [ "groq~=0.23.0" ]
gstreamer = [ "pygobject~=3.50.0" ] gstreamer = [ "pygobject~=3.50.0" ]
@@ -66,22 +66,22 @@ krisp = [ "pipecat-ai-krisp~=0.4.0" ]
koala = [ "pvkoala~=2.0.3" ] koala = [ "pvkoala~=2.0.3" ]
langchain = [ "langchain~=0.3.20", "langchain-community~=0.3.20", "langchain-openai~=0.3.9" ] 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" ] 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" ] local = [ "pyaudio~=0.2.14" ]
mcp = [ "mcp[cli]~=1.9.4" ] mcp = [ "mcp[cli]~=1.9.4" ]
mem0 = [ "mem0ai~=0.1.94" ] mem0 = [ "mem0ai~=0.1.94" ]
mlx-whisper = [ "mlx-whisper~=0.4.2" ] mlx-whisper = [ "mlx-whisper~=0.4.2" ]
moondream = [ "einops~=0.8.0", "timm~=1.0.13", "transformers>=4.48.0" ] moondream = [ "einops~=0.8.0", "timm~=1.0.13", "transformers>=4.48.0" ]
nim = [] nim = []
neuphonic = [ "pyneuphonic~=1.5.13", "websockets~=13.1" ] neuphonic = [ "pyneuphonic~=1.5.13", "websockets>=13.1,<15.0" ]
noisereduce = [ "noisereduce~=3.0.3" ] noisereduce = [ "noisereduce~=3.0.3" ]
openai = [ "websockets~=13.1" ] openai = [ "websockets>=13.1,<15.0" ]
openpipe = [ "openpipe~=4.50.0" ] openpipe = [ "openpipe~=4.50.0" ]
openrouter = [] openrouter = []
perplexity = [] perplexity = []
playht = [ "pyht~=0.1.12", "websockets~=13.1" ] playht = [ "pyht~=0.1.12", "websockets>=13.1,<15.0" ]
qwen = [] qwen = []
rime = [ "websockets~=13.1" ] rime = [ "websockets>=13.1,<15.0" ]
riva = [ "nvidia-riva-client~=2.21.1" ] riva = [ "nvidia-riva-client~=2.21.1" ]
sambanova = [] sambanova = []
sentry = [ "sentry-sdk~=2.23.1" ] 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 = [] remote-smart-turn = []
silero = [ "onnxruntime~=1.20.1" ] silero = [ "onnxruntime~=1.20.1" ]
simli = [ "simli-ai~=0.1.10"] simli = [ "simli-ai~=0.1.10"]
soniox = [ "websockets~=13.1" ] soniox = [ "websockets>=13.1,<15.0" ]
soundfile = [ "soundfile~=0.13.0" ] soundfile = [ "soundfile~=0.13.0" ]
speechmatics = [ "speechmatics-rt>=0.3.1" ] speechmatics = [ "speechmatics-rt>=0.3.1" ]
tavus=[] tavus=[]
@@ -97,7 +97,7 @@ together = []
tracing = [ "opentelemetry-sdk>=1.33.0", "opentelemetry-api>=1.33.0", "opentelemetry-instrumentation>=0.54b0" ] tracing = [ "opentelemetry-sdk>=1.33.0", "opentelemetry-api>=1.33.0", "opentelemetry-instrumentation>=0.54b0" ]
ultravox = [ "transformers>=4.48.0", "vllm~=0.7.3" ] ultravox = [ "transformers>=4.48.0", "vllm~=0.7.3" ]
webrtc = [ "aiortc~=1.11.0", "opencv-python~=4.11.0.86" ] 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" ] whisper = [ "faster-whisper~=1.1.1" ]
[tool.setuptools.packages.find] [tool.setuptools.packages.find]

View File

@@ -192,7 +192,7 @@ class AssemblyAISTTService(STTService):
} }
self._websocket = await websockets.connect( self._websocket = await websockets.connect(
ws_url, ws_url,
extra_headers=headers, additional_headers=headers,
) )
self._connected = True self._connected = True
self._receive_task = self.create_task(self._receive_task_handler()) self._receive_task = self.create_task(self._receive_task_handler())

View File

@@ -238,7 +238,7 @@ class AWSTranscribeSTTService(STTService):
) )
# Add required headers # Add required headers
extra_headers = { additional_headers = {
"Origin": "https://localhost", "Origin": "https://localhost",
"Sec-WebSocket-Key": websocket_key, "Sec-WebSocket-Key": websocket_key,
"Sec-WebSocket-Version": "13", "Sec-WebSocket-Version": "13",
@@ -270,7 +270,7 @@ class AWSTranscribeSTTService(STTService):
# Connect with the required headers and settings # Connect with the required headers and settings
self._ws_client = await websockets.connect( self._ws_client = await websockets.connect(
presigned_url, presigned_url,
extra_headers=extra_headers, additional_headers=additional_headers,
subprotocols=["mqtt"], subprotocols=["mqtt"],
ping_interval=None, ping_interval=None,
ping_timeout=None, ping_timeout=None,

View File

@@ -229,7 +229,7 @@ class CartesiaSTTService(STTService):
headers = {"Cartesia-Version": "2025-04-16", "X-API-Key": self._api_key} headers = {"Cartesia-Version": "2025-04-16", "X-API-Key": self._api_key}
try: 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 # Setup the receiver task to handle the incoming messages from the Cartesia server
if self._receiver_task is None or self._receiver_task.done(): if self._receiver_task is None or self._receiver_task.done():
self._receiver_task = asyncio.create_task(self._receive_messages()) self._receiver_task = asyncio.create_task(self._receive_messages())

View File

@@ -475,7 +475,7 @@ class ElevenLabsTTSService(AudioContextWordTTSService):
# Set max websocket message size to 16MB for large audio responses # Set max websocket message size to 16MB for large audio responses
self._websocket = await websockets.connect( 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: except Exception as e:

View File

@@ -216,7 +216,7 @@ class FishAudioTTSService(InterruptibleTTSService):
logger.debug("Connecting to Fish Audio") logger.debug("Connecting to Fish Audio")
headers = {"Authorization": f"Bearer {self._api_key}"} headers = {"Authorization": f"Bearer {self._api_key}"}
headers["model"] = self.model_name 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 # Send initial start message with ormsgpack
start_message = {"event": "start", "request": {"text": "", **self._settings}} start_message = {"event": "start", "request": {"text": "", **self._settings}}

View File

@@ -292,7 +292,7 @@ class NeuphonicTTSService(InterruptibleTTSService):
headers = {"x-api-key": self._api_key} 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: except Exception as e:
logger.error(f"{self} initialization error: {e}") logger.error(f"{self} initialization error: {e}")
self._websocket = None self._websocket = None

View File

@@ -57,7 +57,7 @@ class AzureRealtimeBetaLLMService(OpenAIRealtimeBetaLLMService):
logger.info(f"Connecting to {self.base_url}, api key: {self.api_key}") logger.info(f"Connecting to {self.base_url}, api key: {self.api_key}")
self._websocket = await websockets.connect( self._websocket = await websockets.connect(
uri=self.base_url, uri=self.base_url,
extra_headers={ additional_headers={
"api-key": self.api_key, "api-key": self.api_key,
}, },
) )

View File

@@ -389,7 +389,7 @@ class OpenAIRealtimeBetaLLMService(LLMService):
return return
self._websocket = await websockets.connect( self._websocket = await websockets.connect(
uri=self.base_url, uri=self.base_url,
extra_headers={ additional_headers={
"Authorization": f"Bearer {self.api_key}", "Authorization": f"Bearer {self.api_key}",
"OpenAI-Beta": "realtime=v1", "OpenAI-Beta": "realtime=v1",
}, },

View File

@@ -244,7 +244,7 @@ class RimeTTSService(AudioContextWordTTSService):
params = "&".join(f"{k}={v}" for k, v in self._settings.items()) params = "&".join(f"{k}={v}" for k, v in self._settings.items())
url = f"{self._url}?{params}" url = f"{self._url}?{params}"
headers = {"Authorization": f"Bearer {self._api_key}"} 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: except Exception as e:
logger.error(f"{self} initialization error: {e}") logger.error(f"{self} initialization error: {e}")
self._websocket = None self._websocket = None