diff --git a/CHANGELOG.md b/CHANGELOG.md index 230e9345a..3cdaea355 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,18 @@ All notable changes to **Pipecat** will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +## Changed + +- `pipecat.frames.frames.KeypadEntry` is deprecated and has been moved to + `pipecat.audio.dtmf.types.KeypadEntry`. + +## Deprecated + +- `pipecat.frames.frames.KeypadEntry` is deprecated use + `pipecat.audio.dtmf.types.KeypadEntry` instead. + ## [0.0.82] - 2025-08-28 ### Added diff --git a/src/pipecat/audio/dtmf/__init__.py b/src/pipecat/audio/dtmf/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/pipecat/audio/dtmf/types.py b/src/pipecat/audio/dtmf/types.py new file mode 100644 index 000000000..2de5ae917 --- /dev/null +++ b/src/pipecat/audio/dtmf/types.py @@ -0,0 +1,47 @@ +# Copyright (c) 2024–2025, Daily +# +# SPDX-License-Identifier: BSD 2-Clause License +# + +"""This module defines generic type for DTMS. + +It defines the `KeypadEntry` enumeration, representing dual-tone multi-frequency +(DTMF) keypad entries for phone system integration. Each entry corresponds to a +key on the telephone keypad, facilitating the handling of input in +telecommunication applications. +""" + +from enum import Enum + + +class KeypadEntry(str, Enum): + """DTMF keypad entries for phone system integration. + + Parameters: + ONE: Number key 1. + TWO: Number key 2. + THREE: Number key 3. + FOUR: Number key 4. + FIVE: Number key 5. + SIX: Number key 6. + SEVEN: Number key 7. + EIGHT: Number key 8. + NINE: Number key 9. + ZERO: Number key 0. + POUND: Pound/hash key (#). + STAR: Star/asterisk key (*). + """ + + ONE = "1" + TWO = "2" + THREE = "3" + FOUR = "4" + FIVE = "5" + SIX = "6" + SEVEN = "7" + EIGHT = "8" + NINE = "9" + ZERO = "0" + + POUND = "#" + STAR = "*" diff --git a/src/pipecat/frames/frames.py b/src/pipecat/frames/frames.py index 484ef36b5..69e79a573 100644 --- a/src/pipecat/frames/frames.py +++ b/src/pipecat/frames/frames.py @@ -12,7 +12,6 @@ and LLM processing. """ from dataclasses import dataclass, field -from enum import Enum from typing import ( TYPE_CHECKING, Any, @@ -28,6 +27,7 @@ from typing import ( ) from pipecat.adapters.schemas.tools_schema import ToolsSchema +from pipecat.audio.dtmf.types import KeypadEntry as NewKeypadEntry from pipecat.audio.interruptions.base_interruption_strategy import BaseInterruptionStrategy from pipecat.audio.turn.smart_turn.base_smart_turn import SmartTurnParams from pipecat.audio.vad.vad_analyzer import VADParams @@ -41,9 +41,13 @@ if TYPE_CHECKING: from pipecat.processors.frame_processor import FrameProcessor -class KeypadEntry(str, Enum): +class DeprecatedKeypadEntry: """DTMF keypad entries for phone system integration. + .. deprecated:: 0.0.82 + This class is deprecated and will be removed in a future version. + Instead, use `audio.dtmf.types.KeypadEntry`. + Parameters: ONE: Number key 1. TWO: Number key 2. @@ -59,18 +63,38 @@ class KeypadEntry(str, Enum): STAR: Star/asterisk key (*). """ - ONE = "1" - TWO = "2" - THREE = "3" - FOUR = "4" - FIVE = "5" - SIX = "6" - SEVEN = "7" - EIGHT = "8" - NINE = "9" - ZERO = "0" - POUND = "#" - STAR = "*" + _enum = NewKeypadEntry + + @classmethod + def _warn(cls): + import warnings + + with warnings.catch_warnings(): + warnings.simplefilter("always") + warnings.warn( + "`pipecat.frames.frames.KeypadEntry` is deprecated and will be removed in a future version. " + "Use `pipecat.audio.dtmf.types.KeypadEntry` instead.", + DeprecationWarning, + stacklevel=2, + ) + + def __call__(self, *args: Any, **kwargs: Any) -> Any: + """Allow the instance to be called as a function.""" + self._warn() + return self._enum(*args, **kwargs) + + def __getattr__(self, name): + """Retrieve an attribute from the underlying enum.""" + self._warn() + return getattr(self._enum, name) + + def __getitem__(self, name): + """Retrieve an item from the underlying enum.""" + self._warn() + return self._enum[name] + + +KeypadEntry = DeprecatedKeypadEntry() def format_pts(pts: Optional[int]): @@ -526,15 +550,16 @@ class LLMMessagesFrame(DataFrame): super().__post_init__() import warnings - warnings.simplefilter("always") - warnings.warn( - "LLMMessagesFrame is deprecated and will be removed in a future version. " - "Instead, use either " - "`LLMMessagesUpdateFrame` with `run_llm=True`, or " - "`OpenAILLMContextFrame` with desired messages in a new context", - DeprecationWarning, - stacklevel=2, - ) + with warnings.catch_warnings(): + warnings.simplefilter("always") + warnings.warn( + "LLMMessagesFrame is deprecated and will be removed in a future version. " + "Instead, use either " + "`LLMMessagesUpdateFrame` with `run_llm=True`, or " + "`OpenAILLMContextFrame` with desired messages in a new context", + DeprecationWarning, + stacklevel=2, + ) @dataclass @@ -668,7 +693,7 @@ class DTMFFrame: button: The DTMF keypad entry that was pressed. """ - button: KeypadEntry + button: NewKeypadEntry @dataclass diff --git a/src/pipecat/processors/aggregators/dtmf_aggregator.py b/src/pipecat/processors/aggregators/dtmf_aggregator.py index 38e1296f6..c50b0d8a8 100644 --- a/src/pipecat/processors/aggregators/dtmf_aggregator.py +++ b/src/pipecat/processors/aggregators/dtmf_aggregator.py @@ -14,13 +14,13 @@ for downstream processing by LLM context aggregators. import asyncio from typing import Optional +from pipecat.audio.dtmf.types import KeypadEntry from pipecat.frames.frames import ( BotInterruptionFrame, CancelFrame, EndFrame, Frame, InputDTMFFrame, - KeypadEntry, StartFrame, TranscriptionFrame, ) diff --git a/src/pipecat/serializers/exotel.py b/src/pipecat/serializers/exotel.py index 3fd2fb92d..9ed342631 100644 --- a/src/pipecat/serializers/exotel.py +++ b/src/pipecat/serializers/exotel.py @@ -13,13 +13,13 @@ from typing import Optional from loguru import logger from pydantic import BaseModel +from pipecat.audio.dtmf.types import KeypadEntry from pipecat.audio.utils import create_stream_resampler from pipecat.frames.frames import ( AudioRawFrame, Frame, InputAudioRawFrame, InputDTMFFrame, - KeypadEntry, StartFrame, StartInterruptionFrame, TransportMessageFrame, diff --git a/src/pipecat/serializers/plivo.py b/src/pipecat/serializers/plivo.py index 11855d850..aa8b4b27e 100644 --- a/src/pipecat/serializers/plivo.py +++ b/src/pipecat/serializers/plivo.py @@ -13,6 +13,7 @@ from typing import Optional from loguru import logger from pydantic import BaseModel +from pipecat.audio.dtmf.types import KeypadEntry from pipecat.audio.utils import create_stream_resampler, pcm_to_ulaw, ulaw_to_pcm from pipecat.frames.frames import ( AudioRawFrame, @@ -21,7 +22,6 @@ from pipecat.frames.frames import ( Frame, InputAudioRawFrame, InputDTMFFrame, - KeypadEntry, StartFrame, StartInterruptionFrame, TransportMessageFrame, diff --git a/src/pipecat/serializers/telnyx.py b/src/pipecat/serializers/telnyx.py index bf8d5d69f..467c01ba2 100644 --- a/src/pipecat/serializers/telnyx.py +++ b/src/pipecat/serializers/telnyx.py @@ -14,6 +14,7 @@ import aiohttp from loguru import logger from pydantic import BaseModel +from pipecat.audio.dtmf.types import KeypadEntry from pipecat.audio.utils import ( alaw_to_pcm, create_stream_resampler, @@ -28,7 +29,6 @@ from pipecat.frames.frames import ( Frame, InputAudioRawFrame, InputDTMFFrame, - KeypadEntry, StartFrame, StartInterruptionFrame, ) diff --git a/src/pipecat/serializers/twilio.py b/src/pipecat/serializers/twilio.py index 7679e8721..57e7c8dba 100644 --- a/src/pipecat/serializers/twilio.py +++ b/src/pipecat/serializers/twilio.py @@ -13,6 +13,7 @@ from typing import Optional from loguru import logger from pydantic import BaseModel +from pipecat.audio.dtmf.types import KeypadEntry from pipecat.audio.utils import create_stream_resampler, pcm_to_ulaw, ulaw_to_pcm from pipecat.frames.frames import ( AudioRawFrame, @@ -21,7 +22,6 @@ from pipecat.frames.frames import ( Frame, InputAudioRawFrame, InputDTMFFrame, - KeypadEntry, StartFrame, StartInterruptionFrame, TransportMessageFrame, diff --git a/tests/test_dtmf_aggregator.py b/tests/test_dtmf_aggregator.py index 697d50d27..5d9d1346a 100644 --- a/tests/test_dtmf_aggregator.py +++ b/tests/test_dtmf_aggregator.py @@ -6,10 +6,10 @@ import unittest +from pipecat.audio.dtmf.types import KeypadEntry from pipecat.frames.frames import ( EndFrame, InputDTMFFrame, - KeypadEntry, TranscriptionFrame, ) from pipecat.processors.aggregators.dtmf_aggregator import DTMFAggregator