getting started on 06-
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
89
src/samples/theoretical-to-real/06-listen-and-respond.py
Normal file
89
src/samples/theoretical-to-real/06-listen-and-respond.py
Normal 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))
|
||||||
Reference in New Issue
Block a user