-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstart.py
More file actions
156 lines (135 loc) · 4.39 KB
/
Copy pathstart.py
File metadata and controls
156 lines (135 loc) · 4.39 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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#!/usr/bin/env python3
"""
Socratis - One-Click Startup Script
Starts all services: Backend (Express), Frontend (Next.js), and Voice Agent (Python)
"""
import subprocess
import sys
import os
import time
import signal
from pathlib import Path
# Get the root directory (where this script is located)
ROOT_DIR = Path(__file__).parent.absolute()
SERVER_DIR = ROOT_DIR / "server"
CLIENT_DIR = ROOT_DIR / "client"
AGENT_DIR = ROOT_DIR / "server" / "agent"
processes = []
def cleanup(signum=None, frame=None):
"""Cleanup all spawned processes"""
print("\n🛑 Shutting down all services...")
for proc in processes:
try:
proc.terminate()
proc.wait(timeout=5)
except:
try:
proc.kill()
except:
pass
print("✅ All services stopped.")
sys.exit(0)
def start_service(name, cmd, cwd, log_file=None):
"""Start a service in a new process"""
print(f"🚀 Starting {name}...")
# Create log file for capturing output
if log_file:
log_path = ROOT_DIR / log_file
stdout = open(log_path, 'w')
stderr = subprocess.STDOUT
else:
stdout = subprocess.PIPE
stderr = subprocess.PIPE
# Start process without CREATE_NEW_CONSOLE to properly track status
proc = subprocess.Popen(
cmd,
cwd=cwd,
shell=True,
stdout=stdout,
stderr=stderr
)
processes.append(proc)
return proc
def main():
print("=" * 60)
print("🎙️ SOCRATIS - AI Interview Platform")
print("=" * 60)
print()
# Register signal handlers for cleanup
signal.signal(signal.SIGINT, cleanup)
signal.signal(signal.SIGTERM, cleanup)
# Check if directories exist
if not SERVER_DIR.exists():
print(f"❌ Server directory not found: {SERVER_DIR}")
sys.exit(1)
if not CLIENT_DIR.exists():
print(f"❌ Client directory not found: {CLIENT_DIR}")
sys.exit(1)
if not AGENT_DIR.exists():
print(f"❌ Agent directory not found: {AGENT_DIR}")
sys.exit(1)
# Start Backend Server (Port 4000)
start_service(
"Backend Server (Port 4000)",
"npm run dev",
SERVER_DIR,
"backend.log"
)
time.sleep(3) # Give server time to start
# Start Frontend (Port 3000)
start_service(
"Frontend (Port 3000)",
"npm run dev",
CLIENT_DIR,
"frontend.log"
)
time.sleep(3) # Give Next.js time to compile
# Start Voice Agent
start_service(
"Voice Agent (LiveKit)",
"python agent.py start",
AGENT_DIR,
"agent.log"
)
print()
print("=" * 60)
print("✅ All services started!")
print()
print("📍 Frontend: http://localhost:3000")
print("📍 Backend: http://localhost:4000")
print("📍 Interview: http://localhost:3000/interview/new")
print()
print("📄 Logs: backend.log, frontend.log, agent.log")
print()
print("Press Ctrl+C to stop all services")
print("=" * 60)
# Service names for error reporting
service_names = ["Backend", "Frontend", "Agent"]
failed_services = set()
# Keep the script running and monitor processes
try:
while True:
time.sleep(2)
# Check if any process has died
for i, proc in enumerate(processes):
if proc.poll() is not None:
exit_code = proc.returncode
log_file = ["backend.log", "frontend.log", "agent.log"][i]
if i == 2: # Agent Logic
print(f"⚠️ Agent stopped (exit code: {exit_code}). Restarting in 1s...")
time.sleep(1)
# Restart Agent
new_proc = start_service(
"Voice Agent (LiveKit) [Restored]",
"python agent.py start",
AGENT_DIR,
"agent.log"
)
processes[i] = new_proc
elif i not in failed_services:
failed_services.add(i)
print(f"⚠️ {service_names[i]} stopped (exit code: {exit_code}) - check {log_file}")
except KeyboardInterrupt:
cleanup()
if __name__ == "__main__":
main()