Skip to content

Commit

Permalink
feat: add support for configuration files and model selection
Browse files Browse the repository at this point in the history
  • Loading branch information
mikaelvesavuori committed Dec 20, 2023
1 parent be5ee12 commit 14e871c
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 26 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
.env
.dccache
.DS_Store
minion.json

# Folders
node_modules/
Expand All @@ -13,6 +14,7 @@ build/
dist/
package/
testing/
ignore/

# Diagrams
**/*.bkp
Expand Down
32 changes: 17 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,13 @@

## The easiest and most lightweight way for developers to use OpenAI APIs in a CLI.

Minion is a simple CLI wrapper that calls OpenAI APIs with prefabbed prompts and your Git diff data. It expedites proactive - rather than reactive - code reviews, commit messaging, test generation, and diagramming.
Minion is a simple CLI wrapper that calls OpenAI APIs (of your choice) with prefabbed prompts and, for some use cases, your Git diff data. It expedites proactive - rather than reactive - code reviews, commit messaging, test generation, and diagramming and many more things.

### Key modalities
Its key modalities are to:

#### Assist

Generate unit tests from code, integration tests from schemas, or any applicable tests from your changes.

#### Feedback

Code reviews from your files or changes.

#### Coaching

Supportive and coaching prompts helps you build better solutions.
- **Assist**: Generate unit tests from code, integration tests from schemas, or any applicable tests from your changes.
- **Feedback**: Code reviews from your files or changes.
- **Coach**: Supportive and coaching prompts helps you build better solutions.

## What to know

Expand Down Expand Up @@ -130,9 +122,19 @@ Feel free to modify the installation script or do it your way if this doesn't ma

You will need to source or reload your IDE for the changes to be activated.

## Configuration
## Configuration and model choice

The model used is `gpt-3.5-turbo-16k`. If you want to change this, simply update the `MODEL` variable to the model you want to use.
Starting with version `1.4.0`, you will be presented with a list of models when you pass a command to Minion.

If you want to use a default model and skip manual input, then simply create a `minion.json` file with a `model` key with the value for the model you want to use. The file will be read from the current directory.

Example:

```json
{
"model": "gpt-3.5-turbo-16k"
}
```

## Usage

Expand Down
126 changes: 115 additions & 11 deletions minion.sh
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
#!/bin/bash

MINION_VERSION="1.3.1"
MINION_VERSION="1.4.0"

# Colors
GREEN='\033[0;32m'
RESET='\033[0m' # Reset color to default

# Models
MODEL_1="gpt-3.5-turbo"
MODEL_2="gpt-3.5-turbo-16k"
MODEL_3="gpt-4"
MODEL_4="gpt-4-32k"
MODEL_5="gpt-4-turbo"

# Presentation
echo -e "${GREEN}--- 👾 Minion: Minimalist CLI wrapper for OpenAI APIs 👾 Version: ${MINION_VERSION} ---${RESET}"

Expand All @@ -15,6 +22,9 @@ if [ -z "$OPENAI_API_KEY" ]; then
exit 1
fi

#
# Call the Open AI APIs.
#
function call_openai_api() {
local PROMPT="$1"
local INCLUDE_CHANGES="$2"
Expand All @@ -33,8 +43,11 @@ function call_openai_api() {
ESCAPED_CHANGES=$(echo "$CHANGES" | jq -sRr @json)
fi

echo
echo "Using model: $MODEL"

local API_URL="https://api.openai.com/v1/chat/completions"
local MODEL="gpt-3.5-turbo-16k"
local MODEL="gpt-3.5-turbo-16k" # See: https://platform.openai.com/docs/models/gpt-4-and-gpt-4-turbo
local PAYLOAD=$(jq -n --arg model "$MODEL" --arg prompt "$PROMPT" --arg changes "$ESCAPED_CHANGES" '
{
messages: [
Expand Down Expand Up @@ -65,13 +78,19 @@ function call_openai_api() {
echo "$RESULT"
}

#
# The "ask" use case.
#
function ask() {
local PROMPT="$1"
local RESULT=$(call_openai_api "$PROMPT" false)

echo "$RESULT"
}

#
# The "commit" use case.
#
function commit() {
local PROMPT="Generate a Conventional Commits style commit message for the following changes. Use a compact and terse style. For things like dependencies and other verbose changes, bundle these changes into an overall change description. These are the changes:"
local RESULT=$(call_openai_api "$PROMPT" true)
Expand All @@ -80,6 +99,9 @@ function commit() {
echo "$RESULT"
}

#
# The "review" use case.
#
function review() {
local OPTION_1="" # Option switch
local OPTION_2="" # Path
Expand Down Expand Up @@ -112,6 +134,9 @@ function review() {
echo "$RESULT"
}

#
# The "test" use case.
#
function test() {
local OPTION_1="" # Option switch
local OPTION_2="" # Tool
Expand All @@ -122,8 +147,8 @@ function test() {
if [ -n "$3" ]; then OPTION_3="$3"; fi

# First input must be a valid keyword
options=("changes" "file" "api")
if [[ ! "${options[@]}" =~ "$OPTION_1" ]]; then
local OPTIONS=("changes" "file" "api")
if [[ ! "${OPTIONS[@]}" =~ "$OPTION_1" ]]; then
echo "Missing one of the required options: 'changes', 'file', or 'api'. Exiting..."
exit 1
fi
Expand Down Expand Up @@ -167,6 +192,9 @@ function test() {
echo "$RESULT"
}

#
# The "diagram" use case.
#
function diagram() {
local OPTION_1="" # Option switch
local OPTION_2="" # Tool
Expand All @@ -177,17 +205,17 @@ function diagram() {
if [ -n "$3" ]; then OPTION_3="$3"; fi

# First input must be a valid keyword
options=("changes" "file")
if [[ ! "${options[@]}" =~ "$OPTION_1" ]]; then
local OPTIONS=("changes" "file")
if [[ ! "${OPTIONS[@]}" =~ "$OPTION_1" ]]; then
echo "Missing one of the required options: 'changes' or 'file'. Exiting..."
exit 1
fi

local VALID_TYPES=("uml" "mermaid" "sequence_diagram" "class_diagram" "flowchart" "graphviz")
local TOOL="Mermaid"

for valid_value in "${VALID_TYPES[@]}"; do
if [ "$OPTION_2" == "$valid_value" ]; then
for VALID_VALUE in "${VALID_TYPES[@]}"; do
if [ "$OPTION_2" == "$VALID_VALUE" ]; then
TOOL="$2"
break
fi
Expand Down Expand Up @@ -220,14 +248,39 @@ function diagram() {
echo "$RESULT"
}

# Main function
#
# Load a Minion configuration file from the current directory.
#
load_config() {
local CONFIG_FILE="minion.json"
local MODEL=""

if [ -e "$CONFIG_FILE" ]; then
CONFIG_DATA=$(jq -c . "$CONFIG_FILE")

if [ $? -eq 0 ]; then
MODEL=$(echo "$CONFIG_DATA" | jq -r .model)
echo "$MODEL"
fi
else
echo
fi
}

#
# Orchestrate the startup and the various use cases.
#
start() {
if [ $# -eq 0 ]; then
if [ $# -le 1 ]; then
echo "Usage: minion [review|commit|test|ask|diagram]"
echo "Valid options: review, commit, test, ask, diagram"
exit 1
fi

local MODEL="$1"
shift # Shift the arguments so $@ contains only the command line arguments
echo

case "$1" in
"ask")
echo "Asking \"$2\"..."
Expand Down Expand Up @@ -259,4 +312,55 @@ start() {
exit 0
}

start "$@"
#
# Display the model menu.
#
model_menu() {
echo "Choose an OpenAI API Model:"
echo "1. $MODEL_1"
echo "2. $MODEL_2"
echo "3. $MODEL_3"
echo "4. $MODEL_4"
echo "5. $MODEL_5"
echo "6. Exit"
}

#
# Handle the choice of AI model.
#
choose_model() {
# Check if we have a model set from the configuration file
local CONFIG_MODEL=$(load_config)
if [ -n "$CONFIG_MODEL" ]; then
MODEL="$CONFIG_MODEL"
return 0
fi

# A model was not provided through configuration, let user enter their choice

model_menu

local CHOICE
read -p "Enter choice [1-6]: " CHOICE

case $CHOICE in
1) MODEL="$MODEL_1" ;;
2) MODEL="$MODEL_2" ;;
3) MODEL="$MODEL_3" ;;
4) MODEL="$MODEL_4" ;;
5) MODEL="$MODEL_5" ;;
6) exit 0 ;;
*) echo "Invalid choice." && return 1 ;;
esac

return 0
}

#
# Start the program.
#
while true; do
choose_model && break
done

start "$MODEL" "$@"

0 comments on commit 14e871c

Please sign in to comment.