Skip to content

Commit

Permalink
Merge pull request Pythagora-io#717 from Pythagora-io/development
Browse files Browse the repository at this point in the history
Development
  • Loading branch information
LeonOstrez authored Mar 12, 2024
2 parents 02037b8 + b76e3d3 commit e42daa3
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 86 deletions.
13 changes: 2 additions & 11 deletions pilot/const/function_calls.py
Original file line number Diff line number Diff line change
Expand Up @@ -520,31 +520,22 @@ def command_definition(description_command='A single command that needs to be ex
'parameters': {
"type": "object",
"properties": {
"reasoning": {
"type": "string",
"description": "Reasoning for asking these questions or for not asking any questions."
},
"missing_data": {
"type": "array",
"items": {
"type": "object",
"properties": {
"category": {
"type": "string",
"enum": ["general", "frontend", "backend", "database", "devops", "other"],
"description": "Category of the question."
},
"question": {
"type": "string",
"description": "Very clear question that needs to be answered to have good bug report.",
},
},
"required": ["category", "question"],
"required": ["question"],
"additionalProperties": False
},
}
},
"required": ["reasoning", "missing_data"],
"required": ["missing_data"],
"additionalProperties": False
}
}],
Expand Down
2 changes: 1 addition & 1 deletion pilot/const/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
WHEN_USER_DONE = 'Once you have completed, enter "continue"'
AFFIRMATIVE_ANSWERS = ['', 'y', 'yes', 'ok', 'okay', 'sure', 'absolutely', 'indeed', 'correct', 'affirmative']
NEGATIVE_ANSWERS = ['n', 'no', 'skip', 'negative', 'not now', 'cancel', 'decline', 'stop']
STUCK_IN_LOOP = 'I\'m stuck in loop'
STUCK_IN_LOOP = 'I\'m stuck in a loop'
NONE_OF_THESE = 'none of these'
MAX_PROJECT_NAME_LENGTH = 50
1 change: 1 addition & 0 deletions pilot/helpers/Project.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ def finish(self):
print('', type='verbose', category='pythagora')
if self.run_command and self.check_ipc():
print(self.run_command, type='run_command')
print('continue', type='button')
feature_description = ask_user(self, "Project is finished! Do you want to add any features or changes? "
"If yes, describe it here and if no, just press ENTER",
require_some_input=False)
Expand Down
77 changes: 32 additions & 45 deletions pilot/helpers/agents/Developer.py
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,7 @@ def continue_development(self, iteration_convo, last_branch_name, continue_descr
print('', type='verbose', category='agent:troubleshooter')
self.project.current_task.inc('iterations')
stuck_in_loop = user_feedback.startswith(STUCK_IN_LOOP)
user_feedback_qa = None
if stuck_in_loop:
# Remove the STUCK_IN_LOOP prefix from the user feedback
user_feedback = user_feedback[len(STUCK_IN_LOOP):]
Expand All @@ -669,9 +670,9 @@ def continue_development(self, iteration_convo, last_branch_name, continue_descr

tried_alternative_solutions_to_current_issue.append(next_solution_to_try)
else:
user_feedback = self.bug_report_generator(user_feedback, user_description)
user_feedback, user_feedback_qa = self.bug_report_generator(user_feedback, user_description)

print_task_progress(1, 1, development_task['description'], 'troubleshooting', 'in_progress')
print_task_progress(1, 1, development_task['description'], 'troubleshooting', 'in_progress', len(llm_solutions) + 1)
iteration_convo = AgentConvo(self)
iteration_description = iteration_convo.send_message('development/iteration.prompt', {
"name": self.project.args['name'],
Expand All @@ -686,7 +687,8 @@ def continue_development(self, iteration_convo, last_branch_name, continue_descr
"current_task": development_task,
"development_tasks": self.project.development_plan,
"files": self.project.get_all_coded_files(),
"user_input": user_feedback,
"user_feedback": user_feedback,
"user_feedback_qa": user_feedback_qa,
"previous_solutions": llm_solutions[-3:],
"next_solution_to_try": next_solution_to_try,
"alternative_solutions_to_current_issue": alternative_solutions_to_current_issue,
Expand All @@ -713,65 +715,50 @@ def continue_development(self, iteration_convo, last_branch_name, continue_descr

task_steps = llm_response['tasks']
self.execute_task(iteration_convo, task_steps, is_root_task=True, task_source='troubleshooting')
print_task_progress(1, 1, development_task['description'], 'troubleshooting', 'done')
print_task_progress(1, 1, development_task['description'], 'troubleshooting', 'done', len(llm_solutions) + 1)

def bug_report_generator(self, user_feedback, task_review_description):
"""
Generate a bug report from the user feedback.
:param user_feedback: The user feedback.
:param task_review_description: The task review description.
:return: The bug report.
:return: The user feedback and the questions and answers.
"""
bug_report_convo = AgentConvo(self)
function_uuid = str(uuid.uuid4())
bug_report_convo.save_branch(function_uuid)
questions_and_answers = []
while True:
llm_response = bug_report_convo.send_message('development/bug_report.prompt', {
"user_feedback": user_feedback,
"app_summary": self.project.project_description,
"files": self.project.get_all_coded_files(),
"task_review_description": task_review_description,
"questions_and_answers": questions_and_answers,
}, GET_BUG_REPORT_MISSING_DATA)

missing_data = llm_response['missing_data']
if len(missing_data) == 0:
break

length_before = len(questions_and_answers)
for missing_data_item in missing_data:
if self.project.check_ipc():
print(missing_data_item['question'], type='verbose')
print('continue/skip question', type='button')
if self.run_command:
print(self.run_command, type='run_command')

answer = ask_user(self.project, missing_data_item['question'], require_some_input=False)
if answer.lower() == 'skip question' or answer.lower() == '' or answer.lower() == 'continue':
continue

questions_and_answers.append({
"question": missing_data_item['question'],
"answer": answer
})
llm_response = bug_report_convo.send_message('development/bug_report.prompt', {
"user_feedback": user_feedback,
"app_summary": self.project.project_description,
"files": self.project.get_all_coded_files(),
"task_review_description": task_review_description,
"questions_and_answers": questions_and_answers,
}, GET_BUG_REPORT_MISSING_DATA)

missing_data = llm_response['missing_data']
if len(missing_data) == 0:
return user_feedback, None

for missing_data_item in missing_data:
if self.project.check_ipc():
print(missing_data_item['question'], type='verbose')
print('continue/skip question', type='button')
if self.run_command:
print(self.run_command, type='run_command')

# if user skips all questions or if we got more than 4 answers, we don't want to get stuck in infinite loop
if length_before == len(questions_and_answers) or len(questions_and_answers) >= MAX_QUESTIONS_FOR_BUG_REPORT:
break
bug_report_convo.load_branch(function_uuid)
answer = ask_user(self.project, missing_data_item['question'], require_some_input=False)
if answer.lower() == 'skip question' or answer.lower() == '' or answer.lower() == 'continue':
continue

if len(questions_and_answers):
bug_report_summary_convo = AgentConvo(self)
user_feedback = bug_report_summary_convo.send_message('development/bug_report_summary.prompt', {
"app_summary": self.project.project_description,
"task_review_description": task_review_description,
"user_feedback": user_feedback,
"questions_and_answers": questions_and_answers,
questions_and_answers.append({
"question": missing_data_item['question'],
"answer": answer
})

return user_feedback
return user_feedback, questions_and_answers

def review_task(self):
"""
Expand Down
23 changes: 9 additions & 14 deletions pilot/prompts/development/bug_report.prompt
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,16 @@ If you have enough information don't ask any questions.

When thinking of questions, consider the following:
- After getting answers to your questions, you must be able to solve the problem.
- Category on which you need more information ("general", "frontend", "backend", "database", "devops", "other")
- User is not very technical person but understands basics. It is crucial that your questions can be answered without looking into code or knowing codebase. Do not ask how something is implemented, how code works or for code snippets.
- Ask questions having in mind that you have access to whole codebase related to this issue.
- Make sure to cover all categories that you need to solve the problem.
- Ask only specific information that you need to solve the problem.
- Ask clear, short and concise questions.
- Ask only crucial questions. Do not ask for information that you do not need to solve the problem.
- Ask least amount of questions to get the most information.
- Ask least amount of questions to solve the problem.
- Do not ask any questions about recent changes in code. You should be able to solve the problem without knowing recent changes in code.
- Ask least amount of questions to get the most information and to solve the problem.
- Ask only questions from the list provided bellow.
- Ask questions in same order as they are in the list.
- Never repeat same question.

Here are some examples of good questions:
"Are there any logs in browser?"
"Can you provide logs from server?"
"What is the error message?"
Here is the list of questions you can ask:
"Can you please provide more information on what exactly you mean?"
"Can you please provide logs from the frontend?"
"Can you please provide logs from the backend?"
"What is the expected behavior?"
"What is the actual behavior?"
"What is the stack trace?"
"On what page does the issue happen?"
24 changes: 12 additions & 12 deletions pilot/prompts/development/iteration.prompt
Original file line number Diff line number Diff line change
Expand Up @@ -24,25 +24,29 @@ You are currently working on task "{{ current_task.description }}" and you have
A part of the app is already finished.
{{ files_list }}


{% if user_input != '' %}
Now, your colleague who is testing the app "{{ name }}" sent you some additional info. Here it is:
```
{{ user_input }}
{% if user_feedback != '' %}
User who was using the app "{{ name }}" sent you this feedback:
```
{% endif %}
{{ user_feedback }}
```{% endif %}
{% if user_feedback_qa %}Feedback was not clear enough so you asked user for additional information and got this response:
```{% for row in user_feedback_qa %}
Q: {{ row.question }}
A: {{ row.answer }}
{% endfor %}
```{% endif %}
{% if next_solution_to_try is not none %}
Focus on solving this issue in the following way:
```
{{ next_solution_to_try }}
```
{% endif %}
Can you debug this issue or implement changes to comply with the additional user input?
Now, you have to debug this issue and comply with the additional user feedback.

**IMPORTANT**
Think about all information provided. Your job is to look at big picture by analysing all files to find where the issue is.
Don't reply with any code, your thoughts or breakdown of the issue. Respond only with description of solution, explaining what should be steps in solving the issue.
Create as little steps as possible to fix the issue. Each step should describe what changes are needed in specific file or describe command that needs to be executed to continue working on the issue.
Create as little steps as possible to fix the issue. Each step should describe, using sentences and not code, what changes are needed in specific file or describe command that needs to be executed to continue working on the issue.
When there are multiple things that have to be done in one file write everything as one step and don't split it in multiple steps.
You can count that the environment is set up previously and packages listed in files are installed so tell me only commands needed for installation of new dependencies, if there are any.

Expand All @@ -52,7 +56,3 @@ If report mentions *multiple* issues, treat it as if you got several separate re
{{ execution_order }}

{{ file_size_limit }}

You do not need to make any automated tests work.

{{ human_intervention_explanation }}
2 changes: 0 additions & 2 deletions pilot/prompts/development/parse_task.prompt
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ Each step can be either:

{{ execution_order }}

{{ logs_and_error_handling }}

**IMPORTANT**: Remember, NEVER output human intervention steps to do manual tests or coding tasks, even if the previous message asks for it! The testing will be done *after* these steps and you MUST NOT include testing in these steps.

Examples:
Expand Down
4 changes: 3 additions & 1 deletion pilot/utils/print.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import re


def print_task_progress(index, num_of_tasks, description, task_source, status):
def print_task_progress(index, num_of_tasks, description, task_source, status, source_index=1):
"""
Print task progress in extension.
Expand All @@ -10,6 +10,7 @@ def print_task_progress(index, num_of_tasks, description, task_source, status):
:param description: Description of the task.
:param task_source: Source of the task, one of: 'app', 'feature', 'debugger', 'troubleshooting', 'review'.
:param status: Status of the task, can be 'in_progress' or 'done'.
:param source_index: Index of the source.
:return: None
"""
Expand All @@ -19,6 +20,7 @@ def print_task_progress(index, num_of_tasks, description, task_source, status):
'description': description,
'source': task_source,
'status': status,
'source_index': source_index,
}}, type='progress')


Expand Down

0 comments on commit e42daa3

Please sign in to comment.