diff --git a/CHANGELOG.md b/CHANGELOG.md index a48fa9c3b..3d56a323f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -93,6 +93,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Updated the default mode for `CartesiaTTSService` and `CartesiaHttpTTSService` to `sonic-2`. +### Removed + +- Removed deprecated `audio.resample_audio()`, use `create_default_resampler()` + instead. + +- Removed deprecated`stt_service` parameter from `STTMuteFilter`. + +- Removed deprecated RTVI processors, use an `RTVIObserver` instead. + +- Removed deprecated `AWSTTSService`, use `PollyTTSService` instead. + +- Removed deprecated field `tier` from `DailyTranscriptionSettings`, use `model` + instead. + +- Removed deprecated `pipecat.vad` package, use `pipecat.audio.vad` instead. + ### Fixed - Fixed an issue in `RimeTTSService` where the last line of text sent didn't diff --git a/src/pipecat/audio/utils.py b/src/pipecat/audio/utils.py index 7c4c25fcc..1f7db648f 100644 --- a/src/pipecat/audio/utils.py +++ b/src/pipecat/audio/utils.py @@ -18,23 +18,6 @@ def create_default_resampler(**kwargs) -> BaseAudioResampler: return SOXRAudioResampler(**kwargs) -def resample_audio(audio: bytes, original_rate: int, target_rate: int) -> bytes: - import warnings - - with warnings.catch_warnings(): - warnings.simplefilter("always") - warnings.warn( - "'resample_audio()' is deprecated, use 'create_default_resampler()' instead.", - DeprecationWarning, - ) - - if original_rate == target_rate: - return audio - audio_data = np.frombuffer(audio, dtype=np.int16) - resampled_audio = soxr.resample(audio_data, original_rate, target_rate) - return resampled_audio.astype(np.int16).tobytes() - - def mix_audio(audio1: bytes, audio2: bytes) -> bytes: data1 = np.frombuffer(audio1, dtype=np.int16) data2 = np.frombuffer(audio2, dtype=np.int16) diff --git a/src/pipecat/processors/filters/stt_mute_filter.py b/src/pipecat/processors/filters/stt_mute_filter.py index c74e495ab..cce087f22 100644 --- a/src/pipecat/processors/filters/stt_mute_filter.py +++ b/src/pipecat/processors/filters/stt_mute_filter.py @@ -92,20 +92,9 @@ class STTMuteFilter(FrameProcessor): **kwargs: Additional arguments passed to parent class """ - def __init__( - self, *, config: STTMuteConfig, stt_service: Optional[FrameProcessor] = None, **kwargs - ): + def __init__(self, *, config: STTMuteConfig, **kwargs): super().__init__(**kwargs) self._config = config - if stt_service is not None: - import warnings - - warnings.warn( - "The stt_service parameter is deprecated and will be removed in a future version. " - "STTMuteFilter now manages mute state internally.", - DeprecationWarning, - stacklevel=2, - ) self._first_speech_handled = False self._bot_is_speaking = False self._function_call_in_progress = False diff --git a/src/pipecat/processors/frameworks/rtvi.py b/src/pipecat/processors/frameworks/rtvi.py index dac903862..29747a582 100644 --- a/src/pipecat/processors/frameworks/rtvi.py +++ b/src/pipecat/processors/frameworks/rtvi.py @@ -391,267 +391,6 @@ class RTVIServerMessageFrame(SystemFrame): return f"{self.name}(data: {self.data})" -class RTVIFrameProcessor(FrameProcessor): - def __init__(self, direction: FrameDirection = FrameDirection.DOWNSTREAM, **kwargs): - super().__init__(**kwargs) - self._direction = direction - - async def _push_transport_message_urgent(self, model: BaseModel, exclude_none: bool = True): - frame = TransportMessageUrgentFrame(message=model.model_dump(exclude_none=exclude_none)) - await self.push_frame(frame, self._direction) - - -class RTVISpeakingProcessor(RTVIFrameProcessor): - def __init__(self, **kwargs): - super().__init__(**kwargs) - - import warnings - - with warnings.catch_warnings(): - warnings.simplefilter("always") - warnings.warn( - "'RTVISpeakingProcessor' is deprecated, use an 'RTVIObserver' instead.", - DeprecationWarning, - ) - - async def process_frame(self, frame: Frame, direction: FrameDirection): - await super().process_frame(frame, direction) - - await self.push_frame(frame, direction) - - if isinstance(frame, (UserStartedSpeakingFrame, UserStoppedSpeakingFrame)): - await self._handle_interruptions(frame) - elif isinstance(frame, (BotStartedSpeakingFrame, BotStoppedSpeakingFrame)): - await self._handle_bot_speaking(frame) - - async def _handle_interruptions(self, frame: Frame): - message = None - if isinstance(frame, UserStartedSpeakingFrame): - message = RTVIUserStartedSpeakingMessage() - elif isinstance(frame, UserStoppedSpeakingFrame): - message = RTVIUserStoppedSpeakingMessage() - - if message: - await self._push_transport_message_urgent(message) - - async def _handle_bot_speaking(self, frame: Frame): - message = None - if isinstance(frame, BotStartedSpeakingFrame): - message = RTVIBotStartedSpeakingMessage() - elif isinstance(frame, BotStoppedSpeakingFrame): - message = RTVIBotStoppedSpeakingMessage() - - if message: - await self._push_transport_message_urgent(message) - - -class RTVIUserTranscriptionProcessor(RTVIFrameProcessor): - def __init__(self, **kwargs): - super().__init__(**kwargs) - - import warnings - - with warnings.catch_warnings(): - warnings.simplefilter("always") - warnings.warn( - "'RTVIUserTranscriptionProcessor' is deprecated, use an 'RTVIObserver' instead.", - DeprecationWarning, - ) - - async def process_frame(self, frame: Frame, direction: FrameDirection): - await super().process_frame(frame, direction) - - await self.push_frame(frame, direction) - - if isinstance(frame, (TranscriptionFrame, InterimTranscriptionFrame)): - await self._handle_user_transcriptions(frame) - - async def _handle_user_transcriptions(self, frame: Frame): - message = None - if isinstance(frame, TranscriptionFrame): - message = RTVIUserTranscriptionMessage( - data=RTVIUserTranscriptionMessageData( - text=frame.text, user_id=frame.user_id, timestamp=frame.timestamp, final=True - ) - ) - elif isinstance(frame, InterimTranscriptionFrame): - message = RTVIUserTranscriptionMessage( - data=RTVIUserTranscriptionMessageData( - text=frame.text, user_id=frame.user_id, timestamp=frame.timestamp, final=False - ) - ) - - if message: - await self._push_transport_message_urgent(message) - - -class RTVIUserLLMTextProcessor(RTVIFrameProcessor): - def __init__(self, **kwargs): - super().__init__(**kwargs) - - import warnings - - with warnings.catch_warnings(): - warnings.simplefilter("always") - warnings.warn( - "'RTVIUserLLMTextProcessor' is deprecated, use an 'RTVIObserver' instead.", - DeprecationWarning, - ) - - async def process_frame(self, frame: Frame, direction: FrameDirection): - await super().process_frame(frame, direction) - - await self.push_frame(frame, direction) - - if isinstance(frame, OpenAILLMContextFrame): - await self._handle_context(frame) - - async def _handle_context(self, frame: OpenAILLMContextFrame): - messages = frame.context.messages - if len(messages) > 0: - message = messages[-1] - if message["role"] == "user": - content = message["content"] - if isinstance(content, list): - text = " ".join(item["text"] for item in content if "text" in item) - else: - text = content - rtvi_message = RTVIUserLLMTextMessage(data=RTVITextMessageData(text=text)) - await self._push_transport_message_urgent(rtvi_message) - - -class RTVIBotTranscriptionProcessor(RTVIFrameProcessor): - def __init__(self): - super().__init__() - self._aggregation = "" - - import warnings - - with warnings.catch_warnings(): - warnings.simplefilter("always") - warnings.warn( - "'RTVIBotTranscriptionProcessor' is deprecated, use an 'RTVIObserver' instead.", - DeprecationWarning, - ) - - async def process_frame(self, frame: Frame, direction: FrameDirection): - await super().process_frame(frame, direction) - - await self.push_frame(frame, direction) - - if isinstance(frame, UserStartedSpeakingFrame): - await self._push_aggregation() - elif isinstance(frame, LLMTextFrame): - self._aggregation += frame.text - if match_endofsentence(self._aggregation): - await self._push_aggregation() - - async def _push_aggregation(self): - if len(self._aggregation) > 0: - message = RTVIBotTranscriptionMessage(data=RTVITextMessageData(text=self._aggregation)) - await self._push_transport_message_urgent(message) - self._aggregation = "" - - -class RTVIBotLLMProcessor(RTVIFrameProcessor): - def __init__(self, **kwargs): - super().__init__(**kwargs) - - import warnings - - with warnings.catch_warnings(): - warnings.simplefilter("always") - warnings.warn( - "'RTVIBotLLMProcessor' is deprecated, use an 'RTVIObserver' instead.", - DeprecationWarning, - ) - - async def process_frame(self, frame: Frame, direction: FrameDirection): - await super().process_frame(frame, direction) - - await self.push_frame(frame, direction) - - if isinstance(frame, LLMFullResponseStartFrame): - await self._push_transport_message_urgent(RTVIBotLLMStartedMessage()) - elif isinstance(frame, LLMFullResponseEndFrame): - await self._push_transport_message_urgent(RTVIBotLLMStoppedMessage()) - elif isinstance(frame, LLMTextFrame): - message = RTVIBotLLMTextMessage(data=RTVITextMessageData(text=frame.text)) - await self._push_transport_message_urgent(message) - - -class RTVIBotTTSProcessor(RTVIFrameProcessor): - def __init__(self, **kwargs): - super().__init__(**kwargs) - - import warnings - - with warnings.catch_warnings(): - warnings.simplefilter("always") - warnings.warn( - "'RTVIBotTTSProcessor' is deprecated, use an 'RTVIObserver' instead.", - DeprecationWarning, - ) - - async def process_frame(self, frame: Frame, direction: FrameDirection): - await super().process_frame(frame, direction) - - await self.push_frame(frame, direction) - - if isinstance(frame, TTSStartedFrame): - await self._push_transport_message_urgent(RTVIBotTTSStartedMessage()) - elif isinstance(frame, TTSStoppedFrame): - await self._push_transport_message_urgent(RTVIBotTTSStoppedMessage()) - elif isinstance(frame, TTSTextFrame): - message = RTVIBotTTSTextMessage(data=RTVITextMessageData(text=frame.text)) - await self._push_transport_message_urgent(message) - - -class RTVIMetricsProcessor(RTVIFrameProcessor): - def __init__(self, **kwargs): - super().__init__(**kwargs) - - import warnings - - with warnings.catch_warnings(): - warnings.simplefilter("always") - warnings.warn( - "'RTVIMetricsProcessor' is deprecated, use an 'RTVIObserver' instead.", - DeprecationWarning, - ) - - async def process_frame(self, frame: Frame, direction: FrameDirection): - await super().process_frame(frame, direction) - - await self.push_frame(frame, direction) - - if isinstance(frame, MetricsFrame): - await self._handle_metrics(frame) - - async def _handle_metrics(self, frame: MetricsFrame): - metrics = {} - for d in frame.data: - if isinstance(d, TTFBMetricsData): - if "ttfb" not in metrics: - metrics["ttfb"] = [] - metrics["ttfb"].append(d.model_dump(exclude_none=True)) - elif isinstance(d, ProcessingMetricsData): - if "processing" not in metrics: - metrics["processing"] = [] - metrics["processing"].append(d.model_dump(exclude_none=True)) - elif isinstance(d, LLMUsageMetricsData): - if "tokens" not in metrics: - metrics["tokens"] = [] - metrics["tokens"].append(d.value.model_dump(exclude_none=True)) - elif isinstance(d, TTSUsageMetricsData): - if "characters" not in metrics: - metrics["characters"] = [] - metrics["characters"].append(d.model_dump(exclude_none=True)) - - message = RTVIMetricsMessage(data=metrics) - await self._push_transport_message_urgent(message) - - class RTVIObserver(BaseObserver): """Pipeline frame observer for RTVI server message handling. @@ -876,18 +615,6 @@ class RTVIProcessor(FrameProcessor): self._input_transport = input_transport self._input_transport.enable_audio_in_stream_on_start(False) - def observer(self) -> RTVIObserver: - import warnings - - with warnings.catch_warnings(): - warnings.simplefilter("always") - warnings.warn( - "'RTVI.observer()' is deprecated, instantiate an 'RTVIObserver' directly instead.", - DeprecationWarning, - ) - - return RTVIObserver(self) - def register_action(self, action: RTVIAction): id = self._action_id(action.service, action.action) self._registered_actions[id] = action diff --git a/src/pipecat/services/aws.py b/src/pipecat/services/aws.py index b83df2f77..4c0417d72 100644 --- a/src/pipecat/services/aws.py +++ b/src/pipecat/services/aws.py @@ -248,16 +248,3 @@ class PollyTTSService(TTSService): finally: yield TTSStoppedFrame() - - -class AWSTTSService(PollyTTSService): - def __init__(self, **kwargs): - super().__init__(**kwargs) - - import warnings - - with warnings.catch_warnings(): - warnings.simplefilter("always") - warnings.warn( - "'AWSTTSService' is deprecated, use 'PollyTTSService' instead.", DeprecationWarning - ) diff --git a/src/pipecat/transports/services/daily.py b/src/pipecat/transports/services/daily.py index 7735ae91f..873b13cd1 100644 --- a/src/pipecat/transports/services/daily.py +++ b/src/pipecat/transports/services/daily.py @@ -6,7 +6,6 @@ import asyncio import time -import warnings from concurrent.futures import ThreadPoolExecutor from dataclasses import dataclass from typing import Any, Awaitable, Callable, Mapping, Optional @@ -18,7 +17,7 @@ from daily import ( VirtualSpeakerDevice, ) from loguru import logger -from pydantic import BaseModel, model_validator +from pydantic import BaseModel from pipecat.audio.vad.vad_analyzer import VADAnalyzer, VADParams from pipecat.frames.frames import ( @@ -124,7 +123,6 @@ class DailyTranscriptionSettings(BaseModel): Attributes: language: ISO language code for transcription (e.g. "en"). - tier: Deprecated. Use model instead. model: Transcription model to use (e.g. "nova-2-general"). profanity_filter: Whether to filter profanity from transcripts. redact: Whether to redact sensitive information. @@ -135,7 +133,6 @@ class DailyTranscriptionSettings(BaseModel): """ language: str = "en" - tier: Optional[str] = None model: str = "nova-2-general" profanity_filter: bool = True redact: bool = False @@ -144,16 +141,6 @@ class DailyTranscriptionSettings(BaseModel): includeRawResponse: bool = True extra: Mapping[str, Any] = {"interim_results": True} - @model_validator(mode="before") - def check_deprecated_fields(cls, values): - with warnings.catch_warnings(): - warnings.simplefilter("always") - if "tier" in values: - warnings.warn( - "Field 'tier' is deprecated, use 'model' instead.", DeprecationWarning - ) - return values - class DailyParams(TransportParams): """Configuration parameters for Daily transport. diff --git a/src/pipecat/vad/__init__.py b/src/pipecat/vad/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/pipecat/vad/silero.py b/src/pipecat/vad/silero.py deleted file mode 100644 index 285e2e0e8..000000000 --- a/src/pipecat/vad/silero.py +++ /dev/null @@ -1,16 +0,0 @@ -# -# Copyright (c) 2024–2025, Daily -# -# SPDX-License-Identifier: BSD 2-Clause License -# - -import warnings - -with warnings.catch_warnings(): - warnings.simplefilter("always") - warnings.warn( - "Package `pipecat.vad` is deprecated, use `pipecat.audio.vad` instead", DeprecationWarning - ) - -from ..audio.vad.silero import SileroVADAnalyzer -from ..processors.audio.vad.silero import SileroVAD diff --git a/src/pipecat/vad/vad_analyzer.py b/src/pipecat/vad/vad_analyzer.py deleted file mode 100644 index 7c8fc4c31..000000000 --- a/src/pipecat/vad/vad_analyzer.py +++ /dev/null @@ -1,15 +0,0 @@ -# -# Copyright (c) 2024–2025, Daily -# -# SPDX-License-Identifier: BSD 2-Clause License -# - -import warnings - -with warnings.catch_warnings(): - warnings.simplefilter("always") - warnings.warn( - "Package `pipecat.vad` is deprecated, use `pipecat.audio.vad` instead", DeprecationWarning - ) - -from ..audio.vad.vad_analyzer import VADAnalyzer, VADParams, VADState