mirror of
https://github.com/Pythagora-io/gpt-pilot.git
synced 2026-01-10 13:37:55 -05:00
Add route files content to prompt for user instructions.
This commit is contained in:
@@ -7,6 +7,8 @@ from core.agents.base import BaseAgent
|
||||
from core.agents.convo import AgentConvo
|
||||
from core.agents.mixins import IterationPromptMixin
|
||||
from core.agents.response import AgentResponse
|
||||
from core.config import ROUTE_FILES_AGENT_NAME
|
||||
from core.db.models.file import File
|
||||
from core.db.models.project_state import TaskStatus
|
||||
from core.llm.parser import JSONParser, OptionalCodeBlockParser
|
||||
from core.log import get_logger
|
||||
@@ -23,6 +25,10 @@ class BugReportQuestions(BaseModel):
|
||||
)
|
||||
|
||||
|
||||
class RouteFilePaths(BaseModel):
|
||||
files: list[str] = Field(description="List of paths for files that contain routes")
|
||||
|
||||
|
||||
class Troubleshooter(IterationPromptMixin, BaseAgent):
|
||||
agent_type = "troubleshooter"
|
||||
display_name = "Troubleshooter"
|
||||
@@ -134,8 +140,12 @@ class Troubleshooter(IterationPromptMixin, BaseAgent):
|
||||
async def get_user_instructions(self) -> Optional[str]:
|
||||
await self.send_message("Determining how to test the app ...")
|
||||
|
||||
route_files = await self._get_route_files()
|
||||
|
||||
llm = self.get_llm()
|
||||
convo = self._get_task_convo().template("define_user_review_goal", task=self.current_state.current_task)
|
||||
convo = self._get_task_convo().template(
|
||||
"define_user_review_goal", task=self.current_state.current_task, route_files=route_files
|
||||
)
|
||||
user_instructions: str = await llm(convo)
|
||||
|
||||
user_instructions = user_instructions.strip()
|
||||
@@ -145,6 +155,17 @@ class Troubleshooter(IterationPromptMixin, BaseAgent):
|
||||
|
||||
return user_instructions
|
||||
|
||||
async def _get_route_files(self) -> list[File]:
|
||||
"""Returns the list of file paths that have routes defined in them."""
|
||||
|
||||
llm = self.get_llm(ROUTE_FILES_AGENT_NAME)
|
||||
convo = self._get_task_convo().template("get_route_files", task=self.current_state.current_task)
|
||||
file_list = await llm(convo, parser=JSONParser(RouteFilePaths))
|
||||
route_files: set[str] = set(file_list.files)
|
||||
|
||||
# Sometimes LLM can return a non-existent file, let's make sure to filter those out
|
||||
return [f for f in self.current_state.files if f.path in route_files]
|
||||
|
||||
async def get_user_feedback(
|
||||
self,
|
||||
run_command: str,
|
||||
|
||||
@@ -34,6 +34,7 @@ IGNORE_SIZE_THRESHOLD = 50000 # 50K+ files are ignored by default
|
||||
# Agents with sane setup in the default configuration
|
||||
DEFAULT_AGENT_NAME = "default"
|
||||
DESCRIBE_FILES_AGENT_NAME = "CodeMonkey.describe_files"
|
||||
ROUTE_FILES_AGENT_NAME = "Troubleshooter.get_route_files"
|
||||
|
||||
# Endpoint for the external documentation
|
||||
EXTERNAL_DOCUMENTATION_API = "http://docs-pythagora-io-439719575.us-east-1.elb.amazonaws.com"
|
||||
@@ -298,6 +299,7 @@ class Config(_StrictModel):
|
||||
default={
|
||||
DEFAULT_AGENT_NAME: AgentLLMConfig(),
|
||||
DESCRIBE_FILES_AGENT_NAME: AgentLLMConfig(model="gpt-3.5-turbo", temperature=0.0),
|
||||
ROUTE_FILES_AGENT_NAME: AgentLLMConfig(model="gpt-4o", temperature=0.0),
|
||||
}
|
||||
)
|
||||
prompt: PromptConfig = PromptConfig()
|
||||
|
||||
@@ -1,3 +1,14 @@
|
||||
{% if route_files %}
|
||||
Here is a list of files the contain route definitions, and their contents. If any of the steps in testing instructions use URLs, use the routes defined in these files.
|
||||
|
||||
---START_OF_FILES---
|
||||
{% for file in route_files %}
|
||||
File **`{{ file.path }}`** ({{file.content.content.splitlines()|length}} lines of code):
|
||||
```
|
||||
{{ file.content.content }}```
|
||||
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
How can a human user test if this task was completed successfully?
|
||||
|
||||
Please list actions, step by step, in order, that the user should take to verify the task. After each action, describe what the expected response is.
|
||||
|
||||
22
core/prompts/troubleshooter/get_route_files.prompt
Normal file
22
core/prompts/troubleshooter/get_route_files.prompt
Normal file
@@ -0,0 +1,22 @@
|
||||
{# eval-tool test ID: 74918173-59e4-4005-bf19-d28f3bc9f06c
|
||||
|
||||
This was added in June 2024, to improve the accuracy of user testing instructions.
|
||||
We've noticed that the LLM would often times include incorrect URLs in the user testing
|
||||
instructions, because it wasn't aware of the routes used in the application.
|
||||
The solution was to add the entire content of all the files that have routes defined in
|
||||
them, and this prompt selects those files.
|
||||
|
||||
#}
|
||||
Your task is to identify all the files, from the above list, that have routes defined in them. Return just the file paths as a JSON list named "files", DO NOT return anything else. If there are no files with routes, return an empty list.
|
||||
|
||||
Example response:
|
||||
```
|
||||
{
|
||||
"files": [
|
||||
"dir/file1.js",
|
||||
"dir/file2.js",
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Your response must be a valid JSON format.
|
||||
31
tests/agents/test_troubleshooter.py
Normal file
31
tests/agents/test_troubleshooter.py
Normal file
@@ -0,0 +1,31 @@
|
||||
import pytest
|
||||
|
||||
from core.agents.troubleshooter import RouteFilePaths, Troubleshooter
|
||||
from core.db.models import File, FileContent
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_route_files_are_included_in_the_prompt(agentcontext):
|
||||
sm, _, ui, mock_get_llm = agentcontext
|
||||
|
||||
sm.current_state.tasks = [{"description": "Some task", "status": "todo", "instructions": "Testing here!"}]
|
||||
files = [
|
||||
File(path="dir/file1.js", content=FileContent(content="File 1 content")),
|
||||
File(path="dir/file2.js", content=FileContent(content="File 2 content")),
|
||||
]
|
||||
|
||||
await sm.commit()
|
||||
sm.current_state.files = files
|
||||
|
||||
ts = Troubleshooter(sm, ui)
|
||||
ts.get_llm = mock_get_llm(
|
||||
side_effect=[
|
||||
RouteFilePaths(files=["dir/file1.js"]), # First LLM call, to select files with routes
|
||||
"", # Second LLM call, to generate the actual instructions
|
||||
]
|
||||
)
|
||||
await ts.get_user_instructions()
|
||||
second_llm_call = ts.get_llm().call_args_list[1]
|
||||
user_msg_contents = [msg["content"] for msg in second_llm_call[0][0] if msg["role"] == "user"]
|
||||
assert "File 1 content" in user_msg_contents[1] # Prompt at [1] has the route file contents
|
||||
assert "File 2 content" not in user_msg_contents[1]
|
||||
Reference in New Issue
Block a user