Remove deprecated EmulateUser{Started,Stopped}SpeakingFrame and emulated field

Remove EmulateUserStartedSpeakingFrame, EmulateUserStoppedSpeakingFrame
(deprecated since v0.0.99), and the emulated field from
UserStartedSpeakingFrame and UserStoppedSpeakingFrame. Clean up the
handling code in base_input.py and a stale comment in nova_sonic/llm.py.
This commit is contained in:
Mark Backman
2026-04-02 11:31:29 -04:00
parent d503383c23
commit 5b67dcd9e7
3 changed files with 7 additions and 91 deletions

View File

@@ -866,16 +866,9 @@ class UserStartedSpeakingFrame(SystemFrame):
Emitted when the user turn starts, which usually means that some Emitted when the user turn starts, which usually means that some
transcriptions are already available. transcriptions are already available.
Parameters:
emulated: Whether this event was emulated rather than detected by VAD.
.. deprecated:: 0.0.99
This field is deprecated and will be removed in a future version.
""" """
emulated: bool = False pass
@dataclass @dataclass
@@ -884,16 +877,9 @@ class UserStoppedSpeakingFrame(SystemFrame):
Emitted when the user turn ends. This usually coincides with the start of Emitted when the user turn ends. This usually coincides with the start of
the bot turn. the bot turn.
Parameters:
emulated: Whether this event was emulated rather than detected by VAD.
.. deprecated:: 0.0.99
This field is deprecated and will be removed in a future version.
""" """
emulated: bool = False pass
@dataclass @dataclass
@@ -928,56 +914,6 @@ class UserSpeakingFrame(SystemFrame):
pass pass
@dataclass
class EmulateUserStartedSpeakingFrame(SystemFrame):
"""Frame to emulate user started speaking behavior.
Emitted by internal processors upstream to emulate VAD behavior when a
user starts speaking.
.. deprecated:: 0.0.99
This frame is deprecated and will be removed in a future version.
"""
def __post_init__(self):
super().__post_init__()
import warnings
with warnings.catch_warnings():
warnings.simplefilter("always")
warnings.warn(
"EmulateUserStartedSpeakingFrame is deprecated and will be removed in a future version.",
DeprecationWarning,
stacklevel=2,
)
@dataclass
class EmulateUserStoppedSpeakingFrame(SystemFrame):
"""Frame to emulate user stopped speaking behavior.
Emitted by internal processors upstream to emulate VAD behavior when a
user stops speaking.
.. deprecated:: 0.0.99
This frame is deprecated and will be removed in a future version.
"""
def __post_init__(self):
super().__post_init__()
import warnings
with warnings.catch_warnings():
warnings.simplefilter("always")
warnings.warn(
"EmulateUserStoppedSpeakingFrame is deprecated and will be removed in a future version.",
DeprecationWarning,
stacklevel=2,
)
@dataclass @dataclass
class VADUserStartedSpeakingFrame(SystemFrame): class VADUserStartedSpeakingFrame(SystemFrame):
"""Frame emitted when VAD definitively detects user started speaking. """Frame emitted when VAD definitively detects user started speaking.

View File

@@ -1281,18 +1281,8 @@ class AWSNovaSonicLLMService(LLMService):
# HACK: Check if this transcription was triggered by our own # HACK: Check if this transcription was triggered by our own
# assistant response trigger. If so, we need to wrap it with # assistant response trigger. If so, we need to wrap it with
# UserStarted/StoppedSpeakingFrames; otherwise the user aggregator # UserStarted/StoppedSpeakingFrames; otherwise the user aggregator
# would fire an EmulatedUserStartedSpeakingFrame, which would # would trigger an interruption, which would prevent us from
# trigger an interruption, which would prevent us from writing the # writing the assistant response to context.
# assistant response to context.
#
# Sending an EmulateUserStartedSpeakingFrame ourselves doesn't
# work: it just causes the interruption we're trying to avoid.
#
# Setting enable_emulated_vad_interruptions also doesn't work: at
# the time the user aggregator receives the TranscriptionFrame, it
# doesn't yet know the assistant has started responding, so it
# doesn't know that emulating the user starting to speak would
# cause an interruption.
should_wrap_in_user_started_stopped_speaking_frames = ( should_wrap_in_user_started_stopped_speaking_frames = (
self._waiting_for_trigger_transcription self._waiting_for_trigger_transcription
and self._user_text_buffer.strip().lower() == "ready" and self._user_text_buffer.strip().lower() == "ready"

View File

@@ -25,8 +25,6 @@ from pipecat.frames.frames import (
BotStartedSpeakingFrame, BotStartedSpeakingFrame,
BotStoppedSpeakingFrame, BotStoppedSpeakingFrame,
CancelFrame, CancelFrame,
EmulateUserStartedSpeakingFrame,
EmulateUserStoppedSpeakingFrame,
EndFrame, EndFrame,
FilterUpdateSettingsFrame, FilterUpdateSettingsFrame,
Frame, Frame,
@@ -313,12 +311,6 @@ class BaseInputTransport(FrameProcessor):
elif isinstance(frame, BotStoppedSpeakingFrame): elif isinstance(frame, BotStoppedSpeakingFrame):
await self._deprecated_handle_bot_stopped_speaking(frame) await self._deprecated_handle_bot_stopped_speaking(frame)
await self.push_frame(frame, direction) await self.push_frame(frame, direction)
elif isinstance(frame, EmulateUserStartedSpeakingFrame):
logger.debug("Emulating user started speaking")
await self._deprecated_handle_user_interruption(VADState.SPEAKING, emulated=True)
elif isinstance(frame, EmulateUserStoppedSpeakingFrame):
logger.debug("Emulating user stopped speaking")
await self._deprecated_handle_user_interruption(VADState.QUIET, emulated=True)
# All other system frames # All other system frames
elif isinstance(frame, SystemFrame): elif isinstance(frame, SystemFrame):
await self.push_frame(frame, direction) await self.push_frame(frame, direction)
@@ -500,15 +492,13 @@ class BaseInputTransport(FrameProcessor):
"""Update bot speaking state when bot stops speaking.""" """Update bot speaking state when bot stops speaking."""
self._bot_speaking = False self._bot_speaking = False
async def _deprecated_handle_user_interruption( async def _deprecated_handle_user_interruption(self, vad_state: VADState):
self, vad_state: VADState, emulated: bool = False
):
"""Handle user interruption events based on speaking state.""" """Handle user interruption events based on speaking state."""
if vad_state == VADState.SPEAKING: if vad_state == VADState.SPEAKING:
logger.debug("User started speaking") logger.debug("User started speaking")
self._user_speaking = True self._user_speaking = True
await self.broadcast_frame(UserStartedSpeakingFrame, emulated=emulated) await self.broadcast_frame(UserStartedSpeakingFrame)
# Make sure we notify about interruptions quickly out-of-band. # Make sure we notify about interruptions quickly out-of-band.
await self.broadcast_interruption() await self.broadcast_interruption()
@@ -516,7 +506,7 @@ class BaseInputTransport(FrameProcessor):
logger.debug("User stopped speaking") logger.debug("User stopped speaking")
self._user_speaking = False self._user_speaking = False
await self.broadcast_frame(UserStoppedSpeakingFrame, emulated=emulated) await self.broadcast_frame(UserStoppedSpeakingFrame)
async def _deprecated_old_handle_vad( async def _deprecated_old_handle_vad(
self, audio_frame: InputAudioRawFrame, vad_state: VADState self, audio_frame: InputAudioRawFrame, vad_state: VADState