Skip to content

Commit 3833009

Browse files
authored
Merge pull request #4004 from pipecat-ai/pk/service-settings-update-frame-can-target-specific-service
Add optional `service` field to `ServiceUpdateSettingsFrame` for targ…
2 parents 3ffa721 + 27b686d commit 3833009

5 files changed

Lines changed: 15 additions & 3 deletions

File tree

changelog/4004.added.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Added optional `service` field to `ServiceUpdateSettingsFrame` (and its subclasses `LLMUpdateSettingsFrame`, `TTSUpdateSettingsFrame`, `STTUpdateSettingsFrame`) to target a specific service instance. When `service` is set, only the matching service applies the settings; others forward the frame unchanged. This enables updating a single service when multiple services of the same type exist in the pipeline.

src/pipecat/frames/frames.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2154,10 +2154,15 @@ class ServiceUpdateSettingsFrame(ControlFrame, UninterruptibleFrame):
21542154
21552155
delta: :class:`~pipecat.services.settings.ServiceSettings` delta-mode
21562156
object describing the fields to change.
2157+
2158+
service: Optional target service instance. When provided, only that
2159+
service will apply the settings; other services will forward the
2160+
frame unchanged.
21572161
"""
21582162

21592163
settings: Mapping[str, Any] = field(default_factory=dict)
21602164
delta: Optional["ServiceSettings"] = None
2165+
service: Optional["FrameProcessor"] = None
21612166

21622167

21632168
@dataclass

src/pipecat/services/llm_service.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,9 @@ async def process_frame(self, frame: Frame, direction: FrameDirection):
403403
elif isinstance(frame, LLMConfigureOutputFrame):
404404
self._skip_tts = frame.skip_tts
405405
elif isinstance(frame, LLMUpdateSettingsFrame):
406-
if frame.delta is not None:
406+
if frame.service is not None and frame.service is not self:
407+
await self.push_frame(frame, direction)
408+
elif frame.delta is not None:
407409
await self._update_settings(frame.delta)
408410
elif frame.settings:
409411
# Backward-compatible path: convert legacy dict to settings object.

src/pipecat/services/stt_service.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,9 @@ async def process_frame(self, frame: Frame, direction: FrameDirection):
357357
await self._handle_vad_user_stopped_speaking(frame)
358358
await self.push_frame(frame, direction)
359359
elif isinstance(frame, STTUpdateSettingsFrame):
360-
if frame.delta is not None:
360+
if frame.service is not None and frame.service is not self:
361+
await self.push_frame(frame, direction)
362+
elif frame.delta is not None:
361363
await self._update_settings(frame.delta)
362364
elif frame.settings:
363365
# Backward-compatible path: convert legacy dict to settings object.

src/pipecat/services/tts_service.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -738,7 +738,9 @@ async def process_frame(self, frame: Frame, direction: FrameDirection):
738738
self._turn_context_id = saved_turn_context_id
739739
self._processing_text = processing_text
740740
elif isinstance(frame, TTSUpdateSettingsFrame):
741-
if frame.delta is not None:
741+
if frame.service is not None and frame.service is not self:
742+
await self.push_frame(frame, direction)
743+
elif frame.delta is not None:
742744
await self._update_settings(frame.delta)
743745
elif frame.settings:
744746
# Backward-compatible path: convert legacy dict to settings object.

0 commit comments

Comments
 (0)