From 7c9ecb1a1d936ed4eeb919fa6dd1d8d0a9ee77a8 Mon Sep 17 00:00:00 2001 From: Moishe Lettvin Date: Fri, 29 Dec 2023 10:12:24 -0500 Subject: [PATCH] Some cleanup, bringing azure ai service up to date --- .../async_processor/async_processor.py | 2 +- src/dailyai/orchestrator.py | 14 ++++-- src/dailyai/services/azure_ai_services.py | 46 ++++++++++++------- src/samples/simple-sample/simple-sample.py | 10 ---- 4 files changed, 42 insertions(+), 30 deletions(-) diff --git a/src/dailyai/async_processor/async_processor.py b/src/dailyai/async_processor/async_processor.py index b1ddd5519..756e2efa4 100644 --- a/src/dailyai/async_processor/async_processor.py +++ b/src/dailyai/async_processor/async_processor.py @@ -318,7 +318,7 @@ class Response(AsyncProcessor): self.play_thread.join() -@dataclass +@dataclass(frozen=True) class ConversationProcessorCollection: introduction: Optional[Type[Response]] = None waiting: Optional[Type[Response]] = None diff --git a/src/dailyai/orchestrator.py b/src/dailyai/orchestrator.py index 0a3e868a0..3b0c48fb9 100644 --- a/src/dailyai/orchestrator.py +++ b/src/dailyai/orchestrator.py @@ -38,14 +38,24 @@ class OrchestratorConfig: bot_name: str expiration: float +# Note that we use this as a default parameter value in the Orchestrator +# constructor. The dataclass is defined with Frozen=True, so this should +# be safe. +default_conversation_collection = ConversationProcessorCollection( + introduction=Response, + waiting=None, + response=Response, + goodbye=None, +) class Orchestrator(EventHandler): + def __init__( self, daily_config: OrchestratorConfig, ai_service_config: AIServiceConfig, - conversation_processors: ConversationProcessorCollection, message_handler: MessageHandler, + conversation_processors: ConversationProcessorCollection = default_conversation_collection, tracer=None, ): self.bot_name: str = daily_config.bot_name @@ -272,8 +282,6 @@ class Orchestrator(EventHandler): except Exception as e: self.logger.error(f"Exception {e} in camera thread.") - print("==== camera thread exitings") - def handle_user_started_talking(self): # TODO: allow configuration of the timer timeout self.logger.error("user started talking") diff --git a/src/dailyai/services/azure_ai_services.py b/src/dailyai/services/azure_ai_services.py index 8420531b8..03d7e574b 100644 --- a/src/dailyai/services/azure_ai_services.py +++ b/src/dailyai/services/azure_ai_services.py @@ -14,13 +14,13 @@ from PIL import Image from azure.cognitiveservices.speech import SpeechSynthesizer, SpeechConfig, ResultReason, CancellationReason class AzureTTSService(TTSService): - def __init__(self): + def __init__(self, speech_key=None, speech_region=None): super().__init__() - self.speech_key = os.getenv("AZURE_SPEECH_SERVICE_KEY") - self.speech_region = os.getenv("AZURE_SPEECH_SERVICE_REGION") + speech_key = speech_key or os.getenv("AZURE_SPEECH_SERVICE_KEY") + speech_region = speech_region or os.getenv("AZURE_SPEECH_SERVICE_REGION") - self.speech_config = SpeechConfig(subscription=self.speech_key, region=self.speech_region) + self.speech_config = SpeechConfig(subscription=speech_key, region=speech_region) self.speech_synthesizer = SpeechSynthesizer(speech_config=self.speech_config, audio_config=None) def run_tts(self, sentence) -> Generator[bytes, None, None]: @@ -46,19 +46,23 @@ class AzureTTSService(TTSService): self.logger.info("Error details: {}".format(cancellation_details.error_details)) class AzureLLMService(LLMService): - def __init__(self): + def __init__(self, api_key=None, azure_endpoint=None, api_version=None, model=None): super().__init__() + api_key = api_key or os.getenv("AZURE_CHATGPT_KEY") + azure_endpoint = azure_endpoint or os.getenv("AZURE_CHATGPT_ENDPOINT") + api_version = api_version or "2023-12-01-preview" self.client = AzureOpenAI( - api_key=os.getenv("AZURE_CHATGPT_KEY"), - azure_endpoint=os.getenv("AZURE_CHATGPT_ENDPOINT"), - api_version="2023-12-01-preview", + api_key=api_key, + azure_endpoint=azure_endpoint, + api_version=api_version, ) + self.model = model or os.getenv("AZURE_CHATGPT_DEPLOYMENT_ID") def get_response(self, messages, stream): return self.client.chat.completions.create( stream=stream, messages=messages, - model=os.getenv("AZURE_CHATGPT_DEPLOYMENT_ID"), + model=self.model, ) def run_llm_async(self, messages) -> Generator[str, None, None]: @@ -89,16 +93,26 @@ class AzureLLMService(LLMService): class AzureImageGenService(ImageGenService): + def __init__(self, api_key=None, azure_endpoint=None, api_version=None, model=None): + super().__init__() + + api_key = api_key or os.getenv("AZURE_DALLE_KEY") + azure_endpoint = azure_endpoint or os.getenv("AZURE_DALLE_ENDPOINT") + api_version = api_version or "2023-12-01-preview" + self.model = model or os.getenv("AZURE_DALLE_DEPLOYMENT_ID") + + self.client = AzureOpenAI( + api_key=api_key, + azure_endpoint=azure_endpoint, + api_version=api_version, + ) + def run_image_gen(self, sentence) -> tuple[str, Image.Image]: self.logger.info("Generating azure image", sentence) - image = OpenAI().images.generate( - api_type="azure", - api_version="2023-06-01-preview", - api_key=os.getenv("AZURE_DALLE_KEY"), - api_base=os.getenv("AZURE_DALLE_ENDPOINT"), - deployment_id=os.getenv("AZURE_DALLE_DEPLOYMENT_ID"), - prompt=f"{sentence} in the style of {self.image_style}", + image = self.client.images.generate( + model=self.model, + prompt=sentence, n=1, size=f"1024x1024", ) diff --git a/src/samples/simple-sample/simple-sample.py b/src/samples/simple-sample/simple-sample.py index cf0fed0b8..5cad855d6 100644 --- a/src/samples/simple-sample/simple-sample.py +++ b/src/samples/simple-sample/simple-sample.py @@ -29,15 +29,6 @@ def add_bot_to_room(room_url, token, expiration) -> None: """ ) - # Use the standard Response classes for the intro and response. Do nothing while waiting - # or saying goodbye. - conversation_processors = ConversationProcessorCollection( - introduction=Response, - waiting=None, - response=Response, - goodbye=None, - ) - # Use Azure services for the TTS, image generation, and LLM. # Note that you'll need to set the following environment variables: # - AZURE_SPEECH_SERVICE_KEY @@ -66,7 +57,6 @@ def add_bot_to_room(room_url, token, expiration) -> None: orchestrator = Orchestrator( orchestrator_config, services, - conversation_processors, message_handler, ) orchestrator.start()