vikramvasudevan commited on
Commit
54d0037
·
verified ·
1 Parent(s): 3ac4267

Upload folder using huggingface_hub

Browse files
.github/workflows/update_space.yml CHANGED
@@ -1,28 +1,28 @@
1
- name: Run Python script
2
-
3
- on:
4
- push:
5
- branches:
6
- - main
7
-
8
- jobs:
9
- build:
10
- runs-on: ubuntu-latest
11
-
12
- steps:
13
- - name: Checkout
14
- uses: actions/checkout@v2
15
-
16
- - name: Set up Python
17
- uses: actions/setup-python@v2
18
- with:
19
- python-version: '3.9'
20
-
21
- - name: Install Gradio
22
- run: python -m pip install gradio
23
-
24
- - name: Log in to Hugging Face
25
- run: python -c 'import huggingface_hub; huggingface_hub.login(token="${{ secrets.hf_token }}")'
26
-
27
- - name: Deploy to Spaces
28
- run: gradio deploy
 
1
+ name: Run Python script
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+
8
+ jobs:
9
+ build:
10
+ runs-on: ubuntu-latest
11
+
12
+ steps:
13
+ - name: Checkout
14
+ uses: actions/checkout@v2
15
+
16
+ - name: Set up Python
17
+ uses: actions/setup-python@v2
18
+ with:
19
+ python-version: '3.9'
20
+
21
+ - name: Install Gradio
22
+ run: python -m pip install gradio
23
+
24
+ - name: Log in to Hugging Face
25
+ run: python -c 'import huggingface_hub; huggingface_hub.login(token="${{ secrets.hf_token }}")'
26
+
27
+ - name: Deploy to Spaces
28
+ run: gradio deploy
.gitignore CHANGED
@@ -1,5 +1,5 @@
1
- .env
2
- __pycache__/
3
- lib/
4
- .DS_Store
5
  /output/
 
1
+ .env
2
+ __pycache__/
3
+ lib/
4
+ .DS_Store
5
  /output/
README.md CHANGED
@@ -1,63 +1,63 @@
1
- ---
2
- title: Engineering_Team_of_Agents
3
- app_file: app.py
4
- sdk: gradio
5
- sdk_version: 5.38.0
6
- python_version: 3.12
7
- ---
8
- # Engineering Crew
9
-
10
- Welcome to theEngineering Crew project, powered by [crewAI](https://crewai.com). This template is designed to help you set up a multi-agent AI system with ease, leveraging the powerful and flexible framework provided by crewAI. Our goal is to enable your agents to collaborate effectively on complex tasks, maximizing their collective intelligence and capabilities.
11
-
12
- ## Installation
13
-
14
- Ensure you have Python >=3.10 <3.14 installed on your system. This project uses [UV](https://docs.astral.sh/uv/) for dependency management and package handling, offering a seamless setup and execution experience.
15
-
16
- First, if you haven't already, install uv:
17
-
18
- ```bash
19
- pip install uv
20
- ```
21
-
22
- Next, navigate to your project directory and install the dependencies:
23
-
24
- (Optional) Lock the dependencies and install them by using the CLI command:
25
- ```bash
26
- crewai install
27
- ```
28
-
29
- ### Customizing
30
-
31
- **Add your `OPENAI_API_KEY` into the `.env` file**
32
-
33
- - Modify `src/engineering_team_using_flow/config/agents.yaml` to define your agents
34
- - Modify `src/engineering_team_using_flow/config/tasks.yaml` to define your tasks
35
- - Modify `src/engineering_team_using_flow/crew.py` to add your own logic, tools and specific args
36
- - Modify `src/engineering_team_using_flow/main.py` to add custom inputs for your agents and tasks
37
-
38
- ## Running the Project
39
-
40
- To kickstart your flow and begin execution, run this from the root folder of your project:
41
-
42
- ```bash
43
- crewai run
44
- ```
45
-
46
- This command initializes the engineering_team_using_flow Flow as defined in your configuration.
47
-
48
- This example, unmodified, will run the create a `report.md` file with the output of a research on LLMs in the root folder.
49
-
50
- ## Understanding Your Crew
51
-
52
- The engineering_team_using_flow Crew is composed of multiple AI agents, each with unique roles, goals, and tools. These agents collaborate on a series of tasks, defined in `config/tasks.yaml`, leveraging their collective skills to achieve complex objectives. The `config/agents.yaml` file outlines the capabilities and configurations of each agent in your crew.
53
-
54
- ## Support
55
-
56
- For support, questions, or feedback regarding theEngineering Crew or crewAI.
57
-
58
- - Visit our [documentation](https://docs.crewai.com)
59
- - Reach out to us through our [GitHub repository](https://github.com/joaomdmoura/crewai)
60
- - [Join our Discord](https://discord.com/invite/X4JWnZnxPb)
61
- - [Chat with our docs](https://chatg.pt/DWjSBZn)
62
-
63
- Let's create wonders together with the power and simplicity of crewAI.
 
1
+ ---
2
+ title: Engineering_Team_of_Agents
3
+ app_file: app.py
4
+ sdk: gradio
5
+ sdk_version: 5.38.0
6
+ python_version: 3.12
7
+ ---
8
+ # Engineering Crew
9
+
10
+ Welcome to theEngineering Crew project, powered by [crewAI](https://crewai.com). This template is designed to help you set up a multi-agent AI system with ease, leveraging the powerful and flexible framework provided by crewAI. Our goal is to enable your agents to collaborate effectively on complex tasks, maximizing their collective intelligence and capabilities.
11
+
12
+ ## Installation
13
+
14
+ Ensure you have Python >=3.10 <3.14 installed on your system. This project uses [UV](https://docs.astral.sh/uv/) for dependency management and package handling, offering a seamless setup and execution experience.
15
+
16
+ First, if you haven't already, install uv:
17
+
18
+ ```bash
19
+ pip install uv
20
+ ```
21
+
22
+ Next, navigate to your project directory and install the dependencies:
23
+
24
+ (Optional) Lock the dependencies and install them by using the CLI command:
25
+ ```bash
26
+ crewai install
27
+ ```
28
+
29
+ ### Customizing
30
+
31
+ **Add your `OPENAI_API_KEY` into the `.env` file**
32
+
33
+ - Modify `src/engineering_team_using_flow/config/agents.yaml` to define your agents
34
+ - Modify `src/engineering_team_using_flow/config/tasks.yaml` to define your tasks
35
+ - Modify `src/engineering_team_using_flow/crew.py` to add your own logic, tools and specific args
36
+ - Modify `src/engineering_team_using_flow/main.py` to add custom inputs for your agents and tasks
37
+
38
+ ## Running the Project
39
+
40
+ To kickstart your flow and begin execution, run this from the root folder of your project:
41
+
42
+ ```bash
43
+ crewai run
44
+ ```
45
+
46
+ This command initializes the engineering_team_using_flow Flow as defined in your configuration.
47
+
48
+ This example, unmodified, will run the create a `report.md` file with the output of a research on LLMs in the root folder.
49
+
50
+ ## Understanding Your Crew
51
+
52
+ The engineering_team_using_flow Crew is composed of multiple AI agents, each with unique roles, goals, and tools. These agents collaborate on a series of tasks, defined in `config/tasks.yaml`, leveraging their collective skills to achieve complex objectives. The `config/agents.yaml` file outlines the capabilities and configurations of each agent in your crew.
53
+
54
+ ## Support
55
+
56
+ For support, questions, or feedback regarding theEngineering Crew or crewAI.
57
+
58
+ - Visit our [documentation](https://docs.crewai.com)
59
+ - Reach out to us through our [GitHub repository](https://github.com/joaomdmoura/crewai)
60
+ - [Join our Discord](https://discord.com/invite/X4JWnZnxPb)
61
+ - [Chat with our docs](https://chatg.pt/DWjSBZn)
62
+
63
+ Let's create wonders together with the power and simplicity of crewAI.
app.py CHANGED
@@ -1,94 +1,99 @@
1
- import time
2
- import random
3
- import gradio as gr
4
- from pydantic import BaseModel
5
- from queue import Queue
6
-
7
- from engineering_team_using_flow.main import EngineeringFlow
8
- from engineering_team_using_flow.shared_queue import (
9
- TaskInfo,
10
- shared_task_output_queue,
11
- add_to_queue,
12
- )
13
-
14
-
15
- def generate_random_statement():
16
- return f"{random.choice(['The cat', 'A dog', 'My friend'])} {random.choice(['eats', 'jumps', 'reads'])} {random.choice(['a book.', 'the newspaper.', 'some food.'])} {random.choice(['quickly', 'happily', 'silently'])}"
17
-
18
-
19
- def start_long_running_process():
20
- print("🚀 Long Running process started")
21
- for i in range(10):
22
- time.sleep(1)
23
- task_type = random.choice(["markdown", "code"])
24
- add_to_queue(
25
- TaskInfo(
26
- name=f"Task {i}",
27
- type=task_type,
28
- output=(
29
- f"\nprint('task {i}')"
30
- if task_type == "code"
31
- else generate_random_statement()
32
- ),
33
- )
34
- )
35
- add_to_queue(TaskInfo(name="Complete", type="markdown", output="✅ Done."))
36
- print("✅ Long Running process Finished")
37
-
38
-
39
- def run_and_stream(module_name: str, requirements: str):
40
- print("🚀 Background process started")
41
- if module_name.strip() == "" or requirements.strip() == "":
42
- yield [{"role" : "assistant", "content" : "### Mandatory fields missing ..."}]
43
- return
44
-
45
- # Start the process in a thread so we can yield live
46
- from threading import Thread
47
-
48
- thread = Thread(target=EngineeringFlow(module_name, requirements).kickoff)
49
- thread.start()
50
-
51
- print("🚀 Monitoring queue ...")
52
- messages = []
53
- curr_role = "user"
54
- while thread.is_alive() or not shared_task_output_queue.empty():
55
- if not shared_task_output_queue.empty():
56
- task = shared_task_output_queue.get()
57
- print(f"🧲 {task.name} - {task.output}")
58
-
59
- curr_role = "assistant" if curr_role == "user" else "user"
60
- messages.append(
61
- {
62
- "role": curr_role,
63
- "content": "",
64
- }
65
- )
66
-
67
- for char in f"{task.output}":
68
- time.sleep(0.005)
69
- messages[-1]["content"] += char
70
- yield messages
71
-
72
- else:
73
- time.sleep(0.2) # small delay to prevent CPU spin
74
-
75
- curr_role = "assistant" if curr_role == "user" else "user"
76
- messages.append({"role":curr_role, "content" : "# All Done!"})
77
- yield(messages)
78
-
79
- # UI
80
- with gr.Blocks(theme=gr.themes.Ocean()) as demo:
81
- module_name = gr.Textbox(
82
- label="Module Name", placeholder="What do you want to call your product?"
83
- )
84
- requirements = gr.Textbox(
85
- label="Business Requirements",
86
- placeholder="I want to build a ... Clearly state your business requirements.",
87
- )
88
- run_button = gr.Button("Create Product", variant="primary")
89
- chat = gr.Chatbot(type="messages", label="Crew Output", height=600)
90
- run_button.click(
91
- fn=run_and_stream, inputs=[module_name, requirements], outputs=chat
92
- )
93
-
94
- demo.launch()
 
 
 
 
 
 
1
+ import sys
2
+ import os
3
+
4
+ sys.path.append(os.path.join(os.path.dirname(__file__), "src"))
5
+
6
+ import time
7
+ import random
8
+ import gradio as gr
9
+ from pydantic import BaseModel
10
+ from queue import Queue
11
+
12
+ from engineering_team_using_flow.main import EngineeringFlow
13
+ from engineering_team_using_flow.shared_queue import (
14
+ TaskInfo,
15
+ shared_task_output_queue,
16
+ add_to_queue,
17
+ )
18
+
19
+
20
+ def generate_random_statement():
21
+ return f"{random.choice(['The cat', 'A dog', 'My friend'])} {random.choice(['eats', 'jumps', 'reads'])} {random.choice(['a book.', 'the newspaper.', 'some food.'])} {random.choice(['quickly', 'happily', 'silently'])}"
22
+
23
+
24
+ def start_long_running_process():
25
+ print("🚀 Long Running process started")
26
+ for i in range(10):
27
+ time.sleep(1)
28
+ task_type = random.choice(["markdown", "code"])
29
+ add_to_queue(
30
+ TaskInfo(
31
+ name=f"Task {i}",
32
+ type=task_type,
33
+ output=(
34
+ f"\nprint('task {i}')"
35
+ if task_type == "code"
36
+ else generate_random_statement()
37
+ ),
38
+ )
39
+ )
40
+ add_to_queue(TaskInfo(name="Complete", type="markdown", output="✅ Done."))
41
+ print(" Long Running process Finished")
42
+
43
+
44
+ def run_and_stream(module_name: str, requirements: str):
45
+ print("🚀 Background process started")
46
+ if module_name.strip() == "" or requirements.strip() == "":
47
+ yield [{"role" : "assistant", "content" : "### Mandatory fields missing ..."}]
48
+ return
49
+
50
+ # Start the process in a thread so we can yield live
51
+ from threading import Thread
52
+
53
+ thread = Thread(target=EngineeringFlow(module_name, requirements).kickoff)
54
+ thread.start()
55
+
56
+ print("🚀 Monitoring queue ...")
57
+ messages = []
58
+ curr_role = "user"
59
+ while thread.is_alive() or not shared_task_output_queue.empty():
60
+ if not shared_task_output_queue.empty():
61
+ task = shared_task_output_queue.get()
62
+ print(f"🧲 {task.name} - {task.output}")
63
+
64
+ curr_role = "assistant" if curr_role == "user" else "user"
65
+ messages.append(
66
+ {
67
+ "role": curr_role,
68
+ "content": "",
69
+ }
70
+ )
71
+
72
+ for char in f"{task.output}":
73
+ time.sleep(0.005)
74
+ messages[-1]["content"] += char
75
+ yield messages
76
+
77
+ else:
78
+ time.sleep(0.2) # small delay to prevent CPU spin
79
+
80
+ curr_role = "assistant" if curr_role == "user" else "user"
81
+ messages.append({"role":curr_role, "content" : "# All Done!"})
82
+ yield(messages)
83
+
84
+ # UI
85
+ with gr.Blocks(theme=gr.themes.Ocean()) as demo:
86
+ module_name = gr.Textbox(
87
+ label="Module Name", placeholder="What do you want to call your product?"
88
+ )
89
+ requirements = gr.Textbox(
90
+ label="Business Requirements",
91
+ placeholder="I want to build a ... Clearly state your business requirements.",
92
+ )
93
+ run_button = gr.Button("Create Product", variant="primary")
94
+ chat = gr.Chatbot(type="messages", label="Crew Output", height=600)
95
+ run_button.click(
96
+ fn=run_and_stream, inputs=[module_name, requirements], outputs=chat
97
+ )
98
+
99
+ demo.launch()
src/engineering_team_using_flow/crews/engineering_crew/config/agents.yaml CHANGED
@@ -1,71 +1,71 @@
1
- development_lead:
2
- role: >
3
- Development Lead
4
- goal: >
5
- For the given requirement, create a detailed design outlining the approach. Include modules, detail out the classes and the functions inside the classes.
6
- generate output a markdown format. keep the design simple and crisp. Do not add unnecessary commentary.
7
- Ensure the design produces a single module. Do not provide any code in the output.
8
- Design should clearly distinguish frontend (Gradio UI) and backend (business logic, APIs, database interactions) and needs to be allocated and built by backend and the frontend engineers.
9
- The requirement is this:
10
- {requirement}
11
- backstory: >
12
- You are a seasoned development lead, a great problem solver who can design complex systems with ease and articulate it well. You have the capability to provide simple solutions for complex popblems.
13
-
14
- backend_engineer:
15
- role: >
16
- Senior Backend Python Developer
17
- goal: >
18
- Develop backend modules using Python for the given requirement. Stick strictly to the design provided by the development lead.
19
- Ensure you add adequate comments and docstrings for clarity. Do not add unit tests. handle exceptions well. Do good logging.
20
- Do not write or include any frontend/UI code such as HTML, CSS, JavaScript, or Gradio components.
21
- Provide ONLY the code as output. Do not use markdown or backquotes. Ensure the code is directly executable.
22
- If the design includes frontend elements, ignore them entirely. They are outside your scope.
23
- You **must not** work on Gradio, HTML, or anything visual. That is exclusively the responsibility of the frontend engineer.
24
- DO NOT USE FLASK for APIs. Just write UI-independent backend modules, simple functions.
25
- the requirement is as follows:
26
- {requirement}
27
- backstory: >
28
- You're a seasoned backend Python developer focused purely on backend logic and infrastructure.
29
- You do not work on frontend or UI development. You collaborate with the development lead and frontend engineers to fulfill your part.
30
-
31
- code_reviewer:
32
- role: >
33
- Code Reviewer
34
- goal: >
35
- Review the code provided by the backend engineer and provide feedback considering the following parameters:
36
- 1. Adherence to the design provided by the development lead
37
- 2. Code Efficiency
38
- 3. Whether the code would achieve the objective stated in the requirements.
39
-
40
- Do not provide unnecessaary commentary. stay on point.
41
-
42
- if there were any review comments during the previous iteration, ensure you review the code again to ensure your earlier comments have been incorporated.
43
-
44
- here is the business requirement:
45
-
46
- {requirement}
47
- backstory: >
48
- You are a seasoned developer who has a knack for details. You are an expert in reviewing the code and providing detailed feedback in a constructive manner.
49
- You can articulate and organize your feedback well.
50
-
51
- test_engineer:
52
- role: >
53
- Senior Test Engineer
54
- goal: >
55
- Develop unit tests for the code written by the backend engineer. Just output the code without any other formatting or commentary. The code should be executable as is.
56
- the requirement is as follows:
57
- {requirement}
58
- backstory: >
59
- You're a seasoned python developer who can write great unit tests for a given requirement.
60
- You are able to work with the developmet lead and the backend engineer to create tests.
61
-
62
- frontend_engineer:
63
- role: >
64
- Frontend Developer
65
- goal: >
66
- Implement the frontend/UI components as described in the design using Gradio. Work only on the interface and not the backend. ONLY provide executable python code as output. no backticks, headers, nothing.
67
- Ensure you add adequate comments and docstrings for clarity. Do not add unit tests. handle exceptions well. Do good logging.
68
- the requirement is as follows:
69
- {requirement}
70
- backstory: >
71
- You are an expert in frontend development and specialize in Gradio. You collaborate with the development lead and backend engineer to deliver a seamless user experience.
 
1
+ development_lead:
2
+ role: >
3
+ Development Lead
4
+ goal: >
5
+ For the given requirement, create a detailed design outlining the approach. Include modules, detail out the classes and the functions inside the classes.
6
+ generate output a markdown format. keep the design simple and crisp. Do not add unnecessary commentary.
7
+ Ensure the design produces a single module. Do not provide any code in the output.
8
+ Design should clearly distinguish frontend (Gradio UI) and backend (business logic, APIs, database interactions) and needs to be allocated and built by backend and the frontend engineers.
9
+ The requirement is this:
10
+ {requirement}
11
+ backstory: >
12
+ You are a seasoned development lead, a great problem solver who can design complex systems with ease and articulate it well. You have the capability to provide simple solutions for complex popblems.
13
+
14
+ backend_engineer:
15
+ role: >
16
+ Senior Backend Python Developer
17
+ goal: >
18
+ Develop backend modules using Python for the given requirement. Stick strictly to the design provided by the development lead.
19
+ Ensure you add adequate comments and docstrings for clarity. Do not add unit tests. handle exceptions well. Do good logging.
20
+ Do not write or include any frontend/UI code such as HTML, CSS, JavaScript, or Gradio components.
21
+ Provide ONLY the code as output. Do not use markdown or backquotes. Ensure the code is directly executable.
22
+ If the design includes frontend elements, ignore them entirely. They are outside your scope.
23
+ You **must not** work on Gradio, HTML, or anything visual. That is exclusively the responsibility of the frontend engineer.
24
+ DO NOT USE FLASK for APIs. Just write UI-independent backend modules, simple functions.
25
+ the requirement is as follows:
26
+ {requirement}
27
+ backstory: >
28
+ You're a seasoned backend Python developer focused purely on backend logic and infrastructure.
29
+ You do not work on frontend or UI development. You collaborate with the development lead and frontend engineers to fulfill your part.
30
+
31
+ code_reviewer:
32
+ role: >
33
+ Code Reviewer
34
+ goal: >
35
+ Review the code provided by the backend engineer and provide feedback considering the following parameters:
36
+ 1. Adherence to the design provided by the development lead
37
+ 2. Code Efficiency
38
+ 3. Whether the code would achieve the objective stated in the requirements.
39
+
40
+ Do not provide unnecessaary commentary. stay on point.
41
+
42
+ if there were any review comments during the previous iteration, ensure you review the code again to ensure your earlier comments have been incorporated.
43
+
44
+ here is the business requirement:
45
+
46
+ {requirement}
47
+ backstory: >
48
+ You are a seasoned developer who has a knack for details. You are an expert in reviewing the code and providing detailed feedback in a constructive manner.
49
+ You can articulate and organize your feedback well.
50
+
51
+ test_engineer:
52
+ role: >
53
+ Senior Test Engineer
54
+ goal: >
55
+ Develop unit tests for the code written by the backend engineer. Just output the code without any other formatting or commentary. The code should be executable as is.
56
+ the requirement is as follows:
57
+ {requirement}
58
+ backstory: >
59
+ You're a seasoned python developer who can write great unit tests for a given requirement.
60
+ You are able to work with the developmet lead and the backend engineer to create tests.
61
+
62
+ frontend_engineer:
63
+ role: >
64
+ Frontend Developer
65
+ goal: >
66
+ Implement the frontend/UI components as described in the design using Gradio. Work only on the interface and not the backend. ONLY provide executable python code as output. no backticks, headers, nothing.
67
+ Ensure you add adequate comments and docstrings for clarity. Do not add unit tests. handle exceptions well. Do good logging.
68
+ the requirement is as follows:
69
+ {requirement}
70
+ backstory: >
71
+ You are an expert in frontend development and specialize in Gradio. You collaborate with the development lead and backend engineer to deliver a seamless user experience.
src/engineering_team_using_flow/crews/engineering_crew/config/tasks.yaml CHANGED
@@ -1,106 +1,106 @@
1
- design_task:
2
- description: >
3
- Take the high level requirements described here and prepare a detailed design for the engineer;
4
- everything should be in 1 python module, but outline the classes and methods in the module.
5
- Here are the requirements: {requirement}
6
- IMPORTANT: Only output the design in markdown format, laying out in detail the classes and functions in the module, describing the functionality. Do not use backquotes and other unnecessary markers.
7
- expected_output: >
8
- A detailed design in markdown format for the engineer, identifying the classes and functions in the module.
9
- agent: development_lead
10
- output_file: output/{module_name}/{id}/design.md
11
-
12
- backend_coding_task:
13
- description: >
14
- Based on the backend design provided by the design task, write crisp code in python for a given requirement. make sure to address only the backend requirements using Gradio.
15
- No clutter and unnecessary commentary please. just the python that we can save as a py file and execute directly should be good enough.
16
- if there are review comments provided by the reviewer, please address those as well. here are the comments:
17
- \n\n---------------------------------------\n\n
18
- {review_comments}
19
-
20
- \n\n---------------------------------------\n\n
21
- Here is the requirement: \n
22
- {requirement}
23
- expected_output: >
24
- A python file containing the backend code for the given requirement.
25
- agent: backend_engineer
26
- output_file: output/{module_name}/{id}/backend.py
27
- context:
28
- - design_task
29
-
30
- frontend_coding_task:
31
- description: >
32
- Create nice and simple UI for the given requirement usin Gradio. Make sure to import the module written by the backend engineer in your interface for backend calls. Do not copy the same code into your code. Refer to it.
33
- The backend module name is "backend"
34
- if there are review comments provided by the reviewer, please address those as well. here are the comments:
35
- \n\n---------------------------------------\n\n
36
- {review_comments}
37
-
38
- \n\n---------------------------------------\n\n
39
- Here is the requirement: \n
40
- The requirement is this : {requirement}
41
- expected_output: >
42
- A python file containing the UI code for the given requirement.
43
- agent: frontend_engineer
44
- output_file: output/{module_name}/{id}/app.py
45
- context:
46
- - backend_coding_task
47
- - design_task
48
-
49
- code_review_task:
50
- description: >
51
- Review the python code provided by the backend engineer and ensure it is done according to the design provided by the development lead.
52
- DO NOT pass if atleast one MAJOR issue is open. Do not review test coverage as that will be handled by the tester.
53
- At the end, provide a summary mentioning whether the code passes the review or not (a clear yes or no should do.)
54
- here is the latest code submitted by the developer:
55
- \n---------------------------------------\n
56
- {backend_code}
57
- \n---------------------------------------\n
58
- The requirement is this : {requirement}
59
- expected_output: >
60
- A code review feedback object of type format CodeReviewFeedback. Also create a json file.
61
- agent: code_reviewer
62
- output_file: output/{module_name}/{id}/backend_code_review_{iteration}.json
63
- context:
64
- - design_task
65
- - backend_coding_task
66
-
67
- frontend_code_review_task:
68
- description: >
69
- Review the python code provided by the frontend engineer and ensure it is done according to the design provided by the development lead.
70
- Just output pure Markdown only. no ```markdown
71
- be lenient in your reviews. Do not review test coverage as that will be handled by the tester.
72
- At the end, provide a summary mentioning whether the code passes the review or not (a clear yes or no should do.)
73
- here is the latest code submitted by the developer:
74
- \n---------------------------------------\n
75
- {frontend_code}
76
- \n---------------------------------------\n
77
- The requirement is this : {requirement}
78
- expected_output: >
79
- A code review feedback object of type format CodeReviewFeedback.
80
- agent: code_reviewer
81
- output_file: output/{module_name}/{id}/frontend_code_review_{iteration}.json
82
- context:
83
- - design_task
84
- - frontend_coding_task
85
-
86
- test_preparation_task:
87
- description: >
88
- Write comprehensive unit test cases for the oode written by the backend & the frontend engineers for the given requirement. Ensure all edge scenarios are covered comprehensively.
89
- Do not return any backquotes or unnecessary markdown formatting. Just pure python code should suffice. Make sure the code is well documented and logged.
90
- backend module name is: backend
91
- frontend module name is: app
92
- here is the backend code
93
- \n---------------------------------------
94
- {backend_code}
95
- \n---------------------------------------
96
- here is the frontend code
97
- \n---------------------------------------
98
- {frontend_code}
99
- \n---------------------------------------
100
- The requirement is this : {requirement}
101
- expected_output: >
102
- A python file containing the code with unit test cases for the given requirement.
103
- agent: test_engineer
104
- output_file: output/{module_name}/{id}/test.py
105
- context:
106
- - code_review_task
 
1
+ design_task:
2
+ description: >
3
+ Take the high level requirements described here and prepare a detailed design for the engineer;
4
+ everything should be in 1 python module, but outline the classes and methods in the module.
5
+ Here are the requirements: {requirement}
6
+ IMPORTANT: Only output the design in markdown format, laying out in detail the classes and functions in the module, describing the functionality. Do not use backquotes and other unnecessary markers.
7
+ expected_output: >
8
+ A detailed design in markdown format for the engineer, identifying the classes and functions in the module.
9
+ agent: development_lead
10
+ output_file: output/{module_name}/{id}/design.md
11
+
12
+ backend_coding_task:
13
+ description: >
14
+ Based on the backend design provided by the design task, write crisp code in python for a given requirement. make sure to address only the backend requirements using Gradio.
15
+ No clutter and unnecessary commentary please. just the python that we can save as a py file and execute directly should be good enough.
16
+ if there are review comments provided by the reviewer, please address those as well. here are the comments:
17
+ \n\n---------------------------------------\n\n
18
+ {review_comments}
19
+
20
+ \n\n---------------------------------------\n\n
21
+ Here is the requirement: \n
22
+ {requirement}
23
+ expected_output: >
24
+ A python file containing the backend code for the given requirement.
25
+ agent: backend_engineer
26
+ output_file: output/{module_name}/{id}/backend.py
27
+ context:
28
+ - design_task
29
+
30
+ frontend_coding_task:
31
+ description: >
32
+ Create nice and simple UI for the given requirement usin Gradio. Make sure to import the module written by the backend engineer in your interface for backend calls. Do not copy the same code into your code. Refer to it.
33
+ The backend module name is "backend"
34
+ if there are review comments provided by the reviewer, please address those as well. here are the comments:
35
+ \n\n---------------------------------------\n\n
36
+ {review_comments}
37
+
38
+ \n\n---------------------------------------\n\n
39
+ Here is the requirement: \n
40
+ The requirement is this : {requirement}
41
+ expected_output: >
42
+ A python file containing the UI code for the given requirement.
43
+ agent: frontend_engineer
44
+ output_file: output/{module_name}/{id}/app.py
45
+ context:
46
+ - backend_coding_task
47
+ - design_task
48
+
49
+ code_review_task:
50
+ description: >
51
+ Review the python code provided by the backend engineer and ensure it is done according to the design provided by the development lead.
52
+ DO NOT pass if atleast one MAJOR issue is open. Do not review test coverage as that will be handled by the tester.
53
+ At the end, provide a summary mentioning whether the code passes the review or not (a clear yes or no should do.)
54
+ here is the latest code submitted by the developer:
55
+ \n---------------------------------------\n
56
+ {backend_code}
57
+ \n---------------------------------------\n
58
+ The requirement is this : {requirement}
59
+ expected_output: >
60
+ A code review feedback object of type format CodeReviewFeedback. Also create a json file.
61
+ agent: code_reviewer
62
+ output_file: output/{module_name}/{id}/backend_code_review_{iteration}.json
63
+ context:
64
+ - design_task
65
+ - backend_coding_task
66
+
67
+ frontend_code_review_task:
68
+ description: >
69
+ Review the python code provided by the frontend engineer and ensure it is done according to the design provided by the development lead.
70
+ Just output pure Markdown only. no ```markdown
71
+ be lenient in your reviews. Do not review test coverage as that will be handled by the tester.
72
+ At the end, provide a summary mentioning whether the code passes the review or not (a clear yes or no should do.)
73
+ here is the latest code submitted by the developer:
74
+ \n---------------------------------------\n
75
+ {frontend_code}
76
+ \n---------------------------------------\n
77
+ The requirement is this : {requirement}
78
+ expected_output: >
79
+ A code review feedback object of type format CodeReviewFeedback.
80
+ agent: code_reviewer
81
+ output_file: output/{module_name}/{id}/frontend_code_review_{iteration}.json
82
+ context:
83
+ - design_task
84
+ - frontend_coding_task
85
+
86
+ test_preparation_task:
87
+ description: >
88
+ Write comprehensive unit test cases for the oode written by the backend & the frontend engineers for the given requirement. Ensure all edge scenarios are covered comprehensively.
89
+ Do not return any backquotes or unnecessary markdown formatting. Just pure python code should suffice. Make sure the code is well documented and logged.
90
+ backend module name is: backend
91
+ frontend module name is: app
92
+ here is the backend code
93
+ \n---------------------------------------
94
+ {backend_code}
95
+ \n---------------------------------------
96
+ here is the frontend code
97
+ \n---------------------------------------
98
+ {frontend_code}
99
+ \n---------------------------------------
100
+ The requirement is this : {requirement}
101
+ expected_output: >
102
+ A python file containing the code with unit test cases for the given requirement.
103
+ agent: test_engineer
104
+ output_file: output/{module_name}/{id}/test.py
105
+ context:
106
+ - code_review_task
src/engineering_team_using_flow/crews/engineering_crew/engineering_crew.py CHANGED
@@ -1,79 +1,79 @@
1
- from crewai import Agent, Crew, Process, Task
2
- from crewai.project import CrewBase, agent, crew, task
3
- from crewai.agents.agent_builder.base_agent import BaseAgent
4
- from typing import List
5
- from litellm import Field
6
- from pydantic import BaseModel
7
- import datetime
8
-
9
- class CodeReviewFeedback(BaseModel):
10
- code_being_reviewed: str = Field(description="the snippet of code being reviewed")
11
- review_comments_markdown: str = Field(description="Review comments in markdown format")
12
- review_timestamp: datetime.datetime = Field(description="Timestamp when review was performed")
13
- passed_review: bool = Field(description="Does the code pass your review or not?")
14
-
15
-
16
- @CrewBase
17
- class EngineeringCrew():
18
- """EngineeringCrew crew"""
19
-
20
- agents: List[BaseAgent]
21
- tasks: List[Task]
22
-
23
- agents_config = "./config/agents.yaml"
24
- tasks_config = "./config/tasks.yaml"
25
-
26
- @agent
27
- def development_lead(self) -> Agent:
28
- return Agent(config=self.agents_config["development_lead"], verbose=True) # type: ignore[index]
29
-
30
- @agent
31
- def backend_engineer(self) -> Agent:
32
- return Agent(config=self.agents_config["backend_engineer"], verbose=True) # type: ignore[index]
33
-
34
- @agent
35
- def code_reviewer(self) -> Agent:
36
- return Agent(config=self.agents_config["code_reviewer"], verbose=True, output_pydantic= CodeReviewFeedback) # type: ignore[index]
37
-
38
- @agent
39
- def frontend_engineer(self) -> Agent:
40
- return Agent(config=self.agents_config["frontend_engineer"], verbose=True) # type: ignore[index]
41
-
42
- @agent
43
- def test_engineer(self) -> Agent:
44
- return Agent(config=self.agents_config["test_engineer"], verbose=True) # type: ignore[index]
45
-
46
- @task
47
- def design_task(self) -> Task:
48
- return Task(config=self.tasks_config["design_task"], verbose=True) # type: ignore[index]
49
-
50
- @task
51
- def backend_coding_task(self) -> Task:
52
- return Task(config=self.tasks_config["backend_coding_task"], verbose=True) # type: ignore[index]
53
-
54
- @task
55
- def code_review_task(self) -> Task:
56
- return Task(config=self.tasks_config["code_review_task"], verbose=True, output_pydantic=CodeReviewFeedback) # type: ignore[index]
57
-
58
- @task
59
- def frontend_code_review_task(self) -> Task:
60
- return Task(config=self.tasks_config["frontend_code_review_task"], verbose=True, output_pydantic=CodeReviewFeedback) # type: ignore[index]
61
-
62
- @task
63
- def test_preparation_task(self) -> Task:
64
- return Task(config=self.tasks_config["test_preparation_task"], verbose=True) # type: ignore[index]
65
-
66
- @task
67
- def frontend_coding_task(self) -> Task:
68
- return Task(config=self.tasks_config["frontend_coding_task"], verbose=True) # type: ignore[index]
69
-
70
-
71
- @crew
72
- def crew(self) -> Crew:
73
- return Crew(
74
- agents=self.agents, # Automatically created by the @agent decorator
75
- tasks=self.tasks, # Automatically created by the @agent decorator,
76
- process=Process.sequential,
77
- verbose=True,
78
- )
79
-
 
1
+ from crewai import Agent, Crew, Process, Task
2
+ from crewai.project import CrewBase, agent, crew, task
3
+ from crewai.agents.agent_builder.base_agent import BaseAgent
4
+ from typing import List
5
+ from litellm import Field
6
+ from pydantic import BaseModel
7
+ import datetime
8
+
9
+ class CodeReviewFeedback(BaseModel):
10
+ code_being_reviewed: str = Field(description="the snippet of code being reviewed")
11
+ review_comments_markdown: str = Field(description="Review comments in markdown format")
12
+ review_timestamp: datetime.datetime = Field(description="Timestamp when review was performed")
13
+ passed_review: bool = Field(description="Does the code pass your review or not?")
14
+
15
+
16
+ @CrewBase
17
+ class EngineeringCrew():
18
+ """EngineeringCrew crew"""
19
+
20
+ agents: List[BaseAgent]
21
+ tasks: List[Task]
22
+
23
+ agents_config = "./config/agents.yaml"
24
+ tasks_config = "./config/tasks.yaml"
25
+
26
+ @agent
27
+ def development_lead(self) -> Agent:
28
+ return Agent(config=self.agents_config["development_lead"], verbose=True) # type: ignore[index]
29
+
30
+ @agent
31
+ def backend_engineer(self) -> Agent:
32
+ return Agent(config=self.agents_config["backend_engineer"], verbose=True) # type: ignore[index]
33
+
34
+ @agent
35
+ def code_reviewer(self) -> Agent:
36
+ return Agent(config=self.agents_config["code_reviewer"], verbose=True, output_pydantic= CodeReviewFeedback) # type: ignore[index]
37
+
38
+ @agent
39
+ def frontend_engineer(self) -> Agent:
40
+ return Agent(config=self.agents_config["frontend_engineer"], verbose=True) # type: ignore[index]
41
+
42
+ @agent
43
+ def test_engineer(self) -> Agent:
44
+ return Agent(config=self.agents_config["test_engineer"], verbose=True) # type: ignore[index]
45
+
46
+ @task
47
+ def design_task(self) -> Task:
48
+ return Task(config=self.tasks_config["design_task"], verbose=True) # type: ignore[index]
49
+
50
+ @task
51
+ def backend_coding_task(self) -> Task:
52
+ return Task(config=self.tasks_config["backend_coding_task"], verbose=True) # type: ignore[index]
53
+
54
+ @task
55
+ def code_review_task(self) -> Task:
56
+ return Task(config=self.tasks_config["code_review_task"], verbose=True, output_pydantic=CodeReviewFeedback) # type: ignore[index]
57
+
58
+ @task
59
+ def frontend_code_review_task(self) -> Task:
60
+ return Task(config=self.tasks_config["frontend_code_review_task"], verbose=True, output_pydantic=CodeReviewFeedback) # type: ignore[index]
61
+
62
+ @task
63
+ def test_preparation_task(self) -> Task:
64
+ return Task(config=self.tasks_config["test_preparation_task"], verbose=True) # type: ignore[index]
65
+
66
+ @task
67
+ def frontend_coding_task(self) -> Task:
68
+ return Task(config=self.tasks_config["frontend_coding_task"], verbose=True) # type: ignore[index]
69
+
70
+
71
+ @crew
72
+ def crew(self) -> Crew:
73
+ return Crew(
74
+ agents=self.agents, # Automatically created by the @agent decorator
75
+ tasks=self.tasks, # Automatically created by the @agent decorator,
76
+ process=Process.sequential,
77
+ verbose=True,
78
+ )
79
+
src/engineering_team_using_flow/main.py CHANGED
@@ -1,349 +1,349 @@
1
- #!/usr/bin/env python
2
- import datetime
3
- from random import randint
4
- from datetime import time
5
- import random
6
- from typing import Optional
7
- from crewai import Crew
8
- from crewai.flow.flow import router, or_
9
- from pydantic import BaseModel
10
- from crewai.flow import Flow, listen, start
11
- from engineering_team_using_flow.crews.engineering_crew.engineering_crew import (
12
- CodeReviewFeedback,
13
- EngineeringCrew,
14
- )
15
- from .shared_queue import TaskInfo, add_to_queue
16
-
17
-
18
- class EngineeringState(BaseModel):
19
- module_name: str = ""
20
- business_requirement: str = ""
21
- technical_design: Optional[str] = ""
22
- backend_code: Optional[str] = ""
23
- frontend_code: Optional[str] = ""
24
- unit_test_code: Optional[str] = ""
25
- backend_code_review_feedbacks: list[CodeReviewFeedback] = []
26
- frontend_code_review_feedbacks: list[CodeReviewFeedback] = []
27
-
28
-
29
- MAX_REVIEW_ITERATIONS = 3
30
- BUSINESS_REQUIREMENTS: list[EngineeringState] = [
31
- EngineeringState(
32
- module_name="mod_series_eval",
33
- business_requirement="Create a web application that allows the user to evaluate the first N terms of a given series and \
34
- multiply the total by X (default to 4). for instance, the series could be something like :\
35
- 1 + 1/3 - 1/5 + 1/7 - 1/9 ... ",
36
- )
37
- ]
38
-
39
-
40
- class EngineeringFlow(Flow[EngineeringState]):
41
-
42
- def __init__(self, module_name:str, business_requirement:str):
43
- super().__init__()
44
- self.module_name = module_name
45
- self.business_requirement = business_requirement
46
-
47
- @start()
48
- def generate_business_requirement(self):
49
- print("Generating business requirement")
50
- self.state.business_requirement = self.business_requirement
51
- self.state.module_name = self.module_name
52
-
53
- add_to_queue(
54
- TaskInfo(
55
- name="Gathering Business Requirements",
56
- type="markdown",
57
- output=f"Gathering Business Requirements for {self.state.module_name}...",
58
- )
59
- )
60
-
61
- # chosen_requirement = random.choice(BUSINESS_REQUIREMENTS)
62
- # self.state.business_requirement = chosen_requirement.business_requirement
63
- # self.state.module_name = chosen_requirement.module_name
64
- add_to_queue(
65
- TaskInfo(
66
- name="Gather Business Requirements",
67
- type="markdown",
68
- output=f"#### Business Requirements for {self.state.module_name}: \n{self.state.business_requirement}",
69
- )
70
- )
71
-
72
- @listen(generate_business_requirement)
73
- def design_product(self):
74
- print("Designing product for requirement: ", self.state)
75
- add_to_queue(
76
- TaskInfo(
77
- name="Generating Design",
78
- type="markdown",
79
- output=f"Designing the product ...",
80
- )
81
- )
82
-
83
- engineeringCrew = EngineeringCrew()
84
-
85
- mycrew = Crew(
86
- agents=[engineeringCrew.development_lead()],
87
- tasks=[engineeringCrew.design_task()],
88
- )
89
- result = mycrew.kickoff(
90
- inputs={
91
- "id": self.state.id,
92
- "requirement": self.state.business_requirement,
93
- "module_name": self.state.module_name,
94
- "review_comments": "",
95
- }
96
- )
97
-
98
- print("Product Design Created", result.raw)
99
- self.state.technical_design = result.raw
100
- add_to_queue(
101
- TaskInfo(
102
- name="Generate Design",
103
- type="markdown",
104
- output=f"{self.state.technical_design}",
105
- )
106
- )
107
-
108
- @listen(or_("design_product", "REWRITE_BACKEND_CODE"))
109
- def develop_backend(self):
110
- print("Developing backend : ", self.state)
111
- add_to_queue(
112
- TaskInfo(
113
- name="Generating Backend Code",
114
- type="markdown",
115
- output=f"Generating Backend Code ...",
116
- )
117
- )
118
- engineeringCrew = EngineeringCrew()
119
-
120
- mycrew = Crew(
121
- agents=[engineeringCrew.backend_engineer()],
122
- tasks=[engineeringCrew.backend_coding_task()],
123
- )
124
- result = mycrew.kickoff(
125
- inputs={
126
- "id": self.state.id,
127
- "requirement": self.state.business_requirement,
128
- "module_name": self.state.module_name,
129
- "review_comments": (
130
- self.state.backend_code_review_feedbacks[
131
- -1
132
- ].review_comments_markdown
133
- if self.state.backend_code_review_feedbacks
134
- else ""
135
- ),
136
- }
137
- )
138
-
139
- print("Backend Code Created", result.raw)
140
- self.state.backend_code = result.raw
141
- add_to_queue(
142
- TaskInfo(
143
- name="Generate Backend Code",
144
- type="markdown",
145
- output=f"#### Backend Code for {self.state.module_name}: \n ```{self.state.backend_code}\n```",
146
- )
147
- )
148
- return "BACKEND_CODE_CREATED"
149
-
150
- @router(develop_backend)
151
- def review_backend_code(self):
152
- print("Reviewing backend code : ", self.state)
153
- if len(self.state.backend_code_review_feedbacks) >= MAX_REVIEW_ITERATIONS:
154
- add_to_queue(
155
- TaskInfo(
156
- name="Maximum Iterations Exceeded!",
157
- type="markdown",
158
- output=f"#### Maximum Iterations Exceeded!",
159
- )
160
- )
161
- return "MAX_REVIEW_ITERATIONS_EXCEEDED"
162
- engineeringCrew = EngineeringCrew()
163
- add_to_queue(
164
- TaskInfo(
165
- name="Reviewing Backend Code",
166
- type="markdown",
167
- output=f"Reviewing Backend Code ...",
168
- )
169
- )
170
-
171
- mycrew = Crew(
172
- agents=[engineeringCrew.code_reviewer()],
173
- tasks=[engineeringCrew.code_review_task()],
174
- )
175
- if self.state.backend_code_review_feedbacks is None:
176
- self.state.backend_code_review_feedbacks = []
177
-
178
- result = mycrew.kickoff(
179
- inputs={
180
- "id": self.state.id,
181
- "requirement": self.state.business_requirement,
182
- "module_name": self.state.module_name,
183
- "backend_code": self.state.backend_code,
184
- "iteration": len(self.state.backend_code_review_feedbacks),
185
- }
186
- )
187
-
188
- codeReviewFeedback: CodeReviewFeedback = result.tasks_output[0].pydantic # type: ignore[index]
189
- print(codeReviewFeedback)
190
- add_to_queue(
191
- TaskInfo(
192
- name="Generate Backend Code Review",
193
- type="markdown",
194
- output=f"#### Backend Code Review Iteration {len(self.state.backend_code_review_feedbacks)} for {self.state.module_name}: \n{codeReviewFeedback.review_comments_markdown}",
195
- )
196
- )
197
- self.state.backend_code_review_feedbacks.append(codeReviewFeedback)
198
-
199
- if codeReviewFeedback.passed_review:
200
- return "BACKEND_CODE_REVIEWED"
201
- else:
202
- return "REWRITE_BACKEND_CODE"
203
-
204
- @listen(or_("BACKEND_CODE_REVIEWED", "REWRITE_FRONTEND_CODE"))
205
- def develop_frontend(self):
206
- print("Developing frontend : ", self.state)
207
- add_to_queue(
208
- TaskInfo(
209
- name="Developing Frontend Code",
210
- type="markdown",
211
- output=f"Developing Frontend Code ...",
212
- )
213
- )
214
- engineeringCrew = EngineeringCrew()
215
-
216
- mycrew = Crew(
217
- agents=[engineeringCrew.frontend_engineer()],
218
- tasks=[engineeringCrew.frontend_coding_task()],
219
- )
220
- result = mycrew.kickoff(
221
- inputs={
222
- "id": self.state.id,
223
- "requirement": self.state.business_requirement,
224
- "module_name": self.state.module_name,
225
- "review_comments": (
226
- self.state.frontend_code_review_feedbacks[
227
- -1
228
- ].review_comments_markdown
229
- if self.state.frontend_code_review_feedbacks
230
- else ""
231
- ),
232
- }
233
- )
234
-
235
- print("Frontend Code Created", result.raw)
236
- self.state.frontend_code = result.raw
237
- add_to_queue(
238
- TaskInfo(
239
- name="Generate Frontend Code",
240
- type="markdown",
241
- output=f"#### Frontend Code for {self.state.module_name}:\n ```{self.state.frontend_code}```",
242
- )
243
- )
244
- return "FRONTEND_CODE_CREATED"
245
-
246
- @router(develop_frontend)
247
- def review_frontend_code(self):
248
- print("Reviewing frontkend code : ", self.state)
249
- if len(self.state.frontend_code_review_feedbacks) >= MAX_REVIEW_ITERATIONS:
250
- add_to_queue(
251
- TaskInfo(
252
- name="Maximum Iterations Exceeded!",
253
- type="markdown",
254
- output=f"#### Maximum Iterations Exceeded!",
255
- )
256
- )
257
- return "MAX_REVIEW_ITERATIONS_EXCEEDED"
258
- engineeringCrew = EngineeringCrew()
259
- add_to_queue(
260
- TaskInfo(
261
- name="Reviewing Frontend Code",
262
- type="markdown",
263
- output=f"Reviewing Frontend Code ...",
264
- )
265
- )
266
-
267
- mycrew = Crew(
268
- agents=[engineeringCrew.code_reviewer()],
269
- tasks=[engineeringCrew.frontend_code_review_task()],
270
- )
271
- if self.state.frontend_code_review_feedbacks is None:
272
- self.state.frontend_code_review_feedbacks = []
273
-
274
- result = mycrew.kickoff(
275
- inputs={
276
- "id": self.state.id,
277
- "requirement": self.state.business_requirement,
278
- "module_name": self.state.module_name,
279
- "frontend_code": self.state.frontend_code,
280
- "iteration": len(self.state.frontend_code_review_feedbacks),
281
- }
282
- )
283
-
284
- codeReviewFeedback: CodeReviewFeedback = result.tasks_output[0].pydantic # type: ignore[index]
285
- print(codeReviewFeedback)
286
- add_to_queue(
287
- TaskInfo(
288
- name="Generate Frontend Code Review",
289
- type="markdown",
290
- output=f"#### Frontend Code Review Iteration {len(self.state.frontend_code_review_feedbacks)} for {self.state.module_name}: \n{codeReviewFeedback.review_comments_markdown}",
291
- )
292
- )
293
- self.state.frontend_code_review_feedbacks.append(codeReviewFeedback)
294
-
295
- if codeReviewFeedback.passed_review:
296
- return "FRONTEND_CODE_REVIEWED"
297
- else:
298
- return "REWRITE_FRONTEND_CODE"
299
-
300
- @listen("FRONTEND_CODE_REVIEWED")
301
- def write_test_cases(self):
302
- print("Writing test cases : ", self.state)
303
- add_to_queue(
304
- TaskInfo(
305
- name="Writing Test Cases",
306
- type="markdown",
307
- output=f"Writing Test Cases ...",
308
- )
309
- )
310
- engineeringCrew = EngineeringCrew()
311
-
312
- mycrew = Crew(
313
- agents=[engineeringCrew.test_engineer()],
314
- tasks=[engineeringCrew.test_preparation_task()],
315
- )
316
- result = mycrew.kickoff(
317
- inputs={
318
- "id": self.state.id,
319
- "requirement": self.state.business_requirement,
320
- "module_name": self.state.module_name,
321
- "backend_code": self.state.backend_code,
322
- "frontend_code": self.state.frontend_code,
323
- }
324
- )
325
-
326
- self.state.unit_test_code = result.raw
327
- add_to_queue(
328
- TaskInfo(
329
- name="Generate Test Cases",
330
- type="markdown",
331
- output=f"#### Test Cases for {self.state.module_name}: \n```{self.state.unit_test_code}```",
332
- )
333
- )
334
-
335
- return "TEST_CASES_PREPARED"
336
-
337
-
338
- def kickoff():
339
- engineering_flow = EngineeringFlow()
340
- engineering_flow.kickoff()
341
-
342
-
343
- def plot():
344
- engineering_flow = EngineeringFlow()
345
- engineering_flow.plot()
346
-
347
-
348
- if __name__ == "__main__":
349
- kickoff()
 
1
+ #!/usr/bin/env python
2
+ import datetime
3
+ from random import randint
4
+ from datetime import time
5
+ import random
6
+ from typing import Optional
7
+ from crewai import Crew
8
+ from crewai.flow.flow import router, or_
9
+ from pydantic import BaseModel
10
+ from crewai.flow import Flow, listen, start
11
+ from engineering_team_using_flow.crews.engineering_crew.engineering_crew import (
12
+ CodeReviewFeedback,
13
+ EngineeringCrew,
14
+ )
15
+ from .shared_queue import TaskInfo, add_to_queue
16
+
17
+
18
+ class EngineeringState(BaseModel):
19
+ module_name: str = ""
20
+ business_requirement: str = ""
21
+ technical_design: Optional[str] = ""
22
+ backend_code: Optional[str] = ""
23
+ frontend_code: Optional[str] = ""
24
+ unit_test_code: Optional[str] = ""
25
+ backend_code_review_feedbacks: list[CodeReviewFeedback] = []
26
+ frontend_code_review_feedbacks: list[CodeReviewFeedback] = []
27
+
28
+
29
+ MAX_REVIEW_ITERATIONS = 3
30
+ BUSINESS_REQUIREMENTS: list[EngineeringState] = [
31
+ EngineeringState(
32
+ module_name="mod_series_eval",
33
+ business_requirement="Create a web application that allows the user to evaluate the first N terms of a given series and \
34
+ multiply the total by X (default to 4). for instance, the series could be something like :\
35
+ 1 + 1/3 - 1/5 + 1/7 - 1/9 ... ",
36
+ )
37
+ ]
38
+
39
+
40
+ class EngineeringFlow(Flow[EngineeringState]):
41
+
42
+ def __init__(self, module_name:str, business_requirement:str):
43
+ super().__init__()
44
+ self.module_name = module_name
45
+ self.business_requirement = business_requirement
46
+
47
+ @start()
48
+ def generate_business_requirement(self):
49
+ print("Generating business requirement")
50
+ self.state.business_requirement = self.business_requirement
51
+ self.state.module_name = self.module_name
52
+
53
+ add_to_queue(
54
+ TaskInfo(
55
+ name="Gathering Business Requirements",
56
+ type="markdown",
57
+ output=f"Gathering Business Requirements for {self.state.module_name}...",
58
+ )
59
+ )
60
+
61
+ # chosen_requirement = random.choice(BUSINESS_REQUIREMENTS)
62
+ # self.state.business_requirement = chosen_requirement.business_requirement
63
+ # self.state.module_name = chosen_requirement.module_name
64
+ add_to_queue(
65
+ TaskInfo(
66
+ name="Gather Business Requirements",
67
+ type="markdown",
68
+ output=f"#### Business Requirements for {self.state.module_name}: \n{self.state.business_requirement}",
69
+ )
70
+ )
71
+
72
+ @listen(generate_business_requirement)
73
+ def design_product(self):
74
+ print("Designing product for requirement: ", self.state)
75
+ add_to_queue(
76
+ TaskInfo(
77
+ name="Generating Design",
78
+ type="markdown",
79
+ output=f"Designing the product ...",
80
+ )
81
+ )
82
+
83
+ engineeringCrew = EngineeringCrew()
84
+
85
+ mycrew = Crew(
86
+ agents=[engineeringCrew.development_lead()],
87
+ tasks=[engineeringCrew.design_task()],
88
+ )
89
+ result = mycrew.kickoff(
90
+ inputs={
91
+ "id": self.state.id,
92
+ "requirement": self.state.business_requirement,
93
+ "module_name": self.state.module_name,
94
+ "review_comments": "",
95
+ }
96
+ )
97
+
98
+ print("Product Design Created", result.raw)
99
+ self.state.technical_design = result.raw
100
+ add_to_queue(
101
+ TaskInfo(
102
+ name="Generate Design",
103
+ type="markdown",
104
+ output=f"{self.state.technical_design}",
105
+ )
106
+ )
107
+
108
+ @listen(or_("design_product", "REWRITE_BACKEND_CODE"))
109
+ def develop_backend(self):
110
+ print("Developing backend : ", self.state)
111
+ add_to_queue(
112
+ TaskInfo(
113
+ name="Generating Backend Code",
114
+ type="markdown",
115
+ output=f"Generating Backend Code ...",
116
+ )
117
+ )
118
+ engineeringCrew = EngineeringCrew()
119
+
120
+ mycrew = Crew(
121
+ agents=[engineeringCrew.backend_engineer()],
122
+ tasks=[engineeringCrew.backend_coding_task()],
123
+ )
124
+ result = mycrew.kickoff(
125
+ inputs={
126
+ "id": self.state.id,
127
+ "requirement": self.state.business_requirement,
128
+ "module_name": self.state.module_name,
129
+ "review_comments": (
130
+ self.state.backend_code_review_feedbacks[
131
+ -1
132
+ ].review_comments_markdown
133
+ if self.state.backend_code_review_feedbacks
134
+ else ""
135
+ ),
136
+ }
137
+ )
138
+
139
+ print("Backend Code Created", result.raw)
140
+ self.state.backend_code = result.raw
141
+ add_to_queue(
142
+ TaskInfo(
143
+ name="Generate Backend Code",
144
+ type="markdown",
145
+ output=f"#### Backend Code for {self.state.module_name}: \n ```{self.state.backend_code}\n```",
146
+ )
147
+ )
148
+ return "BACKEND_CODE_CREATED"
149
+
150
+ @router(develop_backend)
151
+ def review_backend_code(self):
152
+ print("Reviewing backend code : ", self.state)
153
+ if len(self.state.backend_code_review_feedbacks) >= MAX_REVIEW_ITERATIONS:
154
+ add_to_queue(
155
+ TaskInfo(
156
+ name="Maximum Iterations Exceeded!",
157
+ type="markdown",
158
+ output=f"#### Maximum Iterations Exceeded!",
159
+ )
160
+ )
161
+ return "MAX_REVIEW_ITERATIONS_EXCEEDED"
162
+ engineeringCrew = EngineeringCrew()
163
+ add_to_queue(
164
+ TaskInfo(
165
+ name="Reviewing Backend Code",
166
+ type="markdown",
167
+ output=f"Reviewing Backend Code ...",
168
+ )
169
+ )
170
+
171
+ mycrew = Crew(
172
+ agents=[engineeringCrew.code_reviewer()],
173
+ tasks=[engineeringCrew.code_review_task()],
174
+ )
175
+ if self.state.backend_code_review_feedbacks is None:
176
+ self.state.backend_code_review_feedbacks = []
177
+
178
+ result = mycrew.kickoff(
179
+ inputs={
180
+ "id": self.state.id,
181
+ "requirement": self.state.business_requirement,
182
+ "module_name": self.state.module_name,
183
+ "backend_code": self.state.backend_code,
184
+ "iteration": len(self.state.backend_code_review_feedbacks),
185
+ }
186
+ )
187
+
188
+ codeReviewFeedback: CodeReviewFeedback = result.tasks_output[0].pydantic # type: ignore[index]
189
+ print(codeReviewFeedback)
190
+ add_to_queue(
191
+ TaskInfo(
192
+ name="Generate Backend Code Review",
193
+ type="markdown",
194
+ output=f"#### Backend Code Review Iteration {len(self.state.backend_code_review_feedbacks)} for {self.state.module_name}: \n{codeReviewFeedback.review_comments_markdown}",
195
+ )
196
+ )
197
+ self.state.backend_code_review_feedbacks.append(codeReviewFeedback)
198
+
199
+ if codeReviewFeedback.passed_review:
200
+ return "BACKEND_CODE_REVIEWED"
201
+ else:
202
+ return "REWRITE_BACKEND_CODE"
203
+
204
+ @listen(or_("BACKEND_CODE_REVIEWED", "REWRITE_FRONTEND_CODE"))
205
+ def develop_frontend(self):
206
+ print("Developing frontend : ", self.state)
207
+ add_to_queue(
208
+ TaskInfo(
209
+ name="Developing Frontend Code",
210
+ type="markdown",
211
+ output=f"Developing Frontend Code ...",
212
+ )
213
+ )
214
+ engineeringCrew = EngineeringCrew()
215
+
216
+ mycrew = Crew(
217
+ agents=[engineeringCrew.frontend_engineer()],
218
+ tasks=[engineeringCrew.frontend_coding_task()],
219
+ )
220
+ result = mycrew.kickoff(
221
+ inputs={
222
+ "id": self.state.id,
223
+ "requirement": self.state.business_requirement,
224
+ "module_name": self.state.module_name,
225
+ "review_comments": (
226
+ self.state.frontend_code_review_feedbacks[
227
+ -1
228
+ ].review_comments_markdown
229
+ if self.state.frontend_code_review_feedbacks
230
+ else ""
231
+ ),
232
+ }
233
+ )
234
+
235
+ print("Frontend Code Created", result.raw)
236
+ self.state.frontend_code = result.raw
237
+ add_to_queue(
238
+ TaskInfo(
239
+ name="Generate Frontend Code",
240
+ type="markdown",
241
+ output=f"#### Frontend Code for {self.state.module_name}:\n ```{self.state.frontend_code}```",
242
+ )
243
+ )
244
+ return "FRONTEND_CODE_CREATED"
245
+
246
+ @router(develop_frontend)
247
+ def review_frontend_code(self):
248
+ print("Reviewing frontkend code : ", self.state)
249
+ if len(self.state.frontend_code_review_feedbacks) >= MAX_REVIEW_ITERATIONS:
250
+ add_to_queue(
251
+ TaskInfo(
252
+ name="Maximum Iterations Exceeded!",
253
+ type="markdown",
254
+ output=f"#### Maximum Iterations Exceeded!",
255
+ )
256
+ )
257
+ return "MAX_REVIEW_ITERATIONS_EXCEEDED"
258
+ engineeringCrew = EngineeringCrew()
259
+ add_to_queue(
260
+ TaskInfo(
261
+ name="Reviewing Frontend Code",
262
+ type="markdown",
263
+ output=f"Reviewing Frontend Code ...",
264
+ )
265
+ )
266
+
267
+ mycrew = Crew(
268
+ agents=[engineeringCrew.code_reviewer()],
269
+ tasks=[engineeringCrew.frontend_code_review_task()],
270
+ )
271
+ if self.state.frontend_code_review_feedbacks is None:
272
+ self.state.frontend_code_review_feedbacks = []
273
+
274
+ result = mycrew.kickoff(
275
+ inputs={
276
+ "id": self.state.id,
277
+ "requirement": self.state.business_requirement,
278
+ "module_name": self.state.module_name,
279
+ "frontend_code": self.state.frontend_code,
280
+ "iteration": len(self.state.frontend_code_review_feedbacks),
281
+ }
282
+ )
283
+
284
+ codeReviewFeedback: CodeReviewFeedback = result.tasks_output[0].pydantic # type: ignore[index]
285
+ print(codeReviewFeedback)
286
+ add_to_queue(
287
+ TaskInfo(
288
+ name="Generate Frontend Code Review",
289
+ type="markdown",
290
+ output=f"#### Frontend Code Review Iteration {len(self.state.frontend_code_review_feedbacks)} for {self.state.module_name}: \n{codeReviewFeedback.review_comments_markdown}",
291
+ )
292
+ )
293
+ self.state.frontend_code_review_feedbacks.append(codeReviewFeedback)
294
+
295
+ if codeReviewFeedback.passed_review:
296
+ return "FRONTEND_CODE_REVIEWED"
297
+ else:
298
+ return "REWRITE_FRONTEND_CODE"
299
+
300
+ @listen("FRONTEND_CODE_REVIEWED")
301
+ def write_test_cases(self):
302
+ print("Writing test cases : ", self.state)
303
+ add_to_queue(
304
+ TaskInfo(
305
+ name="Writing Test Cases",
306
+ type="markdown",
307
+ output=f"Writing Test Cases ...",
308
+ )
309
+ )
310
+ engineeringCrew = EngineeringCrew()
311
+
312
+ mycrew = Crew(
313
+ agents=[engineeringCrew.test_engineer()],
314
+ tasks=[engineeringCrew.test_preparation_task()],
315
+ )
316
+ result = mycrew.kickoff(
317
+ inputs={
318
+ "id": self.state.id,
319
+ "requirement": self.state.business_requirement,
320
+ "module_name": self.state.module_name,
321
+ "backend_code": self.state.backend_code,
322
+ "frontend_code": self.state.frontend_code,
323
+ }
324
+ )
325
+
326
+ self.state.unit_test_code = result.raw
327
+ add_to_queue(
328
+ TaskInfo(
329
+ name="Generate Test Cases",
330
+ type="markdown",
331
+ output=f"#### Test Cases for {self.state.module_name}: \n```{self.state.unit_test_code}```",
332
+ )
333
+ )
334
+
335
+ return "TEST_CASES_PREPARED"
336
+
337
+
338
+ def kickoff():
339
+ engineering_flow = EngineeringFlow()
340
+ engineering_flow.kickoff()
341
+
342
+
343
+ def plot():
344
+ engineering_flow = EngineeringFlow()
345
+ engineering_flow.plot()
346
+
347
+
348
+ if __name__ == "__main__":
349
+ kickoff()
src/engineering_team_using_flow/shared_queue.py CHANGED
@@ -1,16 +1,16 @@
1
- import queue
2
- from typing import Any
3
-
4
- from pydantic import BaseModel, Field
5
-
6
- class TaskInfo(BaseModel):
7
- name: str = Field(description="Name of the task")
8
- type: str = Field(description="Task type. Could be markdown or code")
9
- output: Any = Field(description="Task output. could be any object")
10
-
11
-
12
- # shared task output queue. this is a singleton apparently :-).
13
- shared_task_output_queue: "queue.Queue[TaskInfo]" = queue.Queue()
14
-
15
- def add_to_queue(taskInfo : TaskInfo):
16
- shared_task_output_queue.put(taskInfo)
 
1
+ import queue
2
+ from typing import Any
3
+
4
+ from pydantic import BaseModel, Field
5
+
6
+ class TaskInfo(BaseModel):
7
+ name: str = Field(description="Name of the task")
8
+ type: str = Field(description="Task type. Could be markdown or code")
9
+ output: Any = Field(description="Task output. could be any object")
10
+
11
+
12
+ # shared task output queue. this is a singleton apparently :-).
13
+ shared_task_output_queue: "queue.Queue[TaskInfo]" = queue.Queue()
14
+
15
+ def add_to_queue(taskInfo : TaskInfo):
16
+ shared_task_output_queue.put(taskInfo)
src/engineering_team_using_flow/tools/custom_tool.py CHANGED
@@ -1,22 +1,22 @@
1
- from typing import Type
2
-
3
- from crewai.tools import BaseTool
4
- from pydantic import BaseModel, Field
5
-
6
-
7
- class MyCustomToolInput(BaseModel):
8
- """Input schema for MyCustomTool."""
9
-
10
- argument: str = Field(..., description="Description of the argument.")
11
-
12
-
13
- class MyCustomTool(BaseTool):
14
- name: str = "Name of my tool"
15
- description: str = (
16
- "Clear description for what this tool is useful for, your agent will need this information to use it."
17
- )
18
- args_schema: Type[BaseModel] = MyCustomToolInput
19
-
20
- def _run(self, argument: str) -> str:
21
- # Implementation goes here
22
- return "this is an example of a tool output, ignore it and move along."
 
1
+ from typing import Type
2
+
3
+ from crewai.tools import BaseTool
4
+ from pydantic import BaseModel, Field
5
+
6
+
7
+ class MyCustomToolInput(BaseModel):
8
+ """Input schema for MyCustomTool."""
9
+
10
+ argument: str = Field(..., description="Description of the argument.")
11
+
12
+
13
+ class MyCustomTool(BaseTool):
14
+ name: str = "Name of my tool"
15
+ description: str = (
16
+ "Clear description for what this tool is useful for, your agent will need this information to use it."
17
+ )
18
+ args_schema: Type[BaseModel] = MyCustomToolInput
19
+
20
+ def _run(self, argument: str) -> str:
21
+ # Implementation goes here
22
+ return "this is an example of a tool output, ignore it and move along."