From bab102f197861e35cd56b3ba2133997ac9bfbd04 Mon Sep 17 00:00:00 2001 From: Moishe Lettvin Date: Fri, 26 Jan 2024 09:54:51 -0500 Subject: [PATCH] little more cleanup --- src/dailyai/conversation_wrappers.py | 6 +-- src/dailyai/queue_aggregators.py | 48 +++++++++++--------- src/samples/foundational/07-interruptible.py | 1 + 3 files changed, 30 insertions(+), 25 deletions(-) diff --git a/src/dailyai/conversation_wrappers.py b/src/dailyai/conversation_wrappers.py index bc7dd902d..bb83f1272 100644 --- a/src/dailyai/conversation_wrappers.py +++ b/src/dailyai/conversation_wrappers.py @@ -2,7 +2,7 @@ import asyncio import copy import functools from typing import AsyncGenerator, Awaitable, Callable -from dailyai.queue_aggregators import LLMContextAggregator +from dailyai.queue_aggregators import LLMAssistantContextAggregator, LLMContextAggregator, LLMUserContextAggregator from dailyai.queue_frame import EndStreamQueueFrame, QueueFrame, TranscriptionQueueFrame @@ -17,8 +17,8 @@ class InterruptibleConversationWrapper: interrupt: Callable[[], None], my_participant_id: str | None, llm_messages: list[dict[str, str]], - llm_context_aggregator_in=LLMContextAggregator, - llm_context_aggregator_out=LLMContextAggregator, + llm_context_aggregator_in=LLMUserContextAggregator, + llm_context_aggregator_out=LLMAssistantContextAggregator, delay_before_speech_seconds: float = 1.0, ): self._frame_generator: Callable[[], AsyncGenerator[QueueFrame, None]] = frame_generator diff --git a/src/dailyai/queue_aggregators.py b/src/dailyai/queue_aggregators.py index 3b0ffbc7e..545c86728 100644 --- a/src/dailyai/queue_aggregators.py +++ b/src/dailyai/queue_aggregators.py @@ -33,7 +33,7 @@ class LLMContextAggregator(AIService): role: str, bot_participant_id=None, complete_sentences=True, - pass_through=False): + pass_through=True): self.messages = messages self.bot_participant_id = bot_participant_id self.role = role @@ -42,28 +42,32 @@ class LLMContextAggregator(AIService): self.pass_through = pass_through async def process_frame(self, frame: QueueFrame) -> AsyncGenerator[QueueFrame, None]: - # TODO: split up transcription by participant - if isinstance(frame, TextQueueFrame): - - # Ignore transcription frames from the bot - if isinstance(frame, TranscriptionQueueFrame): - if frame.participantId == self.bot_participant_id: - return - - if self.complete_sentences: - self.sentence += frame.text - if self.sentence.endswith((".", "?", "!")): - self.messages.append({"role": self.role, "content": self.sentence}) - self.sentence = "" - yield LLMMessagesQueueFrame(self.messages) - else: - self.messages.append({"role": self.role, "content": frame.text}) - yield LLMMessagesQueueFrame(self.messages) - - if self.pass_through: - yield frame - else: + # We don't do anything with non-text frames, pass it along to next in the pipeline. + if not isinstance(frame, TextQueueFrame): yield frame + return + + # The common case for "pass through" is receiving frames from the LLM that we'll + # use to update the "assistant" LLM messages, but also passing the text frames + # along to a TTS service to be spoken to the user. + if self.pass_through: + yield frame + + # Ignore transcription frames from the bot + if isinstance(frame, TranscriptionQueueFrame): + if frame.participantId == self.bot_participant_id: + return + + # TODO: split up transcription by participant + if self.complete_sentences: + self.sentence += frame.text # type: ignore -- the linter thinks this isn't a TextQueueFrame, even though we check it above + if self.sentence.endswith((".", "?", "!")): + self.messages.append({"role": self.role, "content": self.sentence}) + self.sentence = "" + yield LLMMessagesQueueFrame(self.messages) + else: + self.messages.append({"role": self.role, "content": frame.text}) # type: ignore -- the linter thinks this isn't a TextQueueFrame, even though we check it above + yield LLMMessagesQueueFrame(self.messages) class LLMUserContextAggregator(LLMContextAggregator): def __init__(self, diff --git a/src/samples/foundational/07-interruptible.py b/src/samples/foundational/07-interruptible.py index cd18804af..927a5670f 100644 --- a/src/samples/foundational/07-interruptible.py +++ b/src/samples/foundational/07-interruptible.py @@ -25,6 +25,7 @@ async def main(room_url: str, token): transport.mic_enabled = True transport.mic_sample_rate = 16000 transport.camera_enabled = False + transport.start_transcription = True llm = AzureLLMService() tts = ElevenLabsTTSService(voice_id="ErXwobaYiN019PkySvjV")