some progress on the sprite sample app
@@ -80,7 +80,7 @@ class AsyncProcessor:
|
|||||||
|
|
||||||
self.was_interrupted = False
|
self.was_interrupted = False
|
||||||
|
|
||||||
self.logger: logging.Logger = logging.getLogger("bot-instance")
|
self.logger: logging.Logger = logging.getLogger("dailyai")
|
||||||
|
|
||||||
def set_state(self, state: int) -> None:
|
def set_state(self, state: int) -> None:
|
||||||
if state in AsyncProcessorState.state_transitions[self.state]:
|
if state in AsyncProcessorState.state_transitions[self.state]:
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ class IndexingMessageHandler(MessageHandler):
|
|||||||
self.index_writer_thread = Thread(target=self.storage_writer, daemon=True)
|
self.index_writer_thread = Thread(target=self.storage_writer, daemon=True)
|
||||||
self.index_writer_thread.start()
|
self.index_writer_thread.start()
|
||||||
|
|
||||||
self.logger = logging.getLogger("bot-instance")
|
self.logger = logging.getLogger("dailyai")
|
||||||
|
|
||||||
def shutdown(self):
|
def shutdown(self):
|
||||||
self.finalize_user_message()
|
self.finalize_user_message()
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ class Orchestrator(EventHandler):
|
|||||||
self.token: str = daily_config.token
|
self.token: str = daily_config.token
|
||||||
self.expiration: float = daily_config.expiration
|
self.expiration: float = daily_config.expiration
|
||||||
|
|
||||||
self.logger: logging.Logger = logging.getLogger("bot-instance")
|
self.logger: logging.Logger = logging.getLogger("dailyai")
|
||||||
self.tracer = tracer or trace.get_tracer("orchestrator")
|
self.tracer = tracer or trace.get_tracer("orchestrator")
|
||||||
|
|
||||||
self.ctx: Context = context.get_current()
|
self.ctx: Context = context.get_current()
|
||||||
@@ -203,11 +203,12 @@ class Orchestrator(EventHandler):
|
|||||||
self.logger.info("Orchestrator stopped.")
|
self.logger.info("Orchestrator stopped.")
|
||||||
|
|
||||||
def on_intro_played(self, intro):
|
def on_intro_played(self, intro):
|
||||||
|
self.logger.info(f"Introduction has played")
|
||||||
self.can_interrupt = True
|
self.can_interrupt = True
|
||||||
intro.finalize()
|
intro.finalize()
|
||||||
|
|
||||||
def on_intro_finished(self, intro):
|
def on_intro_finished(self, intro):
|
||||||
pass
|
self.logger.info(f"Introduction has finished")
|
||||||
|
|
||||||
def on_response_played(self, response):
|
def on_response_played(self, response):
|
||||||
response.finalize()
|
response.finalize()
|
||||||
@@ -366,6 +367,7 @@ class Orchestrator(EventHandler):
|
|||||||
frame:OutputQueueFrame = self.output_queue.get()
|
frame:OutputQueueFrame = self.output_queue.get()
|
||||||
if frame.frame_type == FrameType.END_STREAM:
|
if frame.frame_type == FrameType.END_STREAM:
|
||||||
self.logger.info("Stopping frame consumer thread")
|
self.logger.info("Stopping frame consumer thread")
|
||||||
|
return
|
||||||
|
|
||||||
# if interrupted, we just pull frames off the queue and discard them
|
# if interrupted, we just pull frames off the queue and discard them
|
||||||
if not self.is_interrupted.is_set():
|
if not self.is_interrupted.is_set():
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ from PIL import Image
|
|||||||
|
|
||||||
class AIService:
|
class AIService:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.logger = logging.getLogger("bot-instance")
|
self.logger = logging.getLogger("dailyai")
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
pass
|
pass
|
||||||
|
|||||||
BIN
src/samples/static-sprite/.DS_Store
vendored
Normal file
@@ -1,5 +1,8 @@
|
|||||||
import argparse
|
import argparse
|
||||||
|
from email.mime import image
|
||||||
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import random
|
||||||
import requests
|
import requests
|
||||||
import time
|
import time
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
@@ -27,7 +30,7 @@ class StaticSpriteResponse(OrchestratorResponse):
|
|||||||
) -> None:
|
) -> None:
|
||||||
super().__init__(services, message_handler, output_queue)
|
super().__init__(services, message_handler, output_queue)
|
||||||
self.image_bytes:bytes | None = None
|
self.image_bytes:bytes | None = None
|
||||||
self.filename = None # override this in subclasses
|
self.filenames = None # override this in subclasses
|
||||||
|
|
||||||
def start_preparation(self) -> None:
|
def start_preparation(self) -> None:
|
||||||
full_path = os.path.join(os.path.dirname(__file__), "sprites/", self.filename)
|
full_path = os.path.join(os.path.dirname(__file__), "sprites/", self.filename)
|
||||||
@@ -36,7 +39,7 @@ class StaticSpriteResponse(OrchestratorResponse):
|
|||||||
with Image.open(full_path) as img:
|
with Image.open(full_path) as img:
|
||||||
self.image_bytes = img.tobytes()
|
self.image_bytes = img.tobytes()
|
||||||
|
|
||||||
def async_play(self) -> None:
|
def do_play(self) -> None:
|
||||||
self.output_queue.put(OutputQueueFrame(FrameType.IMAGE_FRAME, self.image_bytes))
|
self.output_queue.put(OutputQueueFrame(FrameType.IMAGE_FRAME, self.image_bytes))
|
||||||
|
|
||||||
|
|
||||||
@@ -52,6 +55,27 @@ class WaitingSpriteResponse(StaticSpriteResponse):
|
|||||||
self.filename = "waiting.png"
|
self.filename = "waiting.png"
|
||||||
|
|
||||||
|
|
||||||
|
class AnimatedSpriteLLMResponse(LLMResponse):
|
||||||
|
def __init__(self, services, message_handler, output_queue) -> None:
|
||||||
|
super().__init__(services, message_handler, output_queue)
|
||||||
|
self.filenames = ["talk-1.png", "talk-2.png"]
|
||||||
|
self.image_bytes = []
|
||||||
|
|
||||||
|
def start_preparation(self) -> None:
|
||||||
|
for filename in self.filenames:
|
||||||
|
full_path = os.path.join(os.path.dirname(__file__), "sprites/", filename)
|
||||||
|
print(full_path)
|
||||||
|
|
||||||
|
with Image.open(full_path) as img:
|
||||||
|
self.image_bytes.append(img.tobytes())
|
||||||
|
|
||||||
|
def get_frames_from_tts_response(self, audio_frame) -> list[OutputQueueFrame]:
|
||||||
|
return [
|
||||||
|
OutputQueueFrame(FrameType.AUDIO_FRAME, audio_frame),
|
||||||
|
random.choice(self.image_bytes)
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def add_bot_to_room(room_url, token, expiration) -> None:
|
def add_bot_to_room(room_url, token, expiration) -> None:
|
||||||
|
|
||||||
# A simple prompt for a simple sample.
|
# A simple prompt for a simple sample.
|
||||||
@@ -85,7 +109,7 @@ def add_bot_to_room(room_url, token, expiration) -> None:
|
|||||||
sprite_conversation_processors = ConversationProcessorCollection(
|
sprite_conversation_processors = ConversationProcessorCollection(
|
||||||
introduction=IntroSpriteResponse,
|
introduction=IntroSpriteResponse,
|
||||||
waiting=WaitingSpriteResponse,
|
waiting=WaitingSpriteResponse,
|
||||||
response=LLMResponse,
|
response=AnimatedSpriteLLMResponse,
|
||||||
)
|
)
|
||||||
|
|
||||||
orchestrator_config = OrchestratorConfig(
|
orchestrator_config = OrchestratorConfig(
|
||||||
@@ -95,6 +119,15 @@ def add_bot_to_room(room_url, token, expiration) -> None:
|
|||||||
expiration=expiration,
|
expiration=expiration,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
FORMAT = f"%(levelno)s %(asctime)s %(message)s"
|
||||||
|
# Remove any handlers added by imported modules so we can use our formatting
|
||||||
|
while logging.root.handlers:
|
||||||
|
logging.root.removeHandler(logging.root.handlers[-1])
|
||||||
|
logging.basicConfig(format=FORMAT)
|
||||||
|
logger: logging.Logger = logging.getLogger("dailyai")
|
||||||
|
logger.setLevel(logging.DEBUG)
|
||||||
|
logger.info("hello world")
|
||||||
|
|
||||||
orchestrator = Orchestrator(
|
orchestrator = Orchestrator(
|
||||||
orchestrator_config,
|
orchestrator_config,
|
||||||
services,
|
services,
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 868 KiB |
|
Before Width: | Height: | Size: 871 KiB |
|
Before Width: | Height: | Size: 872 KiB |
|
Before Width: | Height: | Size: 868 KiB |
|
Before Width: | Height: | Size: 870 KiB After Width: | Height: | Size: 870 KiB |
|
Before Width: | Height: | Size: 871 KiB After Width: | Height: | Size: 871 KiB |