getting started on 06-

This commit is contained in:
Moishe Lettvin
2024-01-10 13:00:36 -05:00
parent cd204ebd21
commit 7229fc806e
4 changed files with 95 additions and 9 deletions

View File

@@ -1,8 +1,8 @@
import logging import logging
from asyncio import Queue
from abc import abstractmethod from abc import abstractmethod
from collections.abc import AsyncGenerator from typing import AsyncGenerator
from dataclasses import dataclass from dataclasses import dataclass
@@ -16,9 +16,7 @@ class AIService:
class LLMService(AIService): class LLMService(AIService):
# Generate a set of responses to a prompt. Yields a list of responses. # Generate a set of responses to a prompt. Yields a list of responses.
@abstractmethod @abstractmethod
async def run_llm_async( async def run_llm_async(self, messages) -> AsyncGenerator[str, None]:
self, messages
) -> AsyncGenerator[str, None]:
pass pass
# Generate a responses to a prompt. Returns the response # Generate a responses to a prompt. Returns the response

View File

@@ -222,13 +222,13 @@ class DailyTransportService(EventHandler):
pass pass
def on_transcription_stopped(self, stopped_by, stopped_by_error): def on_transcription_stopped(self, stopped_by, stopped_by_error):
self.logger.info(f"Transcription stopped {stopped_by}, {stopped_by_error}") pass
def on_transcription_error(self, message): def on_transcription_error(self, message):
self.logger.error(f"Transcription error {message}") pass
def on_transcription_started(self, status): def on_transcription_started(self, status):
self.logger.info(f"Transcription started {status}") pass
def set_image(self, image: bytes): def set_image(self, image: bytes):
self.image: bytes | None = image self.image: bytes | None = image

View File

@@ -20,7 +20,6 @@ class GoogleAIService(AIService):
) )
def run_tts(self, sentence): def run_tts(self, sentence):
print("running google tts")
synthesis_input = texttospeech.SynthesisInput(text = sentence.strip()) synthesis_input = texttospeech.SynthesisInput(text = sentence.strip())
result = self.client.synthesize_speech(input=synthesis_input, voice=self.voice, audio_config=self.audio_config) result = self.client.synthesize_speech(input=synthesis_input, voice=self.voice, audio_config=self.audio_config)
return result return result

View File

@@ -0,0 +1,89 @@
import argparse
import asyncio
import requests
from dailyai.services.daily_transport_service import DailyTransportService
from dailyai.services.azure_ai_services import AzureLLMService, AzureTTSService
from dailyai.output_queue import OutputQueueFrame, FrameType
async def main(room_url:str, token):
global transport
global llm
global tts
transport = DailyTransportService(
room_url,
token,
"Say Two Things Bot",
1,
)
transport.mic_enabled = True
transport.mic_sample_rate = 16000
transport.camera_enabled = False
llm = AzureLLMService()
tts = AzureTTSService()
@transport.event_handler("on_participant_joined")
async def on_joined(transport, participant):
if participant["id"] == transport.my_participant_id:
return
# queue two pieces of speech: one specified as a text literal,
# and one generated by an llm. We'll kick off the llm first, and let
# it generate a response while we're speaking the literal string.
llm_response_task = asyncio.create_task(llm.run_llm(
[{"role": "system", "content": "tell the user a joke about llamas"}]
))
async for audio_chunk in tts.run_tts("My friend the LLM is now going to tell a joke about llamas."):
transport.output_queue.put(OutputQueueFrame(FrameType.AUDIO_FRAME, audio_chunk))
llm_response = await llm_response_task
async for audio_chunk in tts.run_tts(llm_response):
transport.output_queue.put(OutputQueueFrame(FrameType.AUDIO_FRAME, audio_chunk))
# wait for the output queue to be empty, then leave the meeting
transport.output_queue.join()
transport.stop()
@transport.event_handler("on_transcription_message")
async def on_transcription_message(transport, message) -> None:
print("message received", message)
await transport.run()
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 to join"
)
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"]
asyncio.run(main(args.url, token))