Changed the planning into epics and tasks (added the endpoints specification)

This commit is contained in:
Zvonimir Sabljic
2024-12-16 21:48:08 +01:00
parent a049b8c31f
commit 76eea15381
6 changed files with 44 additions and 23 deletions

View File

@@ -19,6 +19,7 @@ log = get_logger(__name__)
class Epic(BaseModel):
description: str = Field(description=("Description of an epic."))
related_api_endpoints: list[str] = Field(description="API endpoints that will be implemented in this epic.")
class Task(BaseModel):
@@ -181,9 +182,12 @@ class TechLead(BaseAgent):
response: DevelopmentPlan = await llm(convo, parser=JSONParser(DevelopmentPlan))
convo.remove_last_x_messages(1)
formatted_tasks = [f"Epic #{index}: {task.description}" for index, task in enumerate(response.plan, start=1)]
tasks_string = "\n\n".join(formatted_tasks)
convo = convo.assistant(tasks_string)
formatted_epics = [
f"Epic #{index}: {epic.description} ({','.join([f'`{endpoint}`' for endpoint in epic.related_api_endpoints])})"
for index, epic in enumerate(response.plan, start=1)
]
epics_string = "\n\n".join(formatted_epics)
convo = convo.assistant(epics_string)
llm = self.get_llm(TECH_LEAD_EPIC_BREAKDOWN)
if epic.get("source") == "feature" or epic.get("complexity") == "simple":
@@ -211,13 +215,19 @@ class TechLead(BaseAgent):
{
"id": sub_epic_number,
"description": sub_epic.description,
"related_api_endpoints": sub_epic.related_api_endpoints,
}
for sub_epic_number, sub_epic in enumerate(response.plan, start=1)
]
for sub_epic_number, sub_epic in enumerate(response.plan, start=1):
await self.send_message(f"Epic {sub_epic_number}: {sub_epic.description}")
await self.send_message(
f"Epic {sub_epic_number}: {sub_epic.description} ({','.join([f'`{endpoint}`' for endpoint in sub_epic.related_api_endpoints])})"
)
convo = convo.template(
"epic_breakdown", epic_number=sub_epic_number, epic_description=sub_epic.description
"epic_breakdown",
epic_number=sub_epic_number,
epic_description=sub_epic.description,
related_api_endpoints=sub_epic.related_api_endpoints,
).require_schema(EpicPlan)
await self.send_message("Creating tasks for this epic ...")
epic_plan: EpicPlan = await llm(convo, parser=JSONParser(EpicPlan))

View File

@@ -371,8 +371,8 @@ class Config(_StrictModel):
temperature=0.5,
),
TECH_LEAD_PLANNING: AgentLLMConfig(
provider=LLMProvider.OPENAI,
model="gpt-4o-2024-05-13",
provider=LLMProvider.ANTHROPIC,
model="claude-3-5-sonnet-20240620",
temperature=0.5,
),
TECH_LEAD_EPIC_BREAKDOWN: AgentLLMConfig(

View File

@@ -9,7 +9,7 @@
~~RELEVANT_FILES_IMPLEMENTATION~~
These files are currently implemented in the project:
---START_OF_FRONTEND_API_FILES---
{% for file in state.files %}{% if 'client/' in file.path %}
{% for file in state.files %}{% if ((get_only_api_files is not defined or not get_only_api_files) and 'client/' in file.path) or 'client/src/api/' in file.path %}
**`{{ file.path }}`** ({{file.content.content.splitlines()|length}} lines of code):
```
{{ file.content.content }}```

View File

@@ -7,25 +7,26 @@ Every epic must have only coding involved. There should never be a epic that is
Do not leave anything for interpretation, e.g. if something can be done in multiple ways, specify which way should be used and be as clear as possible.
## Rule #2
This rule applies to epic scope.
Each epic must be deliverable that can be verified by non technical user. Each epic must have frontend interface, backend implementation, and a way for non technical user to test epic. Do not use words "backend" and "frontend" in epic descriptions. All details mentioned in project description must be fully implemented once all epics are finished.
## Rule #3
This rule applies to the number of epics you will create.
Every app should have different number of epics depending on complexity. Think epic by epic and create the minimum number of epics that are needed to develop this app.
Simple apps should have only 1 epic. More complex apps should have more epics. Do not create more epics than needed.
## Rule #4
## Rule #3
This rule applies to writing epic 'description'.
Every epic must have a clear, high level, and short 1-2 sentence 'description'. It must be very clear so that even non technical users who are reviewing it and just moved to this project can understand what is goal for the epic.
** MOST IMPORTANT RULES **
## Rule #4 (MOST IMPORTANT RULE)
This rule applies to thinking about the API endpoints specified above between START_OF_FRONTEND_API_FILES and END_OF_FRONTEND_API_FILES.
Each epic must be related to one or more API endpoints that are called from the frontend files. Go through all API endpoints called from the frontend and for each epic, specific which endpoints will be covered in that epic in the `related_api_endpoints` list. If there are multiple endpoints related to a single entity (for example, CRUD operations on a database model), you can put them in the same epic but otherwise, make sure that API endpoints for different entities are in different epics. The epics you create **MUST** cover **ALL** API endpoints mentioned in the frontend files above.
{# !!! TODO zamijeniti FIRST TASK s obzirom na auth !!! #}
## Rule #5
## Rule #5 (MOST IMPORTANT RULE)
This rule applies to order of epics.
Epics will be executed in same order that you output them. You must order them in a logical way so that epics that depend on other functionalities are implemented in later stage. The general order should be as follows:
- The first epic **MUST** be to remove the mocked data for making a register and login API requests from the frontend (in the client/src/api/auth.js file) - nothing is needed for this on the backend.
- The second epic **MUST** be to create any necessary scripts (if there are any). For example, a script to create an admin user, a script to seed the database, etc.
- Finally, implement the database model and CRUD operations (each epic must contain CRUD operations only for one single model - never for multiple) - make sure that **ALL** epics will CRUD operations come before any other epics. Also, pay attention to the API requests inside files in `client/api/` folder because they are currently using mocked data and whenever you implement an API endpoint, you just need to replace the mocked data with the real API request to the backend.
- Finally, all other epics must be about creating database models and CRUD operations (each epic must contain CRUD operations only for one single model - never for multiple). Pay attention to the API requests inside files in `client/api/` folder because they are currently using mocked data and whenever you implement an API endpoint, you just need to replace the mocked data with the real API request to the backend.
Remember, all utility functions that are not related to CRUD operations (eg. 3rd party integrations) **MUST** be mocked because they will be implemented after all epics are finished in the next phase of the project.

View File

@@ -1,7 +1,20 @@
Ok, great. Now, you need to take the epic #{{ epic_number }} ("{{ epic_description }}") and break it down into smaller tasks. Each task is one testable whole that the user can test and commit. Each task will be one commit that has to be testable by a human. Return the list of tasks for the Epic #{{ epic_number }}. For each task, write the the task description and a description of how a human should test if the task is successfully implemented or not. Keep in mind that there can be 1 task or multiple, depending on the complexity of the epic. The epics will be implemented one by one so make sure that the user needs to be able to test each task you write - for example, if something will be implemented in the epics after the epic #{{ epic_number }}, then you cannot write it here because the user won't be able to test it.
Ok, great. Now, you need to take the epic #{{ epic_number }} ("{{ epic_description }}") and break it down into smaller tasks. Each task is one testable whole that the user can test and commit. Each task will be one commit that has to be testable by a human. Return the list of tasks for the Epic #{{ epic_number }}. For each task, write the task description and a description of how a human should test if the task is successfully implemented or not. Keep in mind that there can be 1 task or multiple, depending on the complexity of the epic. The epics will be implemented one by one so make sure that the user needs to be able to test each task you write - for example, if something will be implemented in the epics after the epic #{{ epic_number }}, then you cannot write it here because the user won't be able to test it.
You can think of tasks as a unit of functionality that needs to have a frontend component and a backend component (don't split backend and frontend of the same functionality in separate tasks). In a single task, you can put the frontend API request implementation, backend routing, database creation and a utility function (eg. 3rd party integration) but do not put multiple functionalities in the same task (eg. creating an object, deleting it, updating it should all be separate tasks but each one should contain the necessary frontend, the route, the database and the utility function in the same task).
Here are the endpoints that need to be implemented for this epic:
{% for endpoint in related_api_endpoints %}
{{ "`" ~ endpoint ~ "`" }}{% if not loop.last %}
{% endif %}
{% endfor %}
Frontend is implemented completely but it's using the mocked data instead of doing real API requests. Whenever you implement an API endpoint, you just need to replace the mocked data with the real API request to the backend. {% if epic_number == 1 and state.current_epic.get("source") == "initial_app" %}The first epic **MUST** have only one (1) task which is to only remove the mocked data for making a register and login API requests from the frontend (in the client/src/api/auth.js file) - nothing is needed for this on the backend.{% endif %}
You need to specify tasks so that all these API endpoints get implemented completely. If there are multiple API endpoints related to a single entity (for example, CRUD operations on a database model), you **MUST** put them in the same task but otherwise, you **MUST** create a different task for each API endpoint.
When implementing CRUD operations, the creation of the model and all CRUD operations should be in the same task and all utility functions that are not related to CRUD operations (eg. 3rd party integrations) **MUST** be mocked because they will be implemented after all epics are finished in the next phase of the project.
You can think of tasks as a unit of functionality that needs to have a frontend component and a backend component (don't split backend and frontend of the same functionality in separate tasks).
**IMPORTANT: components of a single task**
When thinking about the scope of a single task, here are the components that need to be put into the same task:
1. The implementation of the backend API endpoint together with the frontend API request implementation (removing the mocked data and replacing it with the real API request)
2. The implementation of the database model
3. The utility function (eg. 3rd party integration) that is needed for this endpoint. Whenever you need to create a utility function that uses a 3rd party integration, you **MUST** mock that function (create the function, return a mocked data, and specify the structure of the input and the output of the function in the comment above the function).
**IMPORTANT**
If you are working on the Epic #1 that needs to remove the mocked data for authentication (register and login), you **MUST** create only one (1) task.

View File

@@ -21,12 +21,9 @@ Finally, here is the description of new feature that needs to be added to the ap
{% if epic.complexity and epic.complexity == 'simple' %}
This is very low complexity {{ task_type }} and because of that, you have to create ONLY one task that is sufficient to fully implement it.
{% else %}
Before we go into the coding part, your job is to split the development process of creating this app into smaller epics.
Before we go into the coding part, your job is to split the development process of building the backend for this app into epics. Above, you can see a part of the backend that's already built and the files from the frontend that make requests to the backend. The rest of the frontend is built but is not shown above because it is not necessary for you to create a list of epics.
Now, based on the project details provided{% if task_type == 'feature' %} and new feature description{% endif %}, think epic by epic and create the entire development plan{% if task_type == 'feature' %} for new feature{% elif task_type == 'app' %}. {% if state.files %}Continue from the existing code listed above{% else %}Start from the project setup{% endif %} and specify each epic until the moment when the entire app should be fully working{% if state.files %}. IMPORTANT: You should not reimplement what's already done - just continue from the implementation already there.{% endif %}{% endif %}
IMPORTANT!
Frontend is already built and you don't need to create epics for it. You only need to create epics for backend implementation and connect it to existing frontend. Keep in mind that some backend functionality is already implemented. The first epic **MUST** be to remove the mocked data for making a register and login API requests from the frontend (in the client/src/api/auth.js file) - nothing is needed for this on the backend.
Strictly follow these rules:
{% include "partials/project_tasks.prompt" %}