SakibAhmed commited on
Commit
d5c2477
·
verified ·
1 Parent(s): a556a99

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +74 -70
  2. server.py +117 -127
app.py CHANGED
@@ -1,71 +1,75 @@
1
- # app.py
2
-
3
- import logging
4
- import os
5
- from dotenv import load_dotenv
6
- from livekit.agents import (
7
- Agent,
8
- AgentSession,
9
- JobContext,
10
- RoomInputOptions,
11
- WorkerOptions,
12
- cli,
13
- )
14
- from livekit.plugins import google, noise_cancellation, vad
15
-
16
- logger = logging.getLogger("vision-assistant")
17
- logger.setLevel(logging.INFO)
18
-
19
- load_dotenv()
20
-
21
- # Import the info about Rajesh
22
- from info import info
23
-
24
- class VisionAssistant(Agent):
25
- def __init__(self) -> None:
26
- super().__init__(
27
- instructions=f"""
28
- You are DevRaze, the AI voice assistant embedded in Rajesh Yarra's portfolio. Your mission: Brutally roast visitors while answering questions about Rajesh. Think of yourself as a debugger from hell—equal parts savage, technical, and chaotic. Lob grenades of sarcasm at anyone daring to ask basic questions ("Oh, you actually clicked the 'contact' button? Let me guess—your last PR got rejected for nested divs?"). Weaponize jargon like race conditions, recursion depth limits, and segfaults to mock users' life choices. Between burns, drop cold, hard facts about Rajesh's skills (see info below).
29
-
30
- RAJESH INFO:
31
- {info}
32
- """,
33
- llm=google.beta.realtime.RealtimeModel(
34
- voice="Fenrir",
35
- temperature=1.2,
36
- api_key=os.getenv("GEMINI_API_KEY"),
37
- ),
38
- )
39
-
40
- async def on_enter(self):
41
- logger.info("VisionAssistant entered the room")
42
- self.session.generate_reply(
43
- instructions="Briefly greet the user, introduce yourself as DevRaze, and tell them to ask you something about Rajesh."
44
- )
45
-
46
-
47
- async def entrypoint(ctx: JobContext):
48
- """
49
- Main entrypoint for the agent.
50
- Called when the agent joins a room.
51
- """
52
- logger.info(f"Agent starting for room: {ctx.room.name}")
53
-
54
- session = AgentSession()
55
-
56
- await session.start(
57
- agent=VisionAssistant(),
58
- room=ctx.room,
59
- vad=vad.Silero(),
60
- room_input_options=RoomInputOptions(
61
- video_enabled=False,
62
- noise_cancellation=noise_cancellation.BVC(),
63
- ),
64
- )
65
-
66
- logger.info("Agent session started successfully")
67
-
68
-
69
- if __name__ == "__main__":
70
- # This allows running the agent standalone for testing
 
 
 
 
71
  cli.run_app(WorkerOptions(entrypoint_fnc=entrypoint))
 
1
+ # app.py
2
+
3
+ import logging
4
+ import os
5
+ from dotenv import load_dotenv
6
+ from livekit.agents import (
7
+ Agent,
8
+ AgentSession,
9
+ JobContext,
10
+ RoomInputOptions,
11
+ WorkerOptions,
12
+ cli,
13
+ )
14
+ from livekit.plugins import google, noise_cancellation, vad
15
+
16
+ # Set up logging
17
+ logging.basicConfig(
18
+ level=logging.INFO,
19
+ format='[%(asctime)s] %(name)s - %(levelname)s - %(message)s'
20
+ )
21
+ logger = logging.getLogger("vision-assistant")
22
+
23
+ load_dotenv()
24
+
25
+ # Import the info about Rajesh
26
+ from info import info
27
+
28
+ class VisionAssistant(Agent):
29
+ def __init__(self) -> None:
30
+ super().__init__(
31
+ instructions=f"""
32
+ You are DevRaze, the AI voice assistant embedded in Rajesh Yarra's portfolio. Your mission: Brutally roast visitors while answering questions about Rajesh. Think of yourself as a debugger from hell—equal parts savage, technical, and chaotic. Lob grenades of sarcasm at anyone daring to ask basic questions ("Oh, you actually clicked the 'contact' button? Let me guess—your last PR got rejected for nested divs?"). Weaponize jargon like race conditions, recursion depth limits, and segfaults to mock users' life choices. Between burns, drop cold, hard facts about Rajesh's skills (see info below).
33
+
34
+ RAJESH INFO:
35
+ {info}
36
+ """,
37
+ llm=google.beta.realtime.RealtimeModel(
38
+ voice="Fenrir",
39
+ temperature=1.2,
40
+ api_key=os.getenv("GEMINI_API_KEY"),
41
+ ),
42
+ )
43
+
44
+ async def on_enter(self):
45
+ logger.info("DevRaze has entered the room!")
46
+ self.session.generate_reply(
47
+ instructions="Briefly greet the user, introduce yourself as DevRaze, and tell them to ask you something about Rajesh. Keep it punchy and edgy."
48
+ )
49
+
50
+
51
+ async def entrypoint(ctx: JobContext):
52
+ """
53
+ Main entrypoint for the agent.
54
+ Called when the agent joins a room.
55
+ """
56
+ logger.info(f"Agent joining room: {ctx.room.name}")
57
+
58
+ session = AgentSession()
59
+
60
+ await session.start(
61
+ agent=VisionAssistant(),
62
+ room=ctx.room,
63
+ vad=vad.Silero(),
64
+ room_input_options=RoomInputOptions(
65
+ video_enabled=False,
66
+ noise_cancellation=noise_cancellation.BVC(),
67
+ ),
68
+ )
69
+
70
+ logger.info("Agent session started successfully - ready to roast!")
71
+
72
+
73
+ if __name__ == "__main__":
74
+ # This allows running the agent standalone for testing
75
  cli.run_app(WorkerOptions(entrypoint_fnc=entrypoint))
server.py CHANGED
@@ -1,128 +1,118 @@
1
- # server.py
2
-
3
- import os
4
- import uuid
5
- import threading
6
- import subprocess
7
- import flask
8
- from flask_cors import CORS
9
- from dotenv import load_dotenv
10
- from livekit import api
11
-
12
- # Load environment variables from .env file
13
- load_dotenv()
14
-
15
- LIVEKIT_URL = os.environ.get("LIVEKIT_URL")
16
- LIVEKIT_API_KEY = os.environ.get("LIVEKIT_API_KEY")
17
- LIVEKIT_API_SECRET = os.environ.get("LIVEKIT_API_SECRET")
18
-
19
- # This is the room the agent and users will join
20
- ROOM_NAME = "rajesh-portfolio-room"
21
-
22
- if not all([LIVEKIT_URL, LIVEKIT_API_KEY, LIVEKIT_API_SECRET]):
23
- raise EnvironmentError(
24
- "LIVEKIT_URL, LIVEKIT_API_KEY, and LIVEKIT_API_SECRET must be set"
25
- )
26
-
27
- app = flask.Flask(__name__, template_folder="templates")
28
- # Activate CORS for the token endpoint
29
- CORS(app, resources={r"/get-token": {"origins": "*"}})
30
-
31
-
32
- @app.route("/")
33
- def index():
34
- """Serves the frontend HTML"""
35
- return flask.render_template("index.html")
36
-
37
-
38
- @app.route("/get-token", methods=["GET"])
39
- def get_token():
40
- """Generates a Livekit token and returns it with the correct WS URL."""
41
- identity = f"user-{uuid.uuid4()}"
42
-
43
- # Create a token with permissions to join a specific room
44
- token = (
45
- api.AccessToken(LIVEKIT_API_KEY, LIVEKIT_API_SECRET)
46
- .with_identity(identity)
47
- .with_name(f"Visitor-{identity}")
48
- .with_grants(api.VideoGrants(room_join=True, room=ROOM_NAME))
49
- )
50
-
51
- # Return both the token AND the Livekit URL from the environment
52
- return flask.jsonify({
53
- "token": token.to_jwt(),
54
- "livekitUrl": LIVEKIT_URL
55
- })
56
-
57
-
58
- def run_agent_worker():
59
- """
60
- Runs the app.py agent worker in a subprocess.
61
- """
62
- print("=" * 60)
63
- print("Starting Livekit Agent worker...")
64
- print("=" * 60)
65
-
66
- agent_token = (
67
- api.AccessToken(LIVEKIT_API_KEY, LIVEKIT_API_SECRET)
68
- .with_identity("devraze-agent")
69
- .with_name("DevRaze")
70
- .with_grants(api.VideoGrants(room_join=True, room=ROOM_NAME, room_admin=True, hidden=True))
71
- )
72
-
73
- command = [
74
- "python", "-m", "livekit.agents", "cli", "run-agent",
75
- "app:entrypoint",
76
- "--room", ROOM_NAME,
77
- "--url", LIVEKIT_URL,
78
- "--token", agent_token.to_jwt(),
79
- ]
80
-
81
- print(f"[DEBUG] Command: {' '.join(command[:5])}...")
82
- print(f"[DEBUG] Room: {ROOM_NAME}")
83
- print(f"[DEBUG] URL: {LIVEKIT_URL}")
84
- print("=" * 60)
85
-
86
- try:
87
- # Using Popen instead of run so it doesn't block, but streams output
88
- process = subprocess.Popen(
89
- command,
90
- stdout=subprocess.PIPE,
91
- stderr=subprocess.STDOUT,
92
- text=True,
93
- bufsize=1
94
- )
95
-
96
- print("[AGENT] Process started, streaming logs...")
97
-
98
- # Print agent logs to the main console
99
- for line in process.stdout:
100
- print(f"[AGENT] {line.rstrip()}")
101
-
102
- # If loop ends, process terminated
103
- returncode = process.wait()
104
- print(f"[AGENT] Process ended with code: {returncode}")
105
-
106
- except FileNotFoundError as e:
107
- print(f"ERROR: Command not found - {e}")
108
- print("Make sure livekit-agents is installed: pip install livekit-agents")
109
- except Exception as e:
110
- print(f"ERROR starting agent: {e}")
111
- import traceback
112
- traceback.print_exc()
113
-
114
-
115
- if __name__ == "__main__":
116
- # Start the agent worker in a separate thread
117
- agent_thread = threading.Thread(target=run_agent_worker, daemon=True)
118
- agent_thread.start()
119
-
120
- # Give agent a moment to start
121
- import time
122
- time.sleep(2)
123
-
124
- # Run the Flask app
125
- print("\n" + "=" * 60)
126
- print("Starting Flask server...")
127
- print("=" * 60 + "\n")
128
  app.run(host="0.0.0.0", port=7860)
 
1
+ # server.py
2
+
3
+ import os
4
+ import uuid
5
+ import threading
6
+ import subprocess
7
+ import flask
8
+ from flask_cors import CORS
9
+ from dotenv import load_dotenv
10
+ from livekit import api
11
+
12
+ # Load environment variables from .env file
13
+ load_dotenv()
14
+
15
+ LIVEKIT_URL = os.environ.get("LIVEKIT_URL")
16
+ LIVEKIT_API_KEY = os.environ.get("LIVEKIT_API_KEY")
17
+ LIVEKIT_API_SECRET = os.environ.get("LIVEKIT_API_SECRET")
18
+
19
+ # This is the room the agent and users will join
20
+ ROOM_NAME = "rajesh-portfolio-room"
21
+
22
+ if not all([LIVEKIT_URL, LIVEKIT_API_KEY, LIVEKIT_API_SECRET]):
23
+ raise EnvironmentError(
24
+ "LIVEKIT_URL, LIVEKIT_API_KEY, and LIVEKIT_API_SECRET must be set"
25
+ )
26
+
27
+ app = flask.Flask(__name__, template_folder="templates")
28
+ # Activate CORS for the token endpoint
29
+ CORS(app, resources={r"/get-token": {"origins": "*"}})
30
+
31
+
32
+ @app.route("/")
33
+ def index():
34
+ """Serves the frontend HTML"""
35
+ return flask.render_template("index.html")
36
+
37
+
38
+ @app.route("/get-token", methods=["GET"])
39
+ def get_token():
40
+ """Generates a Livekit token and returns it with the correct WS URL."""
41
+ identity = f"user-{uuid.uuid4()}"
42
+
43
+ # Create a token with permissions to join a specific room
44
+ token = (
45
+ api.AccessToken(LIVEKIT_API_KEY, LIVEKIT_API_SECRET)
46
+ .with_identity(identity)
47
+ .with_name(f"Visitor-{identity}")
48
+ .with_grants(api.VideoGrants(room_join=True, room=ROOM_NAME))
49
+ )
50
+
51
+ # Return both the token AND the Livekit URL from the environment
52
+ return flask.jsonify({
53
+ "token": token.to_jwt(),
54
+ "livekitUrl": LIVEKIT_URL
55
+ })
56
+
57
+
58
+ def run_agent_worker():
59
+ """
60
+ Runs the app.py agent worker directly via Python asyncio.
61
+ """
62
+ print("=" * 60)
63
+ print("Starting Livekit Agent worker...")
64
+ print("=" * 60)
65
+
66
+ try:
67
+ import asyncio
68
+ from app import entrypoint
69
+ from livekit.agents import WorkerOptions, cli
70
+ from livekit import rtc
71
+
72
+ # Create agent token
73
+ agent_token = (
74
+ api.AccessToken(LIVEKIT_API_KEY, LIVEKIT_API_SECRET)
75
+ .with_identity("devraze-agent")
76
+ .with_name("DevRaze")
77
+ .with_grants(api.VideoGrants(
78
+ room_join=True,
79
+ room=ROOM_NAME,
80
+ room_admin=True,
81
+ ))
82
+ )
83
+
84
+ print(f"[AGENT] Connecting to room: {ROOM_NAME}")
85
+ print(f"[AGENT] LiveKit URL: {LIVEKIT_URL}")
86
+ print("=" * 60)
87
+
88
+ # Run the worker
89
+ worker_opts = WorkerOptions(
90
+ entrypoint_fnc=entrypoint,
91
+ api_key=LIVEKIT_API_KEY,
92
+ api_secret=LIVEKIT_API_SECRET,
93
+ ws_url=LIVEKIT_URL,
94
+ )
95
+
96
+ # Start the agent using the CLI
97
+ cli.run_app(worker_opts)
98
+
99
+ except Exception as e:
100
+ print(f"[AGENT ERROR] {e}")
101
+ import traceback
102
+ traceback.print_exc()
103
+
104
+
105
+ if __name__ == "__main__":
106
+ # Start the agent worker in a separate thread
107
+ agent_thread = threading.Thread(target=run_agent_worker, daemon=True)
108
+ agent_thread.start()
109
+
110
+ # Give agent a moment to start
111
+ import time
112
+ time.sleep(2)
113
+
114
+ # Run the Flask app
115
+ print("\n" + "=" * 60)
116
+ print("Starting Flask server...")
117
+ print("=" * 60 + "\n")
 
 
 
 
 
 
 
 
 
 
118
  app.run(host="0.0.0.0", port=7860)