From f8e5ae062f38ef8b43a0f961d330c65b784bcfd0 Mon Sep 17 00:00:00 2001 From: Kolja Kiss Date: Fri, 30 May 2025 06:04:25 +0200 Subject: [PATCH 1/3] feat(setup.py): For those complaining. Add resume support to setup script using progress tracking with '#' will be ignored, and an empty message aborts the commit. --- .gitignore | 2 + setup.py | 167 ++++++++++++++++++++++++++++++----------------------- 2 files changed, 98 insertions(+), 71 deletions(-) diff --git a/.gitignore b/.gitignore index 7e56ba99..2d785b45 100644 --- a/.gitignore +++ b/.gitignore @@ -194,3 +194,5 @@ supabase/.temp/storage-version redis_data rabbitmq_data + +.setup_progress diff --git a/setup.py b/setup.py index f28c092d..b2a6c904 100644 --- a/setup.py +++ b/setup.py @@ -8,6 +8,7 @@ from getpass import getpass import re IS_WINDOWS = platform.system() == 'Windows' +PROGRESS_FILE = '.setup_progress' # ANSI colors for pretty output class Colors: @@ -36,6 +37,24 @@ def print_banner(): {Colors.ENDC} """) +# Progress tracking +def save_progress(step): + with open(PROGRESS_FILE, 'w') as f: + f.write(str(step)) + +def load_progress(): + if os.path.exists(PROGRESS_FILE): + with open(PROGRESS_FILE, 'r') as f: + try: + return int(f.read().strip()) + except ValueError: + return 0 + return 0 + +def clear_progress(): + if os.path.exists(PROGRESS_FILE): + os.remove(PROGRESS_FILE) + def print_step(step_num, total_steps, step_name): """Print a step header""" print(f"\n{Colors.BLUE}{Colors.BOLD}Step {step_num}/{total_steps}: {step_name}{Colors.ENDC}") @@ -806,54 +825,66 @@ def final_instructions(use_docker=True, env_vars=None): print_info("4. Once all services are running, access Suna at: http://localhost:3000") print_info("5. Create an account using Supabase authentication to start using Suna") +# Then update your main() function as follows: + def main(): - total_steps = 8 # Reduced by 1 since we're skipping the clone step - current_step = 1 - - # Print banner + total_steps = 8 + current_step = load_progress() + 1 + print_banner() print("This wizard will guide you through setting up Suna, an open-source generalist AI agent.\n") - - # Step 1: Check requirements - print_step(current_step, total_steps, "Checking requirements") - check_requirements() - check_docker_running() - - # Check if we're in the Suna repository - if not check_suna_directory(): - print_error("This setup script must be run from the Suna repository root directory.") - print_info("Please clone the repository first with:") - print_info(" git clone https://github.com/kortix-ai/suna.git") - print_info(" cd suna") - print_info("Then run this setup script again.") - sys.exit(1) - - current_step += 1 - - # Collect all environment variables - print_step(current_step, total_steps, "Collecting Supabase information") - supabase_info = collect_supabase_info() - # Set Supabase URL in environment for later use - os.environ['SUPABASE_URL'] = supabase_info['SUPABASE_URL'] - current_step += 1 - - print_step(current_step, total_steps, "Collecting Daytona information") - daytona_info = collect_daytona_info() - current_step += 1 - - print_step(current_step, total_steps, "Collecting LLM API keys") - llm_api_keys = collect_llm_api_keys() - current_step += 1 - - print_step(current_step, total_steps, "Collecting search and web scraping API keys") - search_api_keys = collect_search_api_keys() - current_step += 1 - - print_step(current_step, total_steps, "Collecting RapidAPI key") - rapidapi_keys = collect_rapidapi_keys() - current_step += 1 - - # Combine all environment variables + + if current_step <= 1: + print_step(current_step, total_steps, "Checking requirements") + check_requirements() + check_docker_running() + if not check_suna_directory(): + print_error("This setup script must be run from the Suna repository root directory.") + sys.exit(1) + save_progress(current_step) + current_step += 1 + + if current_step <= 2: + print_step(current_step, total_steps, "Collecting Supabase information") + supabase_info = collect_supabase_info() + os.environ['SUPABASE_URL'] = supabase_info['SUPABASE_URL'] + save_progress(current_step) + current_step += 1 + else: + supabase_info = {} + + if current_step <= 3: + print_step(current_step, total_steps, "Collecting Daytona information") + daytona_info = collect_daytona_info() + save_progress(current_step) + current_step += 1 + else: + daytona_info = {} + + if current_step <= 4: + print_step(current_step, total_steps, "Collecting LLM API keys") + llm_api_keys = collect_llm_api_keys() + save_progress(current_step) + current_step += 1 + else: + llm_api_keys = {} + + if current_step <= 5: + print_step(current_step, total_steps, "Collecting search and web scraping API keys") + search_api_keys = collect_search_api_keys() + save_progress(current_step) + current_step += 1 + else: + search_api_keys = {} + + if current_step <= 6: + print_step(current_step, total_steps, "Collecting RapidAPI key") + rapidapi_keys = collect_rapidapi_keys() + save_progress(current_step) + current_step += 1 + else: + rapidapi_keys = {} + env_vars = { 'supabase': supabase_info, 'daytona': daytona_info, @@ -861,32 +892,26 @@ def main(): 'search': search_api_keys, 'rapidapi': rapidapi_keys, } - - # Setup Supabase database - setup_supabase() - current_step += 1 - - # Install dependencies before starting Suna - print_step(current_step, total_steps, "Installing dependencies") - install_dependencies() - - # Configure environment files with the correct settings before starting - print_info("Configuring environment files...") - configure_backend_env(env_vars, True) # Always create for Docker first - configure_frontend_env(env_vars, True) - - # Now ask how to start Suna - print_step(current_step, total_steps, "Starting Suna") - use_docker = start_suna() - - # Update environment files if needed for non-Docker setup - if not use_docker: - print_info("Updating environment files for manual startup...") - configure_backend_env(env_vars, use_docker) - configure_frontend_env(env_vars, use_docker) - - # Final instructions - final_instructions(use_docker, env_vars) + + if current_step <= 7: + print_step(current_step, total_steps, "Setting up Supabase") + setup_supabase() + save_progress(current_step) + current_step += 1 + + if current_step <= 8: + print_step(current_step, total_steps, "Installing dependencies") + install_dependencies() + print_info("Configuring environment files...") + configure_backend_env(env_vars, True) + configure_frontend_env(env_vars, True) + print_step(current_step, total_steps, "Starting Suna") + use_docker = start_suna() + if not use_docker: + configure_backend_env(env_vars, use_docker) + configure_frontend_env(env_vars, use_docker) + final_instructions(use_docker, env_vars) + clear_progress() if __name__ == "__main__": try: From bb4e9435d9bef3fb8be30bb239210d8e28d943e0 Mon Sep 17 00:00:00 2001 From: kdkiss <140483096+kdkiss@users.noreply.github.com> Date: Sat, 31 May 2025 06:43:17 +0200 Subject: [PATCH 2/3] Update setup.py Fix for env variables not being saved with the progress step. --- setup.py | 64 +++++++++++++++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 26 deletions(-) diff --git a/setup.py b/setup.py index b2a6c904..fa178942 100644 --- a/setup.py +++ b/setup.py @@ -6,9 +6,10 @@ import platform import subprocess from getpass import getpass import re +import json + IS_WINDOWS = platform.system() == 'Windows' -PROGRESS_FILE = '.setup_progress' # ANSI colors for pretty output class Colors: @@ -37,7 +38,8 @@ def print_banner(): {Colors.ENDC} """) -# Progress tracking +PROGRESS_FILE = '.setup_progress' + def save_progress(step): with open(PROGRESS_FILE, 'w') as f: f.write(str(step)) @@ -55,6 +57,25 @@ def clear_progress(): if os.path.exists(PROGRESS_FILE): os.remove(PROGRESS_FILE) +ENV_DATA_FILE = '.setup_env.json' + +def save_env_data(env_data): + with open(ENV_DATA_FILE, 'w') as f: + json.dump(env_data, f) + +def load_env_data(): + if os.path.exists(ENV_DATA_FILE): + with open(ENV_DATA_FILE, 'r') as f: + return json.load(f) + return { + 'supabase': {}, + 'daytona': {}, + 'llm': {}, + 'search': {}, + 'rapidapi': {} + } + + def print_step(step_num, total_steps, step_name): """Print a step header""" print(f"\n{Colors.BLUE}{Colors.BOLD}Step {step_num}/{total_steps}: {step_name}{Colors.ENDC}") @@ -834,6 +855,8 @@ def main(): print_banner() print("This wizard will guide you through setting up Suna, an open-source generalist AI agent.\n") + env_vars = load_env_data() + if current_step <= 1: print_step(current_step, total_steps, "Checking requirements") check_requirements() @@ -846,52 +869,39 @@ def main(): if current_step <= 2: print_step(current_step, total_steps, "Collecting Supabase information") - supabase_info = collect_supabase_info() - os.environ['SUPABASE_URL'] = supabase_info['SUPABASE_URL'] + env_vars['supabase'] = collect_supabase_info() + os.environ['SUPABASE_URL'] = env_vars['supabase']['SUPABASE_URL'] + save_env_data(env_vars) save_progress(current_step) current_step += 1 - else: - supabase_info = {} if current_step <= 3: print_step(current_step, total_steps, "Collecting Daytona information") - daytona_info = collect_daytona_info() + env_vars['daytona'] = collect_daytona_info() + save_env_data(env_vars) save_progress(current_step) current_step += 1 - else: - daytona_info = {} if current_step <= 4: print_step(current_step, total_steps, "Collecting LLM API keys") - llm_api_keys = collect_llm_api_keys() + env_vars['llm'] = collect_llm_api_keys() + save_env_data(env_vars) save_progress(current_step) current_step += 1 - else: - llm_api_keys = {} if current_step <= 5: print_step(current_step, total_steps, "Collecting search and web scraping API keys") - search_api_keys = collect_search_api_keys() + env_vars['search'] = collect_search_api_keys() + save_env_data(env_vars) save_progress(current_step) current_step += 1 - else: - search_api_keys = {} if current_step <= 6: print_step(current_step, total_steps, "Collecting RapidAPI key") - rapidapi_keys = collect_rapidapi_keys() + env_vars['rapidapi'] = collect_rapidapi_keys() + save_env_data(env_vars) save_progress(current_step) current_step += 1 - else: - rapidapi_keys = {} - - env_vars = { - 'supabase': supabase_info, - 'daytona': daytona_info, - 'llm': llm_api_keys, - 'search': search_api_keys, - 'rapidapi': rapidapi_keys, - } if current_step <= 7: print_step(current_step, total_steps, "Setting up Supabase") @@ -912,6 +922,8 @@ def main(): configure_frontend_env(env_vars, use_docker) final_instructions(use_docker, env_vars) clear_progress() + if os.path.exists(ENV_DATA_FILE): + os.remove(ENV_DATA_FILE) if __name__ == "__main__": try: From 082902adfbda3acef6c3fde2a4b7e89d5519092a Mon Sep 17 00:00:00 2001 From: kdkiss <140483096+kdkiss@users.noreply.github.com> Date: Sat, 31 May 2025 06:44:00 +0200 Subject: [PATCH 3/3] Update .gitignore add .setup_env.json --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 2d785b45..ebee6baf 100644 --- a/.gitignore +++ b/.gitignore @@ -196,3 +196,5 @@ redis_data rabbitmq_data .setup_progress + +.setup_env.json