From 70f136eacafb765589ff9f2e1ee8fa7a7703926d Mon Sep 17 00:00:00 2001 From: Enrico Ludwig Date: Fri, 23 Aug 2024 10:12:09 +0200 Subject: [PATCH] Added openai bash integration script --- openai/README.md | 60 ++++++++++++++++++++++++++++++ openai/runai.sh | 95 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 155 insertions(+) create mode 100644 openai/README.md create mode 100755 openai/runai.sh diff --git a/openai/README.md b/openai/README.md new file mode 100644 index 0000000..10861db --- /dev/null +++ b/openai/README.md @@ -0,0 +1,60 @@ +# OpenAI API / ChatGPT bash integration + +The script `runai_alias.sh` can be used to provide the `runai` command in bash. The command enabled you to generate commands directly in your terminal. + +## Requirements + +This script only requires Python 3.7+ and the `openai` Python package to be installed. + +Install Python and Pip on Debian/Ubuntu: `sudo apt install python3 python3-pip` +Install Python and Pip on CentOS/RHEL-based: `sudo yum install epel-release && sudo yum install python3-pip` +Install Python and Pip on ArchLinux: `sudo pacman -Sy && sudo pacman -S python-pip` +Install Python and Pip in Fedora: `sudo dnf install python3-pip` +Install via pip: `pip install openai` + +## Installing as alias command + +**Note:** To keep the alias command working, the script must remain at the same location after setting the alias command. + +Install the alias command using `./runai.sh -a` + +## Example Usage as Script + +```bash +user@host:~$ ./runai.sh scan my primary local network for online hosts +The generated command is: +nmap -sn $(ip route | awk '/default/ {print $3}' | awk -F. '{print $1"."$2"."$3".0/24"}') + +Do you want to execute the command? [Y/n]: y + +... +``` + +You always have the choice whether the command shall be executed or not, unless you pass `-y` as first parameter. When the command is executed, you can also access it later using your history. + +## Example Usage as Alias + +```bash +user@host:~$ ./runai scan my primary local network for online hosts +The generated command is: +nmap -sn $(ip route | awk '/default/ {print $3}' | awk -F. '{print $1"."$2"."$3".0/24"}') + +Do you want to execute the command? [Y/n]: y + +... +``` + +## Example Usage with ALL_YES set + +**WARNING:** Allowing the script to just execute the generated command can be potentially dangerous. Use with care! + +```bash +user@host:~$ ./runai -a scan my primary local network for online hosts +Running the command without asking for confirmation! +Running the command: +nmap -sn $(ip route | awk '/default/ {print $3}' | awk -F. '{print $1"."$2"."$3".0/24"}') + +... +``` + +**NOTE** that you should *never* provide any sensitive data with your prompt! \ No newline at end of file diff --git a/openai/runai.sh b/openai/runai.sh new file mode 100755 index 0000000..78d5917 --- /dev/null +++ b/openai/runai.sh @@ -0,0 +1,95 @@ +#!/bin/bash + +# USER SETTINGS - CHANGE AS NEEDED +OPENAI_API_KEY="" +MODEL="gpt-4o" # gpt-4o, gpt-4, gpt-3.5-turbo, gpt-3.5, gpt-3, curie, babbage, davinci +TEMPERATURE=0.2 # 0.0 to 1.0 (higher is more creative) +MAX_TOKENS=3072 # 1 to 4096 (higher requires more API credits, but can be more accurate) + +# The base prompt describing the rules the AI should follow +read -r -d '' BASE_PROMPT << EOM +Do not explain anything. +Only respond with a command that can be executed on the linux terminal. +Never use code tags. +Always put everything in a single command, e.g. using pipes, semicolons or double ampersands. +Break up the command in multiple lines when using redirections, semicolons or double ampersands, but make sure the command can still be executed (e.g. by using a backslash). +Do not use any formatting except bash escaped newlines. +The question is: +EOM + +# INTERNAL VARIABLES - DO NOT CHANGE +ALL_YES=false # If true, the AI will execute the command without asking for confirmation + +# Check if the OPENAI_API_KEY environment variable is set +# Ignore if -a is passed as a parameter +if [[ "$1" != "-a" && -z "$OPENAI_API_KEY" ]]; then + OPENAI_API_KEY=$(printenv OPENAI_API_KEY) + + if [ -z "$OPENAI_API_KEY" ]; then + + # Check if the OPENAI_API_KEY is set in the ~/.openai file + if [ -f ~/.openai ]; then + source ~/.openai + fi + + if [ -z "$OPENAI_API_KEY" ]; then + echo "Please set the OPENAI_API_KEY environment variable." + exit 1 + fi + fi +fi + +# check if -y is passed as a parameter and set ALL_YES to true +if [ "$1" == "-y" ]; then + ALL_YES=true + shift +fi + +function run_ai() +{ + if [ -z "$*" ]; then + echo "Usage: runai " + return + fi + + # if ALL_YES is set to true, print an info message in red bold font + if [ $ALL_YES == true ]; then + echo -e "\033[1;31mRunning the command without asking for confirmation!\033[0m" + fi + + echo -e -n "\e[38;5;12m" + + command=$(OPENAI_API_KEY=$OPENAI_API_KEY openai api chat.completions.create -m gpt-4o -t 0.4 -M 3072 -g "user" "$BASE_PROMPT $*") + + echo -e -n "\e[0m" + + if [ $ALL_YES == false ]; then + echo -e "The generated command is:\n\033[0;33m$command\n\033[1;31m" + read -p "Do you want to execute the command? [Y/n]: " input + input=$(echo "$input" | tr '"'"'[A-Z]'"'"' '"'"'[a-z]'"'"') + else + echo -e "Running the command:\n\033[0;33m$command\n\033[1;31m" + fi + + if [[ $ALL_YES == true || $input == "y" || $input == "yes" ]]; then + echo -e "\033[0m"; + history -s "runai $*" + history -s "$command" + eval "$command" + fi +} + +# if the parameter -a is passed, set the alias, otherwise run the AI + +if [ "$1" == "-a" ]; then + # check first, if an alias with the same name already exists + if grep -q "alias runai=" ~/.bashrc; then + echo "The alias runai already exists." + exit 0 + else + echo "alias runai='source $0'" >> ~/.bashrc + echo "The alias runai has been set. You can now run the AI by typing runai ." + fi +else + run_ai "$*" +fi \ No newline at end of file