2023-09-16 17:53:28 +00:00
"""
This is a minimal file intended to be run by users to help them manage the autogpt projects .
If you want to contribute , please use only libraries that come as part of Python .
To ensure efficiency , add the imports to the functions so only what is needed is imported .
"""
2023-09-15 13:14:06 +00:00
try :
import click
2023-09-15 17:44:37 +00:00
import github
2023-09-15 13:14:06 +00:00
except ImportError :
import os
2023-09-16 16:28:26 +00:00
os . system ( " pip3 install click " )
os . system ( " pip3 install PyGithub " )
2023-09-15 13:14:06 +00:00
import click
@click.group ( )
def cli ( ) :
pass
2023-09-16 16:28:26 +00:00
2023-09-15 13:14:06 +00:00
@cli.command ( )
def setup ( ) :
2023-09-15 13:44:11 +00:00
""" Installs dependencies needed for your system. Works with Linux, MacOS and Windows WSL. """
2023-09-15 13:14:06 +00:00
import os
import subprocess
2023-09-16 16:28:26 +00:00
2023-09-16 17:53:28 +00:00
click . echo (
click . style (
"""
d8888 888 . d8888b . 8888888 b . 88888888888
d88888 888 d88P Y88b 888 Y88b 888
d88P888 888 888 888 888 888 888
d88P 888 888 888 888888 . d88b . 888 888 d88P 888
d88P 888 888 888 888 d88 " " 88 b 888 88888 8888888 P " 888
d88P 888 888 888 888 888 888 888 888 888 888
d8888888888 Y88b 888 Y88b . Y88 . .88 P Y88b d88P 888 888
d88P 888 " Y88888 " Y888 " Y88P " " Y8888P88 888 888
""" ,
fg = " green " ,
)
)
2023-09-15 13:14:06 +00:00
script_dir = os . path . dirname ( os . path . realpath ( __file__ ) )
2023-09-16 16:28:26 +00:00
setup_script = os . path . join ( script_dir , " setup.sh " )
2023-09-17 16:41:06 +00:00
install_error = False
2023-09-15 13:14:06 +00:00
if os . path . exists ( setup_script ) :
2023-09-16 17:53:28 +00:00
click . echo ( click . style ( " 🚀 Setup initiated... \n " , fg = " green " ) )
2023-09-17 16:41:06 +00:00
try :
subprocess . check_call ( [ setup_script ] , cwd = script_dir )
except subprocess . CalledProcessError :
click . echo (
click . style ( " ❌ There was an issue with the installation. " , fg = " red " )
)
install_error = True
2023-09-15 13:14:06 +00:00
else :
2023-09-16 16:28:26 +00:00
click . echo (
click . style (
" ❌ Error: setup.sh does not exist in the current directory. " , fg = " red "
)
)
2023-09-17 16:41:06 +00:00
install_error = True
2023-09-15 17:44:37 +00:00
try :
# Check if GitHub user name is configured
2023-09-16 16:28:26 +00:00
user_name = (
subprocess . check_output ( [ " git " , " config " , " user.name " ] )
. decode ( " utf-8 " )
. strip ( )
)
user_email = (
subprocess . check_output ( [ " git " , " config " , " user.email " ] )
. decode ( " utf-8 " )
. strip ( )
)
2023-09-15 17:44:37 +00:00
if user_name and user_email :
2023-09-16 16:28:26 +00:00
click . echo (
click . style (
f " ✅ GitHub account is configured with username: { user_name } and email: { user_email } " ,
fg = " green " ,
)
)
2023-09-15 17:44:37 +00:00
else :
2023-09-16 16:28:26 +00:00
raise subprocess . CalledProcessError (
returncode = 1 , cmd = " git config user.name or user.email "
)
2023-09-15 17:44:37 +00:00
except subprocess . CalledProcessError :
# If the GitHub account is not configured, print instructions on how to set it up
2023-09-16 16:28:26 +00:00
click . echo ( click . style ( " ❌ GitHub account is not configured. " , fg = " red " ) )
click . echo (
click . style (
" To configure your GitHub account, use the following commands: " ,
fg = " red " ,
)
)
click . echo (
click . style (
' git config --global user.name " Your GitHub Username " ' , fg = " red "
)
)
click . echo (
click . style (
' git config --global user.email " Your GitHub Email " ' , fg = " red "
)
)
2023-09-17 16:41:06 +00:00
install_error = True
print_access_token_instructions = False
2023-09-15 17:44:37 +00:00
# Check for the existence of the .github_access_token file
2023-09-16 16:28:26 +00:00
if os . path . exists ( " .github_access_token " ) :
with open ( " .github_access_token " , " r " ) as file :
2023-09-15 17:44:37 +00:00
github_access_token = file . read ( ) . strip ( )
if github_access_token :
2023-09-16 16:28:26 +00:00
click . echo (
click . style (
" ✅ GitHub access token loaded successfully. " , fg = " green "
)
)
2023-09-15 17:44:37 +00:00
# Check if the token has the required permissions
import requests
2023-09-16 16:28:26 +00:00
headers = { " Authorization " : f " token { github_access_token } " }
response = requests . get ( " https://api.github.com/user " , headers = headers )
2023-09-15 17:44:37 +00:00
if response . status_code == 200 :
2023-09-16 16:28:26 +00:00
scopes = response . headers . get ( " X-OAuth-Scopes " )
if " public_repo " in scopes or " repo " in scopes :
click . echo (
click . style (
" ✅ GitHub access token has the required permissions. " ,
fg = " green " ,
)
)
2023-09-15 17:44:37 +00:00
else :
2023-09-17 16:41:06 +00:00
install_error = True
2023-09-16 16:28:26 +00:00
click . echo (
click . style (
" ❌ GitHub access token does not have the required permissions. Please ensure it has ' public_repo ' or ' repo ' scope. " ,
fg = " red " ,
)
)
2023-09-15 17:44:37 +00:00
else :
2023-09-17 16:41:06 +00:00
install_error = True
2023-09-16 16:28:26 +00:00
click . echo (
click . style (
" ❌ Failed to validate GitHub access token. Please ensure it is correct. " ,
fg = " red " ,
)
)
2023-09-15 17:44:37 +00:00
else :
2023-09-17 16:41:06 +00:00
install_error = True
2023-09-16 16:28:26 +00:00
click . echo (
click . style (
" ❌ GitHub access token file is empty. Please follow the instructions below to set up your GitHub access token. " ,
fg = " red " ,
)
)
2023-09-17 16:41:06 +00:00
print_access_token_instructions = True
2023-09-15 17:44:37 +00:00
else :
# Create the .github_access_token file if it doesn't exist
2023-09-16 16:28:26 +00:00
with open ( " .github_access_token " , " w " ) as file :
file . write ( " " )
2023-09-17 16:41:06 +00:00
install_error = True
print_access_token_instructions = True
2023-09-15 17:44:37 +00:00
2023-09-17 16:41:06 +00:00
if print_access_token_instructions :
2023-09-15 17:44:37 +00:00
# Instructions to set up GitHub access token
2023-09-16 16:28:26 +00:00
click . echo (
click . style (
" ❌ To configure your GitHub access token, follow these steps: " , fg = " red "
)
)
click . echo (
click . style ( " \t 1. Ensure you are logged into your GitHub account " , fg = " red " )
)
click . echo (
click . style ( " \t 2. Navigate to https://github.com/settings/tokens " , fg = " red " )
)
click . echo ( click . style ( " \t 6. Click on ' Generate new token ' . " , fg = " red " ) )
click . echo (
click . style (
" \t 7. Fill out the form to generate a new token. Ensure you select the ' repo ' scope. " ,
fg = " red " ,
)
)
click . echo (
click . style (
" \t 8. Open the ' .github_access_token ' file in the same directory as this script and paste the token into this file. " ,
fg = " red " ,
)
)
click . echo (
click . style ( " \t 9. Save the file and run the setup command again. " , fg = " red " )
)
2023-09-17 16:41:06 +00:00
if install_error :
click . echo (
click . style (
" \n \n 🔴 If you need help, please raise a ticket on GitHub at https://github.com/Significant-Gravitas/Auto-GPT/issues \n \n " ,
fg = " magenta " ,
bold = True ,
)
)
2023-09-15 17:44:37 +00:00
2023-09-15 13:14:06 +00:00
@cli.group ( )
2023-09-15 17:50:25 +00:00
def agent ( ) :
2023-09-15 13:44:11 +00:00
""" Commands to create, start and stop agents """
2023-09-15 13:14:06 +00:00
pass
2023-09-16 16:28:26 +00:00
2023-09-15 17:50:25 +00:00
@agent.command ( )
2023-09-16 16:28:26 +00:00
@click.argument ( " agent_name " )
2023-09-15 13:14:06 +00:00
def create ( agent_name ) :
""" Create ' s a new agent with the agent name provieded """
import os
import re
2023-09-16 16:28:26 +00:00
import shutil
2023-09-15 13:14:06 +00:00
if not re . match ( " ^[a-zA-Z0-9_-]*$ " , agent_name ) :
2023-09-16 16:28:26 +00:00
click . echo (
click . style (
f " 😞 Agent name ' { agent_name } ' is not valid. It should not contain spaces or special characters other than -_ " ,
fg = " red " ,
)
)
2023-09-15 13:14:06 +00:00
return
try :
2023-09-16 16:28:26 +00:00
new_agent_dir = f " ./autogpts/ { agent_name } "
agent_json_file = f " ./arena/ { agent_name } .json "
2023-09-15 18:31:00 +00:00
if not os . path . exists ( new_agent_dir ) and not os . path . exists ( agent_json_file ) :
2023-09-16 16:28:26 +00:00
shutil . copytree ( " ./autogpts/forge " , new_agent_dir )
click . echo (
click . style (
f " 🎉 New agent ' { agent_name } ' created. The code for your new agent is in: autogpts/ { agent_name } " ,
fg = " green " ,
)
)
click . echo (
click . style (
f " 🚀 If you would like to enter the arena, run ' ./run arena enter { agent_name } ' " ,
fg = " yellow " ,
)
)
2023-09-15 13:14:06 +00:00
else :
2023-09-16 16:28:26 +00:00
click . echo (
click . style (
f " 😞 Agent ' { agent_name } ' already exists. Enter a different name for your agent " ,
fg = " red " ,
)
)
2023-09-15 13:14:06 +00:00
except Exception as e :
2023-09-16 16:28:26 +00:00
click . echo ( click . style ( f " 😢 An error occurred: { e } " , fg = " red " ) )
2023-09-15 13:14:06 +00:00
2023-09-15 17:50:25 +00:00
@agent.command ( )
2023-09-16 16:28:26 +00:00
@click.argument ( " agent_name " )
2023-09-15 13:14:06 +00:00
def start ( agent_name ) :
""" Start agent command """
import os
import subprocess
2023-09-16 16:28:26 +00:00
2023-09-15 13:14:06 +00:00
script_dir = os . path . dirname ( os . path . realpath ( __file__ ) )
2023-09-16 16:28:26 +00:00
agent_dir = os . path . join ( script_dir , f " autogpts/ { agent_name } " )
run_command = os . path . join ( agent_dir , " run " )
2023-09-15 13:14:06 +00:00
if os . path . exists ( agent_dir ) and os . path . isfile ( run_command ) :
os . chdir ( agent_dir )
subprocess . Popen ( [ " ./run " ] , cwd = agent_dir )
click . echo ( f " Agent ' { agent_name } ' started " )
elif not os . path . exists ( agent_dir ) :
2023-09-16 16:28:26 +00:00
click . echo (
click . style (
f " 😞 Agent ' { agent_name } ' does not exist. Please create the agent first. " ,
fg = " red " ,
)
)
2023-09-15 13:14:06 +00:00
else :
2023-09-16 16:28:26 +00:00
click . echo (
click . style (
f " 😞 Run command does not exist in the agent ' { agent_name } ' directory. " ,
fg = " red " ,
)
)
2023-09-15 13:14:06 +00:00
2023-09-15 17:50:25 +00:00
@agent.command ( )
2023-09-15 13:14:06 +00:00
def stop ( ) :
""" Stop agent command """
import os
import signal
2023-09-16 16:28:26 +00:00
import subprocess
2023-09-15 13:14:06 +00:00
try :
pid = int ( subprocess . check_output ( [ " lsof " , " -t " , " -i " , " :8000 " ] ) )
os . kill ( pid , signal . SIGTERM )
click . echo ( " Agent stopped " )
except subprocess . CalledProcessError as e :
click . echo ( " Error: Unexpected error occurred. " )
except ProcessLookupError :
click . echo ( " Error: No process with the specified PID was found. " )
2023-09-15 17:50:25 +00:00
@agent.command ( )
2023-09-15 13:14:06 +00:00
def list ( ) :
""" List agents command """
import os
2023-09-16 16:28:26 +00:00
2023-09-15 13:14:06 +00:00
try :
2023-09-16 16:28:26 +00:00
agents_dir = " ./autogpts "
agents_list = [
d
for d in os . listdir ( agents_dir )
if os . path . isdir ( os . path . join ( agents_dir , d ) )
]
2023-09-15 13:14:06 +00:00
if agents_list :
2023-09-16 16:28:26 +00:00
click . echo ( click . style ( " Available agents: 🤖 " , fg = " green " ) )
2023-09-15 13:14:06 +00:00
for agent in agents_list :
2023-09-16 16:28:26 +00:00
click . echo ( click . style ( f " \t 🐙 { agent } " , fg = " blue " ) )
2023-09-15 13:14:06 +00:00
else :
2023-09-16 16:28:26 +00:00
click . echo ( click . style ( " No agents found 😞 " , fg = " red " ) )
2023-09-15 13:14:06 +00:00
except FileNotFoundError :
2023-09-16 16:28:26 +00:00
click . echo ( click . style ( " The autogpts directory does not exist 😢 " , fg = " red " ) )
2023-09-15 13:14:06 +00:00
except Exception as e :
2023-09-16 16:28:26 +00:00
click . echo ( click . style ( f " An error occurred: { e } 😢 " , fg = " red " ) )
2023-09-15 13:14:06 +00:00
@cli.group ( )
def benchmark ( ) :
2023-09-15 13:44:11 +00:00
""" Commands to start the benchmark and list tests and categories """
2023-09-15 13:14:06 +00:00
pass
2023-09-16 16:28:26 +00:00
@benchmark.command (
context_settings = dict (
ignore_unknown_options = True ,
)
)
@click.argument ( " agent_name " )
@click.argument ( " subprocess_args " , nargs = - 1 , type = click . UNPROCESSED )
2023-09-15 13:14:06 +00:00
def start ( agent_name , subprocess_args ) :
""" Starts the benchmark command """
import os
import subprocess
2023-09-16 16:28:26 +00:00
2023-09-15 13:14:06 +00:00
script_dir = os . path . dirname ( os . path . realpath ( __file__ ) )
2023-09-16 16:28:26 +00:00
agent_dir = os . path . join ( script_dir , f " autogpts/ { agent_name } " )
2023-09-18 15:56:23 +00:00
benchmark_script = os . path . join ( agent_dir , " run_benchmark " )
2023-09-15 13:14:06 +00:00
if os . path . exists ( agent_dir ) and os . path . isfile ( benchmark_script ) :
os . chdir ( agent_dir )
subprocess . Popen ( [ benchmark_script , * subprocess_args ] , cwd = agent_dir )
2023-09-16 16:28:26 +00:00
click . echo (
click . style (
f " 🚀 Running benchmark for ' { agent_name } ' with subprocess arguments: { ' ' . join ( subprocess_args ) } " ,
fg = " green " ,
)
)
2023-09-15 13:14:06 +00:00
else :
2023-09-16 16:28:26 +00:00
click . echo (
click . style (
f " 😞 Agent ' { agent_name } ' does not exist. Please create the agent first. " ,
fg = " red " ,
)
)
2023-09-15 13:14:06 +00:00
2023-09-16 16:28:26 +00:00
@benchmark.group ( name = " categories " )
2023-09-15 13:14:06 +00:00
def benchmark_categories ( ) :
""" Benchmark categories group command """
pass
2023-09-16 16:28:26 +00:00
@benchmark_categories.command ( name = " list " )
2023-09-15 13:14:06 +00:00
def benchmark_categories_list ( ) :
""" List benchmark categories command """
import glob
2023-09-16 16:28:26 +00:00
import json
import os
2023-09-15 13:14:06 +00:00
categories = set ( )
# Get the directory of this file
this_dir = os . path . dirname ( os . path . abspath ( __file__ ) )
2023-09-16 16:28:26 +00:00
glob_path = os . path . join (
this_dir , " ./benchmark/agbenchmark/challenges/**/[!deprecated]*/data.json "
)
2023-09-15 13:14:06 +00:00
# Use it as the base for the glob pattern, excluding 'deprecated' directory
for data_file in glob . glob ( glob_path , recursive = True ) :
2023-09-18 15:56:23 +00:00
if ' deprecated ' not in data_file :
with open ( data_file , " r " ) as f :
try :
data = json . load ( f )
categories . update ( data . get ( " category " , [ ] ) )
except json . JSONDecodeError :
print ( f " Error: { data_file } is not a valid JSON file. " )
continue
except IOError :
print ( f " IOError: file could not be read: { data_file } " )
continue
2023-09-15 13:14:06 +00:00
if categories :
2023-09-16 16:28:26 +00:00
click . echo ( click . style ( " Available categories: 📚 " , fg = " green " ) )
2023-09-15 13:14:06 +00:00
for category in categories :
2023-09-16 16:28:26 +00:00
click . echo ( click . style ( f " \t 📖 { category } " , fg = " blue " ) )
2023-09-15 13:14:06 +00:00
else :
2023-09-16 16:28:26 +00:00
click . echo ( click . style ( " No categories found 😞 " , fg = " red " ) )
2023-09-15 13:14:06 +00:00
2023-09-16 16:28:26 +00:00
@benchmark.group ( name = " tests " )
2023-09-15 13:14:06 +00:00
def benchmark_tests ( ) :
""" Benchmark tests group command """
pass
2023-09-16 16:28:26 +00:00
@benchmark_tests.command ( name = " list " )
2023-09-15 13:14:06 +00:00
def benchmark_tests_list ( ) :
""" List benchmark tests command """
import glob
2023-09-16 16:28:26 +00:00
import json
import os
2023-09-15 13:14:06 +00:00
import re
2023-09-16 16:28:26 +00:00
2023-09-15 13:14:06 +00:00
tests = { }
# Get the directory of this file
this_dir = os . path . dirname ( os . path . abspath ( __file__ ) )
2023-09-16 16:28:26 +00:00
glob_path = os . path . join (
this_dir , " ./benchmark/agbenchmark/challenges/**/[!deprecated]*/data.json "
)
2023-09-15 13:14:06 +00:00
# Use it as the base for the glob pattern, excluding 'deprecated' directory
for data_file in glob . glob ( glob_path , recursive = True ) :
2023-09-18 15:56:23 +00:00
if ' deprecated ' not in data_file :
with open ( data_file , " r " ) as f :
try :
data = json . load ( f )
category = data . get ( " category " , [ ] )
test_name = data . get ( " name " , " " )
if category and test_name :
if category [ 0 ] not in tests :
tests [ category [ 0 ] ] = [ ]
tests [ category [ 0 ] ] . append ( test_name )
except json . JSONDecodeError :
print ( f " Error: { data_file } is not a valid JSON file. " )
continue
except IOError :
print ( f " IOError: file could not be read: { data_file } " )
continue
2023-09-15 13:14:06 +00:00
if tests :
2023-09-16 16:28:26 +00:00
click . echo ( click . style ( " Available tests: 📚 " , fg = " green " ) )
2023-09-15 13:14:06 +00:00
for category , test_list in tests . items ( ) :
2023-09-16 16:28:26 +00:00
click . echo ( click . style ( f " \t 📖 { category } " , fg = " blue " ) )
2023-09-15 13:14:06 +00:00
for test in sorted ( test_list ) :
2023-09-16 16:28:26 +00:00
test_name = (
" " . join ( word for word in re . split ( " ([A-Z][a-z]*) " , test ) if word )
. replace ( " _ " , " " )
2023-09-18 14:40:30 +00:00
. replace ( " C L I " , " CLI " )
2023-09-16 16:28:26 +00:00
. replace ( " " , " " )
)
2023-09-15 13:14:06 +00:00
test_name_padded = f " { test_name : <40 } "
2023-09-18 15:56:23 +00:00
click . echo ( click . style ( f " \t \t 🔬 { test_name_padded } - { test } " , fg = " cyan " ) )
2023-09-15 13:14:06 +00:00
else :
2023-09-16 16:28:26 +00:00
click . echo ( click . style ( " No tests found 😞 " , fg = " red " ) )
@benchmark_tests.command ( name = " details " )
@click.argument ( " test_name " )
2023-09-15 13:14:06 +00:00
def benchmark_tests_details ( test_name ) :
""" Benchmark test details command """
import glob
2023-09-16 16:28:26 +00:00
import json
import os
2023-09-15 13:14:06 +00:00
# Get the directory of this file
this_dir = os . path . dirname ( os . path . abspath ( __file__ ) )
2023-09-16 16:28:26 +00:00
glob_path = os . path . join (
this_dir , " ./benchmark/agbenchmark/challenges/**/[!deprecated]*/data.json "
)
2023-09-15 13:14:06 +00:00
# Use it as the base for the glob pattern, excluding 'deprecated' directory
for data_file in glob . glob ( glob_path , recursive = True ) :
with open ( data_file , " r " ) as f :
try :
data = json . load ( f )
if data . get ( " name " ) == test_name :
2023-09-16 16:28:26 +00:00
click . echo (
click . style (
f " \n { data . get ( ' name ' ) } \n { ' - ' * len ( data . get ( ' name ' ) ) } \n " ,
fg = " blue " ,
)
)
click . echo (
click . style (
f " \t Category: { ' , ' . join ( data . get ( ' category ' ) ) } " ,
fg = " green " ,
)
)
click . echo ( click . style ( f " \t Task: { data . get ( ' task ' ) } " , fg = " green " ) )
click . echo (
click . style (
f " \t Dependencies: { ' , ' . join ( data . get ( ' dependencies ' ) ) if data . get ( ' dependencies ' ) else ' None ' } " ,
fg = " green " ,
)
)
click . echo (
click . style ( f " \t Cutoff: { data . get ( ' cutoff ' ) } \n " , fg = " green " )
)
click . echo (
click . style ( " \t Test Conditions \n \t ------- " , fg = " magenta " )
)
click . echo (
click . style (
f " \t \t Answer: { data . get ( ' ground ' ) . get ( ' answer ' ) } " ,
fg = " magenta " ,
)
)
click . echo (
click . style (
f " \t \t Should Contain: { ' , ' . join ( data . get ( ' ground ' ) . get ( ' should_contain ' ) ) } " ,
fg = " magenta " ,
)
)
click . echo (
click . style (
f " \t \t Should Not Contain: { ' , ' . join ( data . get ( ' ground ' ) . get ( ' should_not_contain ' ) ) } " ,
fg = " magenta " ,
)
)
click . echo (
click . style (
f " \t \t Files: { ' , ' . join ( data . get ( ' ground ' ) . get ( ' files ' ) ) } " ,
fg = " magenta " ,
)
)
click . echo (
click . style (
f " \t \t Eval: { data . get ( ' ground ' ) . get ( ' eval ' ) . get ( ' type ' ) } \n " ,
fg = " magenta " ,
)
)
click . echo ( click . style ( " \t Info \n \t ------- " , fg = " yellow " ) )
click . echo (
click . style (
f " \t \t Difficulty: { data . get ( ' info ' ) . get ( ' difficulty ' ) } " ,
fg = " yellow " ,
)
)
click . echo (
click . style (
f " \t \t Description: { data . get ( ' info ' ) . get ( ' description ' ) } " ,
fg = " yellow " ,
)
)
click . echo (
click . style (
f " \t \t Side Effects: { ' , ' . join ( data . get ( ' info ' ) . get ( ' side_effects ' ) ) } " ,
fg = " yellow " ,
)
)
2023-09-15 13:14:06 +00:00
break
except json . JSONDecodeError :
print ( f " Error: { data_file } is not a valid JSON file. " )
continue
except IOError :
print ( f " IOError: file could not be read: { data_file } " )
continue
2023-09-16 16:28:26 +00:00
2023-09-15 17:44:37 +00:00
@cli.group ( )
def arena ( ) :
""" Commands to enter the arena """
pass
2023-09-16 16:28:26 +00:00
2023-09-15 17:44:37 +00:00
@arena.command ( )
2023-09-16 16:28:26 +00:00
@click.argument ( " agent_name " )
@click.option ( " --branch " , default = " master " , help = " Branch to use instead of master " )
2023-09-15 17:44:37 +00:00
def enter ( agent_name , branch ) :
2023-09-16 16:28:26 +00:00
import json
import os
2023-09-15 17:44:37 +00:00
import subprocess
from datetime import datetime
2023-09-16 16:28:26 +00:00
from github import Github
2023-09-15 17:44:37 +00:00
# Check if the agent_name directory exists in the autogpts directory
2023-09-16 16:28:26 +00:00
agent_dir = f " ./autogpts/ { agent_name } "
2023-09-15 17:44:37 +00:00
if not os . path . exists ( agent_dir ) :
2023-09-16 16:28:26 +00:00
click . echo (
click . style (
f " ❌ The directory for agent ' { agent_name } ' does not exist in the autogpts directory. " ,
fg = " red " ,
)
)
click . echo (
click . style (
f " 🚀 Run ' ./run agent create { agent_name } ' to create the agent. " ,
fg = " yellow " ,
)
)
2023-09-15 17:44:37 +00:00
return
2023-09-16 16:28:26 +00:00
else :
2023-09-15 18:02:04 +00:00
# Check if the agent has already entered the arena
2023-09-16 17:37:52 +00:00
try :
subprocess . check_output (
[
" git " ,
" rev-parse " ,
" --verify " ,
" --quiet " ,
f " arena_submission_ { agent_name } " ,
]
)
except subprocess . CalledProcessError :
pass
else :
2023-09-16 16:28:26 +00:00
click . echo (
click . style (
2023-09-16 16:51:02 +00:00
f " ⚠️ The agent ' { agent_name } ' has already entered the arena. To update your submission, follow these steps: " ,
fg = " yellow " ,
)
)
click . echo (
click . style (
f " 1. Get the git hash of your submission by running ' git rev-parse HEAD ' on the branch you want to submit to the arena. " ,
fg = " yellow " ,
)
)
click . echo (
click . style (
f " 2. Change the branch to ' arena_submission_ { agent_name } ' by running ' git checkout arena_submission_ { agent_name } ' . " ,
fg = " yellow " ,
)
)
click . echo (
click . style (
f " 3. Modify the ' arena/ { agent_name } .json ' to include the new commit hash of your submission (the hash you got from step 1) and an up-to-date timestamp by running ' ./run arena update { agent_name } hash --branch x ' . " ,
fg = " yellow " ,
)
)
click . echo (
click . style (
f " Note: The ' --branch ' option is only needed if you want to change the branch that will be used. " ,
2023-09-16 16:28:26 +00:00
fg = " yellow " ,
)
)
2023-09-15 18:02:04 +00:00
return
2023-09-16 16:28:26 +00:00
2023-09-15 18:10:51 +00:00
# Check if there are staged changes
2023-09-16 16:28:26 +00:00
staged_changes = [
line
for line in subprocess . check_output ( [ " git " , " status " , " --porcelain " ] )
. decode ( " utf-8 " )
. split ( " \n " )
if line and line [ 0 ] in ( " A " , " M " , " D " , " R " , " C " )
]
2023-09-15 18:10:51 +00:00
if staged_changes :
2023-09-16 16:28:26 +00:00
click . echo (
click . style (
f " ❌ There are staged changes. Please commit or stash them and run the command again. " ,
fg = " red " ,
)
)
2023-09-15 18:02:04 +00:00
return
2023-09-15 17:44:37 +00:00
try :
# Load GitHub access token from file
2023-09-16 16:28:26 +00:00
with open ( " .github_access_token " , " r " ) as file :
2023-09-15 17:44:37 +00:00
github_access_token = file . read ( ) . strip ( )
# Get GitHub repository URL
2023-09-16 16:28:26 +00:00
github_repo_url = (
subprocess . check_output ( [ " git " , " config " , " --get " , " remote.origin.url " ] )
. decode ( " utf-8 " )
. strip ( )
)
2023-09-15 17:44:37 +00:00
2023-09-16 17:37:52 +00:00
if github_repo_url . startswith ( " git@ " ) :
github_repo_url = (
2023-09-18 10:27:09 +00:00
github_repo_url . replace ( " : " , " / " )
. replace ( " git@ " , " https:// " )
2023-09-16 17:37:52 +00:00
. replace ( " .git " , " " )
)
2023-09-15 17:44:37 +00:00
# If --branch is passed, use it instead of master
if branch :
branch_to_use = branch
else :
branch_to_use = " master "
# Get the commit hash of HEAD of the branch_to_use
2023-09-16 16:28:26 +00:00
commit_hash_to_benchmark = (
subprocess . check_output ( [ " git " , " rev-parse " , branch_to_use ] )
. decode ( " utf-8 " )
. strip ( )
)
arena_submission_branch = f " arena_submission_ { agent_name } "
2023-09-15 18:38:41 +00:00
# Create a new branch called arena_submission_{agent_name}
2023-09-16 17:37:52 +00:00
subprocess . check_call ( [ " git " , " checkout " , " -b " , arena_submission_branch ] )
2023-09-15 17:44:37 +00:00
# Create a dictionary with the necessary fields
data = {
" github_repo_url " : github_repo_url ,
" timestamp " : datetime . utcnow ( ) . isoformat ( ) ,
" commit_hash_to_benchmark " : commit_hash_to_benchmark ,
}
# If --branch was passed, add branch_to_benchmark to the JSON file
if branch :
data [ " branch_to_benchmark " ] = branch
# Create agent directory if it does not exist
2023-09-16 16:28:26 +00:00
subprocess . check_call ( [ " mkdir " , " -p " , " arena " ] )
2023-09-15 17:44:37 +00:00
# Create a JSON file with the data
2023-09-16 16:28:26 +00:00
with open ( f " arena/ { agent_name } .json " , " w " ) as json_file :
2023-09-15 17:44:37 +00:00
json . dump ( data , json_file , indent = 4 )
# Create a commit with the specified message
2023-09-16 16:28:26 +00:00
subprocess . check_call ( [ " git " , " add " , f " arena/ { agent_name } .json " ] )
subprocess . check_call (
[ " git " , " commit " , " -m " , f " { agent_name } entering the arena " ]
)
2023-09-15 17:44:37 +00:00
# Push the commit
2023-09-16 16:28:26 +00:00
subprocess . check_call ( [ " git " , " push " , " origin " , arena_submission_branch ] )
2023-09-15 17:44:37 +00:00
# Create a PR into the parent repository
g = Github ( github_access_token )
2023-09-18 10:27:09 +00:00
repo_name = github_repo_url . replace ( " https://github.com/ " , ' ' )
repo = g . get_repo ( repo_name )
2023-09-15 17:44:37 +00:00
parent_repo = repo . parent
if parent_repo :
2023-09-18 10:27:09 +00:00
pr_message = f """
2023-09-16 16:51:02 +00:00
### 🌟 Welcome to the AutoGPT Arena Hacks Hackathon! 🌟
Hey there amazing builders ! We ' re thrilled to have you join this exciting journey. Before you dive deep into building, we ' d love to know more about you and the awesome project you are envisioning . Fill out the template below to kickstart your hackathon journey . May the best agent win ! 🏆
#### 🤖 Team Introduction
- * * Agent Name : * * { agent_name }
- * * Team Members : * * ( Who are the amazing minds behind this team ? Do list everyone along with their roles ! )
2023-09-16 17:37:52 +00:00
- * * Repository Link : * * [ { github_repo_url . replace ( ' https://github.com/ ' , ' ' ) } ] ( { github_repo_url } )
2023-09-16 16:51:02 +00:00
#### 🌟 Project Vision
- * * Starting Point : * * ( Are you building from scratch or starting with an existing agent ? Do tell ! )
- * * Preliminary Ideas : * * ( Share your initial ideas and what kind of project you are aiming to build . We are all ears ! )
#### 🏆 Prize Category
- * * Target Prize : * * ( Which prize caught your eye ? Which one are you aiming for ? )
- * * Why this Prize : * * ( We ' d love to know why this prize feels like the right fit for your team!)
#### 🎬 Introduction Video
2023-09-15 18:04:24 +00:00
2023-09-16 16:51:02 +00:00
- * * Video Link : * * ( If you ' d like, share a short video where you introduce your team and talk about your project. We ' d love to see your enthusiastic faces ! )
2023-09-15 18:04:24 +00:00
2023-09-16 16:51:02 +00:00
#### 📝 Notes and Compliance
2023-09-15 18:04:24 +00:00
2023-09-16 16:51:02 +00:00
- * * Additional Notes : * * ( Any other things you want to share ? We ' re here to listen!)
- * * Compliance with Hackathon Rules : * * ( Just a gentle reminder to stick to the rules outlined for the hackathon )
#### ✅ Checklist
- [ ] We have read and are aligned with the [ Hackathon Rules ] ( https : / / lablab . ai / event / autogpt - arena - hacks ) .
- [ ] We confirm that our project will be open - source and adhere to the MIT License .
- [ ] Our lablab . ai registration email matches our OpenAI account to claim the bonus credits ( if applicable ) .
2023-09-18 10:27:09 +00:00
"""
head = f " { repo . owner . login } : { arena_submission_branch } "
pr = parent_repo . create_pull (
title = f " { agent_name } entering the arena " ,
body = pr_message ,
head = head ,
2023-09-15 17:44:37 +00:00
base = branch_to_use ,
)
2023-09-16 16:28:26 +00:00
click . echo (
click . style (
f " 🚀 { agent_name } has entered the arena! Please edit your PR description at the following URL: { pr . html_url } " ,
fg = " green " ,
)
)
2023-09-15 17:44:37 +00:00
else :
2023-09-16 16:28:26 +00:00
click . echo (
click . style (
" ❌ This repository does not have a parent repository to sync with. " ,
fg = " red " ,
)
)
2023-09-15 17:44:37 +00:00
return
# Switch back to the master branch
2023-09-16 16:28:26 +00:00
subprocess . check_call ( [ " git " , " checkout " , branch_to_use ] )
2023-09-15 17:44:37 +00:00
except Exception as e :
2023-09-16 16:28:26 +00:00
click . echo ( click . style ( f " ❌ An error occurred: { e } " , fg = " red " ) )
2023-09-15 19:07:03 +00:00
# Switch back to the master branch
2023-09-16 16:28:26 +00:00
subprocess . check_call ( [ " git " , " checkout " , branch_to_use ] )
2023-09-15 17:44:37 +00:00
2023-09-16 17:37:52 +00:00
2023-09-16 16:51:02 +00:00
@arena.command ( )
@click.argument ( " agent_name " )
@click.argument ( " hash " )
@click.option ( " --branch " , default = None , help = " Branch to use instead of current branch " )
def update ( agent_name , hash , branch ) :
import json
import os
from datetime import datetime
import subprocess
# Check if the agent_name.json file exists in the arena directory
agent_json_file = f " ./arena/ { agent_name } .json "
# Check if they are on the correct branch
current_branch = (
subprocess . check_output ( [ " git " , " rev-parse " , " --abbrev-ref " , " HEAD " ] )
. decode ( " utf-8 " )
. strip ( )
)
correct_branch = f " arena_submission_ { agent_name } "
if current_branch != correct_branch :
click . echo (
click . style (
f " ❌ You are not on the correct branch. Please switch to the ' { correct_branch } ' branch. " ,
fg = " red " ,
)
)
return
2023-09-16 17:37:52 +00:00
2023-09-16 16:51:02 +00:00
if not os . path . exists ( agent_json_file ) :
click . echo (
click . style (
f " ❌ The file for agent ' { agent_name } ' does not exist in the arena directory. " ,
fg = " red " ,
)
)
click . echo (
click . style (
f " ⚠️ You need to enter the arena first. Run ' ./run arena enter { agent_name } ' " ,
fg = " yellow " ,
)
)
return
else :
# Load the existing data
with open ( agent_json_file , " r " ) as json_file :
data = json . load ( json_file )
# Update the commit hash and timestamp
data [ " commit_hash_to_benchmark " ] = hash
data [ " timestamp " ] = datetime . utcnow ( ) . isoformat ( )
# If --branch was passed, update the branch_to_benchmark in the JSON file
if branch :
data [ " branch_to_benchmark " ] = branch
# Write the updated data back to the JSON file
with open ( agent_json_file , " w " ) as json_file :
json . dump ( data , json_file , indent = 4 )
click . echo (
click . style (
f " 🚀 The file for agent ' { agent_name } ' has been updated in the arena directory. " ,
fg = " green " ,
)
)
2023-09-15 17:44:37 +00:00
2023-09-16 16:28:26 +00:00
if __name__ == " __main__ " :
2023-09-15 13:14:06 +00:00
cli ( )