Merge pull request #716 from Pythagora-io/fix-iteration

hardcode troubleshooter questions
This commit is contained in:
LeonOstrez
2024-03-12 00:30:29 -07:00
committed by GitHub
8 changed files with 58 additions and 84 deletions

View File

@@ -520,31 +520,22 @@ GET_BUG_REPORT_MISSING_DATA = {
'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
}
}],

View File

@@ -2,6 +2,6 @@ CHECK_AND_CONTINUE = 'Is everything working? Let me know if something needs to b
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

View File

@@ -239,6 +239,7 @@ class Project:
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)

View File

@@ -652,6 +652,7 @@ class Developer(Agent):
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):]
@@ -669,9 +670,9 @@ class Developer(Agent):
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'],
@@ -686,7 +687,8 @@ class Developer(Agent):
"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,
@@ -713,7 +715,7 @@ class Developer(Agent):
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):
"""
@@ -721,57 +723,42 @@ class Developer(Agent):
: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
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)
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')
missing_data = llm_response['missing_data']
if len(missing_data) == 0:
return user_feedback, None
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
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')
questions_and_answers.append({
"question": missing_data_item['question'],
"answer": answer
})
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 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)
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):
"""

View File

@@ -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?"

View File

@@ -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:
{% if user_feedback != '' %}
User who was using the app "{{ name }}" sent you this feedback:
```
{{ user_input }}
```
{% 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.
@@ -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 }}

View File

@@ -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:

View File

@@ -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.
@@ -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
"""
@@ -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')