#!/usr/bin/env python3 """ DeepCode - AI Research Engine Launcher ๐Ÿงฌ Next-Generation AI Research Automation Platform โšก Transform research papers into working code automatically Cross-platform support: Windows, macOS, Linux """ import os import sys import subprocess import signal import platform import socket import time from pathlib import Path # Global process references for cleanup _backend_process = None _frontend_process = None def get_platform(): """Get current platform""" system = platform.system().lower() if system == "darwin": return "macos" elif system == "windows": return "windows" else: return "linux" def check_dependencies(): """Check if necessary dependencies are installed for new UI""" import importlib.util import shutil print("๐Ÿ” Checking dependencies...") missing_deps = [] missing_system_deps = [] # Check FastAPI availability (for backend) if importlib.util.find_spec("fastapi") is not None: print("โœ… FastAPI is installed") else: missing_deps.append("fastapi>=0.104.0") # Check uvicorn availability (for backend server) if importlib.util.find_spec("uvicorn") is not None: print("โœ… Uvicorn is installed") else: missing_deps.append("uvicorn>=0.24.0") # Check PyYAML availability if importlib.util.find_spec("yaml") is not None: print("โœ… PyYAML is installed") else: missing_deps.append("pyyaml>=6.0") # Check pydantic-settings availability if importlib.util.find_spec("pydantic_settings") is not None: print("โœ… Pydantic-settings is installed") else: missing_deps.append("pydantic-settings>=2.0.0") # Check Node.js availability (for frontend) node_cmd = "node.exe" if get_platform() == "windows" else "node" if shutil.which(node_cmd) or shutil.which("node"): try: result = subprocess.run( ["node", "--version"], capture_output=True, text=True, timeout=5, shell=(get_platform() == "windows"), ) if result.returncode == 0: print(f"โœ… Node.js is installed ({result.stdout.strip()})") except Exception: missing_system_deps.append("Node.js") else: missing_system_deps.append("Node.js") print("โŒ Node.js not found (required for frontend)") # Check npm availability npm_cmd = "npm.cmd" if get_platform() == "windows" else "npm" if shutil.which(npm_cmd) or shutil.which("npm"): print("โœ… npm is available") else: missing_system_deps.append("npm") print("โŒ npm not found (required for frontend)") # Display missing dependencies if missing_deps or missing_system_deps: print("\n๐Ÿ“‹ Dependency Status:") if missing_deps: print("โŒ Missing Python dependencies:") for dep in missing_deps: print(f" - {dep}") print(f"\nInstall with: pip install {' '.join(missing_deps)}") if missing_system_deps: print("\nโŒ Missing system dependencies:") for dep in missing_system_deps: print(f" - {dep}") print("\nInstall Node.js:") print(" - Windows/macOS: https://nodejs.org/") print(" - macOS: brew install node") print(" - Ubuntu/Debian: sudo apt-get install nodejs npm") # Fail if critical dependencies are missing if missing_deps or missing_system_deps: return False else: print("โœ… All dependencies satisfied") return True def is_port_in_use(port: int) -> bool: """Check if a port is in use (cross-platform)""" with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: return s.connect_ex(("localhost", port)) == 0 def kill_process_on_port(port: int): """Kill process using a specific port (cross-platform)""" current_platform = get_platform() try: if current_platform == "windows": # Windows: use netstat and taskkill result = subprocess.run( f"netstat -ano | findstr :{port}", capture_output=True, text=True, shell=True, ) if result.stdout: for line in result.stdout.strip().split("\n"): parts = line.split() if len(parts) >= 5: pid = parts[-1] if pid.isdigit(): subprocess.run( f"taskkill /F /PID {pid}", shell=True, capture_output=True, ) print(f" โœ“ Killed process on port {port} (PID: {pid})") else: # macOS/Linux: use lsof result = subprocess.run( f"lsof -ti :{port}", capture_output=True, text=True, shell=True ) if result.stdout: pids = result.stdout.strip().split("\n") for pid in pids: if pid.isdigit(): os.kill(int(pid), signal.SIGKILL) print(f" โœ“ Killed process on port {port} (PID: {pid})") except Exception as e: print(f" โš ๏ธ Could not kill process on port {port}: {e}") def cleanup_ports(): """Clean up ports 8000 and 5173 if in use""" for port in [8000, 5173]: if is_port_in_use(port): print(f"โš ๏ธ Port {port} is in use, cleaning up...") kill_process_on_port(port) time.sleep(1) def install_backend_deps(): """Install backend dependencies if needed""" import importlib.util if importlib.util.find_spec("fastapi") is None: print("๐Ÿ“ฆ Installing backend dependencies...") deps = [ "fastapi", "uvicorn", "pydantic-settings", "python-multipart", "aiofiles", "websockets", "pyyaml", ] subprocess.run( [sys.executable, "-m", "pip", "install", "-q"] + deps, check=True ) print("โœ… Backend dependencies installed") def install_frontend_deps(frontend_dir: Path): """Install frontend dependencies if needed""" node_modules = frontend_dir / "node_modules" if not node_modules.exists(): print("๐Ÿ“ฆ Installing frontend dependencies (first run)...") npm_cmd = "npm.cmd" if get_platform() == "windows" else "npm" subprocess.run( [npm_cmd, "install"], cwd=frontend_dir, check=True, shell=(get_platform() == "windows"), ) print("โœ… Frontend dependencies installed") def start_backend(backend_dir: Path): """Start the backend server""" global _backend_process print("๐Ÿ”ง Starting backend server...") # Use shell=True on Windows for proper command handling if get_platform() == "windows": _backend_process = subprocess.Popen( f'"{sys.executable}" -m uvicorn main:app --host 0.0.0.0 --port 8000 --reload', cwd=backend_dir, shell=True, creationflags=subprocess.CREATE_NEW_PROCESS_GROUP, ) else: _backend_process = subprocess.Popen( [ sys.executable, "-m", "uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--reload", ], cwd=backend_dir, start_new_session=True, # Create new process group ) # Wait for backend to start time.sleep(2) if _backend_process.poll() is None: print("โœ… Backend started: http://localhost:8000") return True else: print("โŒ Backend failed to start") return False def start_frontend(frontend_dir: Path): """Start the frontend dev server""" global _frontend_process print("๐ŸŽจ Starting frontend server...") npm_cmd = "npm.cmd" if get_platform() == "windows" else "npm" if get_platform() == "windows": _frontend_process = subprocess.Popen( f"{npm_cmd} run dev", cwd=frontend_dir, shell=True, creationflags=subprocess.CREATE_NEW_PROCESS_GROUP, ) else: _frontend_process = subprocess.Popen( [npm_cmd, "run", "dev"], cwd=frontend_dir, start_new_session=True, # Create new process group ) # Wait for frontend to start time.sleep(3) if _frontend_process.poll() is None: print("โœ… Frontend started: http://localhost:5173") return True else: print("โŒ Frontend failed to start") return False def cleanup_processes(): """Clean up running processes""" global _backend_process, _frontend_process print("\n๐Ÿ›‘ Stopping services...") for name, proc in [("Backend", _backend_process), ("Frontend", _frontend_process)]: if proc and proc.poll() is None: try: if get_platform() == "windows": # Windows: use taskkill with /T to kill tree subprocess.run( f"taskkill /F /T /PID {proc.pid}", shell=True, capture_output=True, ) else: # Unix: kill the process group try: os.killpg(os.getpgid(proc.pid), signal.SIGTERM) proc.wait(timeout=5) except Exception: os.killpg(os.getpgid(proc.pid), signal.SIGKILL) print(f" โœ“ {name} stopped") except Exception: # Fallback: try direct terminate try: proc.terminate() proc.wait(timeout=3) print(f" โœ“ {name} stopped") except Exception: try: proc.kill() print(f" โœ“ {name} killed") except Exception: print(f" โš ๏ธ Could not stop {name}") # Also clean up any orphaned processes on ports time.sleep(0.5) for port in [8000, 5173]: if is_port_in_use(port): kill_process_on_port(port) print("โœ… All services stopped") def cleanup_cache(): """Clean up Python cache files""" try: print("๐Ÿงน Cleaning up cache files...") # Clean up __pycache__ directories os.system('find . -type d -name "__pycache__" -exec rm -r {} + 2>/dev/null') # Clean up .pyc files os.system('find . -name "*.pyc" -delete 2>/dev/null') print("โœ… Cache cleanup completed") except Exception as e: print(f"โš ๏ธ Cache cleanup failed: {e}") def print_banner(): """Display startup banner""" banner = """ โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•— โ•‘ โ•‘ โ•‘ ๐Ÿงฌ DeepCode - AI Research Engine โ•‘ โ•‘ โ•‘ โ•‘ โšก NEURAL โ€ข AUTONOMOUS โ€ข REVOLUTIONARY โšก โ•‘ โ•‘ โ•‘ โ•‘ Transform research papers into working code โ•‘ โ•‘ Next-generation AI automation platform โ•‘ โ•‘ โ•‘ โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• """ print(banner) def launch_classic_ui(): """Launch classic Streamlit UI""" import importlib.util print("๐ŸŒ Launching Classic Streamlit UI...") # Check if Streamlit is installed if importlib.util.find_spec("streamlit") is None: print("โŒ Streamlit is not installed.") print("Install with: pip install streamlit") sys.exit(1) current_dir = Path(__file__).parent streamlit_app_path = current_dir / "ui" / "streamlit_app.py" if not streamlit_app_path.exists(): print(f"โŒ Streamlit app not found: {streamlit_app_path}") sys.exit(1) print(f"๐Ÿ“ UI App: {streamlit_app_path}") print("๐Ÿš€ Launching on http://localhost:8501") print("=" * 70) try: cmd = [ sys.executable, "-m", "streamlit", "run", str(streamlit_app_path), "--server.port", "8501", "--server.address", "localhost", "--browser.gatherUsageStats", "false", ] subprocess.run(cmd, check=True) except KeyboardInterrupt: print("\n\n๐Ÿ›‘ Streamlit server stopped by user") except Exception as e: print(f"\nโŒ Error: {e}") sys.exit(1) def launch_paper_test(paper_name: str, fast_mode: bool = False): """Launch paper testing mode""" try: print("\n๐Ÿงช Launching Paper Test Mode") print(f"๐Ÿ“„ Paper: {paper_name}") print(f"โšก Fast mode: {'enabled' if fast_mode else 'disabled'}") print("=" * 60) # Run the test setup setup_cmd = [sys.executable, "test_paper.py", paper_name] if fast_mode: setup_cmd.append("--fast") result = subprocess.run(setup_cmd, check=True) if result.returncode == 0: print("\nโœ… Paper test setup completed successfully!") print("๐Ÿ“ Files are ready in deepcode_lab/papers/") print("\n๐Ÿ’ก Next steps:") print(" 1. Install MCP dependencies: pip install -r requirements.txt") print( f" 2. Run full pipeline: python -m workflows.paper_test_engine --paper {paper_name}" + (" --fast" if fast_mode else "") ) except subprocess.CalledProcessError as e: print(f"\nโŒ Paper test setup failed: {e}") sys.exit(1) except Exception as e: print(f"\nโŒ Unexpected error: {e}") sys.exit(1) def main(): """Main function""" # Parse command line arguments if len(sys.argv) > 1: if sys.argv[1] == "test" and len(sys.argv) >= 3: # Paper testing mode: python deepcode.py test rice [--fast] paper_name = sys.argv[2] fast_mode = "--fast" in sys.argv or "-f" in sys.argv print_banner() launch_paper_test(paper_name, fast_mode) return elif sys.argv[1] == "--classic": # Launch classic Streamlit UI print_banner() launch_classic_ui() return elif sys.argv[1] in ["--help", "-h", "help"]: print_banner() print(""" ๐Ÿ”ง Usage: deepcode - Launch new React-based web UI deepcode test - Test paper reproduction deepcode test --fast - Test paper (fast mode) deepcode --classic - Launch classic Streamlit UI ๐Ÿ“„ Examples: deepcode - Start the new UI (recommended) deepcode test rice - Test RICE paper reproduction deepcode test rice --fast - Test RICE paper (fast mode) ๐ŸŒ New UI Features: โ€ข User-in-Loop interaction โ€ข Real-time progress tracking โ€ข Inline chat interaction โ€ข Modern React-based interface ๐Ÿ“ Available papers:""") # List available papers papers_dir = "papers" if os.path.exists(papers_dir): for item in os.listdir(papers_dir): item_path = os.path.join(papers_dir, item) if os.path.isdir(item_path): paper_md = os.path.join(item_path, "paper.md") addendum_md = os.path.join(item_path, "addendum.md") status = "โœ…" if os.path.exists(paper_md) else "โŒ" addendum_status = "๐Ÿ“„" if os.path.exists(addendum_md) else "โž–" print(f" {status} {item} {addendum_status}") print( "\n Legend: โœ… = paper.md exists, ๐Ÿ“„ = addendum.md exists, โž– = no addendum" ) return print_banner() # Show platform info current_platform = get_platform() print(f"๐Ÿ–ฅ๏ธ Platform: {current_platform.capitalize()}") # Check dependencies if not check_dependencies(): print("\n๐Ÿšจ Please install missing dependencies and try again.") sys.exit(1) # Get paths current_dir = Path(__file__).parent new_ui_dir = current_dir / "new_ui" backend_dir = new_ui_dir / "backend" frontend_dir = new_ui_dir / "frontend" # Check if new_ui directory exists if not new_ui_dir.exists(): print(f"โŒ New UI directory not found: {new_ui_dir}") sys.exit(1) print("\n๐Ÿš€ Starting DeepCode New UI...") print("=" * 70) print("๐ŸŽจ Frontend: http://localhost:5173") print("๐Ÿ”ง Backend: http://localhost:8000") print("๐Ÿ“š API Docs: http://localhost:8000/docs") print("=" * 70) print("๐Ÿ’ก Tip: Keep this terminal open while using the application") print("๐Ÿ›‘ Press Ctrl+C to stop all services") print("=" * 70) try: # Clean up ports if in use cleanup_ports() # Install dependencies if needed install_backend_deps() install_frontend_deps(frontend_dir) # Start services if not start_backend(backend_dir): print("โŒ Failed to start backend") sys.exit(1) if not start_frontend(frontend_dir): print("โŒ Failed to start frontend") cleanup_processes() sys.exit(1) print("\n" + "=" * 70) print("โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—") print("โ•‘ ๐ŸŽ‰ DeepCode New UI is running! โ•‘") print("โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ฃ") print("โ•‘ โ•‘") print("โ•‘ ๐ŸŒ Frontend: http://localhost:5173 โ•‘") print("โ•‘ ๐Ÿ”ง Backend: http://localhost:8000 โ•‘") print("โ•‘ ๐Ÿ“š API Docs: http://localhost:8000/docsโ•‘") print("โ•‘ โ•‘") print("โ•‘ Press Ctrl+C to stop all services โ•‘") print("โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•") print("=" * 70 + "\n") # Wait for processes while True: # Check if processes are still running if _backend_process and _backend_process.poll() is not None: print("โš ๏ธ Backend process exited unexpectedly") break if _frontend_process and _frontend_process.poll() is not None: print("โš ๏ธ Frontend process exited unexpectedly") break time.sleep(1) except KeyboardInterrupt: print("\n") except Exception as e: print(f"\nโŒ Unexpected error: {e}") finally: cleanup_processes() cleanup_cache() print("Thank you for using DeepCode! ๐Ÿงฌ") if __name__ == "__main__": main()