diff --git a/examples/foundational/55h-update-settings-speechmatics-stt.py b/examples/foundational/55h-update-settings-speechmatics-stt.py
index 46ed44016..d041d69d2 100644
--- a/examples/foundational/55h-update-settings-speechmatics-stt.py
+++ b/examples/foundational/55h-update-settings-speechmatics-stt.py
@@ -51,7 +51,14 @@ transport_params = {
async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
logger.info(f"Starting bot")
- stt = SpeechmaticsSTTService(api_key=os.getenv("SPEECHMATICS_API_KEY"))
+ stt = SpeechmaticsSTTService(
+ api_key=os.getenv("SPEECHMATICS_API_KEY"),
+ params=SpeechmaticsSTTService.InputParams(
+ enable_diarization=True,
+ speaker_active_format="<{speaker_id}>{text}{speaker_id}>",
+ speaker_passive_format="<{speaker_id}>{text}{speaker_id}>",
+ ),
+ )
tts = CartesiaTTSService(
api_key=os.getenv("CARTESIA_API_KEY"),
@@ -106,6 +113,24 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
STTUpdateSettingsFrame(update=SpeechmaticsSTTSettings(language=Language.ES))
)
+ await asyncio.sleep(10)
+ logger.info("Updating Speechmatics STT settings: focus_speakers=['S1']")
+ await task.queue_frame(
+ STTUpdateSettingsFrame(update=SpeechmaticsSTTSettings(focus_speakers=["S1"]))
+ )
+
+ await asyncio.sleep(10)
+ logger.info(
+ "Updating Speechmatics STT settings: speaker_active_format={text}"
+ )
+ await task.queue_frame(
+ STTUpdateSettingsFrame(
+ update=SpeechmaticsSTTSettings(
+ speaker_active_format="{text}"
+ )
+ )
+ )
+
@transport.event_handler("on_client_disconnected")
async def on_client_disconnected(transport, client):
logger.info(f"Client disconnected")
diff --git a/src/pipecat/services/speechmatics/stt.py b/src/pipecat/services/speechmatics/stt.py
index c6fe0d16e..166e19d97 100644
--- a/src/pipecat/services/speechmatics/stt.py
+++ b/src/pipecat/services/speechmatics/stt.py
@@ -508,12 +508,14 @@ class SpeechmaticsSTTService(STTService):
needs_reconnect = bool(changed.keys() - no_reconnect)
if needs_reconnect:
+ logger.debug(f"{self} settings update requires reconnect: {changed.keys()}")
# Connection-level fields changed — rebuild the SDK config
# from the now-updated self._settings, then reconnect.
self._config = self._build_config()
await self._disconnect()
await self._connect()
- elif changed & SpeechmaticsSTTSettings.HOT_FIELDS:
+ elif changed.keys() & SpeechmaticsSTTSettings.HOT_FIELDS:
+ logger.debug(f"{self} applying hot settings update: {changed.keys()}")
if self._config.enable_diarization:
# Only hot-updatable fields changed — push to the live session.
self._config.speaker_config.focus_speakers = self._settings.focus_speakers
@@ -522,11 +524,17 @@ class SpeechmaticsSTTService(STTService):
if self._client:
self._client.update_diarization_config(self._config.speaker_config)
else:
- # Diarization not enabled — need a full reconnect to apply.
- self._config = self._build_config()
- await self._disconnect()
- await self._connect()
- # LOCAL_FIELDS: already applied by super(); nothing else to do.
+ logger.debug(
+ f"{self} hot settings updated but diarization not enabled: {changed.keys()}. ignoring."
+ )
+ # Diarization not enabled — the new settings will take effect
+ # if/when diarization is enabled, which does require a reconnect.
+ elif changed.keys() & SpeechmaticsSTTSettings.LOCAL_FIELDS:
+ logger.debug(
+ f"{self} local settings update, no special action required: {changed.keys()}"
+ )
+ # Only local fields changed — no need to push to the STT engine,
+ # the new settings will take effect immediately.
return changed