mirror of https://github.com/kortix-ai/suna.git
183 lines
5.8 KiB
Python
183 lines
5.8 KiB
Python
#!/usr/bin/env python3
|
|
|
|
import subprocess
|
|
import sys
|
|
import platform
|
|
import os
|
|
import json
|
|
|
|
IS_WINDOWS = platform.system() == "Windows"
|
|
PROGRESS_FILE = ".setup_progress"
|
|
|
|
|
|
# --- ANSI Colors ---
|
|
class Colors:
|
|
HEADER = "\033[95m"
|
|
BLUE = "\033[94m"
|
|
CYAN = "\033[96m"
|
|
GREEN = "\033[92m"
|
|
YELLOW = "\033[93m"
|
|
RED = "\033[91m"
|
|
ENDC = "\033[0m"
|
|
BOLD = "\033[1m"
|
|
UNDERLINE = "\033[4m"
|
|
|
|
|
|
def load_progress():
|
|
"""Loads the last saved step and data from setup."""
|
|
if os.path.exists(PROGRESS_FILE):
|
|
with open(PROGRESS_FILE, "r") as f:
|
|
try:
|
|
return json.load(f)
|
|
except (json.JSONDecodeError, KeyError):
|
|
return {"step": 0, "data": {}}
|
|
return {"step": 0, "data": {}}
|
|
|
|
|
|
def get_setup_method():
|
|
"""Gets the setup method chosen during setup."""
|
|
progress = load_progress()
|
|
return progress.get("data", {}).get("setup_method")
|
|
|
|
|
|
def check_docker_compose_up():
|
|
result = subprocess.run(
|
|
["docker", "compose", "ps", "-q"],
|
|
capture_output=True,
|
|
text=True,
|
|
shell=IS_WINDOWS,
|
|
)
|
|
return len(result.stdout.strip()) > 0
|
|
|
|
|
|
def print_manual_instructions():
|
|
"""Prints instructions for manually starting Suna services."""
|
|
print(f"\n{Colors.BLUE}{Colors.BOLD}🚀 Manual Startup Instructions{Colors.ENDC}\n")
|
|
|
|
print("To start Suna, you need to run these commands in separate terminals:\n")
|
|
|
|
print(f"{Colors.BOLD}1. Start Infrastructure (in project root):{Colors.ENDC}")
|
|
print(f"{Colors.CYAN} docker compose up redis -d{Colors.ENDC}\n")
|
|
|
|
print(f"{Colors.BOLD}2. Start Frontend (in a new terminal):{Colors.ENDC}")
|
|
print(f"{Colors.CYAN} cd frontend && npm run dev{Colors.ENDC}\n")
|
|
|
|
print(f"{Colors.BOLD}3. Start Backend (in a new terminal):{Colors.ENDC}")
|
|
print(f"{Colors.CYAN} cd backend && uv run api.py{Colors.ENDC}\n")
|
|
|
|
print(f"{Colors.BOLD}4. Start Background Worker (in a new terminal):{Colors.ENDC}")
|
|
print(
|
|
f"{Colors.CYAN} cd backend && uv run dramatiq run_agent_background{Colors.ENDC}\n"
|
|
)
|
|
|
|
print("Once all services are running, access Suna at: http://localhost:3000\n")
|
|
|
|
print(
|
|
f"{Colors.YELLOW}💡 Tip:{Colors.ENDC} You can use '{Colors.CYAN}./start.py{Colors.ENDC}' to start/stop the infrastructure services."
|
|
)
|
|
|
|
|
|
def main():
|
|
setup_method = get_setup_method()
|
|
|
|
if "--help" in sys.argv:
|
|
print("Usage: ./start.py [OPTION]")
|
|
print("Manage Suna services based on your setup method")
|
|
print("\nOptions:")
|
|
print(" -f\tForce start containers without confirmation")
|
|
print(" --help\tShow this help message")
|
|
return
|
|
|
|
# If setup hasn't been run or method is not determined, default to docker
|
|
if not setup_method:
|
|
print(
|
|
f"{Colors.YELLOW}⚠️ Setup method not detected. Run './setup.py' first or using Docker Compose as default.{Colors.ENDC}"
|
|
)
|
|
setup_method = "docker"
|
|
|
|
if setup_method == "manual":
|
|
# For manual setup, we only manage infrastructure services (redis)
|
|
# and show instructions for the rest
|
|
print(f"{Colors.BLUE}{Colors.BOLD}Manual Setup Detected{Colors.ENDC}")
|
|
print("Managing infrastructure services (Redis)...\n")
|
|
|
|
force = "-f" in sys.argv
|
|
if force:
|
|
print("Force awakened. Skipping confirmation.")
|
|
|
|
is_infra_up = subprocess.run(
|
|
["docker", "compose", "ps", "-q", "redis"],
|
|
capture_output=True,
|
|
text=True,
|
|
shell=IS_WINDOWS,
|
|
)
|
|
is_up = len(is_infra_up.stdout.strip()) > 0
|
|
|
|
if is_up:
|
|
action = "stop"
|
|
msg = "🛑 Stop infrastructure services? [y/N] "
|
|
else:
|
|
action = "start"
|
|
msg = "⚡ Start infrastructure services? [Y/n] "
|
|
|
|
if not force:
|
|
response = input(msg).strip().lower()
|
|
if action == "stop":
|
|
if response != "y":
|
|
print("Aborting.")
|
|
return
|
|
else:
|
|
if response == "n":
|
|
print("Aborting.")
|
|
return
|
|
|
|
if action == "stop":
|
|
subprocess.run(["docker", "compose", "down"], shell=IS_WINDOWS)
|
|
print(f"\n{Colors.GREEN}✅ Infrastructure services stopped.{Colors.ENDC}")
|
|
else:
|
|
subprocess.run(
|
|
["docker", "compose", "up", "redis", "-d"], shell=IS_WINDOWS
|
|
)
|
|
print(f"\n{Colors.GREEN}✅ Infrastructure services started.{Colors.ENDC}")
|
|
print_manual_instructions()
|
|
|
|
else: # docker setup
|
|
print(f"{Colors.BLUE}{Colors.BOLD}Docker Setup Detected{Colors.ENDC}")
|
|
print("Managing all Suna services with Docker Compose...\n")
|
|
|
|
force = "-f" in sys.argv
|
|
if force:
|
|
print("Force awakened. Skipping confirmation.")
|
|
|
|
is_up = check_docker_compose_up()
|
|
|
|
if is_up:
|
|
action = "stop"
|
|
msg = "🛑 Stop all Suna services? [y/N] "
|
|
else:
|
|
action = "start"
|
|
msg = "⚡ Start all Suna services? [Y/n] "
|
|
|
|
if not force:
|
|
response = input(msg).strip().lower()
|
|
if action == "stop":
|
|
if response != "y":
|
|
print("Aborting.")
|
|
return
|
|
else:
|
|
if response == "n":
|
|
print("Aborting.")
|
|
return
|
|
|
|
if action == "stop":
|
|
subprocess.run(["docker", "compose", "down"], shell=IS_WINDOWS)
|
|
print(f"\n{Colors.GREEN}✅ All Suna services stopped.{Colors.ENDC}")
|
|
else:
|
|
subprocess.run(["docker", "compose", "up", "-d"], shell=IS_WINDOWS)
|
|
print(f"\n{Colors.GREEN}✅ All Suna services started.{Colors.ENDC}")
|
|
print(f"{Colors.CYAN}🌐 Access Suna at: http://localhost:3000{Colors.ENDC}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|