From 74af2b6aa4c1b5bead857cbed2dd69b417281b8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleix=20Conchillo=20Flaqu=C3=A9?= Date: Wed, 27 Aug 2025 10:41:10 -0700 Subject: [PATCH 1/3] DailyTransport: fix sending DTMF tones --- CHANGELOG.md | 2 ++ src/pipecat/transports/services/daily.py | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0aa9b4f42..da3074517 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -96,6 +96,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- Fixed a `DailyTransport` issue that prevented DTMF tones from being sent. + - Fixed a missing import in `SentryMetrics`. - Fixed `AWSPollyTTSService` to support AWS credential provider chain (IAM diff --git a/src/pipecat/transports/services/daily.py b/src/pipecat/transports/services/daily.py index 66e17905a..a84d385a6 100644 --- a/src/pipecat/transports/services/daily.py +++ b/src/pipecat/transports/services/daily.py @@ -350,6 +350,7 @@ class DailyTransportClient(EventHandler): self._video_renderers = {} self._transcription_ids = [] self._transcription_status = None + self._dial_out_session_id: str = "" self._joining = False self._joined = False @@ -790,6 +791,14 @@ class DailyTransportClient(EventHandler): Args: settings: DTMF settings including tones and target session. """ + session_id = settings.get("sessionId") or self._dial_out_session_id + if not session_id: + logger.error("Unable to send DTMF: 'sessionId' is not set") + return + + # Update 'sessionId' field. + settings["sessionId"] = session_id + future = self._get_event_loop().create_future() self._client.send_dtmf(settings, completion=completion_callback(future)) await future @@ -1166,6 +1175,7 @@ class DailyTransportClient(EventHandler): Args: data: Dial-out connection data. """ + self._dial_out_session_id = data["sessionId"] if "sessionId" in data else "" self._call_event_callback(self._callbacks.on_dialout_connected, data) def on_dialout_stopped(self, data: Any): @@ -1174,6 +1184,9 @@ class DailyTransportClient(EventHandler): Args: data: Dial-out stop data. """ + # Cleanup only if our session stopped. + if data["sessionId"] == self._dial_out_session_id: + self._dial_out_session_id = "" self._call_event_callback(self._callbacks.on_dialout_stopped, data) def on_dialout_error(self, data: Any): @@ -1182,6 +1195,9 @@ class DailyTransportClient(EventHandler): Args: data: Dial-out error data. """ + # Cleanup only if our session errored out. + if data["sessionId"] == self._dial_out_session_id: + self._dial_out_session_id = "" self._call_event_callback(self._callbacks.on_dialout_error, data) def on_dialout_warning(self, data: Any): From 41d40f9a1112b2ebd2b7f3eaffbab818ff38f27f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleix=20Conchillo=20Flaqu=C3=A9?= Date: Wed, 27 Aug 2025 11:11:15 -0700 Subject: [PATCH 2/3] DailyTransport: make sure we have a client before joining/leaving --- src/pipecat/transports/services/daily.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/pipecat/transports/services/daily.py b/src/pipecat/transports/services/daily.py index a84d385a6..b8ffe2383 100644 --- a/src/pipecat/transports/services/daily.py +++ b/src/pipecat/transports/services/daily.py @@ -640,6 +640,9 @@ class DailyTransportClient(EventHandler): async def _join(self): """Execute the actual room join operation.""" + if not self._client: + return + future = self._get_event_loop().create_future() camera_enabled = self._params.video_out_enabled and self._params.camera_out_enabled @@ -731,6 +734,9 @@ class DailyTransportClient(EventHandler): async def _leave(self): """Execute the actual room leave operation.""" + if not self._client: + return + future = self._get_event_loop().create_future() self._client.leave(completion=completion_callback(future)) return await asyncio.wait_for(future, timeout=10) From 2613da1a1fbb40a606df890d99e5914421accfcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleix=20Conchillo=20Flaqu=C3=A9?= Date: Wed, 27 Aug 2025 11:13:42 -0700 Subject: [PATCH 3/3] PipelineTask: increase CANCEL_TIMEOUT_SECS to 20 --- src/pipecat/pipeline/task.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pipecat/pipeline/task.py b/src/pipecat/pipeline/task.py index 4241762e4..5500dba62 100644 --- a/src/pipecat/pipeline/task.py +++ b/src/pipecat/pipeline/task.py @@ -58,7 +58,7 @@ HEARTBEAT_MONITOR_SECS = HEARTBEAT_SECS * 10 IDLE_TIMEOUT_SECS = 300 -CANCEL_TIMEOUT_SECS = 10.0 +CANCEL_TIMEOUT_SECS = 20.0 class PipelineParams(BaseModel):