mirror of
https://github.com/qodo-ai/pr-agent.git
synced 2025-07-05 21:30:40 +08:00
stable
This commit is contained in:
@ -2,8 +2,10 @@ import re
|
|||||||
|
|
||||||
from pr_agent.tools.pr_code_suggestions import PRCodeSuggestions
|
from pr_agent.tools.pr_code_suggestions import PRCodeSuggestions
|
||||||
from pr_agent.tools.pr_description import PRDescription
|
from pr_agent.tools.pr_description import PRDescription
|
||||||
|
from pr_agent.tools.pr_information_from_user import PRInformationFromUser
|
||||||
from pr_agent.tools.pr_questions import PRQuestions
|
from pr_agent.tools.pr_questions import PRQuestions
|
||||||
from pr_agent.tools.pr_reviewer import PRReviewer
|
from pr_agent.tools.pr_reviewer import PRReviewer
|
||||||
|
from pr_agent.config_loader import settings
|
||||||
|
|
||||||
|
|
||||||
class PRAgent:
|
class PRAgent:
|
||||||
@ -11,7 +13,12 @@ class PRAgent:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
async def handle_request(self, pr_url, request) -> bool:
|
async def handle_request(self, pr_url, request) -> bool:
|
||||||
if any(cmd in request for cmd in ["/review", "/review_pr"]):
|
if any(cmd in request for cmd in ["/answer"]):
|
||||||
|
await PRReviewer(pr_url, is_answer=True).review()
|
||||||
|
elif any(cmd in request for cmd in ["/review", "/review_pr"]):
|
||||||
|
if settings.pr_reviewer.ask_and_reflect:
|
||||||
|
await PRInformationFromUser(pr_url).generate_questions()
|
||||||
|
else:
|
||||||
await PRReviewer(pr_url).review()
|
await PRReviewer(pr_url).review()
|
||||||
elif any(cmd in request for cmd in ["/describe", "/describe_pr"]):
|
elif any(cmd in request for cmd in ["/describe", "/describe_pr"]):
|
||||||
await PRDescription(pr_url).describe()
|
await PRDescription(pr_url).describe()
|
||||||
|
@ -30,7 +30,8 @@ improve / improve_code - Suggest improvements to the code in the PR as pull requ
|
|||||||
'ask', 'ask_question',
|
'ask', 'ask_question',
|
||||||
'describe', 'describe_pr',
|
'describe', 'describe_pr',
|
||||||
'improve', 'improve_code',
|
'improve', 'improve_code',
|
||||||
'user_questions'], default='review')
|
'user_questions', 'user_answers'],
|
||||||
|
default='review')
|
||||||
parser.add_argument('rest', nargs=argparse.REMAINDER, default=[])
|
parser.add_argument('rest', nargs=argparse.REMAINDER, default=[])
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
logging.basicConfig(level=os.environ.get("LOGLEVEL", "INFO"))
|
logging.basicConfig(level=os.environ.get("LOGLEVEL", "INFO"))
|
||||||
@ -60,6 +61,10 @@ improve / improve_code - Suggest improvements to the code in the PR as pull requ
|
|||||||
print(f"Asking the PR author questions: {args.pr_url}")
|
print(f"Asking the PR author questions: {args.pr_url}")
|
||||||
reviewer = PRInformationFromUser(args.pr_url)
|
reviewer = PRInformationFromUser(args.pr_url)
|
||||||
asyncio.run(reviewer.generate_questions())
|
asyncio.run(reviewer.generate_questions())
|
||||||
|
elif command in ['user_answers']:
|
||||||
|
print(f"Processing author answers and sending review: {args.pr_url}")
|
||||||
|
reviewer = PRReviewer(args.pr_url, cli_mode=True, is_answer=True)
|
||||||
|
asyncio.run(reviewer.review())
|
||||||
else:
|
else:
|
||||||
print(f"Unknown command: {command}")
|
print(f"Unknown command: {command}")
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
|
@ -6,6 +6,7 @@ import re
|
|||||||
from pr_agent.config_loader import settings
|
from pr_agent.config_loader import settings
|
||||||
from pr_agent.tools.pr_code_suggestions import PRCodeSuggestions
|
from pr_agent.tools.pr_code_suggestions import PRCodeSuggestions
|
||||||
from pr_agent.tools.pr_description import PRDescription
|
from pr_agent.tools.pr_description import PRDescription
|
||||||
|
from pr_agent.tools.pr_information_from_user import PRInformationFromUser
|
||||||
from pr_agent.tools.pr_questions import PRQuestions
|
from pr_agent.tools.pr_questions import PRQuestions
|
||||||
from pr_agent.tools.pr_reviewer import PRReviewer
|
from pr_agent.tools.pr_reviewer import PRReviewer
|
||||||
|
|
||||||
@ -53,7 +54,12 @@ async def run_action():
|
|||||||
pr_url = event_payload.get("issue", {}).get("pull_request", {}).get("url", None)
|
pr_url = event_payload.get("issue", {}).get("pull_request", {}).get("url", None)
|
||||||
if pr_url:
|
if pr_url:
|
||||||
body = comment_body.strip().lower()
|
body = comment_body.strip().lower()
|
||||||
if any(cmd in body for cmd in ["/review", "/review_pr"]):
|
if any(cmd in body for cmd in ["/answer"]):
|
||||||
|
await PRReviewer(pr_url, is_answer=True).review()
|
||||||
|
elif any(cmd in body for cmd in ["/review", "/review_pr", "/answer"]):
|
||||||
|
if settings.pr_reviewer.ask_and_reflect:
|
||||||
|
await PRInformationFromUser(pr_url).generate_questions()
|
||||||
|
else:
|
||||||
await PRReviewer(pr_url).review()
|
await PRReviewer(pr_url).review()
|
||||||
elif any(cmd in body for cmd in ["/describe", "/describe_pr"]):
|
elif any(cmd in body for cmd in ["/describe", "/describe_pr"]):
|
||||||
await PRDescription(pr_url).describe()
|
await PRDescription(pr_url).describe()
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
model="gpt-4-0613"
|
model="gpt-4-0613"
|
||||||
git_provider="github"
|
git_provider="github"
|
||||||
publish_review=true
|
publish_review=true
|
||||||
verbosity_level=2 # 0,1,2
|
verbosity_level=0 # 0,1,2
|
||||||
|
|
||||||
[pr_reviewer]
|
[pr_reviewer]
|
||||||
require_focused_review=true
|
require_focused_review=true
|
||||||
@ -10,6 +10,7 @@ require_tests_review=true
|
|||||||
require_security_review=true
|
require_security_review=true
|
||||||
num_code_suggestions=3
|
num_code_suggestions=3
|
||||||
inline_code_comments = true
|
inline_code_comments = true
|
||||||
|
ask_and_reflect=false
|
||||||
|
|
||||||
[pr_questions]
|
[pr_questions]
|
||||||
|
|
||||||
|
@ -108,6 +108,16 @@ Description: '{{description}}'
|
|||||||
Main language: {{language}}
|
Main language: {{language}}
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
||||||
|
{%- if question_str %}
|
||||||
|
######
|
||||||
|
Here are questions to better understand the PR. Use the answers to provide better feedback.
|
||||||
|
|
||||||
|
{{question_str|trim}}
|
||||||
|
|
||||||
|
User answers:
|
||||||
|
{{answer_str|trim}}
|
||||||
|
######
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
The PR Git Diff:
|
The PR Git Diff:
|
||||||
```
|
```
|
||||||
|
@ -15,12 +15,14 @@ from pr_agent.servers.help import bot_help_text, actions_help_text
|
|||||||
|
|
||||||
|
|
||||||
class PRReviewer:
|
class PRReviewer:
|
||||||
def __init__(self, pr_url: str, cli_mode=False):
|
def __init__(self, pr_url: str, cli_mode=False, is_answer: bool = False):
|
||||||
|
|
||||||
self.git_provider = get_git_provider()(pr_url)
|
self.git_provider = get_git_provider()(pr_url)
|
||||||
self.main_language = get_main_pr_language(
|
self.main_language = get_main_pr_language(
|
||||||
self.git_provider.get_languages(), self.git_provider.get_files()
|
self.git_provider.get_languages(), self.git_provider.get_files()
|
||||||
)
|
)
|
||||||
|
self.is_answer = is_answer
|
||||||
|
answer_str = question_str = self._get_user_answers()
|
||||||
self.ai_handler = AiHandler()
|
self.ai_handler = AiHandler()
|
||||||
self.patches_diff = None
|
self.patches_diff = None
|
||||||
self.prediction = None
|
self.prediction = None
|
||||||
@ -35,6 +37,9 @@ class PRReviewer:
|
|||||||
"require_security": settings.pr_reviewer.require_security_review,
|
"require_security": settings.pr_reviewer.require_security_review,
|
||||||
"require_focused": settings.pr_reviewer.require_focused_review,
|
"require_focused": settings.pr_reviewer.require_focused_review,
|
||||||
'num_code_suggestions': settings.pr_reviewer.num_code_suggestions,
|
'num_code_suggestions': settings.pr_reviewer.num_code_suggestions,
|
||||||
|
#
|
||||||
|
'question_str': question_str,
|
||||||
|
'answer_str': answer_str,
|
||||||
}
|
}
|
||||||
self.token_handler = TokenHandler(self.git_provider.pr,
|
self.token_handler = TokenHandler(self.git_provider.pr,
|
||||||
self.vars,
|
self.vars,
|
||||||
@ -119,3 +124,16 @@ class PRReviewer:
|
|||||||
content = d['suggestion content']
|
content = d['suggestion content']
|
||||||
|
|
||||||
self.git_provider.publish_inline_comment(content, relevant_file, relevant_line_in_file)
|
self.git_provider.publish_inline_comment(content, relevant_file, relevant_line_in_file)
|
||||||
|
|
||||||
|
def _get_user_answers(self):
|
||||||
|
answer_str = question_str = ""
|
||||||
|
if self.is_answer:
|
||||||
|
discussion_messages = self.git_provider.pr.get_issue_comments()
|
||||||
|
for message in discussion_messages.reversed:
|
||||||
|
if "Questions to better understand the PR:" in message.body:
|
||||||
|
question_str = message.body
|
||||||
|
elif '/answer' in message.body:
|
||||||
|
answer_str = message.body
|
||||||
|
if answer_str and question_str:
|
||||||
|
break
|
||||||
|
return question_str, answer_str
|
||||||
|
Reference in New Issue
Block a user