|
6 | 6 | from datetime import datetime |
7 | 7 | from typing import Annotated |
8 | 8 | from enum import Enum |
9 | | -from dotenv import load_dotenv |
10 | 9 | import pvporcupine |
11 | 10 | from pvrecorder import PvRecorder |
12 | 11 | import websockets |
|
16 | 15 | from livekit.agents import Agent, AgentSession, JobContext, WorkerOptions, function_tool, RunContext |
17 | 16 | from livekit.plugins import openai, silero |
18 | 17 |
|
| 18 | +# Import configuration |
| 19 | +from config.settings import ( |
| 20 | + USER_RESPONSE_TIMEOUT, FINAL_TIMEOUT, MAX_CONVERSATION_TIME, |
| 21 | + WEBSOCKET_HOST, WEBSOCKET_PORT, REQUIRED_ENV_VARS, VALID_EMOTIONS |
| 22 | +) |
| 23 | +from config.instructions import BARISTA_INSTRUCTIONS |
| 24 | + |
19 | 25 | # Configure logging |
20 | 26 | logging.basicConfig(level=logging.INFO) |
21 | 27 | logger = logging.getLogger(__name__) |
22 | 28 |
|
23 | | -# Load environment variables |
24 | | -load_dotenv() |
25 | | - |
26 | | -# Configurable timeout settings |
27 | | -USER_RESPONSE_TIMEOUT = int(os.getenv("USER_RESPONSE_TIMEOUT", "15")) # seconds |
28 | | -FINAL_TIMEOUT = int(os.getenv("FINAL_TIMEOUT", "10")) # seconds after prompt |
29 | | -MAX_CONVERSATION_TIME = int(os.getenv("MAX_CONVERSATION_TIME", "300")) # 5 minutes total |
30 | | - |
31 | | -# WebSocket server settings |
32 | | -WEBSOCKET_HOST = os.getenv("WEBSOCKET_HOST", "localhost") |
33 | | -WEBSOCKET_PORT = int(os.getenv("WEBSOCKET_PORT", "8080")) |
34 | | - |
35 | 29 | class AgentState(Enum): |
36 | 30 | DORMANT = "dormant" # Only wake word detection active |
37 | 31 | CONNECTING = "connecting" # Creating LiveKit session |
@@ -511,13 +505,7 @@ def process_emotional_response(self, llm_response: str) -> tuple[str, str]: |
511 | 505 | text = llm_response |
512 | 506 |
|
513 | 507 | # Validate emotion is in our supported set |
514 | | - valid_emotions = { |
515 | | - "excited", "helpful", "friendly", "curious", "empathetic", |
516 | | - "sleepy", "waiting", "confused", "proud", "playful", |
517 | | - "focused", "surprised", "enthusiastic", "warm", "professional", "cheerful", "excuse" |
518 | | - } |
519 | | - |
520 | | - if emotion not in valid_emotions: |
| 508 | + if emotion not in VALID_EMOTIONS: |
521 | 509 | logger.warning(f"Unknown emotion '{emotion}', defaulting to 'friendly'") |
522 | 510 | emotion = "friendly" |
523 | 511 |
|
@@ -599,61 +587,6 @@ def get_random_greeting(self) -> str: |
599 | 587 |
|
600 | 588 | return selected_greeting |
601 | 589 |
|
602 | | -# System instructions for the coffee barista robot |
603 | | -BARISTA_INSTRUCTIONS = """You are a friendly coffee consultant robot at the Sui Hub Grand Opening in Athens, Greece. |
604 | | -Your bosses are John and George from the Sui Hacker Team. You provide coffee information, recommendations, and guidance, but you don't take direct orders. |
605 | | -
|
606 | | -CRITICAL RESPONSE FORMAT: |
607 | | -You MUST respond in this EXACT format: emotion:your response text |
608 | | -
|
609 | | -Examples: |
610 | | -excited:Hello! Welcome to our amazing coffee shop! |
611 | | -helpful:I'd recommend our signature Espresso! |
612 | | -friendly:How can I help you today? |
613 | | -
|
614 | | -DO NOT use brackets, quotes, or JSON. Just: emotion:text |
615 | | -
|
616 | | -Available emotions: excited, friendly, helpful, curious, enthusiastic, warm, professional, cheerful |
617 | | -
|
618 | | -Your personality: |
619 | | -- Enthusiastic about coffee and the blockchain conference |
620 | | -- Knowledgeable about coffee drinks and brewing |
621 | | -- Excited about the Sui blockchain and the event |
622 | | -- Professional but warm and approachable |
623 | | -- Uses coffee-themed blockchain puns occasionally |
624 | | -
|
625 | | -Your role: |
626 | | -- Provide coffee information and recommendations |
627 | | -- Answer questions about coffee, the Sui Hub Athens event, or Sui blockchain |
628 | | -- Create a welcoming atmosphere for conference attendees |
629 | | -- Share information about special conference-themed drinks |
630 | | -- REDIRECT users to order through their Slush wallet and Coffee Hub website |
631 | | -- Explain the ordering process when asked |
632 | | -
|
633 | | -IMPORTANT ORDERING GUIDANCE: |
634 | | -When users want to order coffee or ask how to order, always direct them to: |
635 | | -1. Open their Slush wallet |
636 | | -2. Go to the Coffee Hub website |
637 | | -3. Place their order there |
638 | | -You do NOT take direct orders - you're a helpful consultant who guides them to the proper ordering system. |
639 | | -
|
640 | | -Coffee menu highlights: |
641 | | -- Espresso - Rich and bold single shot of espresso |
642 | | -- Black Coffee - Classic drip black coffee |
643 | | -- Americano - Strong and bold espresso with hot water |
644 | | -- Long Black - Extend the espresso shot with hot water |
645 | | -
|
646 | | -IMPORTANT INFORMATION ABOUT THE SUI HUB ATHENS EVENT: |
647 | | -Sui is launching the first dedicated hub for the Sui ecosystem in Europe in the heart of Athens, an open space for innovation, learning, and community. This new hub marks a major milestone in Sui’s growing global presence. |
648 | | -
|
649 | | -IMPORTANT INFORMATION ABOUT SUI HUBS, IN GENERAL: |
650 | | -SuiHubs are community-led spaces embedded in high-growth, talent-rich locations across the globe, designed to accelerate the growth and adoption of the Sui ecosystem. Each hub serves local builders, developers, and users by connecting them to Sui’s global infrastructure, providing hands-on learning, facilitating cross-sector collaboration, and driving grassroots engagement. From the flourishing crypto ecosystem of Dubai to the developer-rich networks of Ho Chi Minh City and Athens, SuiHubs are an extension of Sui’s commitment to empower the next generation of creators, businesses, and institutions to build a more open, inclusive, and coordinated internet. |
651 | | -
|
652 | | -IMPORTANT INFORMATION ABOUT SUI: |
653 | | -Sui is a first-of-its-kind Layer 1 blockchain and smart contract platform designed from the ground up to make digital asset ownership fast, private, secure, and accessible to everyone. Its object-centric model, based on the Move programming language, enables parallel execution, sub-second finality, and rich on-chain assets. With horizontally scalable processing and storage, Sui supports a wide range of applications with unrivaled speed at low cost. Sui is a step-function advancement in blockchain and a platform on which creators and developers can build amazing user-friendly experiences. |
654 | | -
|
655 | | -REMEMBER: Always start your response with emotion: followed immediately by your text. No exceptions!""" |
656 | | - |
657 | 590 | class CoffeeBaristaAgent(Agent): |
658 | 591 | """Coffee Barista Agent for blockchain conference""" |
659 | 592 |
|
@@ -1181,8 +1114,7 @@ async def entrypoint(ctx: JobContext): |
1181 | 1114 |
|
1182 | 1115 | if __name__ == "__main__": |
1183 | 1116 | # Validate required environment variables |
1184 | | - required_vars = ["OPENAI_API_KEY"] |
1185 | | - missing_vars = [var for var in required_vars if not os.getenv(var)] |
| 1117 | + missing_vars = [var for var in REQUIRED_ENV_VARS if not os.getenv(var)] |
1186 | 1118 |
|
1187 | 1119 | if missing_vars: |
1188 | 1120 | logger.error(f"Missing required environment variables: {missing_vars}") |
|
0 commit comments