Spaces:
Paused
Paused
Download entrypoint.py from Mapmaven/duol-agent: direct link, hf CLI and curl.
- Browser
- Download file 4.38 kB
-
https://huggingface.co/spaces/Mapmaven/duol-agent/resolve/main/entrypoint.py
- Command line
-
hf download hf://spaces/Mapmaven/duol-agent/entrypoint.py
-
curl -L -o entrypoint.py https://huggingface.co/spaces/Mapmaven/duol-agent/resolve/main/entrypoint.py
4.38 kB
| import sys | |
| import threading | |
| from http.server import HTTPServer, BaseHTTPRequestHandler | |
| import time | |
| import requests | |
| from dotenv import load_dotenv | |
| load_dotenv() | |
| # ββ Simple status web server (HF Spaces requires port 7860) ββββββββββββββββββ | |
| STATUS_HTML = """<!DOCTYPE html> | |
| <html lang="sw"> | |
| <head> | |
| <meta charset="UTF-8"/> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"/> | |
| <title>Habari Jarvis — Swahili AI Agent</title> | |
| <style> | |
| * { box-sizing: border-box; margin: 0; padding: 0; } | |
| body { | |
| font-family: 'Segoe UI', system-ui, sans-serif; | |
| background: linear-gradient(135deg, #0f2027, #203a43, #2c5364); | |
| min-height: 100vh; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| color: #fff; | |
| } | |
| .card { | |
| background: rgba(255,255,255,0.07); | |
| backdrop-filter: blur(16px); | |
| border: 1px solid rgba(255,255,255,0.15); | |
| border-radius: 24px; | |
| padding: 48px 56px; | |
| text-align: center; | |
| max-width: 520px; | |
| width: 90%; | |
| box-shadow: 0 24px 64px rgba(0,0,0,0.4); | |
| } | |
| .emoji { font-size: 64px; margin-bottom: 16px; animation: pulse 2s infinite; } | |
| @keyframes pulse { 0%,100%{transform:scale(1)} 50%{transform:scale(1.08)} } | |
| h1 { font-size: 2rem; font-weight: 700; margin-bottom: 8px; } | |
| .sub { color: rgba(255,255,255,0.65); margin-bottom: 28px; font-size: 1.05rem; } | |
| .badge { | |
| display: inline-flex; align-items: center; gap: 8px; | |
| background: rgba(52,211,153,0.15); | |
| border: 1px solid rgba(52,211,153,0.4); | |
| color: #34d399; | |
| border-radius: 999px; | |
| padding: 8px 20px; | |
| font-size: 0.9rem; | |
| font-weight: 600; | |
| margin-bottom: 28px; | |
| } | |
| .dot { width: 10px; height: 10px; border-radius: 50%; background: #34d399; | |
| animation: blink 1.4s infinite; } | |
| @keyframes blink { 0%,100%{opacity:1} 50%{opacity:0.2} } | |
| .info { font-size: 0.85rem; color: rgba(255,255,255,0.45); line-height: 1.6; } | |
| code { background: rgba(255,255,255,0.1); border-radius: 6px; padding: 2px 8px; } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="card"> | |
| <div class="emoji">π€</div> | |
| <h1>Habari Jarvis</h1> | |
| <p class="sub">Msaidizi wa Akili Bandia • Swahili AI Voice Agent</p> | |
| <div class="badge"><div class="dot"></div> Agent Running</div> | |
| <p class="info"> | |
| Connect via <code>LiveKit</code> to start a voice conversation.<br/> | |
| The agent listens and responds entirely in <strong>Kiswahili</strong>.<br/><br/> | |
| Powered by Groq Whisper • LLaMA 3.3 70B • MMS/API TTS | |
| </p> | |
| </div> | |
| </body> | |
| </html> | |
| """ | |
| class StatusHandler(BaseHTTPRequestHandler): | |
| def do_GET(self): | |
| self.send_response(200) | |
| self.send_header("Content-type", "text/html; charset=utf-8") | |
| self.end_headers() | |
| self.wfile.write(STATUS_HTML.encode("utf-8")) | |
| def log_message(self, *args): # silence access logs | |
| pass | |
| def run_status_server(): | |
| server = HTTPServer(("0.0.0.0", 7860), StatusHandler) | |
| server.serve_forever() | |
| # ββ Auto-ping mechanism to keep HF Space awake βββββββββββββββββββββββββββββββ | |
| def keep_awake(): | |
| # Wait for the server to start | |
| time.sleep(10) | |
| url = "https://huggingface.co/spaces/Mapmaven/duol-agent" | |
| while True: | |
| try: | |
| requests.get(url, timeout=10) | |
| print(f"[OK] Auto-pinged {url} to prevent sleep") | |
| except Exception as e: | |
| print(f"[WARN] Auto-ping failed: {e}") | |
| time.sleep(600) # Ping every 10 minutes | |
| # ββ Start LiveKit agent worker ββββββββββββββββββββββββββββββββββββββββββββββββ | |
| from livekit.agents import WorkerOptions, cli | |
| from agent import entrypoint | |
| if __name__ == "__main__": | |
| # ββ Start servers in background threads βββββββββββββββββββββββββββββββββββββββ | |
| t1 = threading.Thread(target=run_status_server, daemon=True) | |
| t1.start() | |
| t2 = threading.Thread(target=keep_awake, daemon=True) | |
| t2.start() | |
| print("[OK] Status server started on port 7860") | |
| cli.run_app(WorkerOptions(entrypoint_fnc=entrypoint, agent_name="DUOL")) | |