frames: StartInterruptionFrame is deprecated, use InterruptionFrame
This commit is contained in:
@@ -29,6 +29,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
### Deprecated
|
### Deprecated
|
||||||
|
|
||||||
|
- `StartInterruptionFrame` is now deprected, use `InterruptionFrame` instead.
|
||||||
|
|
||||||
- Deprecate `VisionImageFrameAggregator` because `VisionImageRawFrame` has been
|
- Deprecate `VisionImageFrameAggregator` because `VisionImageRawFrame` has been
|
||||||
removed. See the `12*` examples for the new recommended replacement pattern.
|
removed. See the `12*` examples for the new recommended replacement pattern.
|
||||||
|
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ from dotenv import load_dotenv
|
|||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
||||||
from pipecat.frames.frames import (
|
from pipecat.frames.frames import (
|
||||||
|
InterruptionFrame,
|
||||||
LLMRunFrame,
|
LLMRunFrame,
|
||||||
StartInterruptionFrame,
|
|
||||||
UserStartedSpeakingFrame,
|
UserStartedSpeakingFrame,
|
||||||
UserStoppedSpeakingFrame,
|
UserStoppedSpeakingFrame,
|
||||||
)
|
)
|
||||||
@@ -97,7 +97,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
|
|||||||
|
|
||||||
@stt.event_handler("on_speech_started")
|
@stt.event_handler("on_speech_started")
|
||||||
async def on_speech_started(stt, *args, **kwargs):
|
async def on_speech_started(stt, *args, **kwargs):
|
||||||
await task.queue_frames([StartInterruptionFrame(), UserStartedSpeakingFrame()])
|
await task.queue_frames([InterruptionFrame(), UserStartedSpeakingFrame()])
|
||||||
|
|
||||||
@stt.event_handler("on_utterance_end")
|
@stt.event_handler("on_utterance_end")
|
||||||
async def on_utterance_end(stt, *args, **kwargs):
|
async def on_utterance_end(stt, *args, **kwargs):
|
||||||
|
|||||||
@@ -16,10 +16,10 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer
|
|||||||
from pipecat.frames.frames import (
|
from pipecat.frames.frames import (
|
||||||
Frame,
|
Frame,
|
||||||
InputAudioRawFrame,
|
InputAudioRawFrame,
|
||||||
|
InterruptionFrame,
|
||||||
LLMFullResponseEndFrame,
|
LLMFullResponseEndFrame,
|
||||||
LLMFullResponseStartFrame,
|
LLMFullResponseStartFrame,
|
||||||
LLMRunFrame,
|
LLMRunFrame,
|
||||||
StartInterruptionFrame,
|
|
||||||
TextFrame,
|
TextFrame,
|
||||||
TranscriptionFrame,
|
TranscriptionFrame,
|
||||||
UserStartedSpeakingFrame,
|
UserStartedSpeakingFrame,
|
||||||
@@ -181,9 +181,7 @@ class TranscriptionContextFixup(FrameProcessor):
|
|||||||
|
|
||||||
if isinstance(frame, MagicDemoTranscriptionFrame):
|
if isinstance(frame, MagicDemoTranscriptionFrame):
|
||||||
self._transcript = frame.text
|
self._transcript = frame.text
|
||||||
elif isinstance(frame, LLMFullResponseEndFrame) or isinstance(
|
elif isinstance(frame, LLMFullResponseEndFrame) or isinstance(frame, InterruptionFrame):
|
||||||
frame, StartInterruptionFrame
|
|
||||||
):
|
|
||||||
self.swap_user_audio()
|
self.swap_user_audio()
|
||||||
self.add_transcript_back_to_inference_output()
|
self.add_transcript_back_to_inference_output()
|
||||||
self._transcript = ""
|
self._transcript = ""
|
||||||
|
|||||||
@@ -18,9 +18,9 @@ from pipecat.frames.frames import (
|
|||||||
Frame,
|
Frame,
|
||||||
FunctionCallInProgressFrame,
|
FunctionCallInProgressFrame,
|
||||||
FunctionCallResultFrame,
|
FunctionCallResultFrame,
|
||||||
|
InterruptionFrame,
|
||||||
LLMRunFrame,
|
LLMRunFrame,
|
||||||
StartFrame,
|
StartFrame,
|
||||||
StartInterruptionFrame,
|
|
||||||
SystemFrame,
|
SystemFrame,
|
||||||
TextFrame,
|
TextFrame,
|
||||||
TranscriptionFrame,
|
TranscriptionFrame,
|
||||||
@@ -144,7 +144,7 @@ class OutputGate(FrameProcessor):
|
|||||||
await self._start()
|
await self._start()
|
||||||
if isinstance(frame, (EndFrame, CancelFrame)):
|
if isinstance(frame, (EndFrame, CancelFrame)):
|
||||||
await self._stop()
|
await self._stop()
|
||||||
if isinstance(frame, StartInterruptionFrame):
|
if isinstance(frame, InterruptionFrame):
|
||||||
self._frames_buffer = []
|
self._frames_buffer = []
|
||||||
self.close_gate()
|
self.close_gate()
|
||||||
await self.push_frame(frame, direction)
|
await self.push_frame(frame, direction)
|
||||||
@@ -232,7 +232,7 @@ class TurnDetectionLLM(Pipeline):
|
|||||||
async def pass_only_llm_trigger_frames(frame):
|
async def pass_only_llm_trigger_frames(frame):
|
||||||
return (
|
return (
|
||||||
isinstance(frame, OpenAILLMContextFrame)
|
isinstance(frame, OpenAILLMContextFrame)
|
||||||
or isinstance(frame, StartInterruptionFrame)
|
or isinstance(frame, InterruptionFrame)
|
||||||
or isinstance(frame, FunctionCallInProgressFrame)
|
or isinstance(frame, FunctionCallInProgressFrame)
|
||||||
or isinstance(frame, FunctionCallResultFrame)
|
or isinstance(frame, FunctionCallResultFrame)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -18,9 +18,9 @@ from pipecat.frames.frames import (
|
|||||||
Frame,
|
Frame,
|
||||||
FunctionCallInProgressFrame,
|
FunctionCallInProgressFrame,
|
||||||
FunctionCallResultFrame,
|
FunctionCallResultFrame,
|
||||||
|
InterruptionFrame,
|
||||||
LLMRunFrame,
|
LLMRunFrame,
|
||||||
StartFrame,
|
StartFrame,
|
||||||
StartInterruptionFrame,
|
|
||||||
SystemFrame,
|
SystemFrame,
|
||||||
TextFrame,
|
TextFrame,
|
||||||
TranscriptionFrame,
|
TranscriptionFrame,
|
||||||
@@ -347,7 +347,7 @@ class OutputGate(FrameProcessor):
|
|||||||
await self._start()
|
await self._start()
|
||||||
if isinstance(frame, (EndFrame, CancelFrame)):
|
if isinstance(frame, (EndFrame, CancelFrame)):
|
||||||
await self._stop()
|
await self._stop()
|
||||||
if isinstance(frame, StartInterruptionFrame):
|
if isinstance(frame, InterruptionFrame):
|
||||||
self._frames_buffer = []
|
self._frames_buffer = []
|
||||||
self.close_gate()
|
self.close_gate()
|
||||||
await self.push_frame(frame, direction)
|
await self.push_frame(frame, direction)
|
||||||
@@ -426,7 +426,7 @@ class TurnDetectionLLM(Pipeline):
|
|||||||
async def pass_only_llm_trigger_frames(frame):
|
async def pass_only_llm_trigger_frames(frame):
|
||||||
return (
|
return (
|
||||||
isinstance(frame, OpenAILLMContextFrame)
|
isinstance(frame, OpenAILLMContextFrame)
|
||||||
or isinstance(frame, StartInterruptionFrame)
|
or isinstance(frame, InterruptionFrame)
|
||||||
or isinstance(frame, FunctionCallInProgressFrame)
|
or isinstance(frame, FunctionCallInProgressFrame)
|
||||||
or isinstance(frame, FunctionCallResultFrame)
|
or isinstance(frame, FunctionCallResultFrame)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -20,10 +20,10 @@ from pipecat.frames.frames import (
|
|||||||
FunctionCallInProgressFrame,
|
FunctionCallInProgressFrame,
|
||||||
FunctionCallResultFrame,
|
FunctionCallResultFrame,
|
||||||
InputAudioRawFrame,
|
InputAudioRawFrame,
|
||||||
|
InterruptionFrame,
|
||||||
LLMFullResponseStartFrame,
|
LLMFullResponseStartFrame,
|
||||||
LLMRunFrame,
|
LLMRunFrame,
|
||||||
StartFrame,
|
StartFrame,
|
||||||
StartInterruptionFrame,
|
|
||||||
SystemFrame,
|
SystemFrame,
|
||||||
TextFrame,
|
TextFrame,
|
||||||
TranscriptionFrame,
|
TranscriptionFrame,
|
||||||
@@ -570,7 +570,7 @@ class OutputGate(FrameProcessor):
|
|||||||
await self._start()
|
await self._start()
|
||||||
if isinstance(frame, (EndFrame, CancelFrame)):
|
if isinstance(frame, (EndFrame, CancelFrame)):
|
||||||
await self._stop()
|
await self._stop()
|
||||||
if isinstance(frame, StartInterruptionFrame):
|
if isinstance(frame, InterruptionFrame):
|
||||||
self._frames_buffer = []
|
self._frames_buffer = []
|
||||||
self.close_gate()
|
self.close_gate()
|
||||||
await self.push_frame(frame, direction)
|
await self.push_frame(frame, direction)
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ from pipecat.frames.frames import (
|
|||||||
BotStartedSpeakingFrame,
|
BotStartedSpeakingFrame,
|
||||||
BotStoppedSpeakingFrame,
|
BotStoppedSpeakingFrame,
|
||||||
EndFrame,
|
EndFrame,
|
||||||
|
InterruptionFrame,
|
||||||
LLMRunFrame,
|
LLMRunFrame,
|
||||||
StartInterruptionFrame,
|
|
||||||
TTSTextFrame,
|
TTSTextFrame,
|
||||||
UserStartedSpeakingFrame,
|
UserStartedSpeakingFrame,
|
||||||
)
|
)
|
||||||
@@ -69,7 +69,7 @@ class CustomObserver(BaseObserver):
|
|||||||
# Create direction arrow
|
# Create direction arrow
|
||||||
arrow = "→" if direction == FrameDirection.DOWNSTREAM else "←"
|
arrow = "→" if direction == FrameDirection.DOWNSTREAM else "←"
|
||||||
|
|
||||||
if isinstance(frame, StartInterruptionFrame) and isinstance(src, BaseOutputTransport):
|
if isinstance(frame, InterruptionFrame) and isinstance(src, BaseOutputTransport):
|
||||||
logger.info(f"⚡ INTERRUPTION START: {src} {arrow} {dst} at {time_sec:.2f}s")
|
logger.info(f"⚡ INTERRUPTION START: {src} {arrow} {dst} at {time_sec:.2f}s")
|
||||||
elif isinstance(frame, BotStartedSpeakingFrame):
|
elif isinstance(frame, BotStartedSpeakingFrame):
|
||||||
logger.info(f"🤖 BOT START SPEAKING: {src} {arrow} {dst} at {time_sec:.2f}s")
|
logger.info(f"🤖 BOT START SPEAKING: {src} {arrow} {dst} at {time_sec:.2f}s")
|
||||||
|
|||||||
@@ -820,7 +820,7 @@ class FrameProcessorResumeUrgentFrame(SystemFrame):
|
|||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class StartInterruptionFrame(SystemFrame):
|
class InterruptionFrame(SystemFrame):
|
||||||
"""Frame indicating user started speaking (interruption detected).
|
"""Frame indicating user started speaking (interruption detected).
|
||||||
|
|
||||||
Emitted by the BaseInputTransport to indicate that a user has started
|
Emitted by the BaseInputTransport to indicate that a user has started
|
||||||
@@ -832,6 +832,34 @@ class StartInterruptionFrame(SystemFrame):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class StartInterruptionFrame(InterruptionFrame):
|
||||||
|
"""Frame indicating user started speaking (interruption detected).
|
||||||
|
|
||||||
|
.. deprecated:: 0.0.85
|
||||||
|
This frame is deprecated and will be removed in a future version.
|
||||||
|
Instead, use `InterruptionFrame`.
|
||||||
|
|
||||||
|
Emitted by the BaseInputTransport to indicate that a user has started
|
||||||
|
speaking (i.e. is interrupting). This is similar to
|
||||||
|
UserStartedSpeakingFrame except that it should be pushed concurrently
|
||||||
|
with other frames (so the order is not guaranteed).
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __post_init__(self):
|
||||||
|
super().__post_init__()
|
||||||
|
import warnings
|
||||||
|
|
||||||
|
with warnings.catch_warnings():
|
||||||
|
warnings.simplefilter("always")
|
||||||
|
warnings.warn(
|
||||||
|
"StartInterruptionFrame is deprecated and will be removed in a future version. "
|
||||||
|
"Instead, use InterruptionFrame.",
|
||||||
|
DeprecationWarning,
|
||||||
|
stacklevel=2,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class UserStartedSpeakingFrame(SystemFrame):
|
class UserStartedSpeakingFrame(SystemFrame):
|
||||||
"""Frame indicating user has started speaking.
|
"""Frame indicating user has started speaking.
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ from pipecat.frames.frames import (
|
|||||||
FunctionCallsStartedFrame,
|
FunctionCallsStartedFrame,
|
||||||
InputAudioRawFrame,
|
InputAudioRawFrame,
|
||||||
InterimTranscriptionFrame,
|
InterimTranscriptionFrame,
|
||||||
|
InterruptionFrame,
|
||||||
LLMFullResponseEndFrame,
|
LLMFullResponseEndFrame,
|
||||||
LLMFullResponseStartFrame,
|
LLMFullResponseStartFrame,
|
||||||
LLMMessagesAppendFrame,
|
LLMMessagesAppendFrame,
|
||||||
@@ -48,7 +49,6 @@ from pipecat.frames.frames import (
|
|||||||
OpenAILLMContextAssistantTimestampFrame,
|
OpenAILLMContextAssistantTimestampFrame,
|
||||||
SpeechControlParamsFrame,
|
SpeechControlParamsFrame,
|
||||||
StartFrame,
|
StartFrame,
|
||||||
StartInterruptionFrame,
|
|
||||||
TextFrame,
|
TextFrame,
|
||||||
TranscriptionFrame,
|
TranscriptionFrame,
|
||||||
UserImageRawFrame,
|
UserImageRawFrame,
|
||||||
@@ -138,7 +138,7 @@ class LLMFullResponseAggregator(FrameProcessor):
|
|||||||
"""
|
"""
|
||||||
await super().process_frame(frame, direction)
|
await super().process_frame(frame, direction)
|
||||||
|
|
||||||
if isinstance(frame, StartInterruptionFrame):
|
if isinstance(frame, InterruptionFrame):
|
||||||
await self._call_event_handler("on_completion", self._aggregation, False)
|
await self._call_event_handler("on_completion", self._aggregation, False)
|
||||||
self._aggregation = ""
|
self._aggregation = ""
|
||||||
self._started = False
|
self._started = False
|
||||||
@@ -838,7 +838,7 @@ class LLMAssistantContextAggregator(LLMContextResponseAggregator):
|
|||||||
"""
|
"""
|
||||||
await super().process_frame(frame, direction)
|
await super().process_frame(frame, direction)
|
||||||
|
|
||||||
if isinstance(frame, StartInterruptionFrame):
|
if isinstance(frame, InterruptionFrame):
|
||||||
await self._handle_interruptions(frame)
|
await self._handle_interruptions(frame)
|
||||||
await self.push_frame(frame, direction)
|
await self.push_frame(frame, direction)
|
||||||
elif isinstance(frame, LLMFullResponseStartFrame):
|
elif isinstance(frame, LLMFullResponseStartFrame):
|
||||||
@@ -904,7 +904,7 @@ class LLMAssistantContextAggregator(LLMContextResponseAggregator):
|
|||||||
if frame.run_llm:
|
if frame.run_llm:
|
||||||
await self.push_context_frame(FrameDirection.UPSTREAM)
|
await self.push_context_frame(FrameDirection.UPSTREAM)
|
||||||
|
|
||||||
async def _handle_interruptions(self, frame: StartInterruptionFrame):
|
async def _handle_interruptions(self, frame: InterruptionFrame):
|
||||||
await self.push_aggregation()
|
await self.push_aggregation()
|
||||||
self._started = 0
|
self._started = 0
|
||||||
await self.reset()
|
await self.reset()
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ from pipecat.frames.frames import (
|
|||||||
FunctionCallsStartedFrame,
|
FunctionCallsStartedFrame,
|
||||||
InputAudioRawFrame,
|
InputAudioRawFrame,
|
||||||
InterimTranscriptionFrame,
|
InterimTranscriptionFrame,
|
||||||
|
InterruptionFrame,
|
||||||
LLMContextAssistantTimestampFrame,
|
LLMContextAssistantTimestampFrame,
|
||||||
LLMContextFrame,
|
LLMContextFrame,
|
||||||
LLMFullResponseEndFrame,
|
LLMFullResponseEndFrame,
|
||||||
@@ -48,7 +49,6 @@ from pipecat.frames.frames import (
|
|||||||
LLMSetToolsFrame,
|
LLMSetToolsFrame,
|
||||||
SpeechControlParamsFrame,
|
SpeechControlParamsFrame,
|
||||||
StartFrame,
|
StartFrame,
|
||||||
StartInterruptionFrame,
|
|
||||||
TextFrame,
|
TextFrame,
|
||||||
TranscriptionFrame,
|
TranscriptionFrame,
|
||||||
UserImageRawFrame,
|
UserImageRawFrame,
|
||||||
@@ -579,7 +579,7 @@ class LLMAssistantAggregator(LLMContextAggregator):
|
|||||||
"""
|
"""
|
||||||
await super().process_frame(frame, direction)
|
await super().process_frame(frame, direction)
|
||||||
|
|
||||||
if isinstance(frame, StartInterruptionFrame):
|
if isinstance(frame, InterruptionFrame):
|
||||||
await self._handle_interruptions(frame)
|
await self._handle_interruptions(frame)
|
||||||
await self.push_frame(frame, direction)
|
await self.push_frame(frame, direction)
|
||||||
elif isinstance(frame, LLMFullResponseStartFrame):
|
elif isinstance(frame, LLMFullResponseStartFrame):
|
||||||
@@ -645,7 +645,7 @@ class LLMAssistantAggregator(LLMContextAggregator):
|
|||||||
if frame.run_llm:
|
if frame.run_llm:
|
||||||
await self.push_context_frame(FrameDirection.UPSTREAM)
|
await self.push_context_frame(FrameDirection.UPSTREAM)
|
||||||
|
|
||||||
async def _handle_interruptions(self, frame: StartInterruptionFrame):
|
async def _handle_interruptions(self, frame: InterruptionFrame):
|
||||||
await self._push_aggregation()
|
await self._push_aggregation()
|
||||||
self._started = 0
|
self._started = 0
|
||||||
await self.reset()
|
await self.reset()
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ from pipecat.frames.frames import (
|
|||||||
FunctionCallResultFrame,
|
FunctionCallResultFrame,
|
||||||
InputAudioRawFrame,
|
InputAudioRawFrame,
|
||||||
InterimTranscriptionFrame,
|
InterimTranscriptionFrame,
|
||||||
|
InterruptionFrame,
|
||||||
StartFrame,
|
StartFrame,
|
||||||
StartInterruptionFrame,
|
|
||||||
STTMuteFrame,
|
STTMuteFrame,
|
||||||
TranscriptionFrame,
|
TranscriptionFrame,
|
||||||
UserStartedSpeakingFrame,
|
UserStartedSpeakingFrame,
|
||||||
@@ -204,7 +204,7 @@ class STTMuteFilter(FrameProcessor):
|
|||||||
if isinstance(
|
if isinstance(
|
||||||
frame,
|
frame,
|
||||||
(
|
(
|
||||||
StartInterruptionFrame,
|
InterruptionFrame,
|
||||||
VADUserStartedSpeakingFrame,
|
VADUserStartedSpeakingFrame,
|
||||||
VADUserStoppedSpeakingFrame,
|
VADUserStoppedSpeakingFrame,
|
||||||
UserStartedSpeakingFrame,
|
UserStartedSpeakingFrame,
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ from pipecat.frames.frames import (
|
|||||||
FrameProcessorPauseUrgentFrame,
|
FrameProcessorPauseUrgentFrame,
|
||||||
FrameProcessorResumeFrame,
|
FrameProcessorResumeFrame,
|
||||||
FrameProcessorResumeUrgentFrame,
|
FrameProcessorResumeUrgentFrame,
|
||||||
|
InterruptionFrame,
|
||||||
StartFrame,
|
StartFrame,
|
||||||
StartInterruptionFrame,
|
|
||||||
SystemFrame,
|
SystemFrame,
|
||||||
)
|
)
|
||||||
from pipecat.metrics.metrics import LLMTokenUsage, MetricsData
|
from pipecat.metrics.metrics import LLMTokenUsage, MetricsData
|
||||||
@@ -588,7 +588,7 @@ class FrameProcessor(BaseObject):
|
|||||||
|
|
||||||
if isinstance(frame, StartFrame):
|
if isinstance(frame, StartFrame):
|
||||||
await self.__start(frame)
|
await self.__start(frame)
|
||||||
elif isinstance(frame, StartInterruptionFrame):
|
elif isinstance(frame, InterruptionFrame):
|
||||||
await self._start_interruption()
|
await self._start_interruption()
|
||||||
await self.stop_all_metrics()
|
await self.stop_all_metrics()
|
||||||
elif isinstance(frame, CancelFrame):
|
elif isinstance(frame, CancelFrame):
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ from pipecat.frames.frames import (
|
|||||||
CancelFrame,
|
CancelFrame,
|
||||||
EndFrame,
|
EndFrame,
|
||||||
Frame,
|
Frame,
|
||||||
StartInterruptionFrame,
|
InterruptionFrame,
|
||||||
TranscriptionFrame,
|
TranscriptionFrame,
|
||||||
TranscriptionMessage,
|
TranscriptionMessage,
|
||||||
TranscriptionUpdateFrame,
|
TranscriptionUpdateFrame,
|
||||||
@@ -195,7 +195,7 @@ class AssistantTranscriptProcessor(BaseTranscriptProcessor):
|
|||||||
"""
|
"""
|
||||||
await super().process_frame(frame, direction)
|
await super().process_frame(frame, direction)
|
||||||
|
|
||||||
if isinstance(frame, (StartInterruptionFrame, CancelFrame)):
|
if isinstance(frame, (InterruptionFrame, CancelFrame)):
|
||||||
# Push frame first otherwise our emitted transcription update frame
|
# Push frame first otherwise our emitted transcription update frame
|
||||||
# might get cleaned up.
|
# might get cleaned up.
|
||||||
await self.push_frame(frame, direction)
|
await self.push_frame(frame, direction)
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ from pipecat.frames.frames import (
|
|||||||
Frame,
|
Frame,
|
||||||
InputAudioRawFrame,
|
InputAudioRawFrame,
|
||||||
InputDTMFFrame,
|
InputDTMFFrame,
|
||||||
|
InterruptionFrame,
|
||||||
StartFrame,
|
StartFrame,
|
||||||
StartInterruptionFrame,
|
|
||||||
TransportMessageFrame,
|
TransportMessageFrame,
|
||||||
TransportMessageUrgentFrame,
|
TransportMessageUrgentFrame,
|
||||||
)
|
)
|
||||||
@@ -98,7 +98,7 @@ class ExotelFrameSerializer(FrameSerializer):
|
|||||||
Returns:
|
Returns:
|
||||||
Serialized data as string or bytes, or None if the frame isn't handled.
|
Serialized data as string or bytes, or None if the frame isn't handled.
|
||||||
"""
|
"""
|
||||||
if isinstance(frame, StartInterruptionFrame):
|
if isinstance(frame, InterruptionFrame):
|
||||||
answer = {"event": "clear", "streamSid": self._stream_sid}
|
answer = {"event": "clear", "streamSid": self._stream_sid}
|
||||||
return json.dumps(answer)
|
return json.dumps(answer)
|
||||||
elif isinstance(frame, AudioRawFrame):
|
elif isinstance(frame, AudioRawFrame):
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ from pipecat.frames.frames import (
|
|||||||
Frame,
|
Frame,
|
||||||
InputAudioRawFrame,
|
InputAudioRawFrame,
|
||||||
InputDTMFFrame,
|
InputDTMFFrame,
|
||||||
|
InterruptionFrame,
|
||||||
StartFrame,
|
StartFrame,
|
||||||
StartInterruptionFrame,
|
|
||||||
TransportMessageFrame,
|
TransportMessageFrame,
|
||||||
TransportMessageUrgentFrame,
|
TransportMessageUrgentFrame,
|
||||||
)
|
)
|
||||||
@@ -122,7 +122,7 @@ class PlivoFrameSerializer(FrameSerializer):
|
|||||||
self._hangup_attempted = True
|
self._hangup_attempted = True
|
||||||
await self._hang_up_call()
|
await self._hang_up_call()
|
||||||
return None
|
return None
|
||||||
elif isinstance(frame, StartInterruptionFrame):
|
elif isinstance(frame, InterruptionFrame):
|
||||||
answer = {"event": "clearAudio", "streamId": self._stream_id}
|
answer = {"event": "clearAudio", "streamId": self._stream_id}
|
||||||
return json.dumps(answer)
|
return json.dumps(answer)
|
||||||
elif isinstance(frame, AudioRawFrame):
|
elif isinstance(frame, AudioRawFrame):
|
||||||
|
|||||||
@@ -29,8 +29,8 @@ from pipecat.frames.frames import (
|
|||||||
Frame,
|
Frame,
|
||||||
InputAudioRawFrame,
|
InputAudioRawFrame,
|
||||||
InputDTMFFrame,
|
InputDTMFFrame,
|
||||||
|
InterruptionFrame,
|
||||||
StartFrame,
|
StartFrame,
|
||||||
StartInterruptionFrame,
|
|
||||||
)
|
)
|
||||||
from pipecat.serializers.base_serializer import FrameSerializer, FrameSerializerType
|
from pipecat.serializers.base_serializer import FrameSerializer, FrameSerializerType
|
||||||
|
|
||||||
@@ -137,7 +137,7 @@ class TelnyxFrameSerializer(FrameSerializer):
|
|||||||
self._hangup_attempted = True
|
self._hangup_attempted = True
|
||||||
await self._hang_up_call()
|
await self._hang_up_call()
|
||||||
return None
|
return None
|
||||||
elif isinstance(frame, StartInterruptionFrame):
|
elif isinstance(frame, InterruptionFrame):
|
||||||
answer = {"event": "clear"}
|
answer = {"event": "clear"}
|
||||||
return json.dumps(answer)
|
return json.dumps(answer)
|
||||||
elif isinstance(frame, AudioRawFrame):
|
elif isinstance(frame, AudioRawFrame):
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ from pipecat.frames.frames import (
|
|||||||
Frame,
|
Frame,
|
||||||
InputAudioRawFrame,
|
InputAudioRawFrame,
|
||||||
InputDTMFFrame,
|
InputDTMFFrame,
|
||||||
|
InterruptionFrame,
|
||||||
StartFrame,
|
StartFrame,
|
||||||
StartInterruptionFrame,
|
|
||||||
TransportMessageFrame,
|
TransportMessageFrame,
|
||||||
TransportMessageUrgentFrame,
|
TransportMessageUrgentFrame,
|
||||||
)
|
)
|
||||||
@@ -122,7 +122,7 @@ class TwilioFrameSerializer(FrameSerializer):
|
|||||||
self._hangup_attempted = True
|
self._hangup_attempted = True
|
||||||
await self._hang_up_call()
|
await self._hang_up_call()
|
||||||
return None
|
return None
|
||||||
elif isinstance(frame, StartInterruptionFrame):
|
elif isinstance(frame, InterruptionFrame):
|
||||||
answer = {"event": "clear", "streamSid": self._stream_sid}
|
answer = {"event": "clear", "streamSid": self._stream_sid}
|
||||||
return json.dumps(answer)
|
return json.dumps(answer)
|
||||||
elif isinstance(frame, AudioRawFrame):
|
elif isinstance(frame, AudioRawFrame):
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ from pipecat.frames.frames import (
|
|||||||
EndFrame,
|
EndFrame,
|
||||||
ErrorFrame,
|
ErrorFrame,
|
||||||
Frame,
|
Frame,
|
||||||
|
InterruptionFrame,
|
||||||
StartFrame,
|
StartFrame,
|
||||||
StartInterruptionFrame,
|
|
||||||
TTSAudioRawFrame,
|
TTSAudioRawFrame,
|
||||||
TTSStartedFrame,
|
TTSStartedFrame,
|
||||||
TTSStoppedFrame,
|
TTSStoppedFrame,
|
||||||
@@ -275,7 +275,7 @@ class AsyncAITTSService(InterruptibleTTSService):
|
|||||||
direction: The direction to push the frame.
|
direction: The direction to push the frame.
|
||||||
"""
|
"""
|
||||||
await super().push_frame(frame, direction)
|
await super().push_frame(frame, direction)
|
||||||
if isinstance(frame, (TTSStoppedFrame, StartInterruptionFrame)):
|
if isinstance(frame, (TTSStoppedFrame, InterruptionFrame)):
|
||||||
self._started = False
|
self._started = False
|
||||||
|
|
||||||
async def _receive_messages(self):
|
async def _receive_messages(self):
|
||||||
|
|||||||
@@ -21,13 +21,13 @@ from pipecat.frames.frames import (
|
|||||||
DataFrame,
|
DataFrame,
|
||||||
Frame,
|
Frame,
|
||||||
FunctionCallResultFrame,
|
FunctionCallResultFrame,
|
||||||
|
InterruptionFrame,
|
||||||
LLMFullResponseEndFrame,
|
LLMFullResponseEndFrame,
|
||||||
LLMFullResponseStartFrame,
|
LLMFullResponseStartFrame,
|
||||||
LLMMessagesAppendFrame,
|
LLMMessagesAppendFrame,
|
||||||
LLMMessagesUpdateFrame,
|
LLMMessagesUpdateFrame,
|
||||||
LLMSetToolChoiceFrame,
|
LLMSetToolChoiceFrame,
|
||||||
LLMSetToolsFrame,
|
LLMSetToolsFrame,
|
||||||
StartInterruptionFrame,
|
|
||||||
TextFrame,
|
TextFrame,
|
||||||
UserImageRawFrame,
|
UserImageRawFrame,
|
||||||
)
|
)
|
||||||
@@ -306,7 +306,7 @@ class AWSNovaSonicAssistantContextAggregator(OpenAIAssistantContextAggregator):
|
|||||||
if isinstance(
|
if isinstance(
|
||||||
frame,
|
frame,
|
||||||
(
|
(
|
||||||
StartInterruptionFrame,
|
InterruptionFrame,
|
||||||
LLMFullResponseStartFrame,
|
LLMFullResponseStartFrame,
|
||||||
LLMFullResponseEndFrame,
|
LLMFullResponseEndFrame,
|
||||||
TextFrame,
|
TextFrame,
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ from pipecat.frames.frames import (
|
|||||||
EndFrame,
|
EndFrame,
|
||||||
ErrorFrame,
|
ErrorFrame,
|
||||||
Frame,
|
Frame,
|
||||||
|
InterruptionFrame,
|
||||||
StartFrame,
|
StartFrame,
|
||||||
StartInterruptionFrame,
|
|
||||||
TTSAudioRawFrame,
|
TTSAudioRawFrame,
|
||||||
TTSStartedFrame,
|
TTSStartedFrame,
|
||||||
TTSStoppedFrame,
|
TTSStoppedFrame,
|
||||||
@@ -371,7 +371,7 @@ class CartesiaTTSService(AudioContextWordTTSService):
|
|||||||
return self._websocket
|
return self._websocket
|
||||||
raise Exception("Websocket not connected")
|
raise Exception("Websocket not connected")
|
||||||
|
|
||||||
async def _handle_interruption(self, frame: StartInterruptionFrame, direction: FrameDirection):
|
async def _handle_interruption(self, frame: InterruptionFrame, direction: FrameDirection):
|
||||||
await super()._handle_interruption(frame, direction)
|
await super()._handle_interruption(frame, direction)
|
||||||
await self.stop_all_metrics()
|
await self.stop_all_metrics()
|
||||||
if self._context_id:
|
if self._context_id:
|
||||||
|
|||||||
@@ -25,9 +25,9 @@ from pipecat.frames.frames import (
|
|||||||
EndFrame,
|
EndFrame,
|
||||||
ErrorFrame,
|
ErrorFrame,
|
||||||
Frame,
|
Frame,
|
||||||
|
InterruptionFrame,
|
||||||
LLMFullResponseEndFrame,
|
LLMFullResponseEndFrame,
|
||||||
StartFrame,
|
StartFrame,
|
||||||
StartInterruptionFrame,
|
|
||||||
TTSAudioRawFrame,
|
TTSAudioRawFrame,
|
||||||
TTSStartedFrame,
|
TTSStartedFrame,
|
||||||
TTSStoppedFrame,
|
TTSStoppedFrame,
|
||||||
@@ -460,7 +460,7 @@ class ElevenLabsTTSService(AudioContextWordTTSService):
|
|||||||
direction: The direction to push the frame.
|
direction: The direction to push the frame.
|
||||||
"""
|
"""
|
||||||
await super().push_frame(frame, direction)
|
await super().push_frame(frame, direction)
|
||||||
if isinstance(frame, (TTSStoppedFrame, StartInterruptionFrame)):
|
if isinstance(frame, (TTSStoppedFrame, InterruptionFrame)):
|
||||||
self._started = False
|
self._started = False
|
||||||
if isinstance(frame, TTSStoppedFrame):
|
if isinstance(frame, TTSStoppedFrame):
|
||||||
await self.add_word_timestamps([("Reset", 0)])
|
await self.add_word_timestamps([("Reset", 0)])
|
||||||
@@ -549,7 +549,7 @@ class ElevenLabsTTSService(AudioContextWordTTSService):
|
|||||||
return self._websocket
|
return self._websocket
|
||||||
raise Exception("Websocket not connected")
|
raise Exception("Websocket not connected")
|
||||||
|
|
||||||
async def _handle_interruption(self, frame: StartInterruptionFrame, direction: FrameDirection):
|
async def _handle_interruption(self, frame: InterruptionFrame, direction: FrameDirection):
|
||||||
"""Handle interruption by closing the current context."""
|
"""Handle interruption by closing the current context."""
|
||||||
await super()._handle_interruption(frame, direction)
|
await super()._handle_interruption(frame, direction)
|
||||||
|
|
||||||
@@ -856,7 +856,7 @@ class ElevenLabsHttpTTSService(WordTTSService):
|
|||||||
direction: The direction to push the frame.
|
direction: The direction to push the frame.
|
||||||
"""
|
"""
|
||||||
await super().push_frame(frame, direction)
|
await super().push_frame(frame, direction)
|
||||||
if isinstance(frame, (StartInterruptionFrame, TTSStoppedFrame)):
|
if isinstance(frame, (InterruptionFrame, TTSStoppedFrame)):
|
||||||
# Reset timing on interruption or stop
|
# Reset timing on interruption or stop
|
||||||
self._reset_state()
|
self._reset_state()
|
||||||
|
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ from pipecat.frames.frames import (
|
|||||||
EndFrame,
|
EndFrame,
|
||||||
ErrorFrame,
|
ErrorFrame,
|
||||||
Frame,
|
Frame,
|
||||||
|
InterruptionFrame,
|
||||||
StartFrame,
|
StartFrame,
|
||||||
StartInterruptionFrame,
|
|
||||||
TTSAudioRawFrame,
|
TTSAudioRawFrame,
|
||||||
TTSStartedFrame,
|
TTSStartedFrame,
|
||||||
TTSStoppedFrame,
|
TTSStoppedFrame,
|
||||||
@@ -259,7 +259,7 @@ class FishAudioTTSService(InterruptibleTTSService):
|
|||||||
return self._websocket
|
return self._websocket
|
||||||
raise Exception("Websocket not connected")
|
raise Exception("Websocket not connected")
|
||||||
|
|
||||||
async def _handle_interruption(self, frame: StartInterruptionFrame, direction: FrameDirection):
|
async def _handle_interruption(self, frame: InterruptionFrame, direction: FrameDirection):
|
||||||
await super()._handle_interruption(frame, direction)
|
await super()._handle_interruption(frame, direction)
|
||||||
await self.stop_all_metrics()
|
await self.stop_all_metrics()
|
||||||
self._request_id = None
|
self._request_id = None
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ from pipecat.frames.frames import (
|
|||||||
InputAudioRawFrame,
|
InputAudioRawFrame,
|
||||||
InputImageRawFrame,
|
InputImageRawFrame,
|
||||||
InputTextRawFrame,
|
InputTextRawFrame,
|
||||||
|
InterruptionFrame,
|
||||||
LLMContextFrame,
|
LLMContextFrame,
|
||||||
LLMFullResponseEndFrame,
|
LLMFullResponseEndFrame,
|
||||||
LLMFullResponseStartFrame,
|
LLMFullResponseStartFrame,
|
||||||
@@ -41,7 +42,6 @@ from pipecat.frames.frames import (
|
|||||||
LLMTextFrame,
|
LLMTextFrame,
|
||||||
LLMUpdateSettingsFrame,
|
LLMUpdateSettingsFrame,
|
||||||
StartFrame,
|
StartFrame,
|
||||||
StartInterruptionFrame,
|
|
||||||
TranscriptionFrame,
|
TranscriptionFrame,
|
||||||
TTSAudioRawFrame,
|
TTSAudioRawFrame,
|
||||||
TTSStartedFrame,
|
TTSStartedFrame,
|
||||||
@@ -752,7 +752,7 @@ class GeminiMultimodalLiveLLMService(LLMService):
|
|||||||
elif isinstance(frame, InputImageRawFrame):
|
elif isinstance(frame, InputImageRawFrame):
|
||||||
await self._send_user_video(frame)
|
await self._send_user_video(frame)
|
||||||
await self.push_frame(frame, direction)
|
await self.push_frame(frame, direction)
|
||||||
elif isinstance(frame, StartInterruptionFrame):
|
elif isinstance(frame, InterruptionFrame):
|
||||||
await self._handle_interruption()
|
await self._handle_interruption()
|
||||||
await self.push_frame(frame, direction)
|
await self.push_frame(frame, direction)
|
||||||
elif isinstance(frame, UserStartedSpeakingFrame):
|
elif isinstance(frame, UserStartedSpeakingFrame):
|
||||||
|
|||||||
@@ -36,12 +36,12 @@ from pipecat.frames.frames import (
|
|||||||
FunctionCallResultFrame,
|
FunctionCallResultFrame,
|
||||||
FunctionCallResultProperties,
|
FunctionCallResultProperties,
|
||||||
FunctionCallsStartedFrame,
|
FunctionCallsStartedFrame,
|
||||||
|
InterruptionFrame,
|
||||||
LLMConfigureOutputFrame,
|
LLMConfigureOutputFrame,
|
||||||
LLMFullResponseEndFrame,
|
LLMFullResponseEndFrame,
|
||||||
LLMFullResponseStartFrame,
|
LLMFullResponseStartFrame,
|
||||||
LLMTextFrame,
|
LLMTextFrame,
|
||||||
StartFrame,
|
StartFrame,
|
||||||
StartInterruptionFrame,
|
|
||||||
UserImageRequestFrame,
|
UserImageRequestFrame,
|
||||||
)
|
)
|
||||||
from pipecat.processors.aggregators.llm_context import LLMContext
|
from pipecat.processors.aggregators.llm_context import LLMContext
|
||||||
@@ -269,7 +269,7 @@ class LLMService(AIService):
|
|||||||
"""
|
"""
|
||||||
await super().process_frame(frame, direction)
|
await super().process_frame(frame, direction)
|
||||||
|
|
||||||
if isinstance(frame, StartInterruptionFrame):
|
if isinstance(frame, InterruptionFrame):
|
||||||
await self._handle_interruptions(frame)
|
await self._handle_interruptions(frame)
|
||||||
elif isinstance(frame, LLMConfigureOutputFrame):
|
elif isinstance(frame, LLMConfigureOutputFrame):
|
||||||
self._skip_tts = frame.skip_tts
|
self._skip_tts = frame.skip_tts
|
||||||
@@ -286,7 +286,7 @@ class LLMService(AIService):
|
|||||||
|
|
||||||
await super().push_frame(frame, direction)
|
await super().push_frame(frame, direction)
|
||||||
|
|
||||||
async def _handle_interruptions(self, _: StartInterruptionFrame):
|
async def _handle_interruptions(self, _: InterruptionFrame):
|
||||||
for function_name, entry in self._functions.items():
|
for function_name, entry in self._functions.items():
|
||||||
if entry.cancel_on_interruption:
|
if entry.cancel_on_interruption:
|
||||||
await self._cancel_function_call(function_name)
|
await self._cancel_function_call(function_name)
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ from pipecat.frames.frames import (
|
|||||||
EndFrame,
|
EndFrame,
|
||||||
ErrorFrame,
|
ErrorFrame,
|
||||||
Frame,
|
Frame,
|
||||||
|
InterruptionFrame,
|
||||||
StartFrame,
|
StartFrame,
|
||||||
StartInterruptionFrame,
|
|
||||||
TTSAudioRawFrame,
|
TTSAudioRawFrame,
|
||||||
TTSStartedFrame,
|
TTSStartedFrame,
|
||||||
TTSStoppedFrame,
|
TTSStoppedFrame,
|
||||||
@@ -180,7 +180,7 @@ class LmntTTSService(InterruptibleTTSService):
|
|||||||
direction: The direction to push the frame.
|
direction: The direction to push the frame.
|
||||||
"""
|
"""
|
||||||
await super().push_frame(frame, direction)
|
await super().push_frame(frame, direction)
|
||||||
if isinstance(frame, (TTSStoppedFrame, StartInterruptionFrame)):
|
if isinstance(frame, (TTSStoppedFrame, InterruptionFrame)):
|
||||||
self._started = False
|
self._started = False
|
||||||
|
|
||||||
async def _connect(self):
|
async def _connect(self):
|
||||||
|
|||||||
@@ -25,9 +25,9 @@ from pipecat.frames.frames import (
|
|||||||
EndFrame,
|
EndFrame,
|
||||||
ErrorFrame,
|
ErrorFrame,
|
||||||
Frame,
|
Frame,
|
||||||
|
InterruptionFrame,
|
||||||
LLMFullResponseEndFrame,
|
LLMFullResponseEndFrame,
|
||||||
StartFrame,
|
StartFrame,
|
||||||
StartInterruptionFrame,
|
|
||||||
TTSAudioRawFrame,
|
TTSAudioRawFrame,
|
||||||
TTSSpeakFrame,
|
TTSSpeakFrame,
|
||||||
TTSStartedFrame,
|
TTSStartedFrame,
|
||||||
@@ -224,7 +224,7 @@ class NeuphonicTTSService(InterruptibleTTSService):
|
|||||||
direction: The direction to push the frame.
|
direction: The direction to push the frame.
|
||||||
"""
|
"""
|
||||||
await super().push_frame(frame, direction)
|
await super().push_frame(frame, direction)
|
||||||
if isinstance(frame, (TTSStoppedFrame, StartInterruptionFrame)):
|
if isinstance(frame, (TTSStoppedFrame, InterruptionFrame)):
|
||||||
self._started = False
|
self._started = False
|
||||||
|
|
||||||
async def process_frame(self, frame: Frame, direction: FrameDirection):
|
async def process_frame(self, frame: Frame, direction: FrameDirection):
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ from pipecat.frames.frames import (
|
|||||||
Frame,
|
Frame,
|
||||||
InputAudioRawFrame,
|
InputAudioRawFrame,
|
||||||
InterimTranscriptionFrame,
|
InterimTranscriptionFrame,
|
||||||
|
InterruptionFrame,
|
||||||
LLMContextFrame,
|
LLMContextFrame,
|
||||||
LLMFullResponseEndFrame,
|
LLMFullResponseEndFrame,
|
||||||
LLMFullResponseStartFrame,
|
LLMFullResponseStartFrame,
|
||||||
@@ -31,7 +32,6 @@ from pipecat.frames.frames import (
|
|||||||
LLMTextFrame,
|
LLMTextFrame,
|
||||||
LLMUpdateSettingsFrame,
|
LLMUpdateSettingsFrame,
|
||||||
StartFrame,
|
StartFrame,
|
||||||
StartInterruptionFrame,
|
|
||||||
TranscriptionFrame,
|
TranscriptionFrame,
|
||||||
TTSAudioRawFrame,
|
TTSAudioRawFrame,
|
||||||
TTSStartedFrame,
|
TTSStartedFrame,
|
||||||
@@ -366,7 +366,7 @@ class OpenAIRealtimeLLMService(LLMService):
|
|||||||
elif isinstance(frame, InputAudioRawFrame):
|
elif isinstance(frame, InputAudioRawFrame):
|
||||||
if not self._audio_input_paused:
|
if not self._audio_input_paused:
|
||||||
await self._send_user_audio(frame)
|
await self._send_user_audio(frame)
|
||||||
elif isinstance(frame, StartInterruptionFrame):
|
elif isinstance(frame, InterruptionFrame):
|
||||||
await self._handle_interruption()
|
await self._handle_interruption()
|
||||||
elif isinstance(frame, UserStartedSpeakingFrame):
|
elif isinstance(frame, UserStartedSpeakingFrame):
|
||||||
await self._handle_user_started_speaking(frame)
|
await self._handle_user_started_speaking(frame)
|
||||||
@@ -717,7 +717,7 @@ class OpenAIRealtimeLLMService(LLMService):
|
|||||||
async def _handle_evt_speech_started(self, evt):
|
async def _handle_evt_speech_started(self, evt):
|
||||||
await self._truncate_current_audio_response()
|
await self._truncate_current_audio_response()
|
||||||
await self._start_interruption() # cancels this processor task
|
await self._start_interruption() # cancels this processor task
|
||||||
await self.push_frame(StartInterruptionFrame()) # cancels downstream tasks
|
await self.push_frame(InterruptionFrame()) # cancels downstream tasks
|
||||||
await self.push_frame(UserStartedSpeakingFrame())
|
await self.push_frame(UserStartedSpeakingFrame())
|
||||||
|
|
||||||
async def _handle_evt_speech_stopped(self, evt):
|
async def _handle_evt_speech_stopped(self, evt):
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ from pipecat.frames.frames import (
|
|||||||
Frame,
|
Frame,
|
||||||
InputAudioRawFrame,
|
InputAudioRawFrame,
|
||||||
InterimTranscriptionFrame,
|
InterimTranscriptionFrame,
|
||||||
|
InterruptionFrame,
|
||||||
LLMContextFrame,
|
LLMContextFrame,
|
||||||
LLMFullResponseEndFrame,
|
LLMFullResponseEndFrame,
|
||||||
LLMFullResponseStartFrame,
|
LLMFullResponseStartFrame,
|
||||||
@@ -32,7 +33,6 @@ from pipecat.frames.frames import (
|
|||||||
LLMTextFrame,
|
LLMTextFrame,
|
||||||
LLMUpdateSettingsFrame,
|
LLMUpdateSettingsFrame,
|
||||||
StartFrame,
|
StartFrame,
|
||||||
StartInterruptionFrame,
|
|
||||||
TranscriptionFrame,
|
TranscriptionFrame,
|
||||||
TTSAudioRawFrame,
|
TTSAudioRawFrame,
|
||||||
TTSStartedFrame,
|
TTSStartedFrame,
|
||||||
@@ -364,7 +364,7 @@ class OpenAIRealtimeBetaLLMService(LLMService):
|
|||||||
elif isinstance(frame, InputAudioRawFrame):
|
elif isinstance(frame, InputAudioRawFrame):
|
||||||
if not self._audio_input_paused:
|
if not self._audio_input_paused:
|
||||||
await self._send_user_audio(frame)
|
await self._send_user_audio(frame)
|
||||||
elif isinstance(frame, StartInterruptionFrame):
|
elif isinstance(frame, InterruptionFrame):
|
||||||
await self._handle_interruption()
|
await self._handle_interruption()
|
||||||
elif isinstance(frame, UserStartedSpeakingFrame):
|
elif isinstance(frame, UserStartedSpeakingFrame):
|
||||||
await self._handle_user_started_speaking(frame)
|
await self._handle_user_started_speaking(frame)
|
||||||
@@ -659,7 +659,7 @@ class OpenAIRealtimeBetaLLMService(LLMService):
|
|||||||
async def _handle_evt_speech_started(self, evt):
|
async def _handle_evt_speech_started(self, evt):
|
||||||
await self._truncate_current_audio_response()
|
await self._truncate_current_audio_response()
|
||||||
await self._start_interruption() # cancels this processor task
|
await self._start_interruption() # cancels this processor task
|
||||||
await self.push_frame(StartInterruptionFrame()) # cancels downstream tasks
|
await self.push_frame(InterruptionFrame()) # cancels downstream tasks
|
||||||
await self.push_frame(UserStartedSpeakingFrame())
|
await self.push_frame(UserStartedSpeakingFrame())
|
||||||
|
|
||||||
async def _handle_evt_speech_stopped(self, evt):
|
async def _handle_evt_speech_stopped(self, evt):
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ from pipecat.frames.frames import (
|
|||||||
EndFrame,
|
EndFrame,
|
||||||
ErrorFrame,
|
ErrorFrame,
|
||||||
Frame,
|
Frame,
|
||||||
|
InterruptionFrame,
|
||||||
StartFrame,
|
StartFrame,
|
||||||
StartInterruptionFrame,
|
|
||||||
TTSAudioRawFrame,
|
TTSAudioRawFrame,
|
||||||
TTSStartedFrame,
|
TTSStartedFrame,
|
||||||
TTSStoppedFrame,
|
TTSStoppedFrame,
|
||||||
@@ -312,7 +312,7 @@ class PlayHTTTSService(InterruptibleTTSService):
|
|||||||
return self._websocket
|
return self._websocket
|
||||||
raise Exception("Websocket not connected")
|
raise Exception("Websocket not connected")
|
||||||
|
|
||||||
async def _handle_interruption(self, frame: StartInterruptionFrame, direction: FrameDirection):
|
async def _handle_interruption(self, frame: InterruptionFrame, direction: FrameDirection):
|
||||||
"""Handle interruption by stopping metrics and clearing request ID."""
|
"""Handle interruption by stopping metrics and clearing request ID."""
|
||||||
await super()._handle_interruption(frame, direction)
|
await super()._handle_interruption(frame, direction)
|
||||||
await self.stop_all_metrics()
|
await self.stop_all_metrics()
|
||||||
|
|||||||
@@ -24,15 +24,14 @@ from pipecat.frames.frames import (
|
|||||||
EndFrame,
|
EndFrame,
|
||||||
ErrorFrame,
|
ErrorFrame,
|
||||||
Frame,
|
Frame,
|
||||||
|
InterruptionFrame,
|
||||||
StartFrame,
|
StartFrame,
|
||||||
StartInterruptionFrame,
|
|
||||||
TTSAudioRawFrame,
|
TTSAudioRawFrame,
|
||||||
TTSStartedFrame,
|
TTSStartedFrame,
|
||||||
TTSStoppedFrame,
|
TTSStoppedFrame,
|
||||||
)
|
)
|
||||||
from pipecat.processors.frame_processor import FrameDirection
|
from pipecat.processors.frame_processor import FrameDirection
|
||||||
from pipecat.services.tts_service import AudioContextWordTTSService, TTSService
|
from pipecat.services.tts_service import AudioContextWordTTSService, TTSService
|
||||||
from pipecat.transcriptions import language
|
|
||||||
from pipecat.transcriptions.language import Language
|
from pipecat.transcriptions.language import Language
|
||||||
from pipecat.utils.text.base_text_aggregator import BaseTextAggregator
|
from pipecat.utils.text.base_text_aggregator import BaseTextAggregator
|
||||||
from pipecat.utils.text.skip_tags_aggregator import SkipTagsAggregator
|
from pipecat.utils.text.skip_tags_aggregator import SkipTagsAggregator
|
||||||
@@ -280,7 +279,7 @@ class RimeTTSService(AudioContextWordTTSService):
|
|||||||
return self._websocket
|
return self._websocket
|
||||||
raise Exception("Websocket not connected")
|
raise Exception("Websocket not connected")
|
||||||
|
|
||||||
async def _handle_interruption(self, frame: StartInterruptionFrame, direction: FrameDirection):
|
async def _handle_interruption(self, frame: InterruptionFrame, direction: FrameDirection):
|
||||||
"""Handle interruption by clearing current context."""
|
"""Handle interruption by clearing current context."""
|
||||||
await super()._handle_interruption(frame, direction)
|
await super()._handle_interruption(frame, direction)
|
||||||
await self.stop_all_metrics()
|
await self.stop_all_metrics()
|
||||||
@@ -375,7 +374,7 @@ class RimeTTSService(AudioContextWordTTSService):
|
|||||||
direction: The direction to push the frame.
|
direction: The direction to push the frame.
|
||||||
"""
|
"""
|
||||||
await super().push_frame(frame, direction)
|
await super().push_frame(frame, direction)
|
||||||
if isinstance(frame, (TTSStoppedFrame, StartInterruptionFrame)):
|
if isinstance(frame, (TTSStoppedFrame, InterruptionFrame)):
|
||||||
if isinstance(frame, TTSStoppedFrame):
|
if isinstance(frame, TTSStoppedFrame):
|
||||||
await self.add_word_timestamps([("Reset", 0)])
|
await self.add_word_timestamps([("Reset", 0)])
|
||||||
|
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ from pipecat.frames.frames import (
|
|||||||
EndFrame,
|
EndFrame,
|
||||||
ErrorFrame,
|
ErrorFrame,
|
||||||
Frame,
|
Frame,
|
||||||
|
InterruptionFrame,
|
||||||
LLMFullResponseEndFrame,
|
LLMFullResponseEndFrame,
|
||||||
StartFrame,
|
StartFrame,
|
||||||
StartInterruptionFrame,
|
|
||||||
TTSAudioRawFrame,
|
TTSAudioRawFrame,
|
||||||
TTSStartedFrame,
|
TTSStartedFrame,
|
||||||
TTSStoppedFrame,
|
TTSStoppedFrame,
|
||||||
@@ -455,7 +455,7 @@ class SarvamTTSService(InterruptibleTTSService):
|
|||||||
direction: The direction to push the frame.
|
direction: The direction to push the frame.
|
||||||
"""
|
"""
|
||||||
await super().push_frame(frame, direction)
|
await super().push_frame(frame, direction)
|
||||||
if isinstance(frame, (TTSStoppedFrame, StartInterruptionFrame)):
|
if isinstance(frame, (TTSStoppedFrame, InterruptionFrame)):
|
||||||
self._started = False
|
self._started = False
|
||||||
|
|
||||||
async def process_frame(self, frame: Frame, direction: FrameDirection):
|
async def process_frame(self, frame: Frame, direction: FrameDirection):
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ from pipecat.frames.frames import (
|
|||||||
CancelFrame,
|
CancelFrame,
|
||||||
EndFrame,
|
EndFrame,
|
||||||
Frame,
|
Frame,
|
||||||
|
InterruptionFrame,
|
||||||
OutputImageRawFrame,
|
OutputImageRawFrame,
|
||||||
StartInterruptionFrame,
|
|
||||||
TTSAudioRawFrame,
|
TTSAudioRawFrame,
|
||||||
TTSStoppedFrame,
|
TTSStoppedFrame,
|
||||||
UserStartedSpeakingFrame,
|
UserStartedSpeakingFrame,
|
||||||
@@ -179,7 +179,7 @@ class SimliVideoService(FrameProcessor):
|
|||||||
return
|
return
|
||||||
elif isinstance(frame, (EndFrame, CancelFrame)):
|
elif isinstance(frame, (EndFrame, CancelFrame)):
|
||||||
await self._stop()
|
await self._stop()
|
||||||
elif isinstance(frame, (StartInterruptionFrame, UserStartedSpeakingFrame)):
|
elif isinstance(frame, (InterruptionFrame, UserStartedSpeakingFrame)):
|
||||||
if not self._previously_interrupted:
|
if not self._previously_interrupted:
|
||||||
await self._simli_client.clearBuffer()
|
await self._simli_client.clearBuffer()
|
||||||
self._previously_interrupted = self._is_trinity_avatar
|
self._previously_interrupted = self._is_trinity_avatar
|
||||||
|
|||||||
@@ -23,12 +23,12 @@ from pipecat.frames.frames import (
|
|||||||
CancelFrame,
|
CancelFrame,
|
||||||
EndFrame,
|
EndFrame,
|
||||||
Frame,
|
Frame,
|
||||||
|
InterruptionFrame,
|
||||||
OutputAudioRawFrame,
|
OutputAudioRawFrame,
|
||||||
OutputImageRawFrame,
|
OutputImageRawFrame,
|
||||||
OutputTransportReadyFrame,
|
OutputTransportReadyFrame,
|
||||||
SpeechOutputAudioRawFrame,
|
SpeechOutputAudioRawFrame,
|
||||||
StartFrame,
|
StartFrame,
|
||||||
StartInterruptionFrame,
|
|
||||||
TTSAudioRawFrame,
|
TTSAudioRawFrame,
|
||||||
TTSStartedFrame,
|
TTSStartedFrame,
|
||||||
)
|
)
|
||||||
@@ -222,7 +222,7 @@ class TavusVideoService(AIService):
|
|||||||
"""
|
"""
|
||||||
await super().process_frame(frame, direction)
|
await super().process_frame(frame, direction)
|
||||||
|
|
||||||
if isinstance(frame, StartInterruptionFrame):
|
if isinstance(frame, InterruptionFrame):
|
||||||
await self._handle_interruptions()
|
await self._handle_interruptions()
|
||||||
await self.push_frame(frame, direction)
|
await self.push_frame(frame, direction)
|
||||||
elif isinstance(frame, TTSAudioRawFrame):
|
elif isinstance(frame, TTSAudioRawFrame):
|
||||||
|
|||||||
@@ -20,10 +20,10 @@ from pipecat.frames.frames import (
|
|||||||
ErrorFrame,
|
ErrorFrame,
|
||||||
Frame,
|
Frame,
|
||||||
InterimTranscriptionFrame,
|
InterimTranscriptionFrame,
|
||||||
|
InterruptionFrame,
|
||||||
LLMFullResponseEndFrame,
|
LLMFullResponseEndFrame,
|
||||||
LLMFullResponseStartFrame,
|
LLMFullResponseStartFrame,
|
||||||
StartFrame,
|
StartFrame,
|
||||||
StartInterruptionFrame,
|
|
||||||
TextFrame,
|
TextFrame,
|
||||||
TranscriptionFrame,
|
TranscriptionFrame,
|
||||||
TTSAudioRawFrame,
|
TTSAudioRawFrame,
|
||||||
@@ -309,7 +309,7 @@ class TTSService(AIService):
|
|||||||
and not isinstance(frame, TranscriptionFrame)
|
and not isinstance(frame, TranscriptionFrame)
|
||||||
):
|
):
|
||||||
await self._process_text_frame(frame)
|
await self._process_text_frame(frame)
|
||||||
elif isinstance(frame, StartInterruptionFrame):
|
elif isinstance(frame, InterruptionFrame):
|
||||||
await self._handle_interruption(frame, direction)
|
await self._handle_interruption(frame, direction)
|
||||||
await self.push_frame(frame, direction)
|
await self.push_frame(frame, direction)
|
||||||
elif isinstance(frame, (LLMFullResponseEndFrame, EndFrame)):
|
elif isinstance(frame, (LLMFullResponseEndFrame, EndFrame)):
|
||||||
@@ -367,14 +367,14 @@ class TTSService(AIService):
|
|||||||
await super().push_frame(frame, direction)
|
await super().push_frame(frame, direction)
|
||||||
|
|
||||||
if self._push_stop_frames and (
|
if self._push_stop_frames and (
|
||||||
isinstance(frame, StartInterruptionFrame)
|
isinstance(frame, InterruptionFrame)
|
||||||
or isinstance(frame, TTSStartedFrame)
|
or isinstance(frame, TTSStartedFrame)
|
||||||
or isinstance(frame, TTSAudioRawFrame)
|
or isinstance(frame, TTSAudioRawFrame)
|
||||||
or isinstance(frame, TTSStoppedFrame)
|
or isinstance(frame, TTSStoppedFrame)
|
||||||
):
|
):
|
||||||
await self._stop_frame_queue.put(frame)
|
await self._stop_frame_queue.put(frame)
|
||||||
|
|
||||||
async def _handle_interruption(self, frame: StartInterruptionFrame, direction: FrameDirection):
|
async def _handle_interruption(self, frame: InterruptionFrame, direction: FrameDirection):
|
||||||
self._processing_text = False
|
self._processing_text = False
|
||||||
await self._text_aggregator.handle_interruption()
|
await self._text_aggregator.handle_interruption()
|
||||||
for filter in self._text_filters:
|
for filter in self._text_filters:
|
||||||
@@ -438,7 +438,7 @@ class TTSService(AIService):
|
|||||||
)
|
)
|
||||||
if isinstance(frame, TTSStartedFrame):
|
if isinstance(frame, TTSStartedFrame):
|
||||||
has_started = True
|
has_started = True
|
||||||
elif isinstance(frame, (TTSStoppedFrame, StartInterruptionFrame)):
|
elif isinstance(frame, (TTSStoppedFrame, InterruptionFrame)):
|
||||||
has_started = False
|
has_started = False
|
||||||
except asyncio.TimeoutError:
|
except asyncio.TimeoutError:
|
||||||
if has_started:
|
if has_started:
|
||||||
@@ -523,7 +523,7 @@ class WordTTSService(TTSService):
|
|||||||
elif isinstance(frame, (LLMFullResponseEndFrame, EndFrame)):
|
elif isinstance(frame, (LLMFullResponseEndFrame, EndFrame)):
|
||||||
await self.flush_audio()
|
await self.flush_audio()
|
||||||
|
|
||||||
async def _handle_interruption(self, frame: StartInterruptionFrame, direction: FrameDirection):
|
async def _handle_interruption(self, frame: InterruptionFrame, direction: FrameDirection):
|
||||||
await super()._handle_interruption(frame, direction)
|
await super()._handle_interruption(frame, direction)
|
||||||
self._llm_response_started = False
|
self._llm_response_started = False
|
||||||
self.reset_word_timestamps()
|
self.reset_word_timestamps()
|
||||||
@@ -613,7 +613,7 @@ class InterruptibleTTSService(WebsocketTTSService):
|
|||||||
# user interrupts we need to reconnect.
|
# user interrupts we need to reconnect.
|
||||||
self._bot_speaking = False
|
self._bot_speaking = False
|
||||||
|
|
||||||
async def _handle_interruption(self, frame: StartInterruptionFrame, direction: FrameDirection):
|
async def _handle_interruption(self, frame: InterruptionFrame, direction: FrameDirection):
|
||||||
await super()._handle_interruption(frame, direction)
|
await super()._handle_interruption(frame, direction)
|
||||||
if self._bot_speaking:
|
if self._bot_speaking:
|
||||||
await self._disconnect()
|
await self._disconnect()
|
||||||
@@ -685,7 +685,7 @@ class InterruptibleWordTTSService(WebsocketWordTTSService):
|
|||||||
# user interrupts we need to reconnect.
|
# user interrupts we need to reconnect.
|
||||||
self._bot_speaking = False
|
self._bot_speaking = False
|
||||||
|
|
||||||
async def _handle_interruption(self, frame: StartInterruptionFrame, direction: FrameDirection):
|
async def _handle_interruption(self, frame: InterruptionFrame, direction: FrameDirection):
|
||||||
await super()._handle_interruption(frame, direction)
|
await super()._handle_interruption(frame, direction)
|
||||||
if self._bot_speaking:
|
if self._bot_speaking:
|
||||||
await self._disconnect()
|
await self._disconnect()
|
||||||
@@ -813,7 +813,7 @@ class AudioContextWordTTSService(WebsocketWordTTSService):
|
|||||||
await super().cancel(frame)
|
await super().cancel(frame)
|
||||||
await self._stop_audio_context_task()
|
await self._stop_audio_context_task()
|
||||||
|
|
||||||
async def _handle_interruption(self, frame: StartInterruptionFrame, direction: FrameDirection):
|
async def _handle_interruption(self, frame: InterruptionFrame, direction: FrameDirection):
|
||||||
await super()._handle_interruption(frame, direction)
|
await super()._handle_interruption(frame, direction)
|
||||||
await self._stop_audio_context_task()
|
await self._stop_audio_context_task()
|
||||||
self._create_audio_context_task()
|
self._create_audio_context_task()
|
||||||
|
|||||||
@@ -33,10 +33,10 @@ from pipecat.frames.frames import (
|
|||||||
Frame,
|
Frame,
|
||||||
InputAudioRawFrame,
|
InputAudioRawFrame,
|
||||||
InputImageRawFrame,
|
InputImageRawFrame,
|
||||||
|
InterruptionFrame,
|
||||||
MetricsFrame,
|
MetricsFrame,
|
||||||
SpeechControlParamsFrame,
|
SpeechControlParamsFrame,
|
||||||
StartFrame,
|
StartFrame,
|
||||||
StartInterruptionFrame,
|
|
||||||
StopFrame,
|
StopFrame,
|
||||||
SystemFrame,
|
SystemFrame,
|
||||||
UserSpeakingFrame,
|
UserSpeakingFrame,
|
||||||
@@ -340,7 +340,7 @@ class BaseInputTransport(FrameProcessor):
|
|||||||
logger.debug("Bot interruption")
|
logger.debug("Bot interruption")
|
||||||
if self.interruptions_allowed:
|
if self.interruptions_allowed:
|
||||||
await self._start_interruption()
|
await self._start_interruption()
|
||||||
await self.push_frame(StartInterruptionFrame())
|
await self.push_frame(InterruptionFrame())
|
||||||
|
|
||||||
async def _handle_user_interruption(self, vad_state: VADState, emulated: bool = False):
|
async def _handle_user_interruption(self, vad_state: VADState, emulated: bool = False):
|
||||||
"""Handle user interruption events based on speaking state."""
|
"""Handle user interruption events based on speaking state."""
|
||||||
@@ -366,7 +366,7 @@ class BaseInputTransport(FrameProcessor):
|
|||||||
# Push an out-of-band frame (i.e. not using the ordered push
|
# Push an out-of-band frame (i.e. not using the ordered push
|
||||||
# frame task) to stop everything, specially at the output
|
# frame task) to stop everything, specially at the output
|
||||||
# transport.
|
# transport.
|
||||||
await self.push_frame(StartInterruptionFrame())
|
await self.push_frame(InterruptionFrame())
|
||||||
elif self.interruption_strategies and self._bot_speaking:
|
elif self.interruption_strategies and self._bot_speaking:
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"User started speaking while bot is speaking with interruption config - "
|
"User started speaking while bot is speaking with interruption config - "
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ from pipecat.frames.frames import (
|
|||||||
EndFrame,
|
EndFrame,
|
||||||
Frame,
|
Frame,
|
||||||
InputTransportMessageUrgentFrame,
|
InputTransportMessageUrgentFrame,
|
||||||
|
InterruptionFrame,
|
||||||
MixerControlFrame,
|
MixerControlFrame,
|
||||||
OutputAudioRawFrame,
|
OutputAudioRawFrame,
|
||||||
OutputDTMFFrame,
|
OutputDTMFFrame,
|
||||||
@@ -39,7 +40,6 @@ from pipecat.frames.frames import (
|
|||||||
SpeechOutputAudioRawFrame,
|
SpeechOutputAudioRawFrame,
|
||||||
SpriteFrame,
|
SpriteFrame,
|
||||||
StartFrame,
|
StartFrame,
|
||||||
StartInterruptionFrame,
|
|
||||||
SystemFrame,
|
SystemFrame,
|
||||||
TransportMessageFrame,
|
TransportMessageFrame,
|
||||||
TransportMessageUrgentFrame,
|
TransportMessageUrgentFrame,
|
||||||
@@ -299,7 +299,7 @@ class BaseOutputTransport(FrameProcessor):
|
|||||||
elif isinstance(frame, CancelFrame):
|
elif isinstance(frame, CancelFrame):
|
||||||
await self.cancel(frame)
|
await self.cancel(frame)
|
||||||
await self.push_frame(frame, direction)
|
await self.push_frame(frame, direction)
|
||||||
elif isinstance(frame, StartInterruptionFrame):
|
elif isinstance(frame, InterruptionFrame):
|
||||||
await self.push_frame(frame, direction)
|
await self.push_frame(frame, direction)
|
||||||
await self._handle_frame(frame)
|
await self._handle_frame(frame)
|
||||||
elif isinstance(frame, TransportMessageUrgentFrame) and not isinstance(
|
elif isinstance(frame, TransportMessageUrgentFrame) and not isinstance(
|
||||||
@@ -340,7 +340,7 @@ class BaseOutputTransport(FrameProcessor):
|
|||||||
|
|
||||||
sender = self._media_senders[frame.transport_destination]
|
sender = self._media_senders[frame.transport_destination]
|
||||||
|
|
||||||
if isinstance(frame, StartInterruptionFrame):
|
if isinstance(frame, InterruptionFrame):
|
||||||
await sender.handle_interruptions(frame)
|
await sender.handle_interruptions(frame)
|
||||||
elif isinstance(frame, OutputAudioRawFrame):
|
elif isinstance(frame, OutputAudioRawFrame):
|
||||||
await sender.handle_audio_frame(frame)
|
await sender.handle_audio_frame(frame)
|
||||||
@@ -491,7 +491,7 @@ class BaseOutputTransport(FrameProcessor):
|
|||||||
await self._cancel_clock_task()
|
await self._cancel_clock_task()
|
||||||
await self._cancel_video_task()
|
await self._cancel_video_task()
|
||||||
|
|
||||||
async def handle_interruptions(self, _: StartInterruptionFrame):
|
async def handle_interruptions(self, _: InterruptionFrame):
|
||||||
"""Handle interruption events by restarting tasks and clearing buffers.
|
"""Handle interruption events by restarting tasks and clearing buffers.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
|||||||
@@ -25,9 +25,9 @@ from pipecat.frames.frames import (
|
|||||||
EndFrame,
|
EndFrame,
|
||||||
Frame,
|
Frame,
|
||||||
InputAudioRawFrame,
|
InputAudioRawFrame,
|
||||||
|
InterruptionFrame,
|
||||||
OutputAudioRawFrame,
|
OutputAudioRawFrame,
|
||||||
StartFrame,
|
StartFrame,
|
||||||
StartInterruptionFrame,
|
|
||||||
TransportMessageFrame,
|
TransportMessageFrame,
|
||||||
TransportMessageUrgentFrame,
|
TransportMessageUrgentFrame,
|
||||||
)
|
)
|
||||||
@@ -618,7 +618,7 @@ class TavusOutputTransport(BaseOutputTransport):
|
|||||||
direction: The direction of frame flow in the pipeline.
|
direction: The direction of frame flow in the pipeline.
|
||||||
"""
|
"""
|
||||||
await super().process_frame(frame, direction)
|
await super().process_frame(frame, direction)
|
||||||
if isinstance(frame, StartInterruptionFrame):
|
if isinstance(frame, InterruptionFrame):
|
||||||
await self._handle_interruptions()
|
await self._handle_interruptions()
|
||||||
|
|
||||||
async def _handle_interruptions(self):
|
async def _handle_interruptions(self):
|
||||||
|
|||||||
@@ -26,9 +26,9 @@ from pipecat.frames.frames import (
|
|||||||
EndFrame,
|
EndFrame,
|
||||||
Frame,
|
Frame,
|
||||||
InputAudioRawFrame,
|
InputAudioRawFrame,
|
||||||
|
InterruptionFrame,
|
||||||
OutputAudioRawFrame,
|
OutputAudioRawFrame,
|
||||||
StartFrame,
|
StartFrame,
|
||||||
StartInterruptionFrame,
|
|
||||||
TransportMessageFrame,
|
TransportMessageFrame,
|
||||||
TransportMessageUrgentFrame,
|
TransportMessageUrgentFrame,
|
||||||
)
|
)
|
||||||
@@ -398,7 +398,7 @@ class FastAPIWebsocketOutputTransport(BaseOutputTransport):
|
|||||||
"""
|
"""
|
||||||
await super().process_frame(frame, direction)
|
await super().process_frame(frame, direction)
|
||||||
|
|
||||||
if isinstance(frame, StartInterruptionFrame):
|
if isinstance(frame, InterruptionFrame):
|
||||||
await self._write_frame(frame)
|
await self._write_frame(frame)
|
||||||
self._next_send_time = 0
|
self._next_send_time = 0
|
||||||
|
|
||||||
|
|||||||
@@ -25,9 +25,9 @@ from pipecat.frames.frames import (
|
|||||||
EndFrame,
|
EndFrame,
|
||||||
Frame,
|
Frame,
|
||||||
InputAudioRawFrame,
|
InputAudioRawFrame,
|
||||||
|
InterruptionFrame,
|
||||||
OutputAudioRawFrame,
|
OutputAudioRawFrame,
|
||||||
StartFrame,
|
StartFrame,
|
||||||
StartInterruptionFrame,
|
|
||||||
TransportMessageFrame,
|
TransportMessageFrame,
|
||||||
TransportMessageUrgentFrame,
|
TransportMessageUrgentFrame,
|
||||||
)
|
)
|
||||||
@@ -334,7 +334,7 @@ class WebsocketServerOutputTransport(BaseOutputTransport):
|
|||||||
"""
|
"""
|
||||||
await super().process_frame(frame, direction)
|
await super().process_frame(frame, direction)
|
||||||
|
|
||||||
if isinstance(frame, StartInterruptionFrame):
|
if isinstance(frame, InterruptionFrame):
|
||||||
await self._write_frame(frame)
|
await self._write_frame(frame)
|
||||||
self._next_send_time = 0
|
self._next_send_time = 0
|
||||||
|
|
||||||
|
|||||||
@@ -17,11 +17,11 @@ from pipecat.frames.frames import (
|
|||||||
FunctionCallResultFrame,
|
FunctionCallResultFrame,
|
||||||
FunctionCallResultProperties,
|
FunctionCallResultProperties,
|
||||||
InterimTranscriptionFrame,
|
InterimTranscriptionFrame,
|
||||||
|
InterruptionFrame,
|
||||||
LLMFullResponseEndFrame,
|
LLMFullResponseEndFrame,
|
||||||
LLMFullResponseStartFrame,
|
LLMFullResponseStartFrame,
|
||||||
OpenAILLMContextAssistantTimestampFrame,
|
OpenAILLMContextAssistantTimestampFrame,
|
||||||
SpeechControlParamsFrame,
|
SpeechControlParamsFrame,
|
||||||
StartInterruptionFrame,
|
|
||||||
TextFrame,
|
TextFrame,
|
||||||
TranscriptionFrame,
|
TranscriptionFrame,
|
||||||
UserStartedSpeakingFrame,
|
UserStartedSpeakingFrame,
|
||||||
@@ -618,7 +618,7 @@ class BaseTestAssistantContextAggreagator:
|
|||||||
TextFrame(text="Pipecat."),
|
TextFrame(text="Pipecat."),
|
||||||
LLMFullResponseEndFrame(),
|
LLMFullResponseEndFrame(),
|
||||||
SleepFrame(AGGREGATION_SLEEP),
|
SleepFrame(AGGREGATION_SLEEP),
|
||||||
StartInterruptionFrame(),
|
InterruptionFrame(),
|
||||||
LLMFullResponseStartFrame(),
|
LLMFullResponseStartFrame(),
|
||||||
TextFrame(text="How are "),
|
TextFrame(text="How are "),
|
||||||
TextFrame(text="you?"),
|
TextFrame(text="you?"),
|
||||||
@@ -626,7 +626,7 @@ class BaseTestAssistantContextAggreagator:
|
|||||||
]
|
]
|
||||||
expected_down_frames = [
|
expected_down_frames = [
|
||||||
*self.EXPECTED_CONTEXT_FRAMES,
|
*self.EXPECTED_CONTEXT_FRAMES,
|
||||||
StartInterruptionFrame,
|
InterruptionFrame,
|
||||||
*self.EXPECTED_CONTEXT_FRAMES,
|
*self.EXPECTED_CONTEXT_FRAMES,
|
||||||
]
|
]
|
||||||
await run_test(
|
await run_test(
|
||||||
|
|||||||
@@ -7,10 +7,10 @@
|
|||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from pipecat.frames.frames import (
|
from pipecat.frames.frames import (
|
||||||
|
InterruptionFrame,
|
||||||
LLMFullResponseEndFrame,
|
LLMFullResponseEndFrame,
|
||||||
LLMFullResponseStartFrame,
|
LLMFullResponseStartFrame,
|
||||||
LLMTextFrame,
|
LLMTextFrame,
|
||||||
StartInterruptionFrame,
|
|
||||||
)
|
)
|
||||||
from pipecat.processors.aggregators.llm_response import LLMFullResponseAggregator
|
from pipecat.processors.aggregators.llm_response import LLMFullResponseAggregator
|
||||||
from pipecat.tests.utils import SleepFrame, run_test
|
from pipecat.tests.utils import SleepFrame, run_test
|
||||||
@@ -113,7 +113,7 @@ class TestLLMFullResponseAggregator(unittest.IsolatedAsyncioTestCase):
|
|||||||
LLMFullResponseStartFrame(),
|
LLMFullResponseStartFrame(),
|
||||||
LLMTextFrame("Hello "),
|
LLMTextFrame("Hello "),
|
||||||
SleepFrame(),
|
SleepFrame(),
|
||||||
StartInterruptionFrame(),
|
InterruptionFrame(),
|
||||||
LLMFullResponseStartFrame(),
|
LLMFullResponseStartFrame(),
|
||||||
LLMTextFrame("Hello "),
|
LLMTextFrame("Hello "),
|
||||||
LLMTextFrame("there!"),
|
LLMTextFrame("there!"),
|
||||||
@@ -122,7 +122,7 @@ class TestLLMFullResponseAggregator(unittest.IsolatedAsyncioTestCase):
|
|||||||
expected_down_frames = [
|
expected_down_frames = [
|
||||||
LLMFullResponseStartFrame,
|
LLMFullResponseStartFrame,
|
||||||
LLMTextFrame,
|
LLMTextFrame,
|
||||||
StartInterruptionFrame,
|
InterruptionFrame,
|
||||||
LLMFullResponseStartFrame,
|
LLMFullResponseStartFrame,
|
||||||
LLMTextFrame,
|
LLMTextFrame,
|
||||||
LLMTextFrame,
|
LLMTextFrame,
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ from pipecat.frames.frames import (
|
|||||||
BotStartedSpeakingFrame,
|
BotStartedSpeakingFrame,
|
||||||
BotStoppedSpeakingFrame,
|
BotStoppedSpeakingFrame,
|
||||||
CancelFrame,
|
CancelFrame,
|
||||||
StartInterruptionFrame,
|
InterruptionFrame,
|
||||||
TranscriptionFrame,
|
TranscriptionFrame,
|
||||||
TranscriptionMessage,
|
TranscriptionMessage,
|
||||||
TranscriptionUpdateFrame,
|
TranscriptionUpdateFrame,
|
||||||
@@ -238,7 +238,7 @@ class TestUserTranscriptProcessor(unittest.IsolatedAsyncioTestCase):
|
|||||||
TTSTextFrame(text="Hello"),
|
TTSTextFrame(text="Hello"),
|
||||||
TTSTextFrame(text="world!"),
|
TTSTextFrame(text="world!"),
|
||||||
SleepFrame(),
|
SleepFrame(),
|
||||||
StartInterruptionFrame(), # User interrupts here
|
InterruptionFrame(), # User interrupts here
|
||||||
SleepFrame(),
|
SleepFrame(),
|
||||||
BotStartedSpeakingFrame(),
|
BotStartedSpeakingFrame(),
|
||||||
TTSTextFrame(text="New"),
|
TTSTextFrame(text="New"),
|
||||||
@@ -252,7 +252,7 @@ class TestUserTranscriptProcessor(unittest.IsolatedAsyncioTestCase):
|
|||||||
BotStartedSpeakingFrame,
|
BotStartedSpeakingFrame,
|
||||||
TTSTextFrame, # "Hello"
|
TTSTextFrame, # "Hello"
|
||||||
TTSTextFrame, # "world!"
|
TTSTextFrame, # "world!"
|
||||||
StartInterruptionFrame,
|
InterruptionFrame,
|
||||||
TranscriptionUpdateFrame, # First message (emitted due to interruption)
|
TranscriptionUpdateFrame, # First message (emitted due to interruption)
|
||||||
BotStartedSpeakingFrame,
|
BotStartedSpeakingFrame,
|
||||||
TTSTextFrame, # "New"
|
TTSTextFrame, # "New"
|
||||||
|
|||||||
Reference in New Issue
Block a user