Skip to content

Commit 990c219

Browse files
committed
bugfix
1 parent 29a7c6c commit 990c219

File tree

6 files changed

+159
-90
lines changed

6 files changed

+159
-90
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ thoughts
66
dist
77
build
88
.DS_Store
9-
*.egg-info
9+
*.egg-info
10+
.vscode

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ This project is licensed under the Apache-2.0 License. See the [LICENSE](https:/
7575

7676
LazyDev was inspired by the desire to automate the initial setup and coding process for various projects. The underlying GPT models used in this module were developed by OpenAI.
7777

78-
It is inspired by the project [smol-ai/developer](https://github.com/smol-ai/developer), and the principle `Build the thing that builds all the things.`
78+
It is inspired by the project [smol-ai/developer](https://github.com/smol-ai/developer), and the principle `Build the thing that builds all the things`
7979

8080
## Contact
8181

lazydev/modules/developer.py

Lines changed: 89 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -21,56 +21,57 @@
2121

2222
from .utils import Utilities
2323

24+
2425
class Developer():
25-
def __init__(self, requirement:str,root_dir:str, openai_api_key:str,model:str):
26-
self.requirement=requirement
27-
self.root_dir=root_dir
28-
self.api_key=openai_api_key
29-
self.files_written=[]
26+
def __init__(self, requirement: str, root_dir: str, openai_api_key: str, model: str):
27+
self.requirement = requirement
28+
self.root_dir = root_dir
29+
self.api_key = openai_api_key
30+
self.files_written = []
3031
self.brain = ChatOpenAI(
3132
model=model,
3233
openai_api_key=self.api_key,
3334
temperature=0.1,
3435
streaming=False
35-
)
36-
36+
)
3737

38-
def brain_storm(self,prompt:str,step_name="prompt")->str:
38+
def brain_storm(self, prompt: str, step_name="prompt") -> str:
3939
messages = [
4040
SystemMessage(content="you are a senior software developer"),
4141
HumanMessage(content=prompt)
4242
]
43-
aiMessage:AIMessage= self.brain(messages=messages)
43+
aiMessage: AIMessage = self.brain(messages=messages)
4444
if not os.path.exists("./thoughts"):
4545
os.makedirs("./thoughts")
4646
if os.path.exists(f"./thoughts/{step_name}.md"):
4747
os.remove(f"./thoughts/{step_name}.md")
48-
Utilities.write_to_file(f"{prompt}\n\n{aiMessage.content}",f"./thoughts/{step_name}.md")
48+
Utilities.write_to_file(
49+
f"{prompt}\n\n{aiMessage.content}", f"./thoughts/{step_name}.md")
4950
return aiMessage.content
50-
51+
5152
def get_doubts(self):
52-
prompt=PromptBook.expand_requirements(self.requirement)
53-
doubts=self.brain_storm(prompt,'clear-doubts')
54-
doubt_list:List[str]=doubts.split("\n")
55-
doubt_list=[doubt.strip() for doubt in doubt_list if doubt.strip()!=""]
53+
prompt = PromptBook.expand_requirements(self.requirement)
54+
doubts = self.brain_storm(prompt, 'clear-doubts')
55+
doubt_list: List[str] = doubts.split("\n")
56+
doubt_list = [doubt.strip()
57+
for doubt in doubt_list if doubt.strip() != ""]
5658
return doubt_list
57-
58-
def get_clarifications(self,doubts:List[str],answers:List[str]):
59-
clarifications=""
59+
60+
def get_clarifications(self, doubts: List[str], answers: List[str]):
61+
clarifications = ""
6062
for i in range(len(doubts)):
61-
clarifications=f"{clarifications}\n\n{i+1}. {doubts[i]}\n Ans: {answers[i]}"
62-
self.clarifications=clarifications
63+
clarifications = f"{clarifications}\n\n{i+1}. {doubts[i]}\n Ans: {answers[i]}"
64+
self.clarifications = clarifications
6365
return clarifications
64-
6566

6667
def clear_doubts(self):
67-
doubt_list=self.get_doubts()
68+
doubt_list = self.get_doubts()
6869
print("""
6970
Hey there! 😄 It's Lazy Dev, your friendly neighborhood programmer, here to make your awesome project's dreams come true! 🎉
7071
But before I dive into coding magic, I have a few fun and important questions for you.
7172
So, grab a cup of coffee ☕️, sit back, and let's clarify some details, shall we? Here we go! 🚀
7273
""")
73-
answer_list=[]
74+
answer_list = []
7475
for doubt in doubt_list:
7576
answer = input(f"{doubt}\n>>")
7677
answer_list.append(answer)
@@ -84,92 +85,111 @@ def clear_doubts(self):
8485
8586
Cheers! 👨‍💻
8687
""")
87-
return doubt_list,answer_list
88-
88+
return doubt_list, answer_list
89+
8990
def plan_project(self):
90-
prompt=PromptBook.plan_project(self.requirement,self.clarifications)
91-
plannings:str=self.brain_storm(prompt,'plan-project')
92-
self.plannings=plannings
91+
prompt = PromptBook.plan_project(self.requirement, self.clarifications)
92+
plannings: str = self.brain_storm(prompt, 'plan-project')
93+
self.plannings = plannings
9394
return plannings
94-
95+
9596
def generate_folder_structure(self):
96-
prompt=PromptBook.design_folder_structure(
97+
prompt = PromptBook.design_folder_structure(
9798
question=self.requirement,
9899
plan=self.plannings,
99100
clarifications=self.clarifications
100-
)
101-
retry_count=3
102-
while retry_count>0:
101+
)
102+
retry_count = 3
103+
while retry_count > 0:
103104
try:
104105

105-
folder_tree_str:str=self.brain_storm(prompt,"generate-filders")
106-
folder_tree:dict=json.loads(folder_tree_str.strip().strip("`"))
106+
folder_tree_str: str = self.brain_storm(
107+
prompt, "generate-filders")
108+
folder_tree: dict = json.loads(
109+
folder_tree_str.strip().strip("`"))
107110
break
108111
except:
109112
print("Opps messed up the json format, let me try again")
110-
retry_count=retry_count-1
111-
112-
if retry_count==0:
113+
retry_count = retry_count-1
114+
115+
if retry_count == 0:
113116
print("Sorry I was not able to create the folder structure in json correct format, check my instructions and try to refine it sothat i can understan the task better")
114-
sys.exit()
115-
self.root_folder_name, self.file_paths = Utilities.generate_files_and_folders(structure=folder_tree,root_dir=self.root_dir)
117+
sys.exit()
118+
self.root_folder_name, self.file_paths = Utilities.generate_files_and_folders(
119+
structure=folder_tree, root_dir=self.root_dir)
116120
return self.root_folder_name, self.file_paths
117121

118-
119122
def prioratize_files(self):
120-
prompt=PromptBook.prioritise_file_list(self.file_paths)
121-
retry_count=3
122-
while retry_count>0:
123+
prompt = PromptBook.prioritise_file_list(self.file_paths)
124+
retry_count = 3
125+
while retry_count > 0:
123126
try:
124-
file_paths_str=self.brain_storm(prompt,'prioratize_files')
127+
file_paths_str = self.brain_storm(prompt, 'prioratize_files')
125128
break
126129
except:
127130
print("Opps messed up the json format, let me try again")
128-
retry_count=retry_count-1
129-
if retry_count==0:
131+
retry_count = retry_count-1
132+
if retry_count == 0:
130133
print("Sorry I was not able to create the file list in correct format, check my instructions and try to refine it sothat i can understan the task better")
131-
sys.exit()
132-
self.file_paths=file_paths_str.split("\n")
134+
sys.exit()
135+
self.file_paths = file_paths_str.split("\n")
133136
return self.file_paths
134-
135-
def write_file_content(self,file_path):
136-
prompt=PromptBook.write_file(
137+
138+
def write_file_content(self, file_path, review_iteration: int = 1):
139+
prompt = PromptBook.write_file(
137140
question=self.requirement,
138141
clarifications=self.clarifications,
139142
plan=self.plannings,
140143
files_written=self.files_written,
141144
file_path_to_write=file_path,
142145
file_paths=self.file_paths
143-
)
144-
code=self.brain_storm(prompt,f'code-{file_path.split("/")[-1]}')
145-
Utilities.write_to_file(code,file_path=file_path)
146+
)
147+
filename = file_path.split("/")[-1]
148+
code = self.brain_storm(prompt, f'code-{filename}')
149+
if (review_iteration > 1):
150+
print(f"Reviewing the code {filename}")
151+
for i in range(review_iteration-1):
152+
review_prompt = PromptBook.get_code_feedback(
153+
draft=code,
154+
question=self.requirement,
155+
clarifications=self.clarifications,
156+
plan=self.plannings,
157+
files_written=self.files_written,
158+
file_path_to_write=file_path,
159+
file_paths=self.file_paths
160+
)
161+
response = self.brain_storm(
162+
review_prompt, f'code-{file_path.split("/")[-1]}')
163+
response = response.strip('"\'`-\n')
164+
if (response.strip('"\'`-\n') == "NONE"):
165+
break
166+
code = response
167+
168+
Utilities.write_to_file(code, file_path=file_path)
146169
self.files_written.append((
147170
file_path,
148171
code
149172
))
150173

151174
def develop(self):
152175
# clearing all doubts
153-
doubts,answers=self.clear_doubts()
154-
self.clarifications=self.get_clarifications(doubts=doubts,answers=answers)
176+
doubts, answers = self.clear_doubts()
177+
self.clarifications = self.get_clarifications(
178+
doubts=doubts, answers=answers)
155179
# planning the project
156-
print("Planning...")
180+
print("Brainstorming ideas...")
157181
self.plan_project()
158182
print(self.plannings)
159183
print("\n\n")
160184
# creating files and folders for the project
161-
print("Creating files...")
162-
self.generate_folder_structure()
185+
print("Creating folder structure...")
186+
root_folder_name, file_paths = self.generate_folder_structure()
187+
163188
self.prioratize_files()
164-
self.files_written=[]
189+
self.files_written = []
165190
for file_path in self.file_paths:
166-
file_name=file_path.split("/")[-1]
167-
if(file_name.split(".")[-1] in ["png","jpg","jpeg","bimp"]):
191+
file_name = file_path.split("/")[-1]
192+
if (file_name.split(".")[-1] in ["png", "jpg", "jpeg", "bimp", "lock"]):
168193
continue
169194
print(f"\nWriting Code for :{file_name}")
170-
self.write_file_content(file_path)
171-
172-
173-
174-
175-
195+
self.write_file_content(file_path, review_iteration=2)

lazydev/modules/prompts.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,3 +135,46 @@ def write_file(question,clarifications:str,plan:str,files_written:List[List[str]
135135
Content:
136136
"""
137137

138+
def get_code_feedback(draft:str,question,clarifications:str,plan:str,files_written:List[List[str]], file_path_to_write:str,file_paths:List[str])->str:
139+
file_with_conent="\n\n".join([f"File:{file_path}\nContent:\n{content}" for file_path,content in files_written])
140+
all_files_list="\n".join(file_paths)
141+
return f"""
142+
you are a senior programmer below is what your client have asked you to do:
143+
---
144+
{question}
145+
---
146+
here are some clarrification on the requirements
147+
---
148+
{clarifications}
149+
---
150+
below is the what you have already planed what to do:
151+
---
152+
{plan}
153+
---
154+
Below are the full files list that already has been or will be written
155+
--
156+
{all_files_list}
157+
--
158+
159+
you are now writing the code below are the files that already written with content as follows:
160+
---
161+
{file_with_conent}
162+
---
163+
164+
now you are about to write content the following file:
165+
{file_path_to_write}
166+
167+
below is one of the draft version of the code:
168+
---
169+
{draft}
170+
---
171+
172+
your job is to find problems with the code and refine it.
173+
174+
As your response will go to an automated parser, things to keep in mind all the time:
175+
* if no refinement is required then just say NONE, and nothing else
176+
* only write the file content, no expiation, no pretext as this will directly go as code.
177+
* if the language support, add comments at steps, which expains what you are about to do, dont add comment if comment is not supported by the file type example json file
178+
* keep in mind there wont be any additional files other then the full files list given above, only use files that are mentioned in that list
179+
Begin!
180+
"""

lazydev/modules/utils.py

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,49 @@
11
import os
22
from typing import List, Dict
33

4+
45
class Utilities:
56
@staticmethod
67
def touch(path):
78
with open(path, 'a'):
89
os.utime(path, None)
910

1011
@staticmethod
11-
def generate_files_recursively(files:List[Dict],cur_dir:str):
12-
file_paths=[]
12+
def generate_files_recursively(files: List[Dict], cur_dir: str):
13+
file_paths = []
1314
for file in files:
14-
name=file['name']
15-
type=file['type']
16-
item_path=os.path.join(cur_dir,name)
17-
if type=="file":
15+
name = file['name']
16+
type = file['type']
17+
item_path = os.path.join(cur_dir, name)
18+
if type == "file":
1819
Utilities.touch(item_path)
1920
file_paths.append(item_path)
2021
print(f"Created File: {item_path}")
2122
else:
2223
if not os.path.exists(item_path):
2324
os.makedirs(item_path)
2425
print(f"Created Directory: {item_path}")
25-
subfiles:List[Dict]=file['files']
26-
sub_file_paths=Utilities.generate_files_recursively(subfiles,item_path)
27-
file_paths=file_paths+sub_file_paths
26+
if 'files' in file:
27+
subfiles: List[Dict] = file['files']
28+
sub_file_paths = Utilities.generate_files_recursively(
29+
subfiles, item_path)
30+
file_paths = file_paths+sub_file_paths
2831
return file_paths
2932

3033
@staticmethod
31-
def generate_files_and_folders(structure:dict,root_dir:str):
32-
root_dir_name=structure['root_dir_name']
33-
cur_dir=os.path.join(root_dir,root_dir_name)
34-
root_dir_path=cur_dir
34+
def generate_files_and_folders(structure: dict, root_dir: str):
35+
root_dir_name = structure['root_dir_name']
36+
cur_dir = os.path.join(root_dir, root_dir_name)
37+
root_dir_path = cur_dir
3538
if not os.path.exists(cur_dir):
3639
os.makedirs(cur_dir)
3740
print(f"Created Directory: {cur_dir}")
38-
files:List[Dict]=structure['files']
39-
file_paths=Utilities.generate_files_recursively(files=files,cur_dir=cur_dir)
41+
files: List[Dict] = structure['files']
42+
file_paths = Utilities.generate_files_recursively(
43+
files=files, cur_dir=cur_dir)
4044
return root_dir_path, file_paths
4145

42-
def write_to_file(content:str,file_path:str):
46+
def write_to_file(content: str, file_path: str):
4347
# Open the file in write mode
4448
with open(file_path, "w") as file:
4549
# Write the content to the file

setup.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
setup(
77
name="lazydev",
8-
version='0.0.6',
8+
version='0.0.7',
99
packages=find_packages(),
1010
install_requires=[
1111
"langchain>=0.0.188",
@@ -20,7 +20,8 @@
2020
author_email='thecodacus@gmail.com',
2121
description='AI developer for lazy programmer',
2222
long_description=readme, # Assign the contents of README.md to long_description
23-
long_description_content_type='text/markdown', # Specify the type of long description
23+
# Specify the type of long description
24+
long_description_content_type='text/markdown',
2425
url='https://github.com/thecodacus/lazy-dev',
2526
classifiers=[
2627
'Development Status :: 5 - Production/Stable',
@@ -44,4 +45,4 @@
4445
# ('config', ['config.ini']),
4546
# ],
4647

47-
)
48+
)

0 commit comments

Comments
 (0)