Upload folder using huggingface_hub
Browse files- .github/workflows/update_space.yml +28 -28
- .gitignore +4 -4
- README.md +63 -63
- app.py +99 -94
- src/engineering_team_using_flow/crews/engineering_crew/config/agents.yaml +71 -71
- src/engineering_team_using_flow/crews/engineering_crew/config/tasks.yaml +106 -106
- src/engineering_team_using_flow/crews/engineering_crew/engineering_crew.py +79 -79
- src/engineering_team_using_flow/main.py +349 -349
- src/engineering_team_using_flow/shared_queue.py +16 -16
- src/engineering_team_using_flow/tools/custom_tool.py +22 -22
.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
|
| 2 |
-
import
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
)
|
| 93 |
-
|
| 94 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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."
|