|
|
|
import os |
|
import subprocess |
|
import sys |
|
import time |
|
from pathlib import Path |
|
import signal |
|
|
|
def main(): |
|
processes = [] |
|
try: |
|
|
|
api_binary = Path("/app/server/bin/api") |
|
playground_dir = Path("/app/playground") |
|
|
|
|
|
if not api_binary.exists(): |
|
print(f"ERROR: API binary not found at {api_binary}", file=sys.stderr) |
|
return 1 |
|
|
|
if not playground_dir.exists(): |
|
print(f"ERROR: Playground directory not found at {playground_dir}", file=sys.stderr) |
|
return 1 |
|
|
|
|
|
print("Starting TEN-Agent API server on port 8080...") |
|
api_server_process = subprocess.Popen([str(api_binary)]) |
|
processes.append(api_server_process) |
|
|
|
|
|
time.sleep(3) |
|
|
|
|
|
print("Starting Playground UI on port 3000...") |
|
playground_env = os.environ.copy() |
|
playground_env["AGENT_SERVER_URL"] = "http://localhost:8080" |
|
playground_process = subprocess.Popen( |
|
["pnpm", "start", "--", "-p", "3000"], |
|
cwd=str(playground_dir), |
|
env=playground_env |
|
) |
|
processes.append(playground_process) |
|
|
|
|
|
from http.server import HTTPServer, SimpleHTTPRequestHandler |
|
|
|
class CustomHandler(SimpleHTTPRequestHandler): |
|
def do_GET(self): |
|
|
|
if self.path == '/': |
|
self.send_response(301) |
|
self.send_header('Location', 'http://localhost:3000') |
|
self.end_headers() |
|
else: |
|
self.send_response(200) |
|
self.send_header('Content-type', 'text/html; charset=utf-8') |
|
self.end_headers() |
|
|
|
html_content = """ |
|
<!DOCTYPE html> |
|
<html> |
|
<head> |
|
<title>TEN Agent - Hugging Face Space</title> |
|
<meta charset="utf-8"> |
|
<style> |
|
body { font-family: Arial, sans-serif; line-height: 1.6; max-width: 800px; margin: 0 auto; padding: 20px; } |
|
h1 { color: #333; } |
|
.info { background: #f8f9fa; border-left: 4px solid #28a745; padding: 15px; margin-bottom: 20px; } |
|
.endpoint { background: #e9ecef; padding: 10px; border-radius: 5px; font-family: monospace; } |
|
.link { font-size: 18px; margin-top: 30px; text-align: center; } |
|
.link a { display: inline-block; background: #0d6efd; color: white; padding: 10px 20px; text-decoration: none; border-radius: 5px; } |
|
</style> |
|
</head> |
|
<body> |
|
<h1>TEN Agent запущен успешно!</h1> |
|
<div class="info"> |
|
<p>TEN Agent API сервер работает на порту 8080.</p> |
|
<p>Playground UI доступен на порту 3000.</p> |
|
</div> |
|
<div class="link"> |
|
<a href="http://localhost:3000">Открыть Playground UI</a> |
|
</div> |
|
<h2>API эндпоинты:</h2> |
|
<ul> |
|
<li><span class="endpoint">GET /health</span> - проверка состояния сервера</li> |
|
<li><span class="endpoint">GET /list</span> - список запущенных агентов</li> |
|
<li><span class="endpoint">GET /graphs</span> - доступные графы</li> |
|
</ul> |
|
<p>См. <a href="https://github.com/TEN-framework/TEN-Agent" target="_blank">документацию TEN Agent</a> для получения дополнительной информации.</p> |
|
</body> |
|
</html> |
|
""" |
|
|
|
self.wfile.write(html_content.encode('utf-8')) |
|
|
|
|
|
port = 7860 |
|
print(f"Starting HTTP server on port {port}...") |
|
httpd = HTTPServer(('0.0.0.0', port), CustomHandler) |
|
httpd.serve_forever() |
|
|
|
except KeyboardInterrupt: |
|
print("Shutting down...") |
|
finally: |
|
|
|
for proc in processes: |
|
try: |
|
proc.terminate() |
|
proc.wait(timeout=5) |
|
except: |
|
proc.kill() |
|
|
|
return 0 |
|
|
|
if __name__ == "__main__": |
|
|
|
signal.signal(signal.SIGINT, lambda sig, frame: sys.exit(0)) |
|
signal.signal(signal.SIGTERM, lambda sig, frame: sys.exit(0)) |
|
|
|
sys.exit(main()) |