From 9136f2ce9a913abf402d4b6d69816d99856191dd Mon Sep 17 00:00:00 2001 From: wunderwuzzi23 Date: Sat, 18 Mar 2023 19:38:38 -0700 Subject: [PATCH] Squashed commit of the following: commit 7b16b63f5f269baa0441ee171d906419585d2526 Author: wunderwuzzi23 Date: Sat Mar 18 19:34:34 2023 -0700 update text commit d99b7ebf211a517d74fcf3241843e78a71e99d05 Author: wunderwuzzi23 Date: Sat Mar 18 19:31:28 2023 -0700 fix formatting commit 65b1f6218cc32f0a0001637b22b9f1b4640de983 Author: wunderwuzzi23 Date: Sat Mar 18 19:17:08 2023 -0700 updating messages commit 314071228395a595503dc3a15fda2b3c8b5e6095 Author: wunderwuzzi23 Date: Sat Mar 18 19:13:40 2023 -0700 updating install.bat for yolo.yaml settings commit 85c9f381415c86e7c95572bdcbd98d6478f616ef Author: wunderwuzzi23 Date: Sat Mar 18 19:08:09 2023 -0700 load yolo.yaml from executing directory commit d9ee70035e186c8b21875d58e7a7bf3f980eaa60 Author: wunderwuzzi23 Date: Sat Mar 18 18:43:45 2023 -0700 update readme commit f2ae85827c675e3f2c87bf4d455709e227e1bfb4 Author: wunderwuzzi23 Date: Sat Mar 18 18:37:41 2023 -0700 cleanup commit fc5cf55982dd6de3a4e81de2b0286f18788bc87c Author: wunderwuzzi23 Date: Sat Mar 18 18:31:00 2023 -0700 fix formatting commit 3ec4cf959cf4a43d061b0d579c863af5bb495631 Author: wunderwuzzi23 Date: Sat Mar 18 18:27:49 2023 -0700 set safety: True in config commit d13153141bbdb4ada5d9bf742b19fd9c10624c86 Author: wunderwuzzi23 Date: Sat Mar 18 18:25:07 2023 -0700 update readme commit 39f82ee8cf744ef6fbfbe6622e4d39cc6323d69a Author: wunderwuzzi23 Date: Sat Mar 18 18:24:43 2023 -0700 update readme commit 944046c11bdcd3b01b33798dae5ca33e8ddda9db Author: wunderwuzzi23 Date: Sat Mar 18 18:21:47 2023 -0700 update requirements commit 0c22313bdc6b3a9f272faf99b9998930ede9502a Author: wunderwuzzi23 Date: Sat Mar 18 18:15:17 2023 -0700 formatting commit 08e16c67ad8fd588962f9bf22fe0588ac4c0ec3a Author: wunderwuzzi23 Date: Sat Mar 18 17:39:35 2023 -0700 default gpt-3.5-turbo (gpt-4 is waitlist for many) commit eec224fe3b34a2627d771682cde291ccdf96bcac Author: wunderwuzzi23 Date: Sat Mar 18 17:16:57 2023 -0700 add yolo.yaml, gpt-4 support, improve install.sh --- README.md | 47 ++++++++++++++++++------- install.bat | 70 ++++++++++++------------------------- install.sh | 38 ++++++++++++++++---- requirements.txt | 7 ++-- yolo.py | 90 +++++++++++++++++++++++++++++------------------- yolo.yaml | 9 +++++ 6 files changed, 154 insertions(+), 107 deletions(-) mode change 100644 => 100755 install.sh create mode 100644 yolo.yaml diff --git a/README.md b/README.md index 7f15cf5..cdfaa63 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,27 @@ ![Animated GIF](https://github.com/wunderwuzzi23/blog/raw/master/static/images/2023/yolo-shell-anim-gif.gif) +# Update Yolo v0.2 - Support for GPT-4 API + +This update introduces the `yolo.yaml` configuration file. In this file you can specify which OpenAI model you want to query, and other settings. The safety switch also moved into this configuration file. + +For now the default model is still `gpt-3.5-turbo`, but you can update to `gpt-4` if you have gotten access already! + +``` +Yolo v0.2 - by @wunderwuzzi23 + +Usage: yolo [-a] list the current directory information +Argument: -a: Prompt the user before running the command (only useful when safety is off) + +Current configuration per yolo.yaml: +* Model : gpt-3.5-turbo +* Temperature : 0 +* Max. Tokens : 500 +* Safety : on +``` + +Happy Hacking! + # Installation on Linux and macOS ``` @@ -17,17 +38,18 @@ yolo show me some funny unicode characters ## OpenAI API Key configuration -There are two ways to configure the key on Linux and macOS: +There are three ways to configure the key on Linux and macOS: - You can either `export OPENAI_API_KEY=`, or have a `.env` file in the same directory as `yolo.py` with `OPENAI_API_KEY=""` as a line - Create a file at `~/.openai.apikey` with the key in it +- Add the key to the `yolo.yaml` configuration file ## Aliases -To set the alias, like `yolo` or `computer` on each login, add them to your .bashrc or .bash_aliases file. (zsh on macOS) +To set the alias, like `yolo` or `computer` on each login, add them to .bash_aliases (or .zshrc on macOS) file. Make sure the path is the one you want to use. ``` -echo "alias yolo=$TARGET_FULLPATH" >> ~/.bash_aliases -echo "alias computer=$TARGET_FULLPATH" >> ~/.bash_aliases +echo "alias yolo=$(pwd)/yolo.py" >> ~/.bash_aliases +echo "alias computer=$(pwd)/yolo.py" >> ~/.bash_aliases ``` ## Installation script @@ -35,21 +57,20 @@ echo "alias computer=$TARGET_FULLPATH" >> ~/.bash_aliases Another option is to run `source install.sh` after cloning the repo. That does the following: 1. Copies the necessary files to `~/yolo-ai-cmdbot/` 2. Creates two aliases `yolo` and `computer` pointint to `~/yolo-ai-cmdbot/yolo.py` -3. Adds the aliases to the `~/bash_aliases` file (only tested on Ubuntu) +3. Adds the aliases to the `~/.bash_aliases` or `~/.zshrc` file That's it for Linux and macOS. Now make sure you have an OpenAI API key set. - # Windows Installation -On Windows run `.\install.bat` (or double-click) after cloning the repo. By default it does the following: +On Windows you can run `.\install.bat` (or double-click) after cloning the repo. By default it does the following: 1. Copies the necessary files to `~\yolo-ai-cmdbot\` 2. Creates a `yolo.bat` file in `~` that lets you run equivalent to `python.exe ~\yolo-ai-cmdbot\yolo.py` You also have the option to: 1. Change the location where `yolo-ai-cmdbot\` and `yolo.bat` will be created 2. Skip creating `yolo-ai-cmdbot\` and use the folder of the cloned repository instead. -3. Create a `.openai.apikey` and/or `.yolo-safety-off` file in your `~` directory +3. Create a `.openai.apikey` file in your `~` directory That's it basically. @@ -60,6 +81,8 @@ On Windows `export OPENAI_API_KEY=` will not work instead: - Or, Run PowerShell as administrator and run `setx OPENAI_API_KEY ""` - Or, Go to `Start` and search `edit environment variables for your account` and manually create the variable with name `OPENAI_API_KEY` and value `` +Optionally (since v.0.2), the key can also be stored in `yolo.yaml`. + ## Running yolo on Windows Windows is less tested, it does work though and will use PowerShell. @@ -88,13 +111,11 @@ Have fun. # Disabling the safety switch! **Caution!** -By default `yolo` will prompt the user before executing commands. To have yolo run commands right away when they come back from ChatGPT create a file named `~/.yolo-safety-off`. +By default `yolo` will prompt the user before executing commands. -A simple command to do that on Linux would be: +Since v.0.2 the safety switch setting moved to `yolo.yaml`, the old `~/.yolo-safety-off` is not used anymore. -``` -touch ~/.yolo-safety-off -``` +To have yolo run commands right away when they come back from ChatGPT change the `safety` in the `yolo.yaml` to `False`. If you still want to inspect the command that is executed when safety is off, add the `-a` argument, e.g `yolo -a delete the file test.txt`. diff --git a/install.bat b/install.bat index 2ce71bc..10d27fe 100644 --- a/install.bat +++ b/install.bat @@ -4,20 +4,20 @@ setlocal enabledelayedexpansion :: First check if `install.bat` (this) has needed files in same directory if not exist %~dp0\yolo.py ( echo `yolo.py` missing in %~dp0 cannot install & goto :choice_default_3 ) if not exist %~dp0\prompt.txt ( echo `prompt.txt` missing in %~dp0 cannot install & goto :choice_default_3 ) +if not exist %~dp0\yolo.yaml ( echo `yolo.yaml` missing in %~dp0 cannot install & goto :choice_default_3 ) + :: Note: "~" or %HOME% is equivalent to "%HOMEDRIVE%%HOMEPATH%\" but the latter is set in VM environments (from what I can tell) :: INSTALL_DIR = Directory the "yolo-ai-cmdbot\" will go to. :: SCRIPT_DIR = Directory the "yolo.bat" script will go to. :: createDIR = Whether or not a seperate "yolo-ai-cmdbot\" directory will be made/used to hold "yolo.py" and "prompt.txt". 1=Yes, 2=Just_use_Repo (the folder this is in) :: createAPIKEY = Whether to create a ".openai.apikey" at %HOMEDRIVE%%HOMEPATH%\. 1=Yes, 2=No -:: createSafetyOff = Whether to create a ".yolo-safety-off" at %HOMEDRIVE%%HOMEPATH%\. 1=Yes, 2=No :: Default values: set "INSTALL_DIR=%HOMEDRIVE%%HOMEPATH%\" set "SCRIPT_DIR=%HOMEDRIVE%%HOMEPATH%\" set /a "createDIR=1" set /a "createAPIKEY=2" -set /a "createSafetyOff=2" set "installing=1" :: Set Variables To User Defined If Needed @@ -67,6 +67,8 @@ if /i %createDIR%==1 ( call :install_yolo_directory ) if /i %createDIR%==2 ( call :install_yolo_repository ) ::Make sure safety is on when default installing +::Note: when upgrading from v0.1 to v0.2 it will delete the file. +::With v.0.2 the safety switch moved to the config file yolo.yaml if /i !installing!==1 ( del %HOMEDRIVE%%HOMEPATH%\.yolo-safety-off ) :choice_default_4 @@ -123,13 +125,8 @@ cls call :print_apikey choice /n /c YN /m "Let me know which option you want to select: " set /a createAPIKEY=!ERRORLEVEL! -cls -call :print_safetyoff -choice /n /c YN /m "Let me know which option you want to select: " -set /a createSafetyOff=!ERRORLEVEL! if /i !createAPIKEY!==1 ( call :create_openai_apikey ) -if /i !createSafetyOff!==1 ( call :create_safety_off ) goto :EOF :: Creates a directory to hold yolo.py and prompt.txt @@ -139,6 +136,7 @@ echo Installing to !TARGET_DIR! mkdir !TARGET_DIR! copy %~dp0\yolo.py !TARGET_DIR! copy %~dp0\prompt.txt !TARGET_DIR! +copy %~dp0\yolo.yaml !TARGET_DIR! goto :EOF :: Create yolo.bat and input code linking to created directory @@ -165,13 +163,6 @@ if not exist %~dp0\yolo.py ( echo Not Found: Aborting "create_yolo_bat_from_repo ) goto :EOF -:: Creates the safety off file and puts it in ~ for you -:create_safety_off -echo Yolo Safety Off: -echo Creating `.yolo-safety-off` in `%HOMEDRIVE%%HOMEPATH%\` -copy nul %HOMEDRIVE%%HOMEPATH%\.yolo-safety-off -goto :EOF - :: Creates the .openai.apikey if it doesn't already exists (otherwise, does nothing) :create_openai_apikey echo Yolo OpenAi ApiKey: @@ -267,38 +258,17 @@ echo If you do not understand what this means, select [N] echo. goto :EOF -:: Prints a prompt for `.yolo-safety-off` -:print_safetyoff -echo. -echo Installation `.yolo-safety-off` File Options: -echo. -echo This file will remove the confirmation message before running commands given by yolo -echo You can still have a confirmation message appear using the `-a` switch before your prompt: -echo `.\yolo.bat -a [Enter Prompt Here]` -echo. -echo [Y] Yes, Create a `.yolo-safety-off` if it does not exist at `%HOMEDRIVE%%HOMEPATH%\` -echo [N] No, Will skip this. -echo. -echo You probably want to use [N], this may cause you to delete/modify files you did not want to. -echo If you do not understand what this means, select [N] -echo. -goto :EOF - :: Prints a "Finished Installing" and usage message after installing :print_guide echo. -echo Finished Installing Yolo... +echo Finished Installing Yolo. echo. -echo You can run commands by being in the same directory as your `yolo.bat` file ( It is in `!SCRIPT_DIR!` ) with the following command: +echo Run commands by being in the same directory as your `yolo.bat` file ( It is in `!SCRIPT_DIR!` ): echo `.\yolo.bat [Enter Prompt Here]` -echo You can also put your `yolo.bat` file into a $PATH directory and run it like so, instead: +echo. +echo Or, put the `yolo.bat` file into a $PATH directory and run it like so, instead: echo `yolo [Enter Prompt Here]` -echo You can use the `-a` switch to make sure yolo asks you before running the returned command: -echo `yolo -a [Enter Prompt Here]` -echo Make sure to do this when deleting/modifying files/folders with safety off. echo. -echo You should have `C:\Windows\System32` as a path in the $PATH environment variable but you can write the command `echo $env:PATH` into PowerShell for more options... -set /p "wait=Press [Enter] for more:" if /i !createDIR!==1 ( call :print_bat_warning_directory ) if /i !createDIR!==2 ( call :print_bat_warning_repository ) set /p "wait=Press [Enter] for more:" @@ -326,16 +296,20 @@ goto :EOF :print_apikey_guide echo. -echo Api Key: +echo API Key: echo. -echo You will need to provide your openai apikey to use yolo. -echo You can get this at `https://platform.openai.com/account/api-keys` after logging in. -echo - You can then put the apikey straight into a `.openai.apikey` file in `%HOMEDRIVE%%HOMEPATH%\` -echo (You can run this `install.bat` again and select `O`ptional Files to create a `.openai.apikey` file for you) -echo -You can paste `OPENAI_API_KEY="[yourkey]"` into a `.env` file that should be in the folder yolo is installed in currently. +echo You need to provide your OpenAI API key to use yolo. +echo. +echo You can get a key from `https://platform.openai.com/account/api-keys` after logging in. +echo There are multiple options for providing the key: +echo (1) You can put the key into a `.openai.apikey` file in `%HOMEDRIVE%%HOMEPATH%\` +echo Run `install.bat` again and select `O`ptional Files to create a `.openai.apikey` file +echo (2) You can paste `OPENAI_API_KEY="[yourkey]"` into a `.env` file that should be in the folder yolo is installed in currently. if /i !createDIR!==1 ( echo `.env` should be in: !TARGET_DIR! ) if /i !createDIR!==2 ( echo `.env` should be in: %~dp0 ) -echo -You can run `$env:OPENAI_API_KEY="[yourkey]"` in your terminal before using yolo in that terminal -echo -If you run PowerShell as administrator you can then run `setx OPENAI_API_KEY "[yourkey]"` to permanently and use yolo in any terminal (you may need to reopen the terminal once). -echo -Go to `Start` and search `edit environment variables for your account` and manually create the variable with name `OPENAI_API_KEY` and value `[yourkey]` +echo (3) You can run `$env:OPENAI_API_KEY="[yourkey]"` in your terminal before using yolo in that terminal +echo -If you run PowerShell as administrator you can then run `setx OPENAI_API_KEY "[yourkey]"` to permanently and use yolo in any terminal (you may need to reopen the terminal once). +echo -Go to `Start` and search `edit environment variables for your account` and manually create the variable with name `OPENAI_API_KEY` and value `[yourkey]` +echo (4) Another option is to put the API key in the yolo.yaml configuration file (since v.0.2) +echo. goto :EOF \ No newline at end of file diff --git a/install.sh b/install.sh old mode 100644 new mode 100755 index 515666f..76f8a9f --- a/install.sh +++ b/install.sh @@ -1,18 +1,42 @@ -# Installs yolo in the user's home directory +# Simple installer for yolo in the user's home directory +echo "Hello. Installing yolo..." +echo "- Creating yolo-ai-cmdbot in home directory..." TARGET_DIR=~/yolo-ai-cmdbot TARGET_FULLPATH=$TARGET_DIR/yolo.py - mkdir -p $TARGET_DIR -cp yolo.py prompt.txt $TARGET_DIR + +echo "- Copying files..." +cp yolo.py prompt.txt yolo.yaml $TARGET_DIR chmod +x $TARGET_FULLPATH -#Linux/Mac - # Creates two aliases for use +echo "- Creating yolo and computer aliases..." alias yolo=$TARGET_FULLPATH alias computer=$TARGET_FULLPATH # Add the aliases to the logon scripts -echo "alias yolo=$TARGET_FULLPATH" >> ~/.bash_aliases -echo "alias computer=$TARGET_FULLPATH" >> ~/.bash_aliases \ No newline at end of file +# Depends on your shell +if [[ "$SHELL" == "/bin/bash" ]]; then + echo "- Adding aliases to ~/.bash_aliases" + echo "alias yolo=$TARGET_FULLPATH" >> ~/.bash_aliases + echo "alias computer=$TARGET_FULLPATH" >> ~/.bash_aliases +elif [[ "$SHELL" == "/bin/zsh" ]]; then + echo "- Adding aliases to ~/.zshrc" + echo "alias yolo=$TARGET_FULLPATH" >> ~/.zshrc + echo "alias computer=$TARGET_FULLPATH" >> ~/.zshrc +else + echo "Note: Shell was not bash or zsh." + echo " Consider configuring aliases (like yolo and/or computer) manually by adding them to your login script, e.g:" + echo " alias yolo=$TARGET_FULLPATH >> " +fi + +echo +echo "Done." +echo +echo "Make sure you have the OpenAI API key set via one of these options:" +echo " - environment variable" +echo " - .env or an ~/.openai.apikey file or in" +echo " - yolo.yaml" +echo +echo "Have fun!" \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 00f22bc..af5ab24 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,6 @@ openai==0.27 termcolor==2.2.0 -colorama -python-dotenv -distro \ No newline at end of file +colorama==0.4.4 +python-dotenv==1.0.0 +distro==1.7.0 +PyYAML==5.4.1 \ No newline at end of file diff --git a/yolo.py b/yolo.py index 4b1518b..82b2523 100755 --- a/yolo.py +++ b/yolo.py @@ -11,20 +11,21 @@ import sys import subprocess import dotenv import distro +import yaml from termcolor import colored from colorama import init -# Check if the user globally disabled the safety switch -def get_yolo_safety_switch_config(): - - home_path = os.path.expanduser("~") - yolo_safety_off_path = os.path.join(home_path,".yolo-safety-off") - - if os.path.exists(yolo_safety_off_path): - return False - else: - return True +def read_config() -> any: + + ## Find the executing directory (e.g. in case an alias is set) + ## So we can find the config file + yolo_path = os.path.abspath(__file__) + prompt_path = os.path.dirname(yolo_path) + + config_file = os.path.join(prompt_path, "yolo.yaml") + with open(config_file, 'r') as file: + return yaml.safe_load(file) # Construct the prompt def get_full_prompt(user_prompt, shell): @@ -48,12 +49,23 @@ def get_full_prompt(user_prompt, shell): return prompt def print_usage(): - print("Yolo 0.1 - by @wunderwuzzi23") + print("Yolo v0.2 - by @wunderwuzzi23") print() print("Usage: yolo [-a] list the current directory information") - print("Argument: -a: Prompt the user before running the command") + print("Argument: -a: Prompt the user before running the command (only useful when safety is off)") print() - print("Current safety switch setting (~/.yolo-safety-off) is " + str(yolo_safety_switch)) + + yolo_safety_switch = "on" + + if config["safety"] != True: + yolo_safety_switch = "off" + + print("Current configuration per yolo.yaml:") + print("* Model : " + str(config["model"])) + print("* Temperature : " + str(config["temperature"])) + print("* Max. Tokens : " + str(config["max_tokens"])) + print("* Safety : " + yolo_safety_switch) + def get_os_friendly_name(): @@ -70,43 +82,50 @@ def get_os_friendly_name(): return os_name -if __name__ == "__main__": - - # Get the global safety switch setting (default is True/on) - yolo_safety_switch = get_yolo_safety_switch_config() - - # Unix based SHELL (/bin/bash, /bin/zsh), otherwise assuming it's Windows - shell = os.environ.get("SHELL", "powershell.exe") - - command_start_idx = 1 # Question starts at which argv index? - ask_flag = False # safety switch -a command line argument - yolo = "" # user's answer to safety switch (-a) question y/n - - +def set_api_key(): # Two options for the user to specify they openai api key. #1. Place a ".env" file in same directory as this with the line: # OPENAI_API_KEY="" # or do `export OPENAI_API_KEY=` before use dotenv.load_dotenv() openai.api_key = os.getenv("OPENAI_API_KEY") + #2. Place a ".openai.apikey" in the home directory that holds the line: # + # Note: This options will likely be removed in the future if not openai.api_key: #If statement to avoid "invalid filepath" error home_path = os.path.expanduser("~") openai.api_key_path = os.path.join(home_path,".openai.apikey") + #3. Final option is the key might be in the yolo.yaml config file + # openai_apikey: + if not openai.api_key: + openai.api_key = config["openai_api_key"] + +if __name__ == "__main__": + + config = read_config() + set_api_key() + + # Unix based SHELL (/bin/bash, /bin/zsh), otherwise assuming it's Windows + shell = os.environ.get("SHELL", "powershell.exe") + + command_start_idx = 1 # Question starts at which argv index? + ask_flag = False # safety switch -a command line argument + yolo = "" # user's answer to safety switch (-a) question y/n + # Parse arguments and make sure we have at least a single word if len(sys.argv) < 2: print_usage() sys.exit(-1) - # safety switch via argument -a (local override of global setting) + # Safety switch via argument -a (local override of global setting) # Force Y/n questions before running the command if sys.argv[1] == "-a": ask_flag = True command_start_idx = 2 - # to allow easy/natural use we don't require the input to be a + # To allow easy/natural use we don't require the input to be a # single string. So, the user can just type yolo what is my name? # without having to put the question between '' arguments = sys.argv[command_start_idx:] @@ -117,7 +136,6 @@ if __name__ == "__main__": print ("No user prompt specified.") sys.exit(-1) - # Load the correct prompt based on Shell and OS and append the user's prompt prompt = get_full_prompt(user_prompt, shell) @@ -127,13 +145,13 @@ if __name__ == "__main__": # Call the ChatGPT API response = openai.ChatCompletion.create( - model="gpt-3.5-turbo", + model=config["model"], messages=[ {"role": "system", "content": system_prompt}, {"role": "user", "content": prompt} ], - temperature=0, - max_tokens=500, + temperature=config["temperature"], + max_tokens=config["max_tokens"], ) #print (response) @@ -143,8 +161,8 @@ res_command = response.choices[0].message.content.strip() #Enable color output on Windows using colorama init() -prefixes = ("Sorry", "I'm sorry") -if res_command.startswith(prefixes): +prefixes = ("sorry", "i'm sorry", "the question is not clear") +if res_command.lower().startswith(prefixes): print(colored("There was an issue: "+res_command, 'red')) sys.exit(-1) @@ -154,8 +172,8 @@ if res_command.count("```",2): sys.exit(-1) print("Command: " + colored(res_command, 'blue')) -if yolo_safety_switch == True or ask_flag == True: - print("Execute the command? Y/n ==> ", end = '') +if config["safety"] != "off" or ask_flag == True: + print("Execute the command? [Y/n] ==> ", end = '') yolo = input() print() diff --git a/yolo.yaml b/yolo.yaml new file mode 100644 index 0000000..d92a15b --- /dev/null +++ b/yolo.yaml @@ -0,0 +1,9 @@ +model: gpt-3.5-turbo # If you have access to gpt-4 API already, you can update this. +temperature: 0 +max_tokens: 500 + +# Safety: If set to False, commands returned from the AI will be run *without* prompting the user. +safety: True + +# Open AI API Key (optional): The key can aso be provided via environment variable (OPENAI_API_KEY), .env, or ~/.openai.apikey file +openai_api_key: \ No newline at end of file