diff --git a/src/dailyai/orchestrator.py b/src/dailyai/orchestrator.py index 3b0c48fb9..872f9ba1e 100644 --- a/src/dailyai/orchestrator.py +++ b/src/dailyai/orchestrator.py @@ -311,7 +311,6 @@ class Orchestrator(EventHandler): self.is_interrupted.set() self.current_response.interrupt() - self.display_thinking() self.message_handler.add_user_message(fragment) response_type = self.conversation_processors.response or Response @@ -340,55 +339,6 @@ class Orchestrator(EventHandler): self.response_semaphore.release() - def display_waiting(self): - # I don't love this design, need to think more about how to do this well - listening_images = [ - "sc-listen-1", - "sc-listen-1", - "sc-listen-1", - "sc-listen-1", - "sc-listen-2", - "sc-listen-1", - "sc-listen-1", - "sc-listen-1", - "sc-listen-1", - "sc-listen-1", - "sc-listen-1", - "sc-listen-2", - "sc-listen-1", - "sc-listen-2", - "sc-listen-1", - "sc-listen-1", - "sc-listen-1", - "sc-listen-1", - "sc-listen-1", - "sc-listen-1", - "sc-listen-1", - "sc-listen-2", - "sc-listen-1", - "sc-listen-1", - "sc-listen-1", - "sc-listen-1", - "sc-listen-2", - "sc-listen-1", - "sc-listen-1", - "sc-listen-1", - ] - # self.display_images(listening_images) - - def display_thinking(self): - thinking_images = [ - "sc-think-1", - "sc-think-1", - "sc-think-2", - "sc-think-2", - "sc-think-3", - "sc-think-3", - "sc-think-4", - "sc-think-4", - ] - # self.display_images(thinking_images) - def action(self): self.logger.info("Starting camera thread") self.image: bytes | None = None diff --git a/src/samples/simple-sample/simple-sample.py b/src/samples/simple-sample/simple-sample.py index 5cad855d6..5bb8a51a6 100644 --- a/src/samples/simple-sample/simple-sample.py +++ b/src/samples/simple-sample/simple-sample.py @@ -14,9 +14,6 @@ from dailyai.message_handler.message_handler import MessageHandler from dailyai.services.ai_services import AIServiceConfig from dailyai.services.azure_ai_services import AzureImageGenService, AzureTTSService, AzureLLMService -def configure_ai_services() -> AIServiceConfig: - return - def add_bot_to_room(room_url, token, expiration) -> None: # A simple prompt for a simple sample. diff --git a/src/samples/simple-sample/sprite-sample.py b/src/samples/simple-sample/sprite-sample.py new file mode 100644 index 000000000..ba957b8ae --- /dev/null +++ b/src/samples/simple-sample/sprite-sample.py @@ -0,0 +1,110 @@ +import argparse +from email.mime import image +from re import A +import requests +import time +import urllib.parse + +from dailyai.async_processor.async_processor import ( + Response, + ConversationProcessorCollection, +) +from dailyai.orchestrator import OrchestratorConfig, Orchestrator +from dailyai.message_handler.message_handler import MessageHandler +from dailyai.services.ai_services import AIServiceConfig +from dailyai.services.azure_ai_services import AzureImageGenService, AzureTTSService, AzureLLMService + +class SpriteResponse(Response): + def __init__(self, message, image): + super().__init__(message) + self.image = image + + def get_image(self): + return self.image + +def add_bot_to_room(room_url, token, expiration) -> None: + + # A simple prompt for a simple sample. + message_handler = MessageHandler( + """ + You are a sample bot, meant to demonstrate how to use an LLM with transcription at TTS. + Answer user's questions and be friendly, and if you can, give some ideas about how someone + could use a bot like you in a more in-depth way. Because your responses will be spoken, + try to keep them short and sweet. + """ + ) + + # 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 + # - AZURE_SPEECH_SERVICE_REGION + # - AZURE_CHATGPT_KEY + # - AZURE_CHATGPT_ENDPOINT + # - AZURE_CHATGPT_DEPLOYMENT_ID + # + # This demo doesn't use image generation, but if you extend it to do so, + # you'll also need to set: + # - AZURE_DALLE_KEY + # - AZURE_DALLE_ENDPOINT + # - AZURE_DALLE_DEPLOYMENT_ID + + services = AIServiceConfig( + tts=AzureTTSService(), image=AzureImageGenService(), llm=AzureLLMService() + ) + + sprite_conversation_processors = ConversationProcessorCollection( + intro = IntroSpriteResponse, + waiting = WaitingSpriteResponse, + response = ResponseSpriteResponse, + ) + + orchestrator_config = OrchestratorConfig( + room_url=room_url, + token=token, + bot_name="Simple Bot", + expiration=expiration, + ) + + orchestrator = Orchestrator( + orchestrator_config, + services, + message_handler, + ) + orchestrator.start() + + # When the orchestrator's done, we need to shut it down, + # and the various services and handlers we've created. + orchestrator.stop() + message_handler.shutdown() + + services.tts.close() + services.image.close() + services.llm.close() + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Simple Daily Bot Sample") + parser.add_argument("-u", "--url", type=str, required=True, help="URL of the Daily room") + parser.add_argument( + "-k", "--apikey", type=str, required=True, help="Daily API Key (needed to create token)" + ) + + args: argparse.Namespace = parser.parse_args() + + # Create a meeting token for the given room with an expiration 1 hour in the future. + room_name: str = urllib.parse.urlparse(args.url).path[1:] + expiration: float = time.time() + 60 * 60 + + res: requests.Response = requests.post( + f"https://api.daily.co/v1/meeting-tokens", + headers={"Authorization": f"Bearer {args.apikey}"}, + json={ + "properties": {"room_name": room_name, "is_owner": True, "exp": expiration} + }, + ) + + if res.status_code != 200: + raise Exception(f'Failed to create meeting token: {res.status_code} {res.text}') + + token: str = res.json()['token'] + + add_bot_to_room(args.url, token, expiration)