diff --git a/changelog/4220.fixed.md b/changelog/4220.fixed.md
new file mode 100644
index 000000000..c5393f0db
--- /dev/null
+++ b/changelog/4220.fixed.md
@@ -0,0 +1 @@
+- Fixed `CartesiaTTSService` failing with "Context has closed" errors when switching voice, model, or language via `TTSUpdateSettingsFrame`. The service now automatically flushes the current audio context and opens a fresh one when these settings change.
diff --git a/changelog/4220.removed.md b/changelog/4220.removed.md
new file mode 100644
index 000000000..ba3177869
--- /dev/null
+++ b/changelog/4220.removed.md
@@ -0,0 +1,13 @@
+- ⚠️ Removed deprecated service parameters and shims that have been replaced by the `settings=Service.Settings(...)` pattern or direct `__init__` parameters:
+ - `PollyTTSService` alias (use `AWSTTSService`)
+ - `TTSService`: `text_aggregator`, `text_filter` init params
+ - `AWSNovaSonicLLMService`: `send_transcription_frames` init param
+ - `DeepgramSTTService`: `url` init param (use `base_url`)
+ - `FishAudioTTSService`: `model` init param (use `reference_id` or `settings`)
+ - `GladiaSTTService`: `language` and `confidence` from `GladiaInputParams`, `InputParams` class alias
+ - `GeminiTTSService`: `api_key` init param
+ - `GeminiLiveLLMService`: `base_url` init param (use `http_options`)
+ - `GoogleVertexLLMService`: `InputParams` class with `location`/`project_id` fields (use direct init params); `project_id` is now required, `location` defaults to `"us-east4"`
+ - `MiniMaxHttpTTSService`: `english_normalization` from `InputParams` (use `text_normalization`)
+ - `SimliVideoService`: `simli_config` init param (use `api_key`/`face_id`), `use_turn_server` init param; `api_key` and `face_id` are now required
+ - `AnthropicLLMService`: `enable_prompt_caching_beta` from `InputParams` (use `enable_prompt_caching`)
diff --git a/examples/features/features-pattern-pair-voice-switching.py b/examples/features/features-pattern-pair-voice-switching.py
index c246ce599..38926d915 100644
--- a/examples/features/features-pattern-pair-voice-switching.py
+++ b/examples/features/features-pattern-pair-voice-switching.py
@@ -45,7 +45,7 @@ from dotenv import load_dotenv
from loguru import logger
from pipecat.audio.vad.silero import SileroVADAnalyzer
-from pipecat.frames.frames import LLMRunFrame
+from pipecat.frames.frames import LLMRunFrame, TTSUpdateSettingsFrame
from pipecat.pipeline.pipeline import Pipeline
from pipecat.pipeline.runner import PipelineRunner
from pipecat.pipeline.task import PipelineParams, PipelineTask
@@ -54,6 +54,7 @@ from pipecat.processors.aggregators.llm_response_universal import (
LLMContextAggregatorPair,
LLMUserAggregatorParams,
)
+from pipecat.processors.aggregators.llm_text_processor import LLMTextProcessor
from pipecat.runner.types import RunnerArguments
from pipecat.runner.utils import create_transport
from pipecat.services.cartesia.tts import CartesiaTTSService
@@ -100,39 +101,43 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
logger.info(f"Starting bot")
# Create pattern pair aggregator for voice switching
- pattern_aggregator = PatternPairAggregator()
+ llm_text_aggregator = PatternPairAggregator()
# Add pattern for voice switching
- pattern_aggregator.add_pattern(
+ llm_text_aggregator.add_pattern(
type="voice",
start_pattern="",
end_pattern="",
- action=MatchAction.REMOVE, # Remove tags from final text
+ action=MatchAction.AGGREGATE,
)
# Register handler for voice switching
async def on_voice_tag(match: PatternMatch):
voice_name = match.text.strip().lower()
if voice_name in VOICE_IDS:
- # First flush any existing audio to finish the current context
- await tts.flush_audio()
- # Then set the new voice
- await tts.set_voice(VOICE_IDS[voice_name])
+ await llm_text_processor.push_frame(
+ TTSUpdateSettingsFrame(
+ delta=CartesiaTTSService.Settings(voice=VOICE_IDS[voice_name])
+ )
+ )
logger.info(f"Switched to {voice_name} voice")
else:
logger.warning(f"Unknown voice: {voice_name}")
- pattern_aggregator.on_pattern_match("voice", on_voice_tag)
+ llm_text_aggregator.on_pattern_match("voice", on_voice_tag)
stt = DeepgramSTTService(api_key=os.getenv("DEEPGRAM_API_KEY"))
+ # Process LLM text through the pattern aggregator before TTS
+ llm_text_processor = LLMTextProcessor(text_aggregator=llm_text_aggregator)
+
# Initialize TTS with narrator voice as default
tts = CartesiaTTSService(
api_key=os.getenv("CARTESIA_API_KEY"),
settings=CartesiaTTSService.Settings(
voice=VOICE_IDS["narrator"],
),
- text_aggregator=pattern_aggregator,
+ skip_aggregator_types=["voice"], # Skip voice tags in TTS speech
)
# System prompt for storytelling with voice switching
@@ -204,7 +209,8 @@ Remember: Use narrator voice for EVERYTHING except the actual quoted dialogue.""
stt,
user_aggregator,
llm,
- tts, # TTS with pattern aggregator
+ llm_text_processor,
+ tts,
transport.output(),
assistant_aggregator,
]
diff --git a/src/pipecat/services/anthropic/llm.py b/src/pipecat/services/anthropic/llm.py
index 9c07a8444..0a5d5f140 100644
--- a/src/pipecat/services/anthropic/llm.py
+++ b/src/pipecat/services/anthropic/llm.py
@@ -130,11 +130,6 @@ class AnthropicLLMService(LLMService):
Parameters:
enable_prompt_caching: Whether to enable the prompt caching feature.
- enable_prompt_caching_beta (deprecated): Whether to enable the beta prompt caching feature.
-
- .. deprecated:: 0.0.84
- Use the `enable_prompt_caching` parameter instead.
-
max_tokens: Maximum tokens to generate. Must be at least 1.
temperature: Sampling temperature between 0.0 and 1.0.
top_k: Top-k sampling parameter.
@@ -147,7 +142,6 @@ class AnthropicLLMService(LLMService):
"""
enable_prompt_caching: Optional[bool] = None
- enable_prompt_caching_beta: Optional[bool] = None
max_tokens: Optional[int] = Field(default_factory=lambda: 4096, ge=1)
temperature: Optional[float] = Field(default_factory=lambda: NOT_GIVEN, ge=0.0, le=1.0)
top_k: Optional[int] = Field(default_factory=lambda: NOT_GIVEN, ge=0)
@@ -157,18 +151,6 @@ class AnthropicLLMService(LLMService):
)
extra: Optional[Dict[str, Any]] = Field(default_factory=dict)
- def model_post_init(self, __context):
- """Post-initialization to handle deprecated parameters."""
- if self.enable_prompt_caching_beta is not None:
- import warnings
-
- warnings.simplefilter("always")
- warnings.warn(
- "enable_prompt_caching_beta is deprecated. Use enable_prompt_caching instead.",
- DeprecationWarning,
- stacklevel=2,
- )
-
def __init__(
self,
*,
@@ -237,22 +219,8 @@ class AnthropicLLMService(LLMService):
default_settings.thinking = params.thinking
if isinstance(params.extra, dict):
default_settings.extra = params.extra
- # Handle enable_prompt_caching / enable_prompt_caching_beta
- enable_prompt_caching = params.enable_prompt_caching
- if params.enable_prompt_caching_beta is not None:
- import warnings
-
- with warnings.catch_warnings():
- warnings.simplefilter("always")
- warnings.warn(
- "enable_prompt_caching_beta is deprecated. "
- "Use enable_prompt_caching instead.",
- DeprecationWarning,
- stacklevel=2,
- )
- if enable_prompt_caching is None:
- enable_prompt_caching = params.enable_prompt_caching_beta
- default_settings.enable_prompt_caching = enable_prompt_caching or False
+ if params.enable_prompt_caching is not None:
+ default_settings.enable_prompt_caching = params.enable_prompt_caching
# 4. Apply settings delta (canonical API, always wins)
if settings is not None:
diff --git a/src/pipecat/services/aws/nova_sonic/llm.py b/src/pipecat/services/aws/nova_sonic/llm.py
index 9aa36c5db..6f330babb 100644
--- a/src/pipecat/services/aws/nova_sonic/llm.py
+++ b/src/pipecat/services/aws/nova_sonic/llm.py
@@ -258,7 +258,6 @@ class AWSNovaSonicLLMService(LLMService):
settings: Optional[Settings] = None,
system_instruction: Optional[str] = None,
tools: Optional[ToolsSchema] = None,
- send_transcription_frames: bool = True,
**kwargs,
):
"""Initializes the AWS Nova Sonic LLM service.
@@ -302,12 +301,6 @@ class AWSNovaSonicLLMService(LLMService):
.. deprecated:: 0.0.105
Use ``settings=AWSNovaSonicLLMService.Settings(system_instruction=...)`` instead.
tools: Available tools/functions for the model to use.
- send_transcription_frames: Whether to emit transcription frames.
-
- .. deprecated:: 0.0.91
- This parameter is deprecated and will be removed in a future version.
- Transcription frames are always sent.
-
**kwargs: Additional arguments passed to the parent LLMService.
"""
# 1. Initialize default_settings with hardcoded defaults
@@ -391,18 +384,6 @@ class AWSNovaSonicLLMService(LLMService):
)
self._settings.endpointing_sensitivity = None
- if not send_transcription_frames:
- import warnings
-
- with warnings.catch_warnings():
- warnings.simplefilter("always")
- warnings.warn(
- "`send_transcription_frames` is deprecated and will be removed in a future version. "
- "Transcription frames are always sent.",
- DeprecationWarning,
- stacklevel=2,
- )
-
self._context: Optional[LLMContext] = None
self._stream: Optional[
DuplexEventStream[
diff --git a/src/pipecat/services/aws/tts.py b/src/pipecat/services/aws/tts.py
index 32266886e..f46539b9b 100644
--- a/src/pipecat/services/aws/tts.py
+++ b/src/pipecat/services/aws/tts.py
@@ -369,31 +369,3 @@ class AWSPollyTTSService(TTSService):
except (BotoCoreError, ClientError) as error:
error_message = f"AWS Polly TTS error: {str(error)}"
yield ErrorFrame(error=error_message)
-
-
-class PollyTTSService(AWSPollyTTSService):
- """Deprecated alias for AWSPollyTTSService.
-
- .. deprecated:: 0.0.67
- `PollyTTSService` is deprecated, use `AWSPollyTTSService` instead.
-
- """
-
- Settings = AWSPollyTTSSettings
-
- def __init__(self, **kwargs):
- """Initialize the deprecated PollyTTSService.
-
- Args:
- **kwargs: All arguments passed to AWSPollyTTSService.
- """
- super().__init__(**kwargs)
-
- import warnings
-
- with warnings.catch_warnings():
- warnings.simplefilter("always")
- warnings.warn(
- "'PollyTTSService' is deprecated, use 'AWSPollyTTSService' instead.",
- DeprecationWarning,
- )
diff --git a/src/pipecat/services/cartesia/tts.py b/src/pipecat/services/cartesia/tts.py
index d879ff694..e8e033ee9 100644
--- a/src/pipecat/services/cartesia/tts.py
+++ b/src/pipecat/services/cartesia/tts.py
@@ -10,7 +10,7 @@ import base64
import json
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
@@ -28,7 +28,6 @@ from pipecat.frames.frames import (
from pipecat.services.settings import NOT_GIVEN, TTSSettings, _NotGiven
from pipecat.services.tts_service import TextAggregationMode, TTSService, WebsocketTTSService
from pipecat.transcriptions.language import Language, resolve_language
-from pipecat.utils.text.base_text_aggregator import BaseTextAggregator
from pipecat.utils.text.skip_tags_aggregator import SkipTagsAggregator
from pipecat.utils.tracing.service_decorators import traced_tts
@@ -240,7 +239,6 @@ class CartesiaTTSService(WebsocketTTSService):
container: str = "raw",
params: Optional[InputParams] = None,
settings: Optional[Settings] = None,
- text_aggregator: Optional[BaseTextAggregator] = None,
text_aggregation_mode: Optional[TextAggregationMode] = None,
aggregate_sentences: Optional[bool] = None,
**kwargs,
@@ -271,11 +269,6 @@ class CartesiaTTSService(WebsocketTTSService):
settings: Runtime-updatable settings. When provided alongside deprecated
parameters, ``settings`` values take precedence.
- text_aggregator: Custom text aggregator for processing input text.
-
- .. deprecated:: 0.0.95
- Use an LLMTextProcessor before the TTSService for custom text aggregation.
-
text_aggregation_mode: How to aggregate incoming text before synthesis.
aggregate_sentences: Whether to aggregate sentences within the TTSService.
@@ -337,20 +330,18 @@ class CartesiaTTSService(WebsocketTTSService):
pause_frame_processing=False,
sample_rate=sample_rate,
push_start_frame=True,
- text_aggregator=text_aggregator,
settings=default_settings,
**kwargs,
)
- if not text_aggregator:
- # Always skip tags added for spelled-out text
- # Note: This is primarily to support backwards compatibility.
- # The preferred way of taking advantage of Cartesia SSML Tags is
- # to use an LLMTextProcessor and/or a text_transformer to identify
- # and insert these tags for the purpose of the TTS service alone.
- self._text_aggregator = SkipTagsAggregator(
- [("", "")], aggregation_type=self._text_aggregation_mode
- )
+ # Always skip tags added for spelled-out text
+ # Note: This is primarily to support backwards compatibility.
+ # The preferred way of taking advantage of Cartesia SSML Tags is
+ # to use an LLMTextProcessor and/or a text_transformer to identify
+ # and insert these tags for the purpose of the TTS service alone.
+ self._text_aggregator = SkipTagsAggregator(
+ [("", "")], aggregation_type=self._text_aggregation_mode
+ )
self._api_key = api_key
self._cartesia_version = cartesia_version
@@ -599,6 +590,34 @@ 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 = None
+ self._turn_context_id = self.create_context_id()
+
+ return changed
+
async def _process_messages(self):
async for message in self._get_websocket():
msg = json.loads(message)
diff --git a/src/pipecat/services/deepgram/stt.py b/src/pipecat/services/deepgram/stt.py
index d58958da2..3bc584490 100644
--- a/src/pipecat/services/deepgram/stt.py
+++ b/src/pipecat/services/deepgram/stt.py
@@ -314,7 +314,6 @@ class DeepgramSTTService(STTService):
self,
*,
api_key: str,
- url: str = "",
base_url: str = "",
encoding: str = "linear16",
channels: int = 1,
@@ -335,11 +334,6 @@ class DeepgramSTTService(STTService):
Args:
api_key: Deepgram API key for authentication.
- url: Custom Deepgram API base URL.
-
- .. deprecated:: 0.0.64
- Parameter `url` is deprecated, use `base_url` instead.
-
base_url: Custom Deepgram API base URL.
encoding: Audio encoding format. Defaults to "linear16".
channels: Number of audio channels. Defaults to 1.
@@ -374,17 +368,6 @@ class DeepgramSTTService(STTService):
Note:
The `vad_events` option in LiveOptions is deprecated as of version 0.0.99 and will be removed in a future version. Please use the Silero VAD instead.
"""
- if url:
- import warnings
-
- with warnings.catch_warnings():
- warnings.simplefilter("always")
- warnings.warn(
- "Parameter 'url' is deprecated, use 'base_url' instead.",
- DeprecationWarning,
- )
- base_url = url
-
# 1. Initialize default_settings with hardcoded defaults
default_settings = self.Settings(
model="nova-3-general",
diff --git a/src/pipecat/services/fish/tts.py b/src/pipecat/services/fish/tts.py
index 6333ac1c4..f6738fbb8 100644
--- a/src/pipecat/services/fish/tts.py
+++ b/src/pipecat/services/fish/tts.py
@@ -110,7 +110,6 @@ class FishAudioTTSService(InterruptibleTTSService):
*,
api_key: str,
reference_id: Optional[str] = None, # This is the voice ID
- model: Optional[str] = None, # Deprecated
model_id: Optional[str] = None,
output_format: FishAudioOutputFormat = "pcm",
sample_rate: Optional[int] = None,
@@ -127,12 +126,6 @@ class FishAudioTTSService(InterruptibleTTSService):
.. deprecated:: 0.0.105
Use ``settings=FishAudioTTSService.Settings(voice=...)`` instead.
- model: Deprecated. Reference ID of the voice model to use for synthesis.
-
- .. deprecated:: 0.0.74
- The ``model`` parameter is deprecated and will be removed in version 0.1.0.
- Use ``reference_id`` instead to specify the voice model.
-
model_id: Specify which Fish Audio TTS model to use (e.g. "s1").
.. deprecated:: 0.0.105
@@ -149,25 +142,6 @@ class FishAudioTTSService(InterruptibleTTSService):
parameters, ``settings`` values take precedence.
**kwargs: Additional arguments passed to the parent service.
"""
- # Validation for model and reference_id parameters
- if model and reference_id:
- raise ValueError(
- "Cannot specify both 'model' and 'reference_id'. Use 'reference_id' only."
- )
-
- if model:
- import warnings
-
- with warnings.catch_warnings():
- warnings.simplefilter("always")
- warnings.warn(
- "Parameter 'model' is deprecated and will be removed in a future version. "
- "Use 'reference_id' instead.",
- DeprecationWarning,
- stacklevel=2,
- )
- reference_id = model
-
# 1. Initialize default_settings with hardcoded defaults
default_settings = self.Settings(
model="s2-pro",
diff --git a/src/pipecat/services/gladia/config.py b/src/pipecat/services/gladia/config.py
index c492a04a1..917309594 100644
--- a/src/pipecat/services/gladia/config.py
+++ b/src/pipecat/services/gladia/config.py
@@ -10,8 +10,6 @@ from typing import Any, Dict, List, Optional, Union
from pydantic import BaseModel
-from pipecat.transcriptions.language import Language
-
class LanguageConfig(BaseModel):
"""Configuration for language detection and handling.
@@ -163,12 +161,6 @@ class GladiaInputParams(BaseModel):
custom_metadata: Additional metadata to include with requests
endpointing: Silence duration in seconds to mark end of speech
maximum_duration_without_endpointing: Maximum utterance duration without silence
- language: Language code for transcription
-
- .. deprecated:: 0.0.62
- The 'language' parameter is deprecated and will be removed in a future version.
- Use 'language_config' instead.
-
language_config: Detailed language configuration
pre_processing: Audio pre-processing options
realtime_processing: Real-time processing features
@@ -184,7 +176,6 @@ class GladiaInputParams(BaseModel):
custom_metadata: Optional[Dict[str, Any]] = None
endpointing: Optional[float] = None
maximum_duration_without_endpointing: Optional[int] = 5
- language: Optional[Language] = None # Deprecated
language_config: Optional[LanguageConfig] = None
pre_processing: Optional[PreProcessingConfig] = None
realtime_processing: Optional[RealtimeProcessingConfig] = None
diff --git a/src/pipecat/services/gladia/stt.py b/src/pipecat/services/gladia/stt.py
index 2ce2a15b5..f939ff4ba 100644
--- a/src/pipecat/services/gladia/stt.py
+++ b/src/pipecat/services/gladia/stt.py
@@ -13,7 +13,6 @@ supporting multiple languages, custom vocabulary, and various audio processing o
import asyncio
import base64
import json
-import warnings
from dataclasses import dataclass, field
from typing import Any, AsyncGenerator, Literal, Optional
@@ -171,21 +170,6 @@ def language_to_gladia_language(language: Language) -> Optional[str]:
# Deprecation warning for nested InputParams
-class _InputParamsDescriptor:
- """Descriptor for backward compatibility with deprecation warning."""
-
- def __get__(self, obj, objtype=None):
- with warnings.catch_warnings():
- warnings.simplefilter("always")
- warnings.warn(
- "GladiaSTTService.InputParams is deprecated and will be removed in a future version. "
- "Import and use GladiaInputParams directly instead.",
- DeprecationWarning,
- stacklevel=2,
- )
- return GladiaInputParams
-
-
@dataclass
class GladiaSTTSettings(STTSettings):
"""Settings for GladiaSTTService.
@@ -225,17 +209,11 @@ class GladiaSTTService(WebsocketSTTService):
Provides automatic reconnection, audio buffering, and comprehensive error handling.
For complete API documentation, see: https://docs.gladia.io/api-reference/v2/live/init
-
- .. deprecated:: 0.0.62
- Use :class:`~pipecat.services.gladia.config.GladiaInputParams` directly instead.
"""
Settings = GladiaSTTSettings
_settings: Settings
- # Maintain backward compatibility
- InputParams = _InputParamsDescriptor()
-
def __init__(
self,
*,
@@ -245,7 +223,6 @@ class GladiaSTTService(WebsocketSTTService):
encoding: str = "wav/pcm",
bit_depth: int = 16,
channels: int = 1,
- confidence: Optional[float] = None,
sample_rate: Optional[int] = None,
model: Optional[str] = None,
params: Optional[GladiaInputParams] = None,
@@ -264,12 +241,6 @@ class GladiaSTTService(WebsocketSTTService):
encoding: Audio encoding format. Defaults to ``"wav/pcm"``.
bit_depth: Audio bit depth. Defaults to 16.
channels: Number of audio channels. Defaults to 1.
- confidence: Minimum confidence threshold for transcriptions (0.0-1.0).
-
- .. deprecated:: 0.0.86
- The 'confidence' parameter is deprecated and will be removed in a future version.
- No confidence threshold is applied.
-
sample_rate: Audio sample rate in Hz. If None, uses service default.
model: Model to use for transcription.
@@ -291,16 +262,6 @@ class GladiaSTTService(WebsocketSTTService):
Override for your deployment. See https://github.com/pipecat-ai/stt-benchmark
**kwargs: Additional arguments passed to the STTService parent class.
"""
- if confidence:
- with warnings.catch_warnings():
- warnings.simplefilter("always")
- warnings.warn(
- "The 'confidence' parameter is deprecated and will be removed in a future version. "
- "No confidence threshold is applied.",
- DeprecationWarning,
- stacklevel=2,
- )
-
# 1. Initialize default_settings with hardcoded defaults
default_settings = self.Settings(
model="solaria-1",
@@ -323,15 +284,6 @@ class GladiaSTTService(WebsocketSTTService):
# 3. Apply params overrides — only if settings not provided
if params is not None:
self._warn_init_param_moved_to_settings("params")
- if params.language is not None:
- with warnings.catch_warnings():
- warnings.simplefilter("always")
- warnings.warn(
- "The 'language' parameter is deprecated and will be removed in a future "
- "version. Use 'language_config' instead.",
- DeprecationWarning,
- stacklevel=2,
- )
if not settings:
# Extract init-only fields from params
if params.encoding is not None:
@@ -349,15 +301,8 @@ class GladiaSTTService(WebsocketSTTService):
default_settings.realtime_processing = params.realtime_processing
default_settings.messages_config = params.messages_config
default_settings.enable_vad = params.enable_vad
- # Resolve deprecated language → language_config at init time
if params.language_config:
default_settings.language_config = params.language_config
- elif params.language:
- language_code = self.language_to_service_language(params.language)
- if language_code:
- default_settings.language_config = LanguageConfig(
- languages=[language_code], code_switching=False
- )
# 4. Apply settings delta (canonical API, always wins)
if settings is not None:
diff --git a/src/pipecat/services/google/gemini_live/llm.py b/src/pipecat/services/google/gemini_live/llm.py
index 1bd7174b2..b98cfa4d3 100644
--- a/src/pipecat/services/google/gemini_live/llm.py
+++ b/src/pipecat/services/google/gemini_live/llm.py
@@ -380,7 +380,6 @@ class GeminiLiveLLMService(LLMService):
self,
*,
api_key: str,
- base_url: Optional[str] = None,
model: Optional[str] = None,
voice_id: str = "Charon",
start_audio_paused: bool = False,
@@ -398,13 +397,6 @@ class GeminiLiveLLMService(LLMService):
Args:
api_key: Google AI API key for authentication.
- base_url: API endpoint base URL. Defaults to the official Gemini Live endpoint.
-
- .. deprecated:: 0.0.90
- This parameter is deprecated and no longer has any effect.
- Please use `http_options` to customize requests made by the
- API client.
-
model: Model identifier to use.
.. deprecated:: 0.0.105
@@ -431,18 +423,6 @@ class GeminiLiveLLMService(LLMService):
http_options: HTTP options for the client.
**kwargs: Additional arguments passed to parent LLMService.
"""
- # Check for deprecated parameter usage
- if base_url is not None:
- import warnings
-
- with warnings.catch_warnings():
- warnings.simplefilter("always")
- warnings.warn(
- "Parameter 'base_url' is deprecated and no longer has any effect. Please use 'http_options' to customize requests made by the API client.",
- DeprecationWarning,
- stacklevel=2,
- )
-
# 1. Initialize default_settings with hardcoded defaults
default_settings = self.Settings(
model="models/gemini-2.5-flash-native-audio-preview-12-2025",
@@ -515,13 +495,11 @@ class GeminiLiveLLMService(LLMService):
)
super().__init__(
- base_url=base_url,
settings=default_settings,
**kwargs,
)
self._last_sent_time = 0
- self._base_url = base_url
self._system_instruction_from_init = self._settings.system_instruction
self._tools_from_init = tools
diff --git a/src/pipecat/services/google/stt.py b/src/pipecat/services/google/stt.py
index 173b201fe..9bf2685b7 100644
--- a/src/pipecat/services/google/stt.py
+++ b/src/pipecat/services/google/stt.py
@@ -755,7 +755,7 @@ class GoogleSTTService(STTService):
) -> None:
"""Update service options dynamically.
- .. deprecated::
+ .. deprecated:: 0.0.104
Use ``STTUpdateSettingsFrame`` with ``GoogleSTTService.Settings(...)``
instead.
diff --git a/src/pipecat/services/google/tts.py b/src/pipecat/services/google/tts.py
index 93053cc94..5b919d30e 100644
--- a/src/pipecat/services/google/tts.py
+++ b/src/pipecat/services/google/tts.py
@@ -16,7 +16,6 @@ for natural voice control and multi-speaker conversations.
import json
import os
-import warnings
from pipecat.utils.tracing.service_decorators import traced_tts
@@ -1259,7 +1258,6 @@ class GeminiTTSService(GoogleBaseTTSService):
def __init__(
self,
*,
- api_key: Optional[str] = None,
model: Optional[str] = None,
credentials: Optional[str] = None,
credentials_path: Optional[str] = None,
@@ -1273,12 +1271,6 @@ class GeminiTTSService(GoogleBaseTTSService):
"""Initializes the Gemini TTS service.
Args:
- api_key:
-
- .. deprecated:: 0.0.95
- The `api_key` parameter is deprecated. Use `credentials` or
- `credentials_path` instead for Google Cloud authentication.
-
model: Gemini TTS model to use. Must be a TTS model like
"gemini-2.5-flash-tts" or "gemini-2.5-pro-tts".
@@ -1303,15 +1295,6 @@ class GeminiTTSService(GoogleBaseTTSService):
parameters, ``settings`` values take precedence.
**kwargs: Additional arguments passed to parent TTSService.
"""
- # Handle deprecated api_key parameter
- if api_key is not None:
- warnings.warn(
- "The 'api_key' parameter is deprecated and will be removed in a future version. "
- "Use 'credentials' or 'credentials_path' instead for Google Cloud authentication.",
- DeprecationWarning,
- stacklevel=2,
- )
-
if sample_rate and sample_rate != self.GOOGLE_SAMPLE_RATE:
logger.warning(
f"Google TTS only supports {self.GOOGLE_SAMPLE_RATE}Hz sample rate. "
diff --git a/src/pipecat/services/google/vertex/llm.py b/src/pipecat/services/google/vertex/llm.py
index 946a8f1bb..b8b83cb24 100644
--- a/src/pipecat/services/google/vertex/llm.py
+++ b/src/pipecat/services/google/vertex/llm.py
@@ -61,58 +61,14 @@ class GoogleVertexLLMService(GoogleLLMService):
Settings = GoogleVertexLLMSettings
_settings: Settings
- class InputParams(GoogleLLMService.InputParams):
- """Input parameters specific to Vertex AI.
-
- Parameters:
- location: GCP region for Vertex AI endpoint (e.g., "us-east4").
-
- .. deprecated:: 0.0.90
- Use `location` as a direct argument to
- `GoogleVertexLLMService.__init__()` instead.
-
- project_id: Google Cloud project ID.
-
- .. deprecated:: 0.0.90
- Use `project_id` as a direct argument to
- `GoogleVertexLLMService.__init__()` instead.
- """
-
- # https://cloud.google.com/vertex-ai/generative-ai/docs/learn/locations
- location: Optional[str] = None
- project_id: Optional[str] = None
-
- def __init__(self, **kwargs):
- """Initializes the InputParams."""
- import warnings
-
- with warnings.catch_warnings():
- warnings.simplefilter("always")
- if "location" in kwargs and kwargs["location"] is not None:
- warnings.warn(
- "GoogleVertexLLMService.InputParams.location is deprecated. "
- "Please provide 'location' as a direct argument to GoogleVertexLLMService.__init__() instead.",
- DeprecationWarning,
- stacklevel=2,
- )
-
- if "project_id" in kwargs and kwargs["project_id"] is not None:
- warnings.warn(
- "GoogleVertexLLMService.InputParams.project_id is deprecated. "
- "Please provide 'project_id' as a direct argument to GoogleVertexLLMService.__init__() instead.",
- DeprecationWarning,
- stacklevel=2,
- )
- super().__init__(**kwargs)
-
def __init__(
self,
*,
credentials: Optional[str] = None,
credentials_path: Optional[str] = None,
model: Optional[str] = None,
- location: Optional[str] = None,
- project_id: Optional[str] = None,
+ location: str = "us-east4",
+ project_id: str,
params: Optional[GoogleLLMService.InputParams] = None,
settings: Optional[Settings] = None,
system_instruction: Optional[str] = None,
@@ -131,7 +87,7 @@ class GoogleVertexLLMService(GoogleLLMService):
.. deprecated:: 0.0.105
Use ``settings=GoogleVertexLLMService.Settings(model=...)`` instead.
- location: GCP region for Vertex AI endpoint (e.g., "us-east4").
+ location: GCP region for Vertex AI endpoint. Defaults to "us-east4".
project_id: Google Cloud project ID.
params: Input parameters for the model.
@@ -161,34 +117,6 @@ class GoogleVertexLLMService(GoogleLLMService):
"Invalid parameter 'api_key'. Use 'credentials' or 'credentials_path' for Vertex AI authentication."
)
- # Handle deprecated InputParams fields (location/project_id extraction
- # must happen before validation, regardless of settings)
- if params and isinstance(params, GoogleVertexLLMService.InputParams):
- if project_id is None:
- project_id = params.project_id
- if location is None:
- location = params.location
- # Convert to base InputParams
- params = GoogleLLMService.InputParams(
- **params.model_dump(exclude={"location", "project_id"}, exclude_unset=True)
- )
-
- # Validate project_id and location parameters
- # NOTE: once we remove Vertex-specific InputParams class, we can update
- # __init__() signature as follows:
- # - location: str = "us-east4",
- # - project_id: str,
- # But for now, we need them as-is to maintain proper backward
- # compatibility.
- if project_id is None:
- raise ValueError("project_id is required")
- if location is None:
- # If location is not provided, default to "us-east4".
- # Note: this is legacy behavior; ideally location would be
- # required.
- logger.warning("location is not provided. Defaulting to 'us-east4'.")
- location = "us-east4" # Default location if not provided
-
# These need to be set before calling super().__init__() because
# super().__init__() invokes _create_client(), which needs these.
self._credentials = self._get_credentials(credentials, credentials_path)
diff --git a/src/pipecat/services/minimax/tts.py b/src/pipecat/services/minimax/tts.py
index 46502409d..a197bdcbe 100644
--- a/src/pipecat/services/minimax/tts.py
+++ b/src/pipecat/services/minimax/tts.py
@@ -157,12 +157,6 @@ class MiniMaxHttpTTSService(TTSService):
pitch: Pitch adjustment (range: -12 to 12).
emotion: Emotional tone (options: "happy", "sad", "angry", "fearful",
"disgusted", "surprised", "calm", "fluent").
- english_normalization: Deprecated; use `text_normalization` instead
-
- .. deprecated:: 0.0.96
- The `english_normalization` parameter is deprecated and will be removed in a future version.
- Use the `text_normalization` parameter instead.
-
text_normalization: Enable text normalization (Chinese/English).
latex_read: Enable LaTeX formula reading.
exclude_aggregated_audio: Whether to exclude aggregated audio in final chunk.
@@ -173,7 +167,6 @@ class MiniMaxHttpTTSService(TTSService):
volume: Optional[float] = 1.0
pitch: Optional[int] = 0
emotion: Optional[str] = None
- english_normalization: Optional[bool] = None # Deprecated
text_normalization: Optional[bool] = None
latex_read: Optional[bool] = None
exclude_aggregated_audio: Optional[bool] = None
@@ -284,16 +277,6 @@ class MiniMaxHttpTTSService(TTSService):
)
# Resolve text_normalization
- if params.english_normalization is not None:
- import warnings
-
- with warnings.catch_warnings():
- warnings.simplefilter("always")
- warnings.warn(
- "Parameter `english_normalization` is deprecated and will be removed in a future version. Use `text_normalization` instead.",
- DeprecationWarning,
- )
- default_settings.text_normalization = params.english_normalization
if params.text_normalization is not None:
default_settings.text_normalization = params.text_normalization
diff --git a/src/pipecat/services/rime/tts.py b/src/pipecat/services/rime/tts.py
index ead56a37c..41045688c 100644
--- a/src/pipecat/services/rime/tts.py
+++ b/src/pipecat/services/rime/tts.py
@@ -37,7 +37,6 @@ from pipecat.services.tts_service import (
WebsocketTTSService,
)
from pipecat.transcriptions.language import Language, resolve_language
-from pipecat.utils.text.base_text_aggregator import BaseTextAggregator
from pipecat.utils.text.skip_tags_aggregator import SkipTagsAggregator
from pipecat.utils.tracing.service_decorators import traced_tts
@@ -176,7 +175,6 @@ class RimeTTSService(WebsocketTTSService):
sample_rate: Optional[int] = None,
params: Optional[InputParams] = None,
settings: Optional[Settings] = None,
- text_aggregator: Optional[BaseTextAggregator] = None,
text_aggregation_mode: Optional[TextAggregationMode] = None,
aggregate_sentences: Optional[bool] = None,
**kwargs,
@@ -204,11 +202,6 @@ class RimeTTSService(WebsocketTTSService):
settings: Runtime-updatable settings. When provided alongside deprecated
parameters, ``settings`` values take precedence.
- text_aggregator: Custom text aggregator for processing input text.
-
- .. deprecated:: 0.0.95
- Use an LLMTextProcessor before the TTSService for custom text aggregation.
-
text_aggregation_mode: How to aggregate incoming text before synthesis.
aggregate_sentences: Deprecated. Use text_aggregation_mode instead.
@@ -282,15 +275,14 @@ class RimeTTSService(WebsocketTTSService):
self._audio_format = "pcm"
self._sampling_rate = 0 # updated in start()
- if not text_aggregator:
- # Always skip tags added for spelled-out text
- # Note: This is primarily to support backwards compatibility.
- # The preferred way of taking advantage of Rime spelling is
- # to use an LLMTextProcessor and/or a text_transformer to identify
- # and insert these tags for the purpose of the TTS service alone.
- self._text_aggregator = SkipTagsAggregator(
- [("spell(", ")")], aggregation_type=self._text_aggregation_mode
- )
+ # Always skip tags added for spelled-out text
+ # Note: This is primarily to support backwards compatibility.
+ # The preferred way of taking advantage of Rime spelling is
+ # to use an LLMTextProcessor and/or a text_transformer to identify
+ # and insert these tags for the purpose of the TTS service alone.
+ self._text_aggregator = SkipTagsAggregator(
+ [("spell(", ")")], aggregation_type=self._text_aggregation_mode
+ )
# Store service configuration
self._api_key = api_key
diff --git a/src/pipecat/services/simli/video.py b/src/pipecat/services/simli/video.py
index f994ef0dc..ce681d6e8 100644
--- a/src/pipecat/services/simli/video.py
+++ b/src/pipecat/services/simli/video.py
@@ -7,7 +7,6 @@
"""Simli video service for real-time avatar generation."""
import asyncio
-import warnings
from dataclasses import dataclass
from typing import Optional
@@ -79,10 +78,8 @@ class SimliVideoService(AIService):
def __init__(
self,
*,
- api_key: Optional[str] = None,
- face_id: Optional[str] = None,
- simli_config: Optional[SimliConfig] = None,
- use_turn_server: bool = False,
+ api_key: str,
+ face_id: str,
simli_url: str = "https://api.simli.ai",
is_trinity_avatar: bool = False,
params: Optional[InputParams] = None,
@@ -98,18 +95,6 @@ class SimliVideoService(AIService):
api_key: Simli API key for authentication.
face_id: Simli Face ID. For Trinity avatars, specify "faceId/emotionId"
to use a different emotion than the default.
- simli_config: Configuration object for Simli client settings.
- Use api_key and face_id instead.
-
- .. deprecated:: 0.0.92
- The 'simli_config' parameter is deprecated and will be removed in a future version.
- Please use 'api_key' and 'face_id' parameters instead.
-
- use_turn_server: Whether to use TURN server for connection. Defaults to False.
-
- .. deprecated:: 0.0.95
- The 'use_turn_server' parameter is deprecated and will be removed in a future version.
-
simli_url: URL of the simli servers. Can be changed for custom deployments
of enterprise users.
is_trinity_avatar: Boolean to tell simli client that this is a Trinity avatar
@@ -147,49 +132,16 @@ class SimliVideoService(AIService):
# 4. Call super
super().__init__(settings=default_settings, **kwargs)
- # Handle deprecated simli_config parameter
- if simli_config is not None:
- if api_key is not None or face_id is not None:
- raise ValueError(
- "Cannot specify both simli_config and api_key/face_id. "
- "Please use api_key and face_id (simli_config is deprecated)."
- )
+ # Build SimliConfig from parameters
+ config_kwargs = {
+ "faceId": face_id,
+ }
+ if max_session_length is not None:
+ config_kwargs["maxSessionLength"] = max_session_length
+ if max_idle_time is not None:
+ config_kwargs["maxIdleTime"] = max_idle_time
- warnings.warn(
- "The 'simli_config' parameter is deprecated and will be removed in a future version. "
- "Please use 'api_key' and 'face_id' parameters instead, with optional 'params' for "
- "max_session_length and max_idle_time configuration.",
- DeprecationWarning,
- stacklevel=2,
- )
-
- # Use the provided simli_config
- config = simli_config
- else:
- # Validate new parameters
- if api_key is None:
- raise ValueError("api_key is required")
- if face_id is None:
- raise ValueError("face_id is required")
-
- # Build SimliConfig from new parameters
- # Only pass optional parameters if explicitly provided to use SimliConfig defaults
- config_kwargs = {
- "faceId": face_id,
- }
- if max_session_length is not None:
- config_kwargs["maxSessionLength"] = max_session_length
- if max_idle_time is not None:
- config_kwargs["maxIdleTime"] = max_idle_time
-
- config = SimliConfig(**config_kwargs)
-
- if use_turn_server:
- warnings.warn(
- "The 'use_turn_server' parameter is deprecated and will be removed in a future version.",
- DeprecationWarning,
- stacklevel=2,
- )
+ config = SimliConfig(**config_kwargs)
self._initialized = False
# Add buffer time to session limits
diff --git a/src/pipecat/services/tts_service.py b/src/pipecat/services/tts_service.py
index 72830078b..034e2fcd4 100644
--- a/src/pipecat/services/tts_service.py
+++ b/src/pipecat/services/tts_service.py
@@ -58,7 +58,6 @@ from pipecat.services.ai_service import AIService
from pipecat.services.settings import TTSSettings, is_given
from pipecat.services.websocket_service import WebsocketService
from pipecat.transcriptions.language import Language
-from pipecat.utils.text.base_text_aggregator import BaseTextAggregator
from pipecat.utils.text.base_text_filter import BaseTextFilter
from pipecat.utils.text.simple_text_aggregator import SimpleTextAggregator
from pipecat.utils.time import seconds_to_nanoseconds
@@ -168,8 +167,6 @@ class TTSService(AIService):
append_trailing_space: bool = False,
# TTS output sample rate
sample_rate: Optional[int] = None,
- # Text aggregator to aggregate incoming tokens and decide when to push to the TTS.
- text_aggregator: Optional[BaseTextAggregator] = None,
# Types of text aggregations that should not be spoken.
skip_aggregator_types: Optional[List[str]] = [],
# A list of callables to transform text before just before sending it to TTS.
@@ -182,7 +179,6 @@ class TTSService(AIService):
] = None,
# Text filter executed after text has been aggregated.
text_filters: Optional[Sequence[BaseTextFilter]] = None,
- text_filter: Optional[BaseTextFilter] = None,
# Audio transport destination of the generated frames.
transport_destination: Optional[str] = None,
settings: Optional[TTSSettings] = None,
@@ -215,11 +211,6 @@ class TTSService(AIService):
append_trailing_space: Whether to append a trailing space to text before sending to TTS.
This helps prevent some TTS services from vocalizing trailing punctuation (e.g., "dot").
sample_rate: Output sample rate for generated audio.
- text_aggregator: Custom text aggregator for processing incoming text.
-
- .. deprecated:: 0.0.95
- Use an LLMTextProcessor before the TTSService for custom text aggregation.
-
skip_aggregator_types: List of aggregation types that should not be spoken.
text_transforms: A list of callables to transform text before just before sending it
to TTS. Each callable takes the aggregated text and its type, and returns the
@@ -227,11 +218,6 @@ class TTSService(AIService):
(aggregation_type | '*', transform_function).
text_filters: Sequence of text filters to apply after aggregation.
- text_filter: Single text filter (deprecated, use text_filters).
-
- .. deprecated:: 0.0.59
- Use `text_filters` instead, which allows multiple filters.
-
transport_destination: Destination for generated audio frames.
settings: The runtime-updatable settings for the TTS service.
reuse_context_id_within_turn: Whether the service should reuse context IDs within the
@@ -300,18 +286,7 @@ class TTSService(AIService):
self._append_trailing_space: bool = append_trailing_space
self._init_sample_rate = sample_rate
self._sample_rate = 0
- self._text_aggregator: BaseTextAggregator = text_aggregator or SimpleTextAggregator(
- aggregation_type=self._text_aggregation_mode
- )
- if text_aggregator:
- import warnings
-
- with warnings.catch_warnings():
- warnings.simplefilter("always")
- warnings.warn(
- "Parameter 'text_aggregator' is deprecated. Use an LLMTextProcessor before the TTSService for custom text aggregation.",
- DeprecationWarning,
- )
+ self._text_aggregator = SimpleTextAggregator(aggregation_type=self._text_aggregation_mode)
self._skip_aggregator_types: List[str] = skip_aggregator_types or []
self._text_transforms: List[
@@ -320,16 +295,6 @@ class TTSService(AIService):
# TODO: Deprecate _text_filters when added to LLMTextProcessor
self._text_filters: Sequence[BaseTextFilter] = text_filters or []
self._transport_destination: Optional[str] = transport_destination
- if text_filter:
- import warnings
-
- with warnings.catch_warnings():
- warnings.simplefilter("always")
- warnings.warn(
- "Parameter 'text_filter' is deprecated, use 'text_filters' instead.",
- DeprecationWarning,
- )
- self._text_filters = [text_filter]
self._resampler = create_stream_resampler()