Skip to content

Commit

Permalink
Merge pull request #4 from unconv/improvements
Browse files Browse the repository at this point in the history
Added better GPT-3.5 support and other improvements
  • Loading branch information
unconv authored Jun 23, 2023
2 parents b782a1c + a5a082c commit 9b871c9
Show file tree
Hide file tree
Showing 9 changed files with 507 additions and 121 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ config.json
old_demos/
code/
history/
versions/
30 changes: 30 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.1.0] 2023-06-23

### Added

- Better support for GPT-3.5 models
- More command line arguments
- `--conv` to set previous conversation ID to continue from
- `--prompt` to set initial prompt
- `--delete` to delete existing code if present
- `--versions` to create multiple versions of the same project at once
- `--temp` to set temperature of GPT API
- `--better` to automatically make prompt better with GPT
- `--not-better` to not ask to make prompt better with GPT
- `--ask-better` to ask for confirmation of using better prompt when automatically making better prompt
- `--better-versions` to create a separate better prompt for every version

### Fixed

- API loop when invalid model was used in settings (issue #3)

### Changed

- Conversation ID is now set with `--conv` flag, instead of the first command line argument
20 changes: 17 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,31 @@ $ export OPENAI_API_KEY=YOUR_API_KEY
$ pip install --upgrade openai
```

3\. Run the script. It will ask you for a prompt. Pass a conversation ID if you want to continue a previous context from the `history/` folder.
3\. Run the script. It will ask you for a prompt.

```console
$ ./gpt-autopilot.py [CONVERSATION_ID]
$ ./gpt-autopilot.py
```

4\. For example, tell it to "create a JavaScript inventory application for the browser with a form that can add products with a name, quantity and price. Save the products to localstorage and list them in a table in the application. Calculate the total price of the products in the inventory. Add CSS styles to make the application look professional. Add a Inventory System header and hide the product add form when the page is printed."

The files will be written in the `code/` directory

The default model is `gpt-4-0613` and it works best, but you can still use the `gpt-3.5-turbo-0613` model. Just note that it is not as capable. To change, add `"model": "gpt-3.5-turbo-0613"` to the `config.json` file.
The default model is `gpt-4-0613` and it works best, but you can still use the `gpt-3.5-turbo-16k-0613` or `gpt-3.5-turbo-0613` model. Just note that it is not as capable. To change, add `"model": "gpt-3.5-turbo-16k-0613"` to the `config.json` file. Make sure to use the 0613 model since only that supports function calling.

## Multi-version branching

With the new `--versions` flag you can create multiple versions of a project at the same time. This is recommended, as sometimes retrying a prompt will produce a better outcome.

For example, you can create 3 versions of the same project by running:

```console
$ ./gpt-autopilot --versions 3
```

After all the versions have been created, you can inspect them and GPT-AutoPilot will ask you, which one you want to iterate over. It will then create 3 more versions of that version with your next prompt and you can repeat this process until the project is ready.

All versions and version iterations are stored in separate folders in the `versions` folder.

## System Message

Expand Down
5 changes: 3 additions & 2 deletions betterprompter.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import openai

def make_better(prompt, model):
def make_better(prompt, model, temp = 1.0):
if len(prompt.split(" ")) < 80:
words = "an 80 word"
else:
Expand All @@ -9,7 +9,7 @@ def make_better(prompt, model):
messages = [
{
"role": "system",
"content": "You are a prompt designer for an AI agent that can read and write files from the filesystem and run commands on the computer. The AI agent is used to create all kinds of projects, including programming and content creaton. Please note that the agent can not run GUI applications or run tests. Only describe the project, not how it should be implemented."
"content": "You are a prompt designer for an AI agent that can read and write files from the filesystem and run commands on the computer. The AI agent is used to create all kinds of projects, including programming and content creaton. Please note that the agent can not run GUI applications or run tests. Only describe the project, not how it should be implemented. The prompt will be given to the AI agent as a description of the project to accomplish."
},
{
"role": "user",
Expand All @@ -20,6 +20,7 @@ def make_better(prompt, model):
response = openai.ChatCompletion.create(
model=model,
messages=messages,
temperature=temp,
)

return response["choices"][0]["message"]["content"]
51 changes: 44 additions & 7 deletions chatgpt.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,21 @@
import time
import json
import sys
import copy

import gpt_functions

def redact_messages(messages):
messages_redact = copy.deepcopy(messages)
for msg in messages_redact:
if msg["role"] == "assistant" and msg["content"] not in [None, "<message redacted>"]:
msg["content"] = "<message redacted>"
break
if msg["role"] == "function" and msg["name"] == "read_file" and msg["content"] not in [None, "<file contents redacted>"]:
msg["content"] = "<file contents redacted>"
break
return messages_redact

# ChatGPT API Function

def send_message(
Expand All @@ -15,24 +27,45 @@ def send_message(
retries = 0,
print_message = True,
conv_id = None,
temp = 1.0,
):
print("Waiting for ChatGPT...")

# add user message to message list
messages.append(message)

# redact old messages when encountering partial output
if "No END_OF_FILE_CONTENT" in message["content"]:
print("## NOTICE: Partial output detected, dropping messages... ##")
messages[-2]["content"] = "<file content redacted>"
messages = redact_messages(messages)

# save message history
if conv_id is not None:
with open(f"history/{conv_id}.json", "w") as f:
f.write(json.dumps(messages, indent=4))

# gpt-3.5 is not responsible enough for these functions
gpt3_disallow = [
"create_dir",
"move_file",
"copy_file",
"replace_text",
]

if "gpt-4" not in model:
for definition in gpt_functions.definitions:
if definition["name"] in gpt3_disallow:
gpt_functions.definitions.remove(definition)

try:
# send prompt to chatgpt
response = openai.ChatCompletion.create(
model=model,
messages=messages,
functions=gpt_functions.definitions,
function_call=function_call,
temperature=temp,
)
except openai.error.AuthenticationError:
print("AuthenticationError: Check your API-key")
Expand All @@ -41,25 +74,28 @@ def send_message(
if "maximum context length" in str(e):
print("## NOTICE: Context limit reached, dropping old messages... ##")

# remove last message
messages.pop()

# redact first unredacted assistant message
redacted = False
for msg in messages:
if msg["role"] == "assistant" and msg["content"] not in [None, "<message redacted>"]:
msg["content"] = "<message redacted>"
redacted = True
break
redacted_messages = redact_messages(messages)

# show error if no message could be redacted
if redacted == False:
if redacted_messages == messages:
raise

messages = redacted_messages
else:
raise

return send_message(
message=message,
messages=messages,
model=model,
function_call=function_call,
conv_id=conv_id,
print_message=print_message,
temp=temp,
)
except openai.error.PermissionError:
raise
Expand All @@ -82,6 +118,7 @@ def send_message(
retries=retries+1,
conv_id=conv_id,
print_message=print_message,
temp=temp,
)

# add response to message list
Expand Down
15 changes: 15 additions & 0 deletions config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import json

def get_config():
try:
with open("config.json") as f:
config = json.load(f)
except:
config = {
"model": "gpt-4-0613",
}
return config

def save_config(config):
with open("config.json", "w") as f:
f.write(json.dumps(config, indent=4))
Loading

0 comments on commit 9b871c9

Please sign in to comment.