-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathlivekit-gemini.py
More file actions
106 lines (89 loc) · 3.41 KB
/
Copy pathlivekit-gemini.py
File metadata and controls
106 lines (89 loc) · 3.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import logging
import os
import uuid
import dotenv
from livekit import agents
from livekit import api as livekit_api
from livekit.agents import Agent, AgentSession, function_tool
from livekit.agents.utils import images
from livekit.api.room_service import CreateRoomRequest
from livekit.plugins import google
from maxim import Maxim
from maxim.logger.livekit import instrument_livekit
from tavily import TavilyClient
dotenv.load_dotenv(override=True)
logging.basicConfig(level=logging.DEBUG)
logger = Maxim().logger()
TAVILY_API_KEY = os.getenv("TAVILY_API_KEY")
def on_event(event: str, data: dict):
if event == "maxim.trace.started":
trace_id = data["trace_id"]
trace = data["trace"]
logging.debug(f"Trace started - ID: {trace_id}", extra={"trace": trace})
elif event == "maxim.trace.ended":
trace_id = data["trace_id"]
trace = data["trace"]
logging.debug(f"Trace ended - ID: {trace_id}", extra={"trace": trace})
instrument_livekit(logger, on_event)
class Assistant(Agent):
def __init__(self) -> None:
super().__init__(
instructions="You are a helpful voice AI assistant. You can search the web using the web_search tool."
)
@function_tool()
async def web_search(self, query: str) -> str:
"""
Performs a web search for the given query.
"""
if not TAVILY_API_KEY:
return "Tavily API key is not set. Please set the TAVILY_API_KEY environment variable."
tavily_client = TavilyClient(api_key=TAVILY_API_KEY)
try:
response = tavily_client.search(query=query, search_depth="basic")
if response.get("answer"):
return response["answer"]
return str(response.get("results", "No results found."))
except Exception as e:
return f"An error occurred during web search: {e}"
async def entrypoint(ctx: agents.JobContext):
# 1) pick a room name
room_name = os.getenv("LIVEKIT_ROOM_NAME") or f"assistant-room-{uuid.uuid4().hex}"
# 2) provision the room via the server API
lkapi = livekit_api.LiveKitAPI(
url=os.getenv("LIVEKIT_URL"),
api_key=os.getenv("LIVEKIT_API_KEY"),
api_secret=os.getenv("LIVEKIT_API_SECRET"),
)
try:
req = CreateRoomRequest(
name=room_name,
empty_timeout=300, # keep the room alive 5m after empty
max_participants=10, # adjust as needed
)
room = await lkapi.room.create_room(
req
) # :contentReference[oaicite:0]{index=0}
print(f"Room created: {room}")
session = AgentSession(
llm=google.beta.realtime.RealtimeModel(
model="gemini-2.0-flash-exp",
voice="Puck",
modalities=["AUDIO"],
language="en-US",
temperature=0.0,
max_output_tokens=1000,
image_encode_options=images.EncodeOptions(
quality=85,
),
),
)
await session.start(room=room, agent=Assistant())
await ctx.connect()
await session.generate_reply(
instructions="Greet the user and offer your assistance."
)
finally:
await lkapi.aclose()
if __name__ == "__main__":
opts = agents.WorkerOptions(entrypoint_fnc=entrypoint)
agents.cli.run_app(opts)