mirror of
https://github.com/qodo-ai/pr-agent.git
synced 2025-07-16 10:40:16 +08:00
Merge remote-tracking branch 'origin/tr/agent_logic' into tr/agent_logic
# Conflicts: # pr_agent/tools/pr_description.py
This commit is contained in:
@ -14,10 +14,10 @@ def run():
|
||||
parser = argparse.ArgumentParser(description='AI based pull request analyzer', usage="""\
|
||||
Usage: cli.py --pr-url <URL on supported git hosting service> <command> [<args>].
|
||||
For example:
|
||||
- cli.py --pr-url xxx review
|
||||
- cli.py --pr-url xxx describe
|
||||
- cli.py --pr-url xxx improve
|
||||
- cli.py --pr-url xxx ask "write me a poem about this PR"
|
||||
- cli.py --pr-url=... review
|
||||
- cli.py --pr-url=... describe
|
||||
- cli.py --pr-url=... improve
|
||||
- cli.py --pr-url=... ask "write me a poem about this PR"
|
||||
|
||||
Supported commands:
|
||||
review / review_pr - Add a review that includes a summary of the PR and specific suggestions for improvement.
|
||||
|
@ -123,26 +123,11 @@ class GitLabProvider(GitProvider):
|
||||
range = relevant_lines_end - relevant_lines_start + 1
|
||||
body = body.replace('```suggestion', f'```suggestion:-0+{range}')
|
||||
|
||||
d = self.last_diff
|
||||
#
|
||||
# pos_obj = {'position_type': 'text',
|
||||
# 'new_path': target_file.filename,
|
||||
# 'old_path': target_file.old_filename if target_file.old_filename else target_file.filename,
|
||||
# 'base_sha': d.base_commit_sha, 'start_sha': d.start_commit_sha, 'head_sha': d.head_commit_sha}
|
||||
lines = target_file.head_file.splitlines()
|
||||
relevant_line_in_file = lines[relevant_lines_start - 1]
|
||||
edit_type, found, source_line_no, target_file, target_line_no = self.find_in_file(target_file, relevant_line_in_file)
|
||||
self.send_inline_comment(body, edit_type, found, relevant_file, relevant_line_in_file, source_line_no,
|
||||
target_file, target_line_no)
|
||||
# if lines[relevant_lines_start][0] == '-':
|
||||
# pos_obj['old_line'] = relevant_lines_start
|
||||
# elif lines[relevant_lines_start][0] == '+':
|
||||
# pos_obj['new_line'] = relevant_lines_start
|
||||
# else:
|
||||
# pos_obj['new_line'] = relevant_lines_start
|
||||
# pos_obj['old_line'] = relevant_lines_start
|
||||
# self.mr.discussions.create({'body': body,
|
||||
# 'position': pos_obj})
|
||||
|
||||
def search_line(self, relevant_file, relevant_line_in_file):
|
||||
target_file = None
|
||||
|
@ -12,6 +12,9 @@ num_code_suggestions=3
|
||||
inline_code_comments = true
|
||||
ask_and_reflect=false
|
||||
|
||||
[pr_description]
|
||||
publish_description_as_comment=false
|
||||
|
||||
[pr_questions]
|
||||
|
||||
[pr_code_suggestions]
|
||||
|
@ -2,8 +2,11 @@
|
||||
system="""You are CodiumAI-PR-Reviewer, a language model designed to review git pull requests.
|
||||
Your task is to provide constructive and concise feedback for the PR, and also provide meaningfull code suggestions to improve the new PR code (the '+' lines).
|
||||
- Provide up to {{ num_code_suggestions }} code suggestions.
|
||||
{%- if num_code_suggestions > 0 %}
|
||||
- Try to focus on important suggestions like fixing code problems, issues and bugs. As a second priority, provide suggestions for meaningfull code improvements, like performance, vulnerability, modularity, and best practices.
|
||||
- Suggestions should focus on improving the new added code lines.
|
||||
- Make sure not to provide suggestions repeating modifications already implemented in the new PR code (the '+' lines).
|
||||
{%- endif %}
|
||||
|
||||
You must use the following JSON schema to format your answer:
|
||||
```json
|
||||
@ -41,6 +44,7 @@ You must use the following JSON schema to format your answer:
|
||||
"type": "string",
|
||||
"description": "General suggestions and feedback for the contributors and maintainers of this PR. May include important suggestions for the overall structure, primary purpose, best practices, critical bugs, and other aspects of the PR. Explain your suggestions."
|
||||
},
|
||||
{%- if num_code_suggestions > 0 %}
|
||||
"Code suggestions": {
|
||||
"type": "array",
|
||||
"maxItems": {{ num_code_suggestions }},
|
||||
@ -60,6 +64,7 @@ You must use the following JSON schema to format your answer:
|
||||
}
|
||||
}
|
||||
},
|
||||
{%- endif %}
|
||||
{%- if require_security %}
|
||||
"Security concerns": {
|
||||
"type": "string",
|
||||
@ -88,6 +93,7 @@ Example output:
|
||||
"PR Feedback":
|
||||
{
|
||||
"General PR suggestions": "..., `xxx`...",
|
||||
{%- if num_code_suggestions > 0 %}
|
||||
"Code suggestions": [
|
||||
{
|
||||
"relevant file": "directory/xxx.py",
|
||||
@ -96,6 +102,7 @@ Example output:
|
||||
},
|
||||
...
|
||||
]
|
||||
{%- endif %}
|
||||
{%- if require_security %},
|
||||
"Security concerns": "No, because ..."
|
||||
{%- endif %}
|
||||
|
@ -43,10 +43,13 @@ class PRDescription:
|
||||
logging.info('Getting AI prediction...')
|
||||
self.prediction = await self._get_prediction()
|
||||
logging.info('Preparing answer...')
|
||||
pr_title, pr_body = self._prepare_pr_answer()
|
||||
pr_title, pr_body, markdown_text = self._prepare_pr_answer()
|
||||
if settings.config.publish_output:
|
||||
logging.info('Pushing answer...')
|
||||
self.git_provider.publish_description(pr_title, pr_body)
|
||||
if settings.pr_description.publish_description_as_comment:
|
||||
self.git_provider.publish_comment(markdown_text)
|
||||
else:
|
||||
self.git_provider.publish_description(pr_title, pr_body)
|
||||
self.git_provider.remove_initial_comment()
|
||||
return ""
|
||||
|
||||
@ -66,10 +69,11 @@ class PRDescription:
|
||||
|
||||
def _prepare_pr_answer(self):
|
||||
data = json.loads(self.prediction)
|
||||
markdown_text = ""
|
||||
for key, value in data.items():
|
||||
markdown_text += f"## {key}\n\n"
|
||||
markdown_text += f"{value}\n\n"
|
||||
pr_body = ""
|
||||
# for key, value in data.items():
|
||||
# markdown_text += f"## {key}\n\n"
|
||||
# markdown_text += f"{value}\n\n"
|
||||
title = data['PR Title']
|
||||
del data['PR Title']
|
||||
for key, value in data.items():
|
||||
@ -80,4 +84,4 @@ class PRDescription:
|
||||
pr_body += f"**{value}**\n\n___\n"
|
||||
if settings.config.verbosity_level >= 2:
|
||||
logging.info(f"title:\n{title}\n{pr_body}")
|
||||
return title, pr_body
|
||||
return title, pr_body, markdown_text
|
||||
|
@ -94,7 +94,9 @@ class PRReviewer:
|
||||
del data['PR Feedback']['Security concerns']
|
||||
data['PR Analysis']['Security concerns'] = val
|
||||
|
||||
if settings.config.git_provider == 'github' and settings.pr_reviewer.inline_code_comments:
|
||||
if settings.config.git_provider == 'github' and \
|
||||
settings.pr_reviewer.inline_code_comments and \
|
||||
'Code suggestions' in data['PR Feedback']:
|
||||
del data['PR Feedback']['Code suggestions']
|
||||
|
||||
markdown_text = convert_to_markdown(data)
|
||||
@ -112,6 +114,9 @@ class PRReviewer:
|
||||
return markdown_text
|
||||
|
||||
def _publish_inline_code_comments(self):
|
||||
if settings.pr_reviewer.num_code_suggestions == 0:
|
||||
return
|
||||
|
||||
review = self.prediction.strip()
|
||||
try:
|
||||
data = json.loads(review)
|
||||
|
Reference in New Issue
Block a user