Skip to content

Commit

Permalink
bugfix
Browse files Browse the repository at this point in the history
  • Loading branch information
thecodacus committed Jun 4, 2023
1 parent 29a7c6c commit 990c219
Show file tree
Hide file tree
Showing 6 changed files with 159 additions and 90 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ thoughts
dist
build
.DS_Store
*.egg-info
*.egg-info
.vscode
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ This project is licensed under the Apache-2.0 License. See the [LICENSE](https:/

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.

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.`
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`

## Contact

Expand Down
158 changes: 89 additions & 69 deletions lazydev/modules/developer.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,56 +21,57 @@

from .utils import Utilities


class Developer():
def __init__(self, requirement:str,root_dir:str, openai_api_key:str,model:str):
self.requirement=requirement
self.root_dir=root_dir
self.api_key=openai_api_key
self.files_written=[]
def __init__(self, requirement: str, root_dir: str, openai_api_key: str, model: str):
self.requirement = requirement
self.root_dir = root_dir
self.api_key = openai_api_key
self.files_written = []
self.brain = ChatOpenAI(
model=model,
openai_api_key=self.api_key,
temperature=0.1,
streaming=False
)

)

def brain_storm(self,prompt:str,step_name="prompt")->str:
def brain_storm(self, prompt: str, step_name="prompt") -> str:
messages = [
SystemMessage(content="you are a senior software developer"),
HumanMessage(content=prompt)
]
aiMessage:AIMessage= self.brain(messages=messages)
aiMessage: AIMessage = self.brain(messages=messages)
if not os.path.exists("./thoughts"):
os.makedirs("./thoughts")
if os.path.exists(f"./thoughts/{step_name}.md"):
os.remove(f"./thoughts/{step_name}.md")
Utilities.write_to_file(f"{prompt}\n\n{aiMessage.content}",f"./thoughts/{step_name}.md")
Utilities.write_to_file(
f"{prompt}\n\n{aiMessage.content}", f"./thoughts/{step_name}.md")
return aiMessage.content

def get_doubts(self):
prompt=PromptBook.expand_requirements(self.requirement)
doubts=self.brain_storm(prompt,'clear-doubts')
doubt_list:List[str]=doubts.split("\n")
doubt_list=[doubt.strip() for doubt in doubt_list if doubt.strip()!=""]
prompt = PromptBook.expand_requirements(self.requirement)
doubts = self.brain_storm(prompt, 'clear-doubts')
doubt_list: List[str] = doubts.split("\n")
doubt_list = [doubt.strip()
for doubt in doubt_list if doubt.strip() != ""]
return doubt_list
def get_clarifications(self,doubts:List[str],answers:List[str]):
clarifications=""

def get_clarifications(self, doubts: List[str], answers: List[str]):
clarifications = ""
for i in range(len(doubts)):
clarifications=f"{clarifications}\n\n{i+1}. {doubts[i]}\n Ans: {answers[i]}"
self.clarifications=clarifications
clarifications = f"{clarifications}\n\n{i+1}. {doubts[i]}\n Ans: {answers[i]}"
self.clarifications = clarifications
return clarifications


def clear_doubts(self):
doubt_list=self.get_doubts()
doubt_list = self.get_doubts()
print("""
Hey there! 😄 It's Lazy Dev, your friendly neighborhood programmer, here to make your awesome project's dreams come true! 🎉
But before I dive into coding magic, I have a few fun and important questions for you.
So, grab a cup of coffee ☕️, sit back, and let's clarify some details, shall we? Here we go! 🚀
""")
answer_list=[]
answer_list = []
for doubt in doubt_list:
answer = input(f"{doubt}\n>>")
answer_list.append(answer)
Expand All @@ -84,92 +85,111 @@ def clear_doubts(self):
Cheers! 👨‍💻
""")
return doubt_list,answer_list
return doubt_list, answer_list

def plan_project(self):
prompt=PromptBook.plan_project(self.requirement,self.clarifications)
plannings:str=self.brain_storm(prompt,'plan-project')
self.plannings=plannings
prompt = PromptBook.plan_project(self.requirement, self.clarifications)
plannings: str = self.brain_storm(prompt, 'plan-project')
self.plannings = plannings
return plannings

def generate_folder_structure(self):
prompt=PromptBook.design_folder_structure(
prompt = PromptBook.design_folder_structure(
question=self.requirement,
plan=self.plannings,
clarifications=self.clarifications
)
retry_count=3
while retry_count>0:
)
retry_count = 3
while retry_count > 0:
try:

folder_tree_str:str=self.brain_storm(prompt,"generate-filders")
folder_tree:dict=json.loads(folder_tree_str.strip().strip("`"))
folder_tree_str: str = self.brain_storm(
prompt, "generate-filders")
folder_tree: dict = json.loads(
folder_tree_str.strip().strip("`"))
break
except:
print("Opps messed up the json format, let me try again")
retry_count=retry_count-1
if retry_count==0:
retry_count = retry_count-1

if retry_count == 0:
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")
sys.exit()
self.root_folder_name, self.file_paths = Utilities.generate_files_and_folders(structure=folder_tree,root_dir=self.root_dir)
sys.exit()
self.root_folder_name, self.file_paths = Utilities.generate_files_and_folders(
structure=folder_tree, root_dir=self.root_dir)
return self.root_folder_name, self.file_paths


def prioratize_files(self):
prompt=PromptBook.prioritise_file_list(self.file_paths)
retry_count=3
while retry_count>0:
prompt = PromptBook.prioritise_file_list(self.file_paths)
retry_count = 3
while retry_count > 0:
try:
file_paths_str=self.brain_storm(prompt,'prioratize_files')
file_paths_str = self.brain_storm(prompt, 'prioratize_files')
break
except:
print("Opps messed up the json format, let me try again")
retry_count=retry_count-1
if retry_count==0:
retry_count = retry_count-1
if retry_count == 0:
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")
sys.exit()
self.file_paths=file_paths_str.split("\n")
sys.exit()
self.file_paths = file_paths_str.split("\n")
return self.file_paths
def write_file_content(self,file_path):
prompt=PromptBook.write_file(

def write_file_content(self, file_path, review_iteration: int = 1):
prompt = PromptBook.write_file(
question=self.requirement,
clarifications=self.clarifications,
plan=self.plannings,
files_written=self.files_written,
file_path_to_write=file_path,
file_paths=self.file_paths
)
code=self.brain_storm(prompt,f'code-{file_path.split("/")[-1]}')
Utilities.write_to_file(code,file_path=file_path)
)
filename = file_path.split("/")[-1]
code = self.brain_storm(prompt, f'code-{filename}')
if (review_iteration > 1):
print(f"Reviewing the code {filename}")
for i in range(review_iteration-1):
review_prompt = PromptBook.get_code_feedback(
draft=code,
question=self.requirement,
clarifications=self.clarifications,
plan=self.plannings,
files_written=self.files_written,
file_path_to_write=file_path,
file_paths=self.file_paths
)
response = self.brain_storm(
review_prompt, f'code-{file_path.split("/")[-1]}')
response = response.strip('"\'`-\n')
if (response.strip('"\'`-\n') == "NONE"):
break
code = response

Utilities.write_to_file(code, file_path=file_path)
self.files_written.append((
file_path,
code
))

def develop(self):
# clearing all doubts
doubts,answers=self.clear_doubts()
self.clarifications=self.get_clarifications(doubts=doubts,answers=answers)
doubts, answers = self.clear_doubts()
self.clarifications = self.get_clarifications(
doubts=doubts, answers=answers)
# planning the project
print("Planning...")
print("Brainstorming ideas...")
self.plan_project()
print(self.plannings)
print("\n\n")
# creating files and folders for the project
print("Creating files...")
self.generate_folder_structure()
print("Creating folder structure...")
root_folder_name, file_paths = self.generate_folder_structure()

self.prioratize_files()
self.files_written=[]
self.files_written = []
for file_path in self.file_paths:
file_name=file_path.split("/")[-1]
if(file_name.split(".")[-1] in ["png","jpg","jpeg","bimp"]):
file_name = file_path.split("/")[-1]
if (file_name.split(".")[-1] in ["png", "jpg", "jpeg", "bimp", "lock"]):
continue
print(f"\nWriting Code for :{file_name}")
self.write_file_content(file_path)





self.write_file_content(file_path, review_iteration=2)
43 changes: 43 additions & 0 deletions lazydev/modules/prompts.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,46 @@ def write_file(question,clarifications:str,plan:str,files_written:List[List[str]
Content:
"""

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:
file_with_conent="\n\n".join([f"File:{file_path}\nContent:\n{content}" for file_path,content in files_written])
all_files_list="\n".join(file_paths)
return f"""
you are a senior programmer below is what your client have asked you to do:
---
{question}
---
here are some clarrification on the requirements
---
{clarifications}
---
below is the what you have already planed what to do:
---
{plan}
---
Below are the full files list that already has been or will be written
--
{all_files_list}
--
you are now writing the code below are the files that already written with content as follows:
---
{file_with_conent}
---
now you are about to write content the following file:
{file_path_to_write}
below is one of the draft version of the code:
---
{draft}
---
your job is to find problems with the code and refine it.
As your response will go to an automated parser, things to keep in mind all the time:
* if no refinement is required then just say NONE, and nothing else
* only write the file content, no expiation, no pretext as this will directly go as code.
* 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
* 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
Begin!
"""
36 changes: 20 additions & 16 deletions lazydev/modules/utils.py
Original file line number Diff line number Diff line change
@@ -1,45 +1,49 @@
import os
from typing import List, Dict


class Utilities:
@staticmethod
def touch(path):
with open(path, 'a'):
os.utime(path, None)

@staticmethod
def generate_files_recursively(files:List[Dict],cur_dir:str):
file_paths=[]
def generate_files_recursively(files: List[Dict], cur_dir: str):
file_paths = []
for file in files:
name=file['name']
type=file['type']
item_path=os.path.join(cur_dir,name)
if type=="file":
name = file['name']
type = file['type']
item_path = os.path.join(cur_dir, name)
if type == "file":
Utilities.touch(item_path)
file_paths.append(item_path)
print(f"Created File: {item_path}")
else:
if not os.path.exists(item_path):
os.makedirs(item_path)
print(f"Created Directory: {item_path}")
subfiles:List[Dict]=file['files']
sub_file_paths=Utilities.generate_files_recursively(subfiles,item_path)
file_paths=file_paths+sub_file_paths
if 'files' in file:
subfiles: List[Dict] = file['files']
sub_file_paths = Utilities.generate_files_recursively(
subfiles, item_path)
file_paths = file_paths+sub_file_paths
return file_paths

@staticmethod
def generate_files_and_folders(structure:dict,root_dir:str):
root_dir_name=structure['root_dir_name']
cur_dir=os.path.join(root_dir,root_dir_name)
root_dir_path=cur_dir
def generate_files_and_folders(structure: dict, root_dir: str):
root_dir_name = structure['root_dir_name']
cur_dir = os.path.join(root_dir, root_dir_name)
root_dir_path = cur_dir
if not os.path.exists(cur_dir):
os.makedirs(cur_dir)
print(f"Created Directory: {cur_dir}")
files:List[Dict]=structure['files']
file_paths=Utilities.generate_files_recursively(files=files,cur_dir=cur_dir)
files: List[Dict] = structure['files']
file_paths = Utilities.generate_files_recursively(
files=files, cur_dir=cur_dir)
return root_dir_path, file_paths

def write_to_file(content:str,file_path:str):
def write_to_file(content: str, file_path: str):
# Open the file in write mode
with open(file_path, "w") as file:
# Write the content to the file
Expand Down
7 changes: 4 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setup(
name="lazydev",
version='0.0.6',
version='0.0.7',
packages=find_packages(),
install_requires=[
"langchain>=0.0.188",
Expand All @@ -20,7 +20,8 @@
author_email='thecodacus@gmail.com',
description='AI developer for lazy programmer',
long_description=readme, # Assign the contents of README.md to long_description
long_description_content_type='text/markdown', # Specify the type of long description
# Specify the type of long description
long_description_content_type='text/markdown',
url='https://github.com/thecodacus/lazy-dev',
classifiers=[
'Development Status :: 5 - Production/Stable',
Expand All @@ -44,4 +45,4 @@
# ('config', ['config.ini']),
# ],

)
)

0 comments on commit 990c219

Please sign in to comment.