DailyRESTHelper now receives an aiohttp client session
This commit is contained in:
@@ -9,6 +9,8 @@ import argparse
|
|||||||
import subprocess
|
import subprocess
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
from contextlib import asynccontextmanager
|
||||||
|
|
||||||
from fastapi import FastAPI, Request, HTTPException
|
from fastapi import FastAPI, Request, HTTPException
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
from fastapi.responses import JSONResponse
|
from fastapi.responses import JSONResponse
|
||||||
@@ -39,14 +41,23 @@ FLY_HEADERS = {
|
|||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
}
|
}
|
||||||
|
|
||||||
daily_rest_helper = DailyRESTHelper(
|
daily_helpers = {}
|
||||||
os.getenv("DAILY_API_KEY", ""),
|
|
||||||
os.getenv("DAILY_API_URL", 'https://api.daily.co/v1'))
|
|
||||||
|
|
||||||
|
|
||||||
# ----------------- API ----------------- #
|
# ----------------- API ----------------- #
|
||||||
|
|
||||||
app = FastAPI()
|
@asynccontextmanager
|
||||||
|
async def lifespan(app: FastAPI):
|
||||||
|
aiohttp_session = aiohttp.ClientSession()
|
||||||
|
daily_helpers["rest"] = DailyRESTHelper(
|
||||||
|
daily_api_key=os.getenv("DAILY_API_KEY", ""),
|
||||||
|
daily_api_url=os.getenv("DAILY_API_URL", 'https://api.daily.co/v1'),
|
||||||
|
aiohttp_session=aiohttp_session
|
||||||
|
)
|
||||||
|
yield
|
||||||
|
await aiohttp_session.close()
|
||||||
|
|
||||||
|
app = FastAPI(lifespan=lifespan)
|
||||||
|
|
||||||
app.add_middleware(
|
app.add_middleware(
|
||||||
CORSMiddleware,
|
CORSMiddleware,
|
||||||
@@ -127,7 +138,7 @@ async def start_bot(request: Request) -> JSONResponse:
|
|||||||
properties=DailyRoomProperties()
|
properties=DailyRoomProperties()
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
room: DailyRoomObject = await daily_rest_helper.create_room(params=params)
|
room: DailyRoomObject = await daily_helpers["rest"].create_room(params=params)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=500,
|
status_code=500,
|
||||||
@@ -135,13 +146,13 @@ async def start_bot(request: Request) -> JSONResponse:
|
|||||||
else:
|
else:
|
||||||
# Check passed room URL exists, we should assume that it already has a sip set up
|
# Check passed room URL exists, we should assume that it already has a sip set up
|
||||||
try:
|
try:
|
||||||
room: DailyRoomObject = await daily_rest_helper.get_room_from_url(room_url)
|
room: DailyRoomObject = await daily_helpers["rest"].get_room_from_url(room_url)
|
||||||
except Exception:
|
except Exception:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=500, detail=f"Room not found: {room_url}")
|
status_code=500, detail=f"Room not found: {room_url}")
|
||||||
|
|
||||||
# Give the agent a token to join the session
|
# Give the agent a token to join the session
|
||||||
token = await daily_rest_helper.get_token(room.url, MAX_SESSION_TIME)
|
token = await daily_helpers["rest"].get_token(room.url, MAX_SESSION_TIME)
|
||||||
|
|
||||||
if not room or not token:
|
if not room or not token:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
@@ -168,7 +179,7 @@ async def start_bot(request: Request) -> JSONResponse:
|
|||||||
status_code=500, detail=f"Failed to spawn VM: {e}")
|
status_code=500, detail=f"Failed to spawn VM: {e}")
|
||||||
|
|
||||||
# Grab a token for the user to join with
|
# Grab a token for the user to join with
|
||||||
user_token = await daily_rest_helper.get_token(room.url, MAX_SESSION_TIME)
|
user_token = await daily_helpers["rest"].get_token(room.url, MAX_SESSION_TIME)
|
||||||
|
|
||||||
return JSONResponse({
|
return JSONResponse({
|
||||||
"room_url": room.url,
|
"room_url": room.url,
|
||||||
@@ -200,6 +211,5 @@ if __name__ == "__main__":
|
|||||||
port=config.port,
|
port=config.port,
|
||||||
reload=config.reload
|
reload=config.reload
|
||||||
)
|
)
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
print("Pipecat runner shutting down...")
|
print("Pipecat runner shutting down...")
|
||||||
|
|||||||
@@ -7,10 +7,14 @@ provisioning a room and starting a Pipecat bot in response.
|
|||||||
Refer to README for more information.
|
Refer to README for more information.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
import aiohttp
|
||||||
import os
|
import os
|
||||||
import argparse
|
import argparse
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
|
from contextlib import asynccontextmanager
|
||||||
|
|
||||||
from fastapi import FastAPI, Request, HTTPException
|
from fastapi import FastAPI, Request, HTTPException
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
from fastapi.responses import JSONResponse, PlainTextResponse
|
from fastapi.responses import JSONResponse, PlainTextResponse
|
||||||
@@ -33,14 +37,23 @@ MAX_SESSION_TIME = 5 * 60 # 5 minutes
|
|||||||
REQUIRED_ENV_VARS = ['OPENAI_API_KEY', 'DAILY_API_KEY',
|
REQUIRED_ENV_VARS = ['OPENAI_API_KEY', 'DAILY_API_KEY',
|
||||||
'ELEVENLABS_API_KEY', 'ELEVENLABS_VOICE_ID']
|
'ELEVENLABS_API_KEY', 'ELEVENLABS_VOICE_ID']
|
||||||
|
|
||||||
daily_rest_helper = DailyRESTHelper(
|
daily_helpers = {}
|
||||||
os.getenv("DAILY_API_KEY", ""),
|
|
||||||
os.getenv("DAILY_API_URL", 'https://api.daily.co/v1'))
|
|
||||||
|
|
||||||
|
|
||||||
# ----------------- API ----------------- #
|
# ----------------- API ----------------- #
|
||||||
|
|
||||||
app = FastAPI()
|
|
||||||
|
@asynccontextmanager
|
||||||
|
async def lifespan(app: FastAPI):
|
||||||
|
aiohttp_session = aiohttp.ClientSession()
|
||||||
|
daily_helpers["rest"] = DailyRESTHelper(
|
||||||
|
daily_api_key=os.getenv("DAILY_API_KEY", ""),
|
||||||
|
daily_api_url=os.getenv("DAILY_API_URL", 'https://api.daily.co/v1'),
|
||||||
|
aiohttp_session=aiohttp_session
|
||||||
|
)
|
||||||
|
yield
|
||||||
|
await aiohttp_session.close()
|
||||||
|
|
||||||
|
app = FastAPI(lifespan=lifespan)
|
||||||
|
|
||||||
app.add_middleware(
|
app.add_middleware(
|
||||||
CORSMiddleware,
|
CORSMiddleware,
|
||||||
@@ -76,13 +89,13 @@ async def _create_daily_room(room_url, callId, callDomain=None, vendor="daily"):
|
|||||||
)
|
)
|
||||||
|
|
||||||
print(f"Creating new room...")
|
print(f"Creating new room...")
|
||||||
room: DailyRoomObject = await daily_rest_helper.create_room(params=params)
|
room: DailyRoomObject = await daily_helpers["rest"].create_room(params=params)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# Check passed room URL exist (we assume that it already has a sip set up!)
|
# Check passed room URL exist (we assume that it already has a sip set up!)
|
||||||
try:
|
try:
|
||||||
print(f"Joining existing room: {room_url}")
|
print(f"Joining existing room: {room_url}")
|
||||||
room: DailyRoomObject = await daily_rest_helper.get_room_from_url(room_url)
|
room: DailyRoomObject = await daily_helpers["rest"].get_room_from_url(room_url)
|
||||||
except Exception:
|
except Exception:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=500, detail=f"Room not found: {room_url}")
|
status_code=500, detail=f"Room not found: {room_url}")
|
||||||
@@ -90,7 +103,7 @@ async def _create_daily_room(room_url, callId, callDomain=None, vendor="daily"):
|
|||||||
print(f"Daily room: {room.url} {room.config.sip_endpoint}")
|
print(f"Daily room: {room.url} {room.config.sip_endpoint}")
|
||||||
|
|
||||||
# Give the agent a token to join the session
|
# Give the agent a token to join the session
|
||||||
token = await daily_rest_helper.get_token(room.url, MAX_SESSION_TIME)
|
token = await daily_helpers["rest"].get_token(room.url, MAX_SESSION_TIME)
|
||||||
|
|
||||||
if not room or not token:
|
if not room or not token:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
|
|||||||
@@ -28,8 +28,9 @@ logger.add(sys.stderr, level="DEBUG")
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
(room_url, _) = await configure()
|
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
|
(room_url, _) = await configure(session)
|
||||||
|
|
||||||
transport = DailyTransport(
|
transport = DailyTransport(
|
||||||
room_url, None, "Say One Thing", DailyParams(audio_out_enabled=True))
|
room_url, None, "Say One Thing", DailyParams(audio_out_enabled=True))
|
||||||
|
|
||||||
|
|||||||
@@ -29,8 +29,9 @@ logger.add(sys.stderr, level="DEBUG")
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
(room_url, _) = await configure()
|
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
|
(room_url, _) = await configure(session)
|
||||||
|
|
||||||
transport = DailyTransport(
|
transport = DailyTransport(
|
||||||
room_url,
|
room_url,
|
||||||
None,
|
None,
|
||||||
|
|||||||
@@ -28,8 +28,9 @@ logger.add(sys.stderr, level="DEBUG")
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
(room_url, _) = await configure()
|
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
|
(room_url, _) = await configure(session)
|
||||||
|
|
||||||
transport = DailyTransport(
|
transport = DailyTransport(
|
||||||
room_url,
|
room_url,
|
||||||
None,
|
None,
|
||||||
|
|||||||
@@ -31,8 +31,9 @@ logger.add(sys.stderr, level="DEBUG")
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
(room_url, _) = await configure()
|
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
|
(room_url, _) = await configure(session)
|
||||||
|
|
||||||
transport = DailyTransport(room_url, None, "Static And Dynamic Speech")
|
transport = DailyTransport(room_url, None, "Static And Dynamic Speech")
|
||||||
|
|
||||||
meeting = TransportServiceOutput(transport, mic_enabled=True)
|
meeting = TransportServiceOutput(transport, mic_enabled=True)
|
||||||
|
|||||||
@@ -74,8 +74,9 @@ class MonthPrepender(FrameProcessor):
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
(room_url, _) = await configure()
|
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
|
(room_url, _) = await configure(session)
|
||||||
|
|
||||||
transport = DailyTransport(
|
transport = DailyTransport(
|
||||||
room_url,
|
room_url,
|
||||||
None,
|
None,
|
||||||
|
|||||||
@@ -35,8 +35,9 @@ logger.add(sys.stderr, level="DEBUG")
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
(room_url, token) = await configure()
|
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
|
(room_url, token) = await configure(session)
|
||||||
|
|
||||||
transport = DailyTransport(
|
transport = DailyTransport(
|
||||||
room_url,
|
room_url,
|
||||||
token,
|
token,
|
||||||
|
|||||||
@@ -60,8 +60,9 @@ class ImageSyncAggregator(FrameProcessor):
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
(room_url, token) = await configure()
|
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
|
(room_url, token) = await configure(session)
|
||||||
|
|
||||||
transport = DailyTransport(
|
transport = DailyTransport(
|
||||||
room_url,
|
room_url,
|
||||||
token,
|
token,
|
||||||
|
|||||||
@@ -32,9 +32,9 @@ logger.add(sys.stderr, level="DEBUG")
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
(room_url, token) = await configure()
|
|
||||||
|
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
|
(room_url, token) = await configure(session)
|
||||||
|
|
||||||
transport = DailyTransport(
|
transport = DailyTransport(
|
||||||
room_url,
|
room_url,
|
||||||
token,
|
token,
|
||||||
|
|||||||
@@ -32,8 +32,9 @@ logger.add(sys.stderr, level="DEBUG")
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
(room_url, token) = await configure()
|
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
|
(room_url, token) = await configure(session)
|
||||||
|
|
||||||
transport = DailyTransport(
|
transport = DailyTransport(
|
||||||
room_url,
|
room_url,
|
||||||
token,
|
token,
|
||||||
|
|||||||
@@ -48,8 +48,9 @@ def get_session_history(session_id: str) -> BaseChatMessageHistory:
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
(room_url, token) = await configure()
|
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
|
(room_url, token) = await configure(session)
|
||||||
|
|
||||||
transport = DailyTransport(
|
transport = DailyTransport(
|
||||||
room_url,
|
room_url,
|
||||||
token,
|
token,
|
||||||
|
|||||||
@@ -32,8 +32,9 @@ logger.add(sys.stderr, level="DEBUG")
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
(room_url, token) = await configure()
|
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
|
(room_url, token) = await configure(session)
|
||||||
|
|
||||||
transport = DailyTransport(
|
transport = DailyTransport(
|
||||||
room_url,
|
room_url,
|
||||||
token,
|
token,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
# SPDX-License-Identifier: BSD 2-Clause License
|
# SPDX-License-Identifier: BSD 2-Clause License
|
||||||
#
|
#
|
||||||
|
|
||||||
|
import aiohttp
|
||||||
import asyncio
|
import asyncio
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
@@ -32,62 +33,64 @@ logger.add(sys.stderr, level="DEBUG")
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
(room_url, token) = await configure()
|
async with aiohttp.ClientSession() as session:
|
||||||
transport = DailyTransport(
|
(room_url, token) = await configure(session)
|
||||||
room_url,
|
|
||||||
token,
|
transport = DailyTransport(
|
||||||
"Respond bot",
|
room_url,
|
||||||
DailyParams(
|
token,
|
||||||
audio_out_sample_rate=44100,
|
"Respond bot",
|
||||||
audio_out_enabled=True,
|
DailyParams(
|
||||||
transcription_enabled=True,
|
audio_out_sample_rate=44100,
|
||||||
vad_enabled=True,
|
audio_out_enabled=True,
|
||||||
vad_analyzer=SileroVADAnalyzer()
|
transcription_enabled=True,
|
||||||
|
vad_enabled=True,
|
||||||
|
vad_analyzer=SileroVADAnalyzer()
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
|
||||||
|
|
||||||
tts = CartesiaTTSService(
|
tts = CartesiaTTSService(
|
||||||
api_key=os.getenv("CARTESIA_API_KEY"),
|
api_key=os.getenv("CARTESIA_API_KEY"),
|
||||||
voice_id="a0e99841-438c-4a64-b679-ae501e7d6091", # Barbershop Man
|
voice_id="a0e99841-438c-4a64-b679-ae501e7d6091", # Barbershop Man
|
||||||
sample_rate=44100,
|
sample_rate=44100,
|
||||||
)
|
)
|
||||||
|
|
||||||
llm = OpenAILLMService(
|
llm = OpenAILLMService(
|
||||||
api_key=os.getenv("OPENAI_API_KEY"),
|
api_key=os.getenv("OPENAI_API_KEY"),
|
||||||
model="gpt-4o")
|
model="gpt-4o")
|
||||||
|
|
||||||
messages = [
|
messages = [
|
||||||
{
|
{
|
||||||
"role": "system",
|
"role": "system",
|
||||||
"content": "You are a helpful LLM in a WebRTC call. Your goal is to demonstrate your capabilities in a succinct way. Your output will be converted to audio so don't include special characters in your answers. Respond to what the user said in a creative and helpful way.",
|
"content": "You are a helpful LLM in a WebRTC call. Your goal is to demonstrate your capabilities in a succinct way. Your output will be converted to audio so don't include special characters in your answers. Respond to what the user said in a creative and helpful way.",
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
tma_in = LLMUserResponseAggregator(messages)
|
tma_in = LLMUserResponseAggregator(messages)
|
||||||
tma_out = LLMAssistantResponseAggregator(messages)
|
tma_out = LLMAssistantResponseAggregator(messages)
|
||||||
|
|
||||||
pipeline = Pipeline([
|
pipeline = Pipeline([
|
||||||
transport.input(), # Transport user input
|
transport.input(), # Transport user input
|
||||||
tma_in, # User responses
|
tma_in, # User responses
|
||||||
llm, # LLM
|
llm, # LLM
|
||||||
tts, # TTS
|
tts, # TTS
|
||||||
tma_out, # Goes before the transport because cartesia has word-level timestamps!
|
tma_out, # Goes before the transport because cartesia has word-level timestamps!
|
||||||
transport.output(), # Transport bot output
|
transport.output(), # Transport bot output
|
||||||
])
|
])
|
||||||
|
|
||||||
task = PipelineTask(pipeline, PipelineParams(allow_interruptions=True, enable_metrics=True))
|
task = PipelineTask(pipeline, PipelineParams(allow_interruptions=True, enable_metrics=True))
|
||||||
|
|
||||||
@transport.event_handler("on_first_participant_joined")
|
@transport.event_handler("on_first_participant_joined")
|
||||||
async def on_first_participant_joined(transport, participant):
|
async def on_first_participant_joined(transport, participant):
|
||||||
transport.capture_participant_transcription(participant["id"])
|
transport.capture_participant_transcription(participant["id"])
|
||||||
# Kick off the conversation.
|
# Kick off the conversation.
|
||||||
messages.append(
|
messages.append(
|
||||||
{"role": "system", "content": "Please introduce yourself to the user."})
|
{"role": "system", "content": "Please introduce yourself to the user."})
|
||||||
await task.queue_frames([LLMMessagesFrame(messages)])
|
await task.queue_frames([LLMMessagesFrame(messages)])
|
||||||
|
|
||||||
runner = PipelineRunner()
|
runner = PipelineRunner()
|
||||||
|
|
||||||
await runner.run(task)
|
await runner.run(task)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
# SPDX-License-Identifier: BSD 2-Clause License
|
# SPDX-License-Identifier: BSD 2-Clause License
|
||||||
#
|
#
|
||||||
|
|
||||||
|
import aiohttp
|
||||||
import asyncio
|
import asyncio
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
@@ -31,62 +32,64 @@ logger.add(sys.stderr, level="DEBUG")
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
(room_url, token) = await configure()
|
async with aiohttp.ClientSession() as session:
|
||||||
transport = DailyTransport(
|
(room_url, token) = await configure(session)
|
||||||
room_url,
|
|
||||||
token,
|
transport = DailyTransport(
|
||||||
"Respond bot",
|
room_url,
|
||||||
DailyParams(
|
token,
|
||||||
audio_out_enabled=True,
|
"Respond bot",
|
||||||
audio_out_sample_rate=16000,
|
DailyParams(
|
||||||
transcription_enabled=True,
|
audio_out_enabled=True,
|
||||||
vad_enabled=True,
|
audio_out_sample_rate=16000,
|
||||||
vad_analyzer=SileroVADAnalyzer()
|
transcription_enabled=True,
|
||||||
|
vad_enabled=True,
|
||||||
|
vad_analyzer=SileroVADAnalyzer()
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
|
||||||
|
|
||||||
tts = PlayHTTTSService(
|
tts = PlayHTTTSService(
|
||||||
user_id=os.getenv("PLAYHT_USER_ID"),
|
user_id=os.getenv("PLAYHT_USER_ID"),
|
||||||
api_key=os.getenv("PLAYHT_API_KEY"),
|
api_key=os.getenv("PLAYHT_API_KEY"),
|
||||||
voice_url="s3://voice-cloning-zero-shot/801a663f-efd0-4254-98d0-5c175514c3e8/jennifer/manifest.json",
|
voice_url="s3://voice-cloning-zero-shot/801a663f-efd0-4254-98d0-5c175514c3e8/jennifer/manifest.json",
|
||||||
)
|
)
|
||||||
|
|
||||||
llm = OpenAILLMService(
|
llm = OpenAILLMService(
|
||||||
api_key=os.getenv("OPENAI_API_KEY"),
|
api_key=os.getenv("OPENAI_API_KEY"),
|
||||||
model="gpt-4o")
|
model="gpt-4o")
|
||||||
|
|
||||||
messages = [
|
messages = [
|
||||||
{
|
{
|
||||||
"role": "system",
|
"role": "system",
|
||||||
"content": "You are a helpful LLM in a WebRTC call. Your goal is to demonstrate your capabilities in a succinct way. Your output will be converted to audio so don't include special characters in your answers. Respond to what the user said in a creative and helpful way.",
|
"content": "You are a helpful LLM in a WebRTC call. Your goal is to demonstrate your capabilities in a succinct way. Your output will be converted to audio so don't include special characters in your answers. Respond to what the user said in a creative and helpful way.",
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
tma_in = LLMUserResponseAggregator(messages)
|
tma_in = LLMUserResponseAggregator(messages)
|
||||||
tma_out = LLMAssistantResponseAggregator(messages)
|
tma_out = LLMAssistantResponseAggregator(messages)
|
||||||
|
|
||||||
pipeline = Pipeline([
|
pipeline = Pipeline([
|
||||||
transport.input(), # Transport user input
|
transport.input(), # Transport user input
|
||||||
tma_in, # User responses
|
tma_in, # User responses
|
||||||
llm, # LLM
|
llm, # LLM
|
||||||
tts, # TTS
|
tts, # TTS
|
||||||
transport.output(), # Transport bot output
|
transport.output(), # Transport bot output
|
||||||
tma_out # Assistant spoken responses
|
tma_out # Assistant spoken responses
|
||||||
])
|
])
|
||||||
|
|
||||||
task = PipelineTask(pipeline, PipelineParams(allow_interruptions=True))
|
task = PipelineTask(pipeline, PipelineParams(allow_interruptions=True))
|
||||||
|
|
||||||
@transport.event_handler("on_first_participant_joined")
|
@transport.event_handler("on_first_participant_joined")
|
||||||
async def on_first_participant_joined(transport, participant):
|
async def on_first_participant_joined(transport, participant):
|
||||||
transport.capture_participant_transcription(participant["id"])
|
transport.capture_participant_transcription(participant["id"])
|
||||||
# Kick off the conversation.
|
# Kick off the conversation.
|
||||||
messages.append(
|
messages.append(
|
||||||
{"role": "system", "content": "Please introduce yourself to the user."})
|
{"role": "system", "content": "Please introduce yourself to the user."})
|
||||||
await task.queue_frames([LLMMessagesFrame(messages)])
|
await task.queue_frames([LLMMessagesFrame(messages)])
|
||||||
|
|
||||||
runner = PipelineRunner()
|
runner = PipelineRunner()
|
||||||
|
|
||||||
await runner.run(task)
|
await runner.run(task)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
# SPDX-License-Identifier: BSD 2-Clause License
|
# SPDX-License-Identifier: BSD 2-Clause License
|
||||||
#
|
#
|
||||||
|
|
||||||
|
import aiohttp
|
||||||
import asyncio
|
import asyncio
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
@@ -31,69 +32,71 @@ logger.add(sys.stderr, level="DEBUG")
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
(room_url, token) = await configure()
|
async with aiohttp.ClientSession() as session:
|
||||||
transport = DailyTransport(
|
(room_url, token) = await configure(session)
|
||||||
room_url,
|
|
||||||
token,
|
transport = DailyTransport(
|
||||||
"Respond bot",
|
room_url,
|
||||||
DailyParams(
|
token,
|
||||||
audio_out_enabled=True,
|
"Respond bot",
|
||||||
audio_out_sample_rate=16000,
|
DailyParams(
|
||||||
vad_enabled=True,
|
audio_out_enabled=True,
|
||||||
vad_analyzer=SileroVADAnalyzer(),
|
audio_out_sample_rate=16000,
|
||||||
vad_audio_passthrough=True,
|
vad_enabled=True,
|
||||||
|
vad_analyzer=SileroVADAnalyzer(),
|
||||||
|
vad_audio_passthrough=True,
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
|
||||||
|
|
||||||
stt = AzureSTTService(
|
stt = AzureSTTService(
|
||||||
api_key=os.getenv("AZURE_SPEECH_API_KEY"),
|
api_key=os.getenv("AZURE_SPEECH_API_KEY"),
|
||||||
region=os.getenv("AZURE_SPEECH_REGION"),
|
region=os.getenv("AZURE_SPEECH_REGION"),
|
||||||
)
|
)
|
||||||
|
|
||||||
tts = AzureTTSService(
|
tts = AzureTTSService(
|
||||||
api_key=os.getenv("AZURE_SPEECH_API_KEY"),
|
api_key=os.getenv("AZURE_SPEECH_API_KEY"),
|
||||||
region=os.getenv("AZURE_SPEECH_REGION"),
|
region=os.getenv("AZURE_SPEECH_REGION"),
|
||||||
)
|
)
|
||||||
|
|
||||||
llm = AzureLLMService(
|
llm = AzureLLMService(
|
||||||
api_key=os.getenv("AZURE_CHATGPT_API_KEY"),
|
api_key=os.getenv("AZURE_CHATGPT_API_KEY"),
|
||||||
endpoint=os.getenv("AZURE_CHATGPT_ENDPOINT"),
|
endpoint=os.getenv("AZURE_CHATGPT_ENDPOINT"),
|
||||||
model=os.getenv("AZURE_CHATGPT_MODEL"),
|
model=os.getenv("AZURE_CHATGPT_MODEL"),
|
||||||
)
|
)
|
||||||
|
|
||||||
messages = [
|
messages = [
|
||||||
{
|
{
|
||||||
"role": "system",
|
"role": "system",
|
||||||
"content": "You are a helpful LLM in a WebRTC call. Your goal is to demonstrate your capabilities in a succinct way. Your output will be converted to audio so don't include special characters in your answers. Respond to what the user said in a creative and helpful way.",
|
"content": "You are a helpful LLM in a WebRTC call. Your goal is to demonstrate your capabilities in a succinct way. Your output will be converted to audio so don't include special characters in your answers. Respond to what the user said in a creative and helpful way.",
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
tma_in = LLMUserResponseAggregator(messages)
|
tma_in = LLMUserResponseAggregator(messages)
|
||||||
tma_out = LLMAssistantResponseAggregator(messages)
|
tma_out = LLMAssistantResponseAggregator(messages)
|
||||||
|
|
||||||
pipeline = Pipeline([
|
pipeline = Pipeline([
|
||||||
transport.input(), # Transport user input
|
transport.input(), # Transport user input
|
||||||
stt, # STT
|
stt, # STT
|
||||||
tma_in, # User responses
|
tma_in, # User responses
|
||||||
llm, # LLM
|
llm, # LLM
|
||||||
tts, # TTS
|
tts, # TTS
|
||||||
transport.output(), # Transport bot output
|
transport.output(), # Transport bot output
|
||||||
tma_out # Assistant spoken responses
|
tma_out # Assistant spoken responses
|
||||||
])
|
])
|
||||||
|
|
||||||
task = PipelineTask(pipeline, PipelineParams(allow_interruptions=True))
|
task = PipelineTask(pipeline, PipelineParams(allow_interruptions=True))
|
||||||
|
|
||||||
@transport.event_handler("on_first_participant_joined")
|
@transport.event_handler("on_first_participant_joined")
|
||||||
async def on_first_participant_joined(transport, participant):
|
async def on_first_participant_joined(transport, participant):
|
||||||
transport.capture_participant_transcription(participant["id"])
|
transport.capture_participant_transcription(participant["id"])
|
||||||
# Kick off the conversation.
|
# Kick off the conversation.
|
||||||
messages.append(
|
messages.append(
|
||||||
{"role": "system", "content": "Please introduce yourself to the user."})
|
{"role": "system", "content": "Please introduce yourself to the user."})
|
||||||
await task.queue_frames([LLMMessagesFrame(messages)])
|
await task.queue_frames([LLMMessagesFrame(messages)])
|
||||||
|
|
||||||
runner = PipelineRunner()
|
runner = PipelineRunner()
|
||||||
|
|
||||||
await runner.run(task)
|
await runner.run(task)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
# SPDX-License-Identifier: BSD 2-Clause License
|
# SPDX-License-Identifier: BSD 2-Clause License
|
||||||
#
|
#
|
||||||
|
|
||||||
|
import aiohttp
|
||||||
import asyncio
|
import asyncio
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
@@ -31,62 +32,63 @@ logger.add(sys.stderr, level="DEBUG")
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
(room_url, token) = await configure()
|
async with aiohttp.ClientSession() as session:
|
||||||
|
(room_url, token) = await configure(session)
|
||||||
|
|
||||||
transport = DailyTransport(
|
transport = DailyTransport(
|
||||||
room_url,
|
room_url,
|
||||||
token,
|
token,
|
||||||
"Respond bot",
|
"Respond bot",
|
||||||
DailyParams(
|
DailyParams(
|
||||||
audio_out_enabled=True,
|
audio_out_enabled=True,
|
||||||
audio_out_sample_rate=24000,
|
audio_out_sample_rate=24000,
|
||||||
transcription_enabled=True,
|
transcription_enabled=True,
|
||||||
vad_enabled=True,
|
vad_enabled=True,
|
||||||
vad_analyzer=SileroVADAnalyzer()
|
vad_analyzer=SileroVADAnalyzer()
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
|
||||||
|
|
||||||
tts = OpenAITTSService(
|
tts = OpenAITTSService(
|
||||||
api_key=os.getenv("OPENAI_API_KEY"),
|
api_key=os.getenv("OPENAI_API_KEY"),
|
||||||
voice="alloy"
|
voice="alloy"
|
||||||
)
|
)
|
||||||
|
|
||||||
llm = OpenAILLMService(
|
llm = OpenAILLMService(
|
||||||
api_key=os.getenv("OPENAI_API_KEY"),
|
api_key=os.getenv("OPENAI_API_KEY"),
|
||||||
model="gpt-4o")
|
model="gpt-4o")
|
||||||
|
|
||||||
messages = [
|
messages = [
|
||||||
{
|
{
|
||||||
"role": "system",
|
"role": "system",
|
||||||
"content": "You are a helpful LLM in a WebRTC call. Your goal is to demonstrate your capabilities in a succinct way. Your output will be converted to audio so don't include special characters in your answers. Respond to what the user said in a creative and helpful way.",
|
"content": "You are a helpful LLM in a WebRTC call. Your goal is to demonstrate your capabilities in a succinct way. Your output will be converted to audio so don't include special characters in your answers. Respond to what the user said in a creative and helpful way.",
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
tma_in = LLMUserResponseAggregator(messages)
|
tma_in = LLMUserResponseAggregator(messages)
|
||||||
tma_out = LLMAssistantResponseAggregator(messages)
|
tma_out = LLMAssistantResponseAggregator(messages)
|
||||||
|
|
||||||
pipeline = Pipeline([
|
pipeline = Pipeline([
|
||||||
transport.input(), # Transport user input
|
transport.input(), # Transport user input
|
||||||
tma_in, # User responses
|
tma_in, # User responses
|
||||||
llm, # LLM
|
llm, # LLM
|
||||||
tts, # TTS
|
tts, # TTS
|
||||||
transport.output(), # Transport bot output
|
transport.output(), # Transport bot output
|
||||||
tma_out # Assistant spoken responses
|
tma_out # Assistant spoken responses
|
||||||
])
|
])
|
||||||
|
|
||||||
task = PipelineTask(pipeline, PipelineParams(allow_interruptions=True))
|
task = PipelineTask(pipeline, PipelineParams(allow_interruptions=True))
|
||||||
|
|
||||||
@transport.event_handler("on_first_participant_joined")
|
@transport.event_handler("on_first_participant_joined")
|
||||||
async def on_first_participant_joined(transport, participant):
|
async def on_first_participant_joined(transport, participant):
|
||||||
transport.capture_participant_transcription(participant["id"])
|
transport.capture_participant_transcription(participant["id"])
|
||||||
# Kick off the conversation.
|
# Kick off the conversation.
|
||||||
messages.append(
|
messages.append(
|
||||||
{"role": "system", "content": "Please introduce yourself to the user."})
|
{"role": "system", "content": "Please introduce yourself to the user."})
|
||||||
await task.queue_frames([LLMMessagesFrame(messages)])
|
await task.queue_frames([LLMMessagesFrame(messages)])
|
||||||
|
|
||||||
runner = PipelineRunner()
|
runner = PipelineRunner()
|
||||||
|
|
||||||
await runner.run(task)
|
await runner.run(task)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -35,9 +35,9 @@ logger.add(sys.stderr, level="DEBUG")
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
(room_url, token) = await configure()
|
|
||||||
|
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
|
(room_url, token) = await configure(session)
|
||||||
|
|
||||||
transport = DailyTransport(
|
transport = DailyTransport(
|
||||||
room_url,
|
room_url,
|
||||||
token,
|
token,
|
||||||
|
|||||||
@@ -33,9 +33,9 @@ logger.add(sys.stderr, level="DEBUG")
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
(room_url, token) = await configure()
|
|
||||||
|
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
|
(room_url, token) = await configure(session)
|
||||||
|
|
||||||
transport = DailyTransport(
|
transport = DailyTransport(
|
||||||
room_url,
|
room_url,
|
||||||
token,
|
token,
|
||||||
|
|||||||
@@ -34,9 +34,9 @@ logger.add(sys.stderr, level="DEBUG")
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
(room_url, token) = await configure()
|
|
||||||
|
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
|
(room_url, token) = await configure(session)
|
||||||
|
|
||||||
transport = DailyTransport(
|
transport = DailyTransport(
|
||||||
room_url,
|
room_url,
|
||||||
token,
|
token,
|
||||||
|
|||||||
@@ -23,9 +23,9 @@ logger.setLevel(logging.DEBUG)
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
(room_url, _) = await configure()
|
|
||||||
|
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
|
(room_url, _) = await configure(session)
|
||||||
|
|
||||||
transport = DailyTransport(
|
transport = DailyTransport(
|
||||||
room_url,
|
room_url,
|
||||||
None,
|
None,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
# SPDX-License-Identifier: BSD 2-Clause License
|
# SPDX-License-Identifier: BSD 2-Clause License
|
||||||
#
|
#
|
||||||
|
|
||||||
|
import aiohttp
|
||||||
import asyncio
|
import asyncio
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
@@ -24,31 +25,32 @@ logger.add(sys.stderr, level="DEBUG")
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
(room_url, token) = await configure()
|
async with aiohttp.ClientSession() as session:
|
||||||
|
(room_url, token) = await configure(session)
|
||||||
|
|
||||||
transport = DailyTransport(
|
transport = DailyTransport(
|
||||||
room_url, token, "Test",
|
room_url, token, "Test",
|
||||||
DailyParams(
|
DailyParams(
|
||||||
audio_in_enabled=True,
|
audio_in_enabled=True,
|
||||||
audio_out_enabled=True,
|
audio_out_enabled=True,
|
||||||
camera_out_enabled=True,
|
camera_out_enabled=True,
|
||||||
camera_out_is_live=True,
|
camera_out_is_live=True,
|
||||||
camera_out_width=1280,
|
camera_out_width=1280,
|
||||||
camera_out_height=720
|
camera_out_height=720
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
|
||||||
|
|
||||||
@transport.event_handler("on_first_participant_joined")
|
@transport.event_handler("on_first_participant_joined")
|
||||||
async def on_first_participant_joined(transport, participant):
|
async def on_first_participant_joined(transport, participant):
|
||||||
transport.capture_participant_video(participant["id"])
|
transport.capture_participant_video(participant["id"])
|
||||||
|
|
||||||
pipeline = Pipeline([transport.input(), transport.output()])
|
pipeline = Pipeline([transport.input(), transport.output()])
|
||||||
|
|
||||||
runner = PipelineRunner()
|
runner = PipelineRunner()
|
||||||
|
|
||||||
task = PipelineTask(pipeline)
|
task = PipelineTask(pipeline)
|
||||||
|
|
||||||
await runner.run(task)
|
await runner.run(task)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
# SPDX-License-Identifier: BSD 2-Clause License
|
# SPDX-License-Identifier: BSD 2-Clause License
|
||||||
#
|
#
|
||||||
|
|
||||||
|
import aiohttp
|
||||||
import asyncio
|
import asyncio
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
@@ -28,39 +29,42 @@ logger.add(sys.stderr, level="DEBUG")
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
(room_url, token) = await configure()
|
async with aiohttp.ClientSession() as session:
|
||||||
|
(room_url, token) = await configure(session)
|
||||||
|
|
||||||
tk_root = tk.Tk()
|
tk_root = tk.Tk()
|
||||||
tk_root.title("Local Mirror")
|
tk_root.title("Local Mirror")
|
||||||
|
|
||||||
daily_transport = DailyTransport(room_url, token, "Test", DailyParams(audio_in_enabled=True))
|
daily_transport = DailyTransport(
|
||||||
|
room_url, token, "Test", DailyParams(
|
||||||
|
audio_in_enabled=True))
|
||||||
|
|
||||||
tk_transport = TkLocalTransport(
|
tk_transport = TkLocalTransport(
|
||||||
tk_root,
|
tk_root,
|
||||||
TransportParams(
|
TransportParams(
|
||||||
audio_out_enabled=True,
|
audio_out_enabled=True,
|
||||||
camera_out_enabled=True,
|
camera_out_enabled=True,
|
||||||
camera_out_is_live=True,
|
camera_out_is_live=True,
|
||||||
camera_out_width=1280,
|
camera_out_width=1280,
|
||||||
camera_out_height=720))
|
camera_out_height=720))
|
||||||
|
|
||||||
@daily_transport.event_handler("on_first_participant_joined")
|
@daily_transport.event_handler("on_first_participant_joined")
|
||||||
async def on_first_participant_joined(transport, participant):
|
async def on_first_participant_joined(transport, participant):
|
||||||
transport.capture_participant_video(participant["id"])
|
transport.capture_participant_video(participant["id"])
|
||||||
|
|
||||||
pipeline = Pipeline([daily_transport.input(), tk_transport.output()])
|
pipeline = Pipeline([daily_transport.input(), tk_transport.output()])
|
||||||
|
|
||||||
task = PipelineTask(pipeline)
|
task = PipelineTask(pipeline)
|
||||||
|
|
||||||
async def run_tk():
|
async def run_tk():
|
||||||
while not task.has_finished():
|
while not task.has_finished():
|
||||||
tk_root.update()
|
tk_root.update()
|
||||||
tk_root.update_idletasks()
|
tk_root.update_idletasks()
|
||||||
await asyncio.sleep(0.1)
|
await asyncio.sleep(0.1)
|
||||||
|
|
||||||
runner = PipelineRunner()
|
runner = PipelineRunner()
|
||||||
|
|
||||||
await asyncio.gather(runner.run(task), run_tk())
|
await asyncio.gather(runner.run(task), run_tk())
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -32,9 +32,9 @@ logger.add(sys.stderr, level="DEBUG")
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
(room_url, token) = await configure()
|
|
||||||
|
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
|
(room_url, token) = await configure(session)
|
||||||
|
|
||||||
transport = DailyTransport(
|
transport = DailyTransport(
|
||||||
room_url,
|
room_url,
|
||||||
token,
|
token,
|
||||||
|
|||||||
@@ -84,9 +84,9 @@ class InboundSoundEffectWrapper(FrameProcessor):
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
(room_url, token) = await configure()
|
|
||||||
|
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
|
(room_url, token) = await configure(session)
|
||||||
|
|
||||||
transport = DailyTransport(
|
transport = DailyTransport(
|
||||||
room_url,
|
room_url,
|
||||||
token,
|
token,
|
||||||
|
|||||||
@@ -50,9 +50,9 @@ class UserImageRequester(FrameProcessor):
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
(room_url, token) = await configure()
|
|
||||||
|
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
|
(room_url, token) = await configure(session)
|
||||||
|
|
||||||
transport = DailyTransport(
|
transport = DailyTransport(
|
||||||
room_url,
|
room_url,
|
||||||
token,
|
token,
|
||||||
|
|||||||
@@ -50,9 +50,9 @@ class UserImageRequester(FrameProcessor):
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
(room_url, token) = await configure()
|
|
||||||
|
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
|
(room_url, token) = await configure(session)
|
||||||
|
|
||||||
transport = DailyTransport(
|
transport = DailyTransport(
|
||||||
room_url,
|
room_url,
|
||||||
token,
|
token,
|
||||||
|
|||||||
@@ -50,9 +50,9 @@ class UserImageRequester(FrameProcessor):
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
(room_url, token) = await configure()
|
|
||||||
|
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
|
(room_url, token) = await configure(session)
|
||||||
|
|
||||||
transport = DailyTransport(
|
transport = DailyTransport(
|
||||||
room_url,
|
room_url,
|
||||||
token,
|
token,
|
||||||
|
|||||||
@@ -50,9 +50,9 @@ class UserImageRequester(FrameProcessor):
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
(room_url, token) = await configure()
|
|
||||||
|
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
|
(room_url, token) = await configure(session)
|
||||||
|
|
||||||
transport = DailyTransport(
|
transport = DailyTransport(
|
||||||
room_url,
|
room_url,
|
||||||
token,
|
token,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
# SPDX-License-Identifier: BSD 2-Clause License
|
# SPDX-License-Identifier: BSD 2-Clause License
|
||||||
#
|
#
|
||||||
|
|
||||||
|
import aiohttp
|
||||||
import asyncio
|
import asyncio
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
@@ -36,22 +37,23 @@ class TranscriptionLogger(FrameProcessor):
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
(room_url, _) = await configure()
|
async with aiohttp.ClientSession() as session:
|
||||||
|
(room_url, _) = await configure(session)
|
||||||
|
|
||||||
transport = DailyTransport(room_url, None, "Transcription bot",
|
transport = DailyTransport(room_url, None, "Transcription bot",
|
||||||
DailyParams(audio_in_enabled=True))
|
DailyParams(audio_in_enabled=True))
|
||||||
|
|
||||||
stt = WhisperSTTService()
|
stt = WhisperSTTService()
|
||||||
|
|
||||||
tl = TranscriptionLogger()
|
tl = TranscriptionLogger()
|
||||||
|
|
||||||
pipeline = Pipeline([transport.input(), stt, tl])
|
pipeline = Pipeline([transport.input(), stt, tl])
|
||||||
|
|
||||||
task = PipelineTask(pipeline)
|
task = PipelineTask(pipeline)
|
||||||
|
|
||||||
runner = PipelineRunner()
|
runner = PipelineRunner()
|
||||||
|
|
||||||
await runner.run(task)
|
await runner.run(task)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
# SPDX-License-Identifier: BSD 2-Clause License
|
# SPDX-License-Identifier: BSD 2-Clause License
|
||||||
#
|
#
|
||||||
|
|
||||||
|
import aiohttp
|
||||||
import asyncio
|
import asyncio
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
@@ -37,22 +38,23 @@ class TranscriptionLogger(FrameProcessor):
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
(room_url, _) = await configure()
|
async with aiohttp.ClientSession() as session:
|
||||||
|
(room_url, _) = await configure(session)
|
||||||
|
|
||||||
transport = DailyTransport(room_url, None, "Transcription bot",
|
transport = DailyTransport(room_url, None, "Transcription bot",
|
||||||
DailyParams(audio_in_enabled=True))
|
DailyParams(audio_in_enabled=True))
|
||||||
|
|
||||||
stt = DeepgramSTTService(api_key=os.getenv("DEEPGRAM_API_KEY"))
|
stt = DeepgramSTTService(api_key=os.getenv("DEEPGRAM_API_KEY"))
|
||||||
|
|
||||||
tl = TranscriptionLogger()
|
tl = TranscriptionLogger()
|
||||||
|
|
||||||
pipeline = Pipeline([transport.input(), stt, tl])
|
pipeline = Pipeline([transport.input(), stt, tl])
|
||||||
|
|
||||||
task = PipelineTask(pipeline)
|
task = PipelineTask(pipeline)
|
||||||
|
|
||||||
runner = PipelineRunner()
|
runner = PipelineRunner()
|
||||||
|
|
||||||
await runner.run(task)
|
await runner.run(task)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -45,9 +45,9 @@ async def fetch_weather_from_api(llm, args):
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
(room_url, token) = await configure()
|
|
||||||
|
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
|
(room_url, token) = await configure(session)
|
||||||
|
|
||||||
transport = DailyTransport(
|
transport = DailyTransport(
|
||||||
room_url,
|
room_url,
|
||||||
token,
|
token,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
# SPDX-License-Identifier: BSD 2-Clause License
|
# SPDX-License-Identifier: BSD 2-Clause License
|
||||||
#
|
#
|
||||||
|
|
||||||
|
import aiohttp
|
||||||
import asyncio
|
import asyncio
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
@@ -58,96 +59,97 @@ async def barbershop_man_filter(frame) -> bool:
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
(room_url, token) = await configure()
|
async with aiohttp.ClientSession() as session:
|
||||||
|
(room_url, token) = await configure(session)
|
||||||
|
|
||||||
transport = DailyTransport(
|
transport = DailyTransport(
|
||||||
room_url,
|
room_url,
|
||||||
token,
|
token,
|
||||||
"Pipecat",
|
"Pipecat",
|
||||||
DailyParams(
|
DailyParams(
|
||||||
audio_out_enabled=True,
|
audio_out_enabled=True,
|
||||||
transcription_enabled=True,
|
transcription_enabled=True,
|
||||||
vad_enabled=True,
|
vad_enabled=True,
|
||||||
vad_analyzer=SileroVADAnalyzer()
|
vad_analyzer=SileroVADAnalyzer()
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
|
||||||
|
|
||||||
news_lady = CartesiaTTSService(
|
news_lady = CartesiaTTSService(
|
||||||
api_key=os.getenv("CARTESIA_API_KEY"),
|
api_key=os.getenv("CARTESIA_API_KEY"),
|
||||||
voice_id="bf991597-6c13-47e4-8411-91ec2de5c466", # Newslady
|
voice_id="bf991597-6c13-47e4-8411-91ec2de5c466", # Newslady
|
||||||
)
|
)
|
||||||
|
|
||||||
british_lady = CartesiaTTSService(
|
british_lady = CartesiaTTSService(
|
||||||
api_key=os.getenv("CARTESIA_API_KEY"),
|
api_key=os.getenv("CARTESIA_API_KEY"),
|
||||||
voice_id="79a125e8-cd45-4c13-8a67-188112f4dd22", # British Lady
|
voice_id="79a125e8-cd45-4c13-8a67-188112f4dd22", # British Lady
|
||||||
)
|
)
|
||||||
|
|
||||||
barbershop_man = CartesiaTTSService(
|
barbershop_man = CartesiaTTSService(
|
||||||
api_key=os.getenv("CARTESIA_API_KEY"),
|
api_key=os.getenv("CARTESIA_API_KEY"),
|
||||||
voice_id="a0e99841-438c-4a64-b679-ae501e7d6091", # Barbershop Man
|
voice_id="a0e99841-438c-4a64-b679-ae501e7d6091", # Barbershop Man
|
||||||
)
|
)
|
||||||
|
|
||||||
llm = OpenAILLMService(
|
llm = OpenAILLMService(
|
||||||
api_key=os.getenv("OPENAI_API_KEY"),
|
api_key=os.getenv("OPENAI_API_KEY"),
|
||||||
model="gpt-4o")
|
model="gpt-4o")
|
||||||
llm.register_function("switch_voice", switch_voice)
|
llm.register_function("switch_voice", switch_voice)
|
||||||
|
|
||||||
tools = [
|
tools = [
|
||||||
ChatCompletionToolParam(
|
ChatCompletionToolParam(
|
||||||
type="function",
|
type="function",
|
||||||
function={
|
function={
|
||||||
"name": "switch_voice",
|
"name": "switch_voice",
|
||||||
"description": "Switch your voice only when the user asks you to",
|
"description": "Switch your voice only when the user asks you to",
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"voice": {
|
"voice": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "The voice the user wants you to use",
|
"description": "The voice the user wants you to use",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
"required": ["voice"],
|
||||||
},
|
},
|
||||||
"required": ["voice"],
|
})]
|
||||||
},
|
messages = [
|
||||||
})]
|
|
||||||
messages = [
|
|
||||||
{
|
|
||||||
"role": "system",
|
|
||||||
"content": "You are a helpful LLM in a WebRTC call. Your goal is to demonstrate your capabilities. Respond to what the user said in a creative and helpful way. Your output should not include non-alphanumeric characters. You can do the following voices: 'News Lady', 'British Lady' and 'Barbershop Man'.",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
context = OpenAILLMContext(messages, tools)
|
|
||||||
tma_in = LLMUserContextAggregator(context)
|
|
||||||
tma_out = LLMAssistantContextAggregator(context)
|
|
||||||
|
|
||||||
pipeline = Pipeline([
|
|
||||||
transport.input(), # Transport user input
|
|
||||||
tma_in, # User responses
|
|
||||||
llm, # LLM
|
|
||||||
ParallelPipeline( # TTS (one of the following vocies)
|
|
||||||
[FunctionFilter(news_lady_filter), news_lady], # News Lady voice
|
|
||||||
[FunctionFilter(british_lady_filter), british_lady], # British Lady voice
|
|
||||||
[FunctionFilter(barbershop_man_filter), barbershop_man], # Barbershop Man voice
|
|
||||||
),
|
|
||||||
transport.output(), # Transport bot output
|
|
||||||
tma_out # Assistant spoken responses
|
|
||||||
])
|
|
||||||
|
|
||||||
task = PipelineTask(pipeline, PipelineParams(allow_interruptions=True))
|
|
||||||
|
|
||||||
@transport.event_handler("on_first_participant_joined")
|
|
||||||
async def on_first_participant_joined(transport, participant):
|
|
||||||
transport.capture_participant_transcription(participant["id"])
|
|
||||||
# Kick off the conversation.
|
|
||||||
messages.append(
|
|
||||||
{
|
{
|
||||||
"role": "system",
|
"role": "system",
|
||||||
"content": f"Please introduce yourself to the user and let them know the voices you can do. Your initial responses should be as if you were a {current_voice}."})
|
"content": "You are a helpful LLM in a WebRTC call. Your goal is to demonstrate your capabilities. Respond to what the user said in a creative and helpful way. Your output should not include non-alphanumeric characters. You can do the following voices: 'News Lady', 'British Lady' and 'Barbershop Man'.",
|
||||||
await task.queue_frames([LLMMessagesFrame(messages)])
|
},
|
||||||
|
]
|
||||||
|
|
||||||
runner = PipelineRunner()
|
context = OpenAILLMContext(messages, tools)
|
||||||
|
tma_in = LLMUserContextAggregator(context)
|
||||||
|
tma_out = LLMAssistantContextAggregator(context)
|
||||||
|
|
||||||
await runner.run(task)
|
pipeline = Pipeline([
|
||||||
|
transport.input(), # Transport user input
|
||||||
|
tma_in, # User responses
|
||||||
|
llm, # LLM
|
||||||
|
ParallelPipeline( # TTS (one of the following vocies)
|
||||||
|
[FunctionFilter(news_lady_filter), news_lady], # News Lady voice
|
||||||
|
[FunctionFilter(british_lady_filter), british_lady], # British Lady voice
|
||||||
|
[FunctionFilter(barbershop_man_filter), barbershop_man], # Barbershop Man voice
|
||||||
|
),
|
||||||
|
transport.output(), # Transport bot output
|
||||||
|
tma_out # Assistant spoken responses
|
||||||
|
])
|
||||||
|
|
||||||
|
task = PipelineTask(pipeline, PipelineParams(allow_interruptions=True))
|
||||||
|
|
||||||
|
@transport.event_handler("on_first_participant_joined")
|
||||||
|
async def on_first_participant_joined(transport, participant):
|
||||||
|
transport.capture_participant_transcription(participant["id"])
|
||||||
|
# Kick off the conversation.
|
||||||
|
messages.append(
|
||||||
|
{
|
||||||
|
"role": "system",
|
||||||
|
"content": f"Please introduce yourself to the user and let them know the voices you can do. Your initial responses should be as if you were a {current_voice}."})
|
||||||
|
await task.queue_frames([LLMMessagesFrame(messages)])
|
||||||
|
|
||||||
|
runner = PipelineRunner()
|
||||||
|
|
||||||
|
await runner.run(task)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -56,9 +56,9 @@ async def spanish_filter(frame) -> bool:
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
(room_url, token) = await configure()
|
|
||||||
|
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
|
(room_url, token) = await configure(session)
|
||||||
|
|
||||||
transport = DailyTransport(
|
transport = DailyTransport(
|
||||||
room_url,
|
room_url,
|
||||||
token,
|
token,
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import asyncio
|
|||||||
import aiohttp
|
import aiohttp
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import json
|
|
||||||
|
|
||||||
from pipecat.frames.frames import LLMMessagesFrame
|
from pipecat.frames.frames import LLMMessagesFrame
|
||||||
from pipecat.pipeline.pipeline import Pipeline
|
from pipecat.pipeline.pipeline import Pipeline
|
||||||
@@ -33,9 +32,9 @@ logger.add(sys.stderr, level="DEBUG")
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
(room_url, token) = await configure()
|
|
||||||
|
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
|
(room_url, token) = await configure(session)
|
||||||
|
|
||||||
transport = DailyTransport(
|
transport = DailyTransport(
|
||||||
room_url,
|
room_url,
|
||||||
token,
|
token,
|
||||||
|
|||||||
@@ -34,9 +34,9 @@ logger.add(sys.stderr, level="DEBUG")
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
(room_url, token) = await configure()
|
|
||||||
|
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
|
(room_url, token) = await configure(session)
|
||||||
|
|
||||||
transport = DailyTransport(
|
transport = DailyTransport(
|
||||||
room_url,
|
room_url,
|
||||||
token,
|
token,
|
||||||
|
|||||||
@@ -4,13 +4,14 @@
|
|||||||
# SPDX-License-Identifier: BSD 2-Clause License
|
# SPDX-License-Identifier: BSD 2-Clause License
|
||||||
#
|
#
|
||||||
|
|
||||||
|
import aiohttp
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from pipecat.transports.services.helpers.daily_rest import DailyRESTHelper
|
from pipecat.transports.services.helpers.daily_rest import DailyRESTHelper
|
||||||
|
|
||||||
|
|
||||||
async def configure():
|
async def configure(aiohttp_session: aiohttp.ClientSession):
|
||||||
parser = argparse.ArgumentParser(description="Daily AI SDK Bot Sample")
|
parser = argparse.ArgumentParser(description="Daily AI SDK Bot Sample")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-u",
|
"-u",
|
||||||
@@ -38,7 +39,10 @@ async def configure():
|
|||||||
if not key:
|
if not key:
|
||||||
raise Exception("No Daily API key specified. use the -k/--apikey option from the command line, or set DAILY_API_KEY in your environment to specify a Daily API key, available from https://dashboard.daily.co/developers.")
|
raise Exception("No Daily API key specified. use the -k/--apikey option from the command line, or set DAILY_API_KEY in your environment to specify a Daily API key, available from https://dashboard.daily.co/developers.")
|
||||||
|
|
||||||
daily_rest_helper = DailyRESTHelper(key, os.getenv("DAILY_API_URL", "https://api.daily.co/v1"))
|
daily_rest_helper = DailyRESTHelper(
|
||||||
|
daily_api_key=key,
|
||||||
|
daily_api_url=os.getenv("DAILY_API_URL", "https://api.daily.co/v1"),
|
||||||
|
aiohttp_session=aiohttp_session)
|
||||||
|
|
||||||
# Create a meeting token for the given room with an expiration 1 hour in
|
# Create a meeting token for the given room with an expiration 1 hour in
|
||||||
# the future.
|
# the future.
|
||||||
|
|||||||
@@ -135,8 +135,9 @@ class ImageFilterProcessor(FrameProcessor):
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
(room_url, token) = await configure()
|
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
|
(room_url, token) = await configure(session)
|
||||||
|
|
||||||
transport = DailyTransport(
|
transport = DailyTransport(
|
||||||
room_url,
|
room_url,
|
||||||
token,
|
token,
|
||||||
|
|||||||
@@ -4,13 +4,14 @@
|
|||||||
# SPDX-License-Identifier: BSD 2-Clause License
|
# SPDX-License-Identifier: BSD 2-Clause License
|
||||||
#
|
#
|
||||||
|
|
||||||
|
import aiohttp
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from pipecat.transports.services.helpers.daily_rest import DailyRESTHelper
|
from pipecat.transports.services.helpers.daily_rest import DailyRESTHelper
|
||||||
|
|
||||||
|
|
||||||
async def configure():
|
async def configure(aiohttp_session: aiohttp.ClientSession):
|
||||||
parser = argparse.ArgumentParser(description="Daily AI SDK Bot Sample")
|
parser = argparse.ArgumentParser(description="Daily AI SDK Bot Sample")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-u",
|
"-u",
|
||||||
@@ -38,7 +39,11 @@ async def configure():
|
|||||||
if not key:
|
if not key:
|
||||||
raise Exception("No Daily API key specified. use the -k/--apikey option from the command line, or set DAILY_API_KEY in your environment to specify a Daily API key, available from https://dashboard.daily.co/developers.")
|
raise Exception("No Daily API key specified. use the -k/--apikey option from the command line, or set DAILY_API_KEY in your environment to specify a Daily API key, available from https://dashboard.daily.co/developers.")
|
||||||
|
|
||||||
daily_rest_helper = DailyRESTHelper(key, os.getenv("DAILY_API_URL", "https://api.daily.co/v1"))
|
daily_rest_helper = DailyRESTHelper(
|
||||||
|
daily_api_key=key,
|
||||||
|
daily_api_url=os.getenv("DAILY_API_URL", "https://api.daily.co/v1"),
|
||||||
|
aiohttp_session=aiohttp_session
|
||||||
|
)
|
||||||
|
|
||||||
# Create a meeting token for the given room with an expiration 1 hour in
|
# Create a meeting token for the given room with an expiration 1 hour in
|
||||||
# the future.
|
# the future.
|
||||||
|
|||||||
@@ -4,10 +4,12 @@
|
|||||||
# SPDX-License-Identifier: BSD 2-Clause License
|
# SPDX-License-Identifier: BSD 2-Clause License
|
||||||
#
|
#
|
||||||
|
|
||||||
|
import aiohttp
|
||||||
import os
|
import os
|
||||||
import argparse
|
import argparse
|
||||||
import subprocess
|
import subprocess
|
||||||
import atexit
|
|
||||||
|
from contextlib import asynccontextmanager
|
||||||
|
|
||||||
from fastapi import FastAPI, Request, HTTPException
|
from fastapi import FastAPI, Request, HTTPException
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
@@ -20,9 +22,7 @@ MAX_BOTS_PER_ROOM = 1
|
|||||||
# Bot sub-process dict for status reporting and concurrency control
|
# Bot sub-process dict for status reporting and concurrency control
|
||||||
bot_procs = {}
|
bot_procs = {}
|
||||||
|
|
||||||
daily_rest_helper = DailyRESTHelper(
|
daily_helpers = {}
|
||||||
os.getenv("DAILY_API_KEY", ""),
|
|
||||||
os.getenv("DAILY_API_URL", 'https://api.daily.co/v1'))
|
|
||||||
|
|
||||||
|
|
||||||
def cleanup():
|
def cleanup():
|
||||||
@@ -33,10 +33,19 @@ def cleanup():
|
|||||||
proc.wait()
|
proc.wait()
|
||||||
|
|
||||||
|
|
||||||
atexit.register(cleanup)
|
@asynccontextmanager
|
||||||
|
async def lifespan(app: FastAPI):
|
||||||
|
aiohttp_session = aiohttp.ClientSession()
|
||||||
|
daily_helpers["rest"] = DailyRESTHelper(
|
||||||
|
daily_api_key=os.getenv("DAILY_API_KEY", ""),
|
||||||
|
daily_api_url=os.getenv("DAILY_API_URL", 'https://api.daily.co/v1'),
|
||||||
|
aiohttp_session=aiohttp_session
|
||||||
|
)
|
||||||
|
yield
|
||||||
|
await aiohttp_session.close()
|
||||||
|
cleanup()
|
||||||
|
|
||||||
|
app = FastAPI(lifespan=lifespan)
|
||||||
app = FastAPI()
|
|
||||||
|
|
||||||
app.add_middleware(
|
app.add_middleware(
|
||||||
CORSMiddleware,
|
CORSMiddleware,
|
||||||
@@ -50,7 +59,7 @@ app.add_middleware(
|
|||||||
@app.get("/start")
|
@app.get("/start")
|
||||||
async def start_agent(request: Request):
|
async def start_agent(request: Request):
|
||||||
print(f"!!! Creating room")
|
print(f"!!! Creating room")
|
||||||
room = await daily_rest_helper.create_room(DailyRoomParams())
|
room = await daily_helpers["rest"].create_room(DailyRoomParams())
|
||||||
print(f"!!! Room URL: {room.url}")
|
print(f"!!! Room URL: {room.url}")
|
||||||
# Ensure the room property is present
|
# Ensure the room property is present
|
||||||
if not room.url:
|
if not room.url:
|
||||||
@@ -66,7 +75,7 @@ async def start_agent(request: Request):
|
|||||||
status_code=500, detail=f"Max bot limited reach for room: {room.url}")
|
status_code=500, detail=f"Max bot limited reach for room: {room.url}")
|
||||||
|
|
||||||
# Get the token for the room
|
# Get the token for the room
|
||||||
token = await daily_rest_helper.get_token(room.url)
|
token = await daily_helpers["rest"].get_token(room.url)
|
||||||
|
|
||||||
if not token:
|
if not token:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
|
|||||||
@@ -258,8 +258,9 @@ class IntakeProcessor:
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
(room_url, token) = await configure()
|
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
|
(room_url, token) = await configure(session)
|
||||||
|
|
||||||
transport = DailyTransport(
|
transport = DailyTransport(
|
||||||
room_url,
|
room_url,
|
||||||
token,
|
token,
|
||||||
|
|||||||
@@ -4,13 +4,14 @@
|
|||||||
# SPDX-License-Identifier: BSD 2-Clause License
|
# SPDX-License-Identifier: BSD 2-Clause License
|
||||||
#
|
#
|
||||||
|
|
||||||
|
import aiohttp
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from pipecat.transports.services.helpers.daily_rest import DailyRESTHelper
|
from pipecat.transports.services.helpers.daily_rest import DailyRESTHelper
|
||||||
|
|
||||||
|
|
||||||
async def configure():
|
async def configure(aiohttp_session: aiohttp.ClientSession):
|
||||||
parser = argparse.ArgumentParser(description="Daily AI SDK Bot Sample")
|
parser = argparse.ArgumentParser(description="Daily AI SDK Bot Sample")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-u",
|
"-u",
|
||||||
@@ -38,7 +39,10 @@ async def configure():
|
|||||||
if not key:
|
if not key:
|
||||||
raise Exception("No Daily API key specified. use the -k/--apikey option from the command line, or set DAILY_API_KEY in your environment to specify a Daily API key, available from https://dashboard.daily.co/developers.")
|
raise Exception("No Daily API key specified. use the -k/--apikey option from the command line, or set DAILY_API_KEY in your environment to specify a Daily API key, available from https://dashboard.daily.co/developers.")
|
||||||
|
|
||||||
daily_rest_helper = DailyRESTHelper(key, os.getenv("DAILY_API_URL", "https://api.daily.co/v1"))
|
daily_rest_helper = DailyRESTHelper(
|
||||||
|
daily_api_key=key,
|
||||||
|
daily_api_url=os.getenv("DAILY_API_URL", "https://api.daily.co/v1"),
|
||||||
|
aiohttp_session=aiohttp_session)
|
||||||
|
|
||||||
# Create a meeting token for the given room with an expiration 1 hour in
|
# Create a meeting token for the given room with an expiration 1 hour in
|
||||||
# the future.
|
# the future.
|
||||||
|
|||||||
@@ -4,10 +4,12 @@
|
|||||||
# SPDX-License-Identifier: BSD 2-Clause License
|
# SPDX-License-Identifier: BSD 2-Clause License
|
||||||
#
|
#
|
||||||
|
|
||||||
|
import aiohttp
|
||||||
import os
|
import os
|
||||||
import argparse
|
import argparse
|
||||||
import subprocess
|
import subprocess
|
||||||
import atexit
|
|
||||||
|
from contextlib import asynccontextmanager
|
||||||
|
|
||||||
from fastapi import FastAPI, Request, HTTPException
|
from fastapi import FastAPI, Request, HTTPException
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
@@ -20,9 +22,7 @@ MAX_BOTS_PER_ROOM = 1
|
|||||||
# Bot sub-process dict for status reporting and concurrency control
|
# Bot sub-process dict for status reporting and concurrency control
|
||||||
bot_procs = {}
|
bot_procs = {}
|
||||||
|
|
||||||
daily_rest_helper = DailyRESTHelper(
|
daily_helpers = {}
|
||||||
os.getenv("DAILY_API_KEY", ""),
|
|
||||||
os.getenv("DAILY_API_URL", 'https://api.daily.co/v1'))
|
|
||||||
|
|
||||||
|
|
||||||
def cleanup():
|
def cleanup():
|
||||||
@@ -33,10 +33,19 @@ def cleanup():
|
|||||||
proc.wait()
|
proc.wait()
|
||||||
|
|
||||||
|
|
||||||
atexit.register(cleanup)
|
@asynccontextmanager
|
||||||
|
async def lifespan(app: FastAPI):
|
||||||
|
aiohttp_session = aiohttp.ClientSession()
|
||||||
|
daily_helpers["rest"] = DailyRESTHelper(
|
||||||
|
daily_api_key=os.getenv("DAILY_API_KEY", ""),
|
||||||
|
daily_api_url=os.getenv("DAILY_API_URL", 'https://api.daily.co/v1'),
|
||||||
|
aiohttp_session=aiohttp_session
|
||||||
|
)
|
||||||
|
yield
|
||||||
|
await aiohttp_session.close()
|
||||||
|
cleanup()
|
||||||
|
|
||||||
|
app = FastAPI(lifespan=lifespan)
|
||||||
app = FastAPI()
|
|
||||||
|
|
||||||
app.add_middleware(
|
app.add_middleware(
|
||||||
CORSMiddleware,
|
CORSMiddleware,
|
||||||
@@ -50,7 +59,7 @@ app.add_middleware(
|
|||||||
@app.get("/start")
|
@app.get("/start")
|
||||||
async def start_agent(request: Request):
|
async def start_agent(request: Request):
|
||||||
print(f"!!! Creating room")
|
print(f"!!! Creating room")
|
||||||
room = await daily_rest_helper.create_room(DailyRoomParams())
|
room = await daily_helpers["rest"].create_room(DailyRoomParams())
|
||||||
print(f"!!! Room URL: {room.url}")
|
print(f"!!! Room URL: {room.url}")
|
||||||
# Ensure the room property is present
|
# Ensure the room property is present
|
||||||
if not room.url:
|
if not room.url:
|
||||||
@@ -66,7 +75,7 @@ async def start_agent(request: Request):
|
|||||||
status_code=500, detail=f"Max bot limited reach for room: {room.url}")
|
status_code=500, detail=f"Max bot limited reach for room: {room.url}")
|
||||||
|
|
||||||
# Get the token for the room
|
# Get the token for the room
|
||||||
token = await daily_rest_helper.get_token(room.url)
|
token = await daily_helpers["rest"].get_token(room.url)
|
||||||
|
|
||||||
if not token:
|
if not token:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
|
|||||||
@@ -84,8 +84,9 @@ class TalkingAnimation(FrameProcessor):
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
(room_url, token) = await configure()
|
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
|
(room_url, token) = await configure(session)
|
||||||
|
|
||||||
transport = DailyTransport(
|
transport = DailyTransport(
|
||||||
room_url,
|
room_url,
|
||||||
token,
|
token,
|
||||||
|
|||||||
@@ -4,13 +4,14 @@
|
|||||||
# SPDX-License-Identifier: BSD 2-Clause License
|
# SPDX-License-Identifier: BSD 2-Clause License
|
||||||
#
|
#
|
||||||
|
|
||||||
|
import aiohttp
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from pipecat.transports.services.helpers.daily_rest import DailyRESTHelper
|
from pipecat.transports.services.helpers.daily_rest import DailyRESTHelper
|
||||||
|
|
||||||
|
|
||||||
async def configure():
|
async def configure(aiohttp_session: aiohttp.ClientSession):
|
||||||
parser = argparse.ArgumentParser(description="Daily AI SDK Bot Sample")
|
parser = argparse.ArgumentParser(description="Daily AI SDK Bot Sample")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-u",
|
"-u",
|
||||||
@@ -38,7 +39,11 @@ async def configure():
|
|||||||
if not key:
|
if not key:
|
||||||
raise Exception("No Daily API key specified. use the -k/--apikey option from the command line, or set DAILY_API_KEY in your environment to specify a Daily API key, available from https://dashboard.daily.co/developers.")
|
raise Exception("No Daily API key specified. use the -k/--apikey option from the command line, or set DAILY_API_KEY in your environment to specify a Daily API key, available from https://dashboard.daily.co/developers.")
|
||||||
|
|
||||||
daily_rest_helper = DailyRESTHelper(key, os.getenv("DAILY_API_URL", "https://api.daily.co/v1"))
|
daily_rest_helper = DailyRESTHelper(
|
||||||
|
daily_api_key=key,
|
||||||
|
daily_api_url=os.getenv("DAILY_API_URL", "https://api.daily.co/v1"),
|
||||||
|
aiohttp_session=aiohttp_session
|
||||||
|
)
|
||||||
|
|
||||||
# Create a meeting token for the given room with an expiration 1 hour in
|
# Create a meeting token for the given room with an expiration 1 hour in
|
||||||
# the future.
|
# the future.
|
||||||
|
|||||||
@@ -4,10 +4,12 @@
|
|||||||
# SPDX-License-Identifier: BSD 2-Clause License
|
# SPDX-License-Identifier: BSD 2-Clause License
|
||||||
#
|
#
|
||||||
|
|
||||||
|
import aiohttp
|
||||||
import os
|
import os
|
||||||
import argparse
|
import argparse
|
||||||
import subprocess
|
import subprocess
|
||||||
import atexit
|
|
||||||
|
from contextlib import asynccontextmanager
|
||||||
|
|
||||||
from fastapi import FastAPI, Request, HTTPException
|
from fastapi import FastAPI, Request, HTTPException
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
@@ -20,9 +22,7 @@ MAX_BOTS_PER_ROOM = 1
|
|||||||
# Bot sub-process dict for status reporting and concurrency control
|
# Bot sub-process dict for status reporting and concurrency control
|
||||||
bot_procs = {}
|
bot_procs = {}
|
||||||
|
|
||||||
daily_rest_helper = DailyRESTHelper(
|
daily_helpers = {}
|
||||||
os.getenv("DAILY_API_KEY", ""),
|
|
||||||
os.getenv("DAILY_API_URL", 'https://api.daily.co/v1'))
|
|
||||||
|
|
||||||
|
|
||||||
def cleanup():
|
def cleanup():
|
||||||
@@ -33,10 +33,19 @@ def cleanup():
|
|||||||
proc.wait()
|
proc.wait()
|
||||||
|
|
||||||
|
|
||||||
atexit.register(cleanup)
|
@asynccontextmanager
|
||||||
|
async def lifespan(app: FastAPI):
|
||||||
|
aiohttp_session = aiohttp.ClientSession()
|
||||||
|
daily_helpers["rest"] = DailyRESTHelper(
|
||||||
|
daily_api_key=os.getenv("DAILY_API_KEY", ""),
|
||||||
|
daily_api_url=os.getenv("DAILY_API_URL", 'https://api.daily.co/v1'),
|
||||||
|
aiohttp_session=aiohttp_session
|
||||||
|
)
|
||||||
|
yield
|
||||||
|
await aiohttp_session.close()
|
||||||
|
cleanup()
|
||||||
|
|
||||||
|
app = FastAPI(lifespan=lifespan)
|
||||||
app = FastAPI()
|
|
||||||
|
|
||||||
app.add_middleware(
|
app.add_middleware(
|
||||||
CORSMiddleware,
|
CORSMiddleware,
|
||||||
@@ -50,7 +59,7 @@ app.add_middleware(
|
|||||||
@app.get("/start")
|
@app.get("/start")
|
||||||
async def start_agent(request: Request):
|
async def start_agent(request: Request):
|
||||||
print(f"!!! Creating room")
|
print(f"!!! Creating room")
|
||||||
room = await daily_rest_helper.create_room(DailyRoomParams())
|
room = await daily_helpers["rest"].create_room(DailyRoomParams())
|
||||||
print(f"!!! Room URL: {room.url}")
|
print(f"!!! Room URL: {room.url}")
|
||||||
# Ensure the room property is present
|
# Ensure the room property is present
|
||||||
if not room.url:
|
if not room.url:
|
||||||
@@ -66,7 +75,7 @@ async def start_agent(request: Request):
|
|||||||
status_code=500, detail=f"Max bot limited reach for room: {room.url}")
|
status_code=500, detail=f"Max bot limited reach for room: {room.url}")
|
||||||
|
|
||||||
# Get the token for the room
|
# Get the token for the room
|
||||||
token = await daily_rest_helper.get_token(room.url)
|
token = await daily_helpers["rest"].get_token(room.url)
|
||||||
|
|
||||||
if not token:
|
if not token:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ import os
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
|
from contextlib import asynccontextmanager
|
||||||
|
|
||||||
from fastapi import FastAPI, Request, HTTPException
|
from fastapi import FastAPI, Request, HTTPException
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
from fastapi.staticfiles import StaticFiles
|
from fastapi.staticfiles import StaticFiles
|
||||||
@@ -28,12 +30,21 @@ load_dotenv(override=True)
|
|||||||
|
|
||||||
MAX_SESSION_TIME = 5 * 60 # 5 minutes
|
MAX_SESSION_TIME = 5 * 60 # 5 minutes
|
||||||
|
|
||||||
daily_rest_helper = DailyRESTHelper(
|
daily_helpers = {}
|
||||||
os.getenv("DAILY_API_KEY", ""),
|
|
||||||
os.getenv("DAILY_API_URL", 'https://api.daily.co/v1'))
|
|
||||||
|
|
||||||
|
|
||||||
app = FastAPI()
|
@asynccontextmanager
|
||||||
|
async def lifespan(app: FastAPI):
|
||||||
|
aiohttp_session = aiohttp.ClientSession()
|
||||||
|
daily_helpers["rest"] = DailyRESTHelper(
|
||||||
|
daily_api_key=os.getenv("DAILY_API_KEY", ""),
|
||||||
|
daily_api_url=os.getenv("DAILY_API_URL", 'https://api.daily.co/v1'),
|
||||||
|
aiohttp_session=aiohttp_session
|
||||||
|
)
|
||||||
|
yield
|
||||||
|
await aiohttp_session.close()
|
||||||
|
|
||||||
|
app = FastAPI(lifespan=lifespan)
|
||||||
|
|
||||||
app.add_middleware(
|
app.add_middleware(
|
||||||
CORSMiddleware,
|
CORSMiddleware,
|
||||||
@@ -78,7 +89,7 @@ async def start_bot(request: Request) -> JSONResponse:
|
|||||||
properties=DailyRoomProperties()
|
properties=DailyRoomProperties()
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
room: DailyRoomObject = await daily_rest_helper.create_room(params=params)
|
room: DailyRoomObject = await daily_helpers["rest"].create_room(params=params)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=500,
|
status_code=500,
|
||||||
@@ -86,13 +97,13 @@ async def start_bot(request: Request) -> JSONResponse:
|
|||||||
else:
|
else:
|
||||||
# Check passed room URL exists, we should assume that it already has a sip set up
|
# Check passed room URL exists, we should assume that it already has a sip set up
|
||||||
try:
|
try:
|
||||||
room: DailyRoomObject = await daily_rest_helper.get_room_from_url(room_url)
|
room: DailyRoomObject = await daily_helpers["rest"].get_room_from_url(room_url)
|
||||||
except Exception:
|
except Exception:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=500, detail=f"Room not found: {room_url}")
|
status_code=500, detail=f"Room not found: {room_url}")
|
||||||
|
|
||||||
# Give the agent a token to join the session
|
# Give the agent a token to join the session
|
||||||
token = await daily_rest_helper.get_token(room.url, MAX_SESSION_TIME)
|
token = await daily_helpers["rest"].get_token(room.url, MAX_SESSION_TIME)
|
||||||
|
|
||||||
if not room or not token:
|
if not room or not token:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
@@ -117,7 +128,7 @@ async def start_bot(request: Request) -> JSONResponse:
|
|||||||
status_code=500, detail=f"Failed to start subprocess: {e}")
|
status_code=500, detail=f"Failed to start subprocess: {e}")
|
||||||
|
|
||||||
# Grab a token for the user to join with
|
# Grab a token for the user to join with
|
||||||
user_token = await daily_rest_helper.get_token(room.url, MAX_SESSION_TIME)
|
user_token = await daily_helpers["rest"].get_token(room.url, MAX_SESSION_TIME)
|
||||||
|
|
||||||
return JSONResponse({
|
return JSONResponse({
|
||||||
"room_url": room.url,
|
"room_url": room.url,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
# SPDX-License-Identifier: BSD 2-Clause License
|
# SPDX-License-Identifier: BSD 2-Clause License
|
||||||
#
|
#
|
||||||
|
|
||||||
|
import aiohttp
|
||||||
import asyncio
|
import asyncio
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
@@ -89,57 +90,58 @@ class TranslationSubtitles(FrameProcessor):
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
(room_url, token) = await configure()
|
async with aiohttp.ClientSession() as session:
|
||||||
|
(room_url, token) = await configure(session)
|
||||||
|
|
||||||
transport = DailyTransport(
|
transport = DailyTransport(
|
||||||
room_url,
|
room_url,
|
||||||
token,
|
token,
|
||||||
"Translator",
|
"Translator",
|
||||||
DailyParams(
|
DailyParams(
|
||||||
audio_out_enabled=True,
|
audio_out_enabled=True,
|
||||||
transcription_enabled=True,
|
transcription_enabled=True,
|
||||||
transcription_settings=DailyTranscriptionSettings(extra={
|
transcription_settings=DailyTranscriptionSettings(extra={
|
||||||
"interim_results": False
|
"interim_results": False
|
||||||
})
|
})
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
|
||||||
|
|
||||||
tts = AzureTTSService(
|
tts = AzureTTSService(
|
||||||
api_key=os.getenv("AZURE_SPEECH_API_KEY"),
|
api_key=os.getenv("AZURE_SPEECH_API_KEY"),
|
||||||
region=os.getenv("AZURE_SPEECH_REGION"),
|
region=os.getenv("AZURE_SPEECH_REGION"),
|
||||||
voice="es-ES-AlvaroNeural",
|
voice="es-ES-AlvaroNeural",
|
||||||
)
|
)
|
||||||
|
|
||||||
llm = OpenAILLMService(
|
llm = OpenAILLMService(
|
||||||
api_key=os.getenv("OPENAI_API_KEY"),
|
api_key=os.getenv("OPENAI_API_KEY"),
|
||||||
model="gpt-4o"
|
model="gpt-4o"
|
||||||
)
|
)
|
||||||
|
|
||||||
sa = SentenceAggregator()
|
sa = SentenceAggregator()
|
||||||
tp = TranslationProcessor("Spanish")
|
tp = TranslationProcessor("Spanish")
|
||||||
lfra = LLMFullResponseAggregator()
|
lfra = LLMFullResponseAggregator()
|
||||||
ts = TranslationSubtitles("spanish")
|
ts = TranslationSubtitles("spanish")
|
||||||
|
|
||||||
pipeline = Pipeline([
|
pipeline = Pipeline([
|
||||||
transport.input(),
|
transport.input(),
|
||||||
sa,
|
sa,
|
||||||
tp,
|
tp,
|
||||||
llm,
|
llm,
|
||||||
lfra,
|
lfra,
|
||||||
ts,
|
ts,
|
||||||
tts,
|
tts,
|
||||||
transport.output()
|
transport.output()
|
||||||
])
|
])
|
||||||
|
|
||||||
task = PipelineTask(pipeline)
|
task = PipelineTask(pipeline)
|
||||||
|
|
||||||
@transport.event_handler("on_first_participant_joined")
|
@transport.event_handler("on_first_participant_joined")
|
||||||
async def on_first_participant_joined(transport, participant):
|
async def on_first_participant_joined(transport, participant):
|
||||||
transport.capture_participant_transcription(participant["id"])
|
transport.capture_participant_transcription(participant["id"])
|
||||||
|
|
||||||
runner = PipelineRunner()
|
runner = PipelineRunner()
|
||||||
|
|
||||||
await runner.run(task)
|
await runner.run(task)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -7,10 +7,12 @@
|
|||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
import aiohttp
|
||||||
|
|
||||||
from pipecat.transports.services.helpers.daily_rest import DailyRESTHelper
|
from pipecat.transports.services.helpers.daily_rest import DailyRESTHelper
|
||||||
|
|
||||||
|
|
||||||
async def configure():
|
async def configure(aiohttp_session: aiohttp.ClientSession):
|
||||||
parser = argparse.ArgumentParser(description="Daily AI SDK Bot Sample")
|
parser = argparse.ArgumentParser(description="Daily AI SDK Bot Sample")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-u",
|
"-u",
|
||||||
@@ -38,7 +40,11 @@ async def configure():
|
|||||||
if not key:
|
if not key:
|
||||||
raise Exception("No Daily API key specified. use the -k/--apikey option from the command line, or set DAILY_API_KEY in your environment to specify a Daily API key, available from https://dashboard.daily.co/developers.")
|
raise Exception("No Daily API key specified. use the -k/--apikey option from the command line, or set DAILY_API_KEY in your environment to specify a Daily API key, available from https://dashboard.daily.co/developers.")
|
||||||
|
|
||||||
daily_rest_helper = DailyRESTHelper(key, os.getenv("DAILY_API_URL", "https://api.daily.co/v1"))
|
daily_rest_helper = DailyRESTHelper(
|
||||||
|
daily_api_key=key,
|
||||||
|
daily_api_url=os.getenv("DAILY_API_URL", "https://api.daily.co/v1"),
|
||||||
|
aiohttp_session=aiohttp_session
|
||||||
|
)
|
||||||
|
|
||||||
# Create a meeting token for the given room with an expiration 1 hour in
|
# Create a meeting token for the given room with an expiration 1 hour in
|
||||||
# the future.
|
# the future.
|
||||||
|
|||||||
@@ -4,10 +4,12 @@
|
|||||||
# SPDX-License-Identifier: BSD 2-Clause License
|
# SPDX-License-Identifier: BSD 2-Clause License
|
||||||
#
|
#
|
||||||
|
|
||||||
|
import aiohttp
|
||||||
import os
|
import os
|
||||||
import argparse
|
import argparse
|
||||||
import subprocess
|
import subprocess
|
||||||
import atexit
|
|
||||||
|
from contextlib import asynccontextmanager
|
||||||
|
|
||||||
from fastapi import FastAPI, Request, HTTPException
|
from fastapi import FastAPI, Request, HTTPException
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
@@ -20,9 +22,7 @@ MAX_BOTS_PER_ROOM = 1
|
|||||||
# Bot sub-process dict for status reporting and concurrency control
|
# Bot sub-process dict for status reporting and concurrency control
|
||||||
bot_procs = {}
|
bot_procs = {}
|
||||||
|
|
||||||
daily_rest_helper = DailyRESTHelper(
|
daily_helpers = {}
|
||||||
os.getenv("DAILY_API_KEY", ""),
|
|
||||||
os.getenv("DAILY_API_URL", 'https://api.daily.co/v1'))
|
|
||||||
|
|
||||||
|
|
||||||
def cleanup():
|
def cleanup():
|
||||||
@@ -33,10 +33,19 @@ def cleanup():
|
|||||||
proc.wait()
|
proc.wait()
|
||||||
|
|
||||||
|
|
||||||
atexit.register(cleanup)
|
@asynccontextmanager
|
||||||
|
async def lifespan(app: FastAPI):
|
||||||
|
aiohttp_session = aiohttp.ClientSession()
|
||||||
|
daily_helpers["rest"] = DailyRESTHelper(
|
||||||
|
daily_api_key=os.getenv("DAILY_API_KEY", ""),
|
||||||
|
daily_api_url=os.getenv("DAILY_API_URL", 'https://api.daily.co/v1'),
|
||||||
|
aiohttp_session=aiohttp_session
|
||||||
|
)
|
||||||
|
yield
|
||||||
|
await aiohttp_session.close()
|
||||||
|
cleanup()
|
||||||
|
|
||||||
|
app = FastAPI(lifespan=lifespan)
|
||||||
app = FastAPI()
|
|
||||||
|
|
||||||
app.add_middleware(
|
app.add_middleware(
|
||||||
CORSMiddleware,
|
CORSMiddleware,
|
||||||
@@ -50,7 +59,7 @@ app.add_middleware(
|
|||||||
@app.get("/start")
|
@app.get("/start")
|
||||||
async def start_agent(request: Request):
|
async def start_agent(request: Request):
|
||||||
print(f"!!! Creating room")
|
print(f"!!! Creating room")
|
||||||
room = await daily_rest_helper.create_room(DailyRoomParams())
|
room = await daily_helpers["rest"].create_room(DailyRoomParams())
|
||||||
print(f"!!! Room URL: {room.url}")
|
print(f"!!! Room URL: {room.url}")
|
||||||
# Ensure the room property is present
|
# Ensure the room property is present
|
||||||
if not room.url:
|
if not room.url:
|
||||||
@@ -66,7 +75,7 @@ async def start_agent(request: Request):
|
|||||||
status_code=500, detail=f"Max bot limited reach for room: {room.url}")
|
status_code=500, detail=f"Max bot limited reach for room: {room.url}")
|
||||||
|
|
||||||
# Get the token for the room
|
# Get the token for the room
|
||||||
token = await daily_rest_helper.get_token(room.url)
|
token = await daily_helpers["rest"].get_token(room.url)
|
||||||
|
|
||||||
if not token:
|
if not token:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
|
|||||||
@@ -62,24 +62,26 @@ class DailyRoomObject(BaseModel):
|
|||||||
|
|
||||||
class DailyRESTHelper:
|
class DailyRESTHelper:
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
|
*,
|
||||||
daily_api_key: str,
|
daily_api_key: str,
|
||||||
daily_api_url: str = "https://api.daily.co/v1"):
|
daily_api_url: str = "https://api.daily.co/v1",
|
||||||
|
aiohttp_session: aiohttp.ClientSession):
|
||||||
self.daily_api_key = daily_api_key
|
self.daily_api_key = daily_api_key
|
||||||
self.daily_api_url = daily_api_url
|
self.daily_api_url = daily_api_url
|
||||||
|
self.aiohttp_session = aiohttp_session
|
||||||
|
|
||||||
def _get_name_from_url(self, room_url: str) -> str:
|
def _get_name_from_url(self, room_url: str) -> str:
|
||||||
return urlparse(room_url).path[1:]
|
return urlparse(room_url).path[1:]
|
||||||
|
|
||||||
async def create_room(self, params: DailyRoomParams) -> DailyRoomObject:
|
async def create_room(self, params: DailyRoomParams) -> DailyRoomObject:
|
||||||
async with aiohttp.ClientSession() as session:
|
headers = {"Authorization": f"Bearer {self.daily_api_key}"}
|
||||||
headers = {"Authorization": f"Bearer {self.daily_api_key}"}
|
json = {**params.model_dump(exclude_none=True)}
|
||||||
json = {**params.model_dump(exclude_none=True)}
|
async with self.aiohttp_session.post(f"{self.daily_api_url}/rooms", headers=headers, json=json) as r:
|
||||||
async with session.post(f"{self.daily_api_url}/rooms", headers=headers, json=json) as r:
|
if r.status != 200:
|
||||||
if r.status != 200:
|
text = await r.text()
|
||||||
text = await r.text()
|
raise Exception(f"Unable to create room: {text}")
|
||||||
raise Exception(f"Unable to create room: {text}")
|
|
||||||
|
|
||||||
data = await r.json()
|
data = await r.json()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
room = DailyRoomObject(**data)
|
room = DailyRoomObject(**data)
|
||||||
@@ -89,17 +91,17 @@ class DailyRESTHelper:
|
|||||||
return room
|
return room
|
||||||
|
|
||||||
async def _get_room_from_name(self, room_name: str) -> DailyRoomObject:
|
async def _get_room_from_name(self, room_name: str) -> DailyRoomObject:
|
||||||
async with aiohttp.ClientSession() as session:
|
headers = {"Authorization": f"Bearer {self.daily_api_key}"}
|
||||||
headers = {"Authorization": f"Bearer {self.daily_api_key}"}
|
async with self.aiohttp_session.get(f"{self.daily_api_url}/rooms/{room_name}", headers=headers) as r:
|
||||||
async with session.get(f"{self.daily_api_url}/rooms/{room_name}", headers=headers) as r:
|
if r.status != 200:
|
||||||
if r.status != 200:
|
raise Exception(f"Room not found: {room_name}")
|
||||||
raise Exception(f"Room not found: {room_name}")
|
|
||||||
|
|
||||||
data = await r.json()
|
data = await r.json()
|
||||||
try:
|
|
||||||
room = DailyRoomObject(**data)
|
try:
|
||||||
except ValidationError as e:
|
room = DailyRoomObject(**data)
|
||||||
raise Exception(f"Invalid response: {e}")
|
except ValidationError as e:
|
||||||
|
raise Exception(f"Invalid response: {e}")
|
||||||
|
|
||||||
return room
|
return room
|
||||||
|
|
||||||
@@ -120,21 +122,19 @@ class DailyRESTHelper:
|
|||||||
|
|
||||||
room_name = self._get_name_from_url(room_url)
|
room_name = self._get_name_from_url(room_url)
|
||||||
|
|
||||||
async with aiohttp.ClientSession() as session:
|
headers = {"Authorization": f"Bearer {self.daily_api_key}"}
|
||||||
headers = {"Authorization": f"Bearer {self.daily_api_key}"}
|
json = {
|
||||||
json = {
|
"properties": {
|
||||||
"properties": {
|
"room_name": room_name,
|
||||||
"room_name": room_name,
|
"is_owner": owner,
|
||||||
"is_owner": owner,
|
"exp": expiration
|
||||||
"exp": expiration
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
async with session.post(f"{self.daily_api_url}/meeting-tokens", headers=headers, json=json) as r:
|
}
|
||||||
if r.status != 200:
|
async with self.aiohttp_session.post(f"{self.daily_api_url}/meeting-tokens", headers=headers, json=json) as r:
|
||||||
text = await r.text()
|
if r.status != 200:
|
||||||
raise Exception(f"Failed to create meeting token: {r.status} {text}")
|
text = await r.text()
|
||||||
|
raise Exception(f"Failed to create meeting token: {r.status} {text}")
|
||||||
|
|
||||||
data = await r.json()
|
data = await r.json()
|
||||||
token: str = data["token"]
|
|
||||||
|
|
||||||
return token
|
return data["token"]
|
||||||
|
|||||||
Reference in New Issue
Block a user