mirror of
https://github.com/qodo-ai/pr-agent.git
synced 2025-07-05 21:30:40 +08:00
feat: Add line link generation in git providers and refactor code suggestions generation
This commit is contained in:
@ -89,6 +89,9 @@ class GitProvider(ABC):
|
|||||||
def get_pr_id(self):
|
def get_pr_id(self):
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
def get_line_link(self, relevant_file: str, relevant_line_start: int, relevant_line_end: int = None) -> str:
|
||||||
|
return ""
|
||||||
|
|
||||||
#### comments operations ####
|
#### comments operations ####
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def publish_comment(self, pr_comment: str, is_temporary: bool = False):
|
def publish_comment(self, pr_comment: str, is_temporary: bool = False):
|
||||||
|
@ -501,6 +501,16 @@ class GithubProvider(GitProvider):
|
|||||||
|
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
def get_line_link(self, relevant_file: str, relevant_line_start: int, relevant_line_end: int = None) -> str:
|
||||||
|
sha_file = hashlib.sha256(relevant_file.encode('utf-8')).hexdigest()
|
||||||
|
if relevant_line_end:
|
||||||
|
link = f"https://github.com/{self.repo}/pull/{self.pr_num}/files#diff-{sha_file}R{relevant_line_start}-R{relevant_line_end}"
|
||||||
|
else:
|
||||||
|
link = f"https://github.com/{self.repo}/pull/{self.pr_num}/files#diff-{sha_file}R{relevant_line_start}"
|
||||||
|
return link
|
||||||
|
|
||||||
|
|
||||||
def get_pr_id(self):
|
def get_pr_id(self):
|
||||||
try:
|
try:
|
||||||
pr_id = f"{self.repo}/{self.pr_num}"
|
pr_id = f"{self.repo}/{self.pr_num}"
|
||||||
|
@ -57,6 +57,7 @@ include_generated_by_header=true
|
|||||||
|
|
||||||
[pr_code_suggestions] # /improve #
|
[pr_code_suggestions] # /improve #
|
||||||
num_code_suggestions=4
|
num_code_suggestions=4
|
||||||
|
summarize = false
|
||||||
extra_instructions = ""
|
extra_instructions = ""
|
||||||
rank_suggestions = false
|
rank_suggestions = false
|
||||||
# params for '/improve --extended' mode
|
# params for '/improve --extended' mode
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import copy
|
import copy
|
||||||
import textwrap
|
import textwrap
|
||||||
from typing import Dict, List
|
from typing import Dict, List
|
||||||
|
import difflib
|
||||||
from jinja2 import Environment, StrictUndefined
|
from jinja2 import Environment, StrictUndefined
|
||||||
|
|
||||||
from pr_agent.algo.ai_handler import AiHandler
|
from pr_agent.algo.ai_handler import AiHandler
|
||||||
@ -55,9 +55,9 @@ class PRCodeSuggestions:
|
|||||||
try:
|
try:
|
||||||
get_logger().info('Generating code suggestions for PR...')
|
get_logger().info('Generating code suggestions for PR...')
|
||||||
if get_settings().config.publish_output:
|
if get_settings().config.publish_output:
|
||||||
self.git_provider.publish_comment("Preparing review...", is_temporary=True)
|
self.git_provider.publish_comment("Preparing suggestions...", is_temporary=True)
|
||||||
|
|
||||||
get_logger().info('Preparing PR review...')
|
get_logger().info('Preparing PR code suggestions...')
|
||||||
if not self.is_extended:
|
if not self.is_extended:
|
||||||
await retry_with_fallback_models(self._prepare_prediction)
|
await retry_with_fallback_models(self._prepare_prediction)
|
||||||
data = self._prepare_pr_code_suggestions()
|
data = self._prepare_pr_code_suggestions()
|
||||||
@ -73,29 +73,11 @@ class PRCodeSuggestions:
|
|||||||
data['Code suggestions'] = await self.rank_suggestions(data['Code suggestions'])
|
data['Code suggestions'] = await self.rank_suggestions(data['Code suggestions'])
|
||||||
|
|
||||||
if get_settings().config.publish_output:
|
if get_settings().config.publish_output:
|
||||||
get_logger().info('Pushing PR review...')
|
get_logger().info('Pushing PR code suggestions...')
|
||||||
self.git_provider.remove_initial_comment()
|
self.git_provider.remove_initial_comment()
|
||||||
if get_settings().pr_code_suggestions.summarize:
|
if get_settings().pr_code_suggestions.summarize:
|
||||||
get_logger().info('Pushing summarize code suggestions...')
|
get_logger().info('Pushing summarize code suggestions...')
|
||||||
data_markdown = "## Code suggestions\n\n"
|
self.publish_summarizes_suggestions(data)
|
||||||
for s in data['Code suggestions']:
|
|
||||||
import hashlib
|
|
||||||
relevant_file = s['relevant file']
|
|
||||||
sha_file = hashlib.sha256(relevant_file.encode('utf-8')).hexdigest()
|
|
||||||
absolute_position_start = s['relevant lines start']
|
|
||||||
absolute_position_end = s['relevant lines end']
|
|
||||||
link = f"https://github.com/{self.git_provider.repo}/pull/{self.git_provider.pr_num}/files#diff-{sha_file}R{absolute_position_start}-R{absolute_position_end}"
|
|
||||||
|
|
||||||
data_markdown += f"File:\n [{s['relevant file']}({absolute_position_start}-{absolute_position_end})]({link})\n"
|
|
||||||
data_markdown += f"\nSuggestion:\n**{s['suggestion content']}**\n"
|
|
||||||
data_markdown += "<details> <summary> Example code:</summary>\n"
|
|
||||||
data_markdown += f"Existing code:\n```suggestion\n{s['existing code']}\n```\n"
|
|
||||||
data_markdown += f"Improved code:\n```suggestion\n{s['improved code']}\n```\n"
|
|
||||||
data_markdown += "</details>\n"
|
|
||||||
data_markdown += "\n___\n\n"
|
|
||||||
# data_markdown = convert_to_markdown(data)
|
|
||||||
self.git_provider.publish_comment(data_markdown)
|
|
||||||
aaa = 3
|
|
||||||
else:
|
else:
|
||||||
get_logger().info('Pushing inline code suggestions...')
|
get_logger().info('Pushing inline code suggestions...')
|
||||||
self.push_inline_code_suggestions(data)
|
self.push_inline_code_suggestions(data)
|
||||||
@ -266,4 +248,26 @@ class PRCodeSuggestions:
|
|||||||
|
|
||||||
return data_sorted
|
return data_sorted
|
||||||
|
|
||||||
|
def publish_summarizes_suggestions(self, data: Dict):
|
||||||
|
try:
|
||||||
|
data_markdown = "## Code Suggestions\n\n"
|
||||||
|
for s in data['Code suggestions']:
|
||||||
|
code_snippet_link = self.git_provider.get_line_link(s['relevant file'], s['relevant lines start'],
|
||||||
|
s['relevant lines end'])
|
||||||
|
if code_snippet_link:
|
||||||
|
data_markdown += f"📌 File:\n[{s['relevant file']}({s['relevant lines start']}-{s['relevant lines end']})]({code_snippet_link})\n"
|
||||||
|
else:
|
||||||
|
data_markdown += f"📌 File:\n{s['relevant file']}({s['relevant lines start']}-{s['relevant lines end']})\n"
|
||||||
|
data_markdown += f"\nSuggestion:\n**{s['suggestion content']}**\n"
|
||||||
|
if self.git_provider.is_supported("gfm_markdown"):
|
||||||
|
data_markdown += "<details> <summary> Example code:</summary>\n\n___\n\n"
|
||||||
|
data_markdown += f"Existing code:\n```{self.main_language}\n{s['existing code']}\n```\n"
|
||||||
|
data_markdown += f"Improved code:\n```{self.main_language}\n{s['improved code']}\n```\n"
|
||||||
|
if self.git_provider.is_supported("gfm_markdown"):
|
||||||
|
data_markdown += "</details>\n"
|
||||||
|
data_markdown += "\n___\n\n"
|
||||||
|
self.git_provider.publish_comment(data_markdown)
|
||||||
|
except Exception as e:
|
||||||
|
get_logger().info(f"Failed to publish summarized code suggestions, error: {e}")
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user