Merge pull request #1153 from Codium-ai/tr/protections2

Tr/protections2
This commit is contained in:
Tal
2024-08-18 08:34:19 +03:00
committed by GitHub
7 changed files with 37 additions and 28 deletions

View File

@ -130,18 +130,6 @@ class AzureDevopsProvider(GitProvider):
def get_pr_description_full(self) -> str:
return self.pr.description
def delete_comment(self, comment):
try:
self.azure_devops_client.delete_comment(
repository_id=self.repo_slug,
pull_request_id=self.pr_num,
thread_id=comment.thread_id,
comment_id=comment.id,
project=self.workspace_slug,
)
except Exception as e:
get_logger().exception(f"Failed to delete comment, error: {e}")
def edit_comment(self, comment, body: str):
try:
self.azure_devops_client.update_comment(

View File

@ -208,9 +208,6 @@ class GitProvider(ABC):
def get_comment_url(self, comment) -> str:
return ""
def delete_comment(self, comment):
comment.delete()
#### labels operations ####
@abstractmethod
def publish_labels(self, labels):

View File

@ -452,8 +452,8 @@ class GithubProvider(GitProvider):
def edit_comment_from_comment_id(self, comment_id: int, body: str):
try:
body = self.limit_output_characters(body, self.max_comment_chars)
# self.pr.get_issue_comment(comment_id).edit(body)
body = self.limit_output_characters(body, self.max_comment_chars)
headers, data_patch = self.pr._requester.requestJsonAndCheck(
"PATCH", f"{self.base_url}/repos/{self.repo}/issues/comments/{comment_id}",
input={"body": body}
@ -463,8 +463,8 @@ class GithubProvider(GitProvider):
def reply_to_comment_from_comment_id(self, comment_id: int, body: str):
try:
body = self.limit_output_characters(body, self.max_comment_chars)
# self.pr.get_issue_comment(comment_id).edit(body)
body = self.limit_output_characters(body, self.max_comment_chars)
headers, data_patch = self.pr._requester.requestJsonAndCheck(
"POST", f"{self.base_url}/repos/{self.repo}/pulls/{self.pr_num}/comments/{comment_id}/replies",
input={"body": body}
@ -490,6 +490,7 @@ class GithubProvider(GitProvider):
)
for comment in file_comments:
comment['commit_id'] = self.last_commit_id.sha
comment['body'] = self.limit_output_characters(comment['body'], self.max_comment_chars)
found = False
for existing_comment in existing_comments:
@ -592,7 +593,7 @@ class GithubProvider(GitProvider):
)
return data_patch.get("id", None)
except Exception as e:
get_logger().exception(f"Failed to add eyes reaction, error: {e}")
get_logger().warning(f"Failed to add eyes reaction, error: {e}")
return None
def remove_reaction(self, issue_comment_id: int, reaction_id: str) -> bool:
@ -829,8 +830,11 @@ class GithubProvider(GitProvider):
"""
line_start = component_range.line_start + 1
line_end = component_range.line_end + 1
# link = (f"https://github.com/{self.repo}/blob/{self.last_commit_id.sha}/{filepath}/"
# f"#L{line_start}-L{line_end}")
link = (f"{self.base_url_html}/{self.repo}/blob/{self.last_commit_id.sha}/{filepath}/"
f"#L{line_start}-L{line_end}")
return link
def get_pr_id(self):

View File

@ -1,4 +1,5 @@
import asyncio
import traceback
from datetime import datetime, timezone
import aiohttp
@ -35,6 +36,7 @@ async def polling_loop():
user_id = git_provider.get_user_id()
agent = PRAgent()
get_settings().set("CONFIG.PUBLISH_OUTPUT_PROGRESS", False)
get_settings().set("pr_description.publish_description_as_comment", True)
try:
deployment_type = get_settings().github.deployment_type
@ -92,7 +94,8 @@ async def polling_loop():
comment_body = comment['body'] if 'body' in comment else ''
commenter_github_user = comment['user']['login'] \
if 'user' in comment else ''
get_logger().info(f"Commenter: {commenter_github_user}\nComment: {comment_body}")
get_logger().info(f"Polling, pr_url: {pr_url}",
artifact={"comment": comment_body})
user_tag = "@" + user_id
if user_tag not in comment_body:
continue
@ -100,7 +103,8 @@ async def polling_loop():
comment_id = comment['id']
git_provider.set_pr(pr_url)
success = await agent.handle_request(pr_url, rest_of_comment,
notify=lambda: git_provider.add_eyes_reaction(comment_id)) # noqa E501
notify=lambda: git_provider.add_eyes_reaction(
comment_id)) # noqa E501
if not success:
git_provider.set_pr(pr_url)
@ -108,7 +112,8 @@ async def polling_loop():
print(f"Failed to fetch notifications. Status code: {response.status}")
except Exception as e:
get_logger().error(f"Exception during processing of a notification: {e}")
get_logger().error(f"Polling exception during processing of a notification: {e}",
artifact={"traceback": traceback.format_exc()})
if __name__ == '__main__':

View File

@ -52,6 +52,7 @@ class PRCodeSuggestions:
self.ai_handler.main_pr_language = self.main_language
self.patches_diff = None
self.prediction = None
self.pr_url = pr_url
self.cli_mode = cli_mode
self.vars = {
"title": self.git_provider.pr.title,
@ -81,6 +82,10 @@ class PRCodeSuggestions:
async def run(self):
try:
if not self.git_provider.get_files():
get_logger().info(f"PR has no files: {self.pr_url}, skipping code suggestions")
return None
get_logger().info('Generating code suggestions for PR...')
relevant_configs = {'pr_code_suggestions': dict(get_settings().pr_code_suggestions),
'config': dict(get_settings().config)}
@ -159,6 +164,8 @@ class PRCodeSuggestions:
self.push_inline_code_suggestions(data)
if self.progress_response:
self.progress_response.delete()
else:
get_logger().info('Code suggestions generated for PR, but not published since publish_output is False.')
except Exception as e:
get_logger().error(f"Failed to generate code suggestions for PR, error: {e}")
if self.progress_response:
@ -177,6 +184,7 @@ class PRCodeSuggestions:
final_update_message=True,
max_previous_comments=4,
progress_response=None):
if isinstance(self.git_provider, AzureDevopsProvider): # get_latest_commit_url is not supported yet
if progress_response:
self.git_provider.edit_comment(progress_response, pr_comment)
@ -256,7 +264,7 @@ class PRCodeSuggestions:
get_logger().info(f"Persistent mode - updating comment {comment_url} to latest {name} message")
if progress_response: # publish to 'progress_response' comment, because it refreshes immediately
self.git_provider.edit_comment(progress_response, pr_comment_updated)
self.git_provider.delete_comment(comment)
self.git_provider.remove_comment(comment)
else:
self.git_provider.edit_comment(comment, pr_comment_updated)
return
@ -361,12 +369,14 @@ class PRCodeSuggestions:
one_sentence_summary_list = []
for i, suggestion in enumerate(data['code_suggestions']):
try:
needed_keys = ['one_sentence_summary', 'label', 'relevant_file', 'relevant_lines_start', 'relevant_lines_end']
needed_keys = ['one_sentence_summary', 'label', 'relevant_file', 'relevant_lines_start',
'relevant_lines_end']
is_valid_keys = True
for key in needed_keys:
if key not in suggestion:
is_valid_keys = False
get_logger().debug(f"Skipping suggestion {i + 1}, because it does not contain '{key}':\n'{suggestion}")
get_logger().debug(
f"Skipping suggestion {i + 1}, because it does not contain '{key}':\n'{suggestion}")
break
if not is_valid_keys:
continue
@ -529,7 +539,7 @@ class PRCodeSuggestions:
get_logger().error(f"Error getting PR diff for suggestion {i} in call {j}, error: {e}")
self.data = data
else:
get_logger().error(f"Error getting PR diff")
get_logger().warning(f"Empty PR diff list")
self.data = data = None
return data

View File

@ -508,7 +508,8 @@ extra_file_yaml =
def _prepare_file_labels(self):
file_label_dict = {}
if not self.data or 'pr_files' not in self.data:
if (not self.data or not isinstance(self.data, dict) or
'pr_files' not in self.data or not self.data['pr_files']):
return file_label_dict
for file in self.data['pr_files']:
try:

View File

@ -96,6 +96,10 @@ class PRReviewer:
async def run(self) -> None:
try:
if not self.git_provider.get_files():
get_logger().info(f"PR has no files: {self.pr_url}, skipping review")
return None
if self.incremental.is_incremental and not self._can_run_incremental_review():
return None
@ -158,7 +162,7 @@ class PRReviewer:
get_logger().debug(f"PR diff", diff=self.patches_diff)
self.prediction = await self._get_prediction(model)
else:
get_logger().error(f"Error getting PR diff")
get_logger().warning(f"Empty diff for PR: {self.pr_url}")
self.prediction = None
async def _get_prediction(self, model: str) -> str: