Skip to content

Commit 3aee82e

Browse files
blazickjpDFScience+1-at-298147827574
andauthored
Dev (#13)
* .env update * Adding tests * python version for tests * fixing github actions for tests * Need to figure out how to mock codebase * Try again * Adding multiple OS's (#12) * Adding multiple OS's * Updated * New badge * More badges * License Badge * Minor UI changes * postgres setup update * disabling summaries and embeddings by default * Updates * Fixing bulleted lists in UI --------- Co-authored-by: DFScience+1-at-298147827574 <jblazick@amazon.com>
1 parent 67b93de commit 3aee82e

15 files changed

Lines changed: 102 additions & 87 deletions

File tree

.github/workflows/pytest_ubuntu.yml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,14 @@ on:
44
pull_request:
55
branches:
66
- main # or the name of your default branch
7+
- dev
78

89
jobs:
910
test:
10-
runs-on: ubuntu-latest
11+
strategy:
12+
matrix:
13+
os: [ubuntu-latest, macos-latest, windows-latest]
14+
runs-on: ${{ matrix.os }}
1115

1216
steps:
1317
- name: Checkout code
@@ -16,7 +20,8 @@ jobs:
1620
- name: Set up Python
1721
uses: actions/setup-python@v2
1822
with:
19-
python-version: 3.10.4 # or any other version you prefer
23+
python-version: 3.10.4 # or any othe
24+
2025

2126
- name: Install dependencies
2227
run: |

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ __pycache__/
55

66
# C extensions
77
*.so
8-
8+
*.cfg
9+
/backend/bin/*
910
# Distribution / packaging
1011
.Python
1112
build/

README.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
# GPT-CodeApp
22

3-
![GitHub stars](https://img.shields.io/github/stars/blazickjp/GPT-CodeApp?style=social) ![GitHub release (latest by date)](https://img.shields.io/github/v/release/blazickjp/GPT-CodeApp) ![GitHub All Releases](https://img.shields.io/github/downloads/blazickjp/GPT-CodeApp/total)
3+
![GitHub stars](https://img.shields.io/github/stars/blazickjp/GPT-CodeApp?style=social) ![GitHub release (latest by date)](https://img.shields.io/github/v/release/blazickjp/GPT-CodeApp) ![GitHub All Releases](https://img.shields.io/github/downloads/blazickjp/GPT-CodeApp/total) [![Run Pytest](https://github.com/blazickjp/GPT-CodeApp/actions/workflows/pytest_ubuntu.yml/badge.svg)](https://github.com/blazickjp/GPT-CodeApp/actions/workflows/pytest_ubuntu.yml) ![GitHub contributors](https://img.shields.io/github/contributors/blazickjp/GPT-CodeApp) ![GitHub](https://img.shields.io/github/license/blazickjp/GPT-CodeApp)
4+
5+
6+
47

58
> This project is a clone of Chat-GPT with all the features we wish were available. After getting frustrated by constantly copying and pasting from VS Code into the UI, losing context in the conversation memory, and having little visibility into what's going on under the hood I decided to test the AI's coding ability by making this app. This project started as a tool to better manage the model's conversational memory and context but now we're setting new goals! We're giving the models access to read, write, and edit files but the user has full control! Until these models get better (GPT-5?) we're putting more control in the users hands, but offloading all of the tedious work to the models. This App is very much still a work in progress, but come test it out!
69
@@ -34,11 +37,11 @@ To install necessary dependencies, run the following commands:
3437

3538
### Install PostgresSQL
3639
1. Install PostgreSQL:
37-
- For macOS: `brew install postgresql`
40+
- For macOS: `brew install postgresql@14`
3841
- For Ubuntu: `sudo apt-get install postgresql`
3942

4043
2. Start the PostgreSQL service:
41-
- For macOS: `brew services start postgresql`
44+
- For macOS: `brew services start postgresql@14`
4245
- For Ubuntu: `sudo service postgresql start`
4346

4447
3. Create a new database:

backend/agent/agent_functions/changes.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
from dotenv import load_dotenv
55
from typing import List, Optional, Tuple
6-
from pydantic import Field, field_validator
6+
from pydantic import Field
77
from openai_function_call import OpenAISchema
88

99
load_dotenv()
@@ -24,11 +24,11 @@ class Change(OpenAISchema):
2424
original: str = Field(..., description="Code to be replaced.")
2525
updated: str = Field(..., description="New code.")
2626

27-
@field_validator("original")
28-
def original_must_not_be_blank(cls, v):
29-
if v == "":
30-
raise ValueError("Original cannot be blank.")
31-
return v
27+
# @field_validator("original")
28+
# def original_must_not_be_blank(cls, v):
29+
# if v == "":
30+
# raise ValueError("Original cannot be blank.")
31+
# return v
3232

3333
def to_dict(self) -> dict:
3434
"""
@@ -50,16 +50,16 @@ class Changes(OpenAISchema):
5050
new code
5151
<<<<<< UPDATED
5252
53-
Please provide the old code exactly as you read it and the correct new replacement code.
54-
Be mindful of formatting, number of spaces, and newline characters.
55-
Your code is always valid, correct, and addresses the requests of the human.
56-
When adding new code, include original code to determine where to put the new code (The original field should never be an empty string)
57-
The 'updated' field can be blank when you need to delete the old code.
58-
The file_name is always the relative path from the root of the codebase.
53+
You always follow the below instructions:
54+
- Please provide the old code exactly as you read it.
55+
- Be mindful of formatting, number of spaces, and newline characters.
56+
- Your code is always valid, correct, and addresses the requests of the human.
57+
- The original field should never be an empty string.
58+
- The 'updated' field can be blank when you need to delete old code.
59+
- The file_name is always the relative path from the root of the codebase.
5960
6061
Args:
6162
file_name (str): The relative path from the root of the codebase.
62-
thought (str): A description of your thought process.
6363
changes (List[Change]): A list of Change Objects that represent all the changes you want to make to this file.
6464
"""
6565

backend/agent/agent_functions/shell_commands.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from dotenv import load_dotenv
55
from enum import Enum
66
from typing import Optional, List, Generator
7-
from pydantic import Field, field_validator
7+
from pydantic import Field
88
from openai_function_call import OpenAISchema
99

1010
load_dotenv()
@@ -38,15 +38,15 @@ class Command(OpenAISchema):
3838
)
3939
command_line: Optional[str] = Field(None, description="Command to execute")
4040

41-
@field_validator("command_line")
42-
def check_command(cls, v, values):
43-
if (
44-
"command_type" in values
45-
and values["command_type"] == CommandType.BASH_COMMAND
46-
and v is None
47-
):
48-
raise ValueError("Command is required when command_type is BASH_COMMAND")
49-
return v
41+
# @field_validator("command_line")
42+
# def check_command(cls, v, values):
43+
# if (
44+
# "command_type" in values
45+
# and values["command_type"] == CommandType.BASH_COMMAND
46+
# and v is None
47+
# ):
48+
# raise ValueError("Command is required when command_type is BASH_COMMAND")
49+
# return v
5050

5151
def execute(self, with_results: CommandResults) -> CommandResult:
5252
if self.command_type == CommandType.NEW_FILE:

backend/agent/memory_manager.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,8 @@ def set_system(self, input: dict = {}) -> None:
152152
else:
153153
self.system = (
154154
self.identity
155-
+ "\n\n"
156-
+ "********* Contextual Information *********\n\n"
155+
+ "\n\n" # noqa 503
156+
+ "********* Contextual Information *********\n\n" # noqa 503
157157
)
158158
self.system += (
159159
"The project directory is setup as follows:\n" + self.tree + "\n\n"

backend/database/my_codebase.py

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class MyCodebase:
3333
load_dotenv()
3434
IGNORE_DIRS = os.getenv("IGNORE_DIRS")
3535
FILE_EXTENSIONS = os.getenv("FILE_EXTENSIONS")
36+
UPDATE_FULL = os.getenv("AUTO_UPDATE_EMBEDDINGS", False)
3637

3738
def __init__(
3839
self, directory: str = ".", db_connection: Optional[connection] = None
@@ -78,9 +79,37 @@ def update_file(self, file_path: str) -> None:
7879
else:
7980
print(f"Updating file {file_path}")
8081

81-
embedding = list(self.encode(text))
8282
token_count = len(ENCODER.encode(text))
83+
84+
# The dict's key is the file path, and value is a dict containing the text and embedding
85+
self.cur.execute(
86+
sql.SQL(
87+
"""
88+
INSERT INTO files (file_path, text, token_count, last_updated)
89+
VALUES (%s, %s, %s, %s)
90+
ON CONFLICT (file_path)
91+
DO UPDATE SET text = %s, token_count = %s, last_updated = %s
92+
""",
93+
),
94+
(
95+
file_path,
96+
text,
97+
token_count,
98+
last_modified,
99+
text,
100+
token_count,
101+
last_modified,
102+
),
103+
)
104+
self.conn.commit()
105+
106+
if self.UPDATE_FULL:
107+
self.update_embed_and_summary(file_path, text)
108+
109+
def update_embed_and_summary(self, file_path: str, text: str):
110+
embedding = list(self.encode(text))
83111
embedding = np.array(embedding).tobytes()
112+
84113
response = openai.ChatCompletion.create(
85114
model=SUMMARY_MODEL,
86115
messages=[
@@ -98,25 +127,13 @@ def update_file(self, file_path: str) -> None:
98127
self.cur.execute(
99128
sql.SQL(
100129
"""
101-
INSERT INTO files (file_path, text, embedding, token_count, summary, last_updated)
102-
VALUES (%s, %s, %s, %s, %s, %s)
103-
ON CONFLICT (file_path)
104-
DO UPDATE SET text = %s, embedding = %s, token_count = %s, summary = %s, last_updated = %s
105-
""",
106-
),
107-
(
108-
file_path,
109-
text,
110-
embedding,
111-
token_count,
112-
file_summary,
113-
last_modified,
114-
text,
115-
embedding,
116-
token_count,
117-
file_summary,
118-
last_modified,
130+
INSERT INTO files (file_path, embedding, summary)
131+
VALUES (%s, %s, %s)
132+
ON CONFLICT (file_path)
133+
DO UPDATE SET embedding = %s, summary = %s
134+
""",
119135
),
136+
(file_path, embedding, file_summary, embedding, file_summary),
120137
)
121138
self.conn.commit()
122139

@@ -277,6 +294,8 @@ def _update_files_and_embeddings(self) -> None:
277294
def _is_valid_file(file_name):
278295
return (
279296
not file_name.startswith(".")
280-
and not file_name.startswith("_")
281-
and any(file_name.endswith(ext) for ext in MyCodebase.FILE_EXTENSIONS)
297+
and not file_name.startswith("_") # noqa 503
298+
and any( # noqa 503
299+
file_name.endswith(ext) for ext in MyCodebase.FILE_EXTENSIONS
300+
)
282301
) or file_name == "Dockerfile"

backend/main.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
# Base
21
import json
32
import os
43
from uuid import uuid4
@@ -7,6 +6,10 @@
76
from fastapi.responses import JSONResponse, StreamingResponse
87
from app_setup import setup_app, app
98

9+
# import openai
10+
11+
# openai.api_base = "http://127.0.0.1:5001/v1"
12+
1013

1114
ENCODER = tiktoken.encoding_for_model("gpt-3.5-turbo")
1215
AGENT, CODEBASE = setup_app()

frontend/components/ChatBox.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,15 @@ const CodeBlock = React.memo(({ node, inline, className, children }) => {
3333

3434

3535
function CustomListItem({ node, ...props }) {
36+
return (
37+
<ul {...props} className=' whitespace-normal list-disc list-inside'/>
38+
)
39+
}
40+
41+
function CustomOrderedList({ node, ...props }) {
3642
return (
3743
<ol {...props} className=' whitespace-normal'/>
38-
);
44+
)
3945
}
4046

4147

@@ -50,7 +56,7 @@ const Chatbox = ({ messages }) => {
5056
return (
5157
<div className={message.user === 'human' ? "bg-gray-700 text-white p-5" : "bg-gray-600 p-5 text-white"}>
5258
<div className='flex flex-row w-1/2 mx-auto whitespace-pre-wrap'>
53-
<ReactMarkdown children={message.text} className='flex-grow overflow-x-auto' components={{ code: CodeBlock, ol: CustomListItem }} />
59+
<ReactMarkdown children={message.text} className='flex-grow overflow-x-auto' components={{ code: CodeBlock, ol: CustomOrderedList, ul: CustomListItem }} />
5460
</div>
5561
</div>
5662
);

frontend/components/ModalBar.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ const ModalBar = () => {
9191
<button onClick={fetchSystemPromptAndOpenModal}>
9292
System Prompt:
9393
<span className="ml-2 inline-block bg-green-500 text-white text-xs px-2 rounded-full uppercase font-semibold tracking-wide">
94-
{systemTokens} tokens
94+
{systemTokens}
9595
</span>
9696
</button>
9797
<SystemPromptModal />
@@ -100,7 +100,7 @@ const ModalBar = () => {
100100
< button onClick={fetchFunctionsAndOpenModal} >
101101
Functions:
102102
<span className="ml-2 inline-block bg-green-500 text-white text-xs px-2 rounded-full uppercase font-semibold tracking-wide">
103-
{functionTokens} tokens
103+
{functionTokens}
104104
</span>
105105
</button >
106106
<FunctionsModal />
@@ -109,7 +109,7 @@ const ModalBar = () => {
109109
<button onClick={fetchMessagesAndOpenModal}>
110110
Message History:
111111
<span className="ml-2 inline-block bg-green-500 text-white text-xs px-2 rounded-full uppercase font-semibold tracking-wide">
112-
{messageTokens} tokens
112+
{messageTokens}
113113
</span>
114114
</button>
115115
<MessageHistoryModal />

0 commit comments

Comments
 (0)