diff --git a/pr_agent/git_providers/bitbucket_provider.py b/pr_agent/git_providers/bitbucket_provider.py index a29e25bef..fde2cbcee 100644 --- a/pr_agent/git_providers/bitbucket_provider.py +++ b/pr_agent/git_providers/bitbucket_provider.py @@ -30,6 +30,7 @@ def __init__( s.headers["Content-Type"] = "application/json" self.headers = s.headers self.bitbucket_client = Cloud(session=s) + self.max_comment_length = 31000 self.workspace_slug = None self.repo_slug = None self.repo = None @@ -211,6 +212,7 @@ def publish_persistent_comment(self, pr_comment: str, self.publish_comment(pr_comment) def publish_comment(self, pr_comment: str, is_temporary: bool = False): + pr_comment = self.limit_output_characters(pr_comment, self.max_comment_length) comment = self.pr.comment(pr_comment) if is_temporary: self.temp_comments.append(comment["id"]) @@ -218,6 +220,7 @@ def publish_comment(self, pr_comment: str, is_temporary: bool = False): def edit_comment(self, comment, body: str): try: + body = self.limit_output_characters(body, self.max_comment_length) comment.update(body) except Exception as e: get_logger().exception(f"Failed to update comment, error: {e}") @@ -237,6 +240,7 @@ def remove_comment(self, comment): # function to create_inline_comment def create_inline_comment(self, body: str, relevant_file: str, relevant_line_in_file: str, absolute_position: int = None): + body = self.limit_output_characters(body, self.max_comment_length) position, absolute_position = find_line_number_of_relevant_line_in_file(self.get_diff_files(), relevant_file.strip('`'), relevant_line_in_file, absolute_position) @@ -251,6 +255,7 @@ def create_inline_comment(self, body: str, relevant_file: str, relevant_line_in_ def publish_inline_comment(self, comment: str, from_line: int, file: str): + comment = self.limit_output_characters(comment, self.max_comment_length) payload = json.dumps( { "content": { "raw": comment, diff --git a/pr_agent/git_providers/git_provider.py b/pr_agent/git_providers/git_provider.py index 2e514ac89..6a0d1b694 100644 --- a/pr_agent/git_providers/git_provider.py +++ b/pr_agent/git_providers/git_provider.py @@ -256,6 +256,9 @@ def get_num_of_files(self): except Exception as e: return -1 + def limit_output_characters(self, output: str, max_chars: int): + return output[:max_chars] + '...' if len(output) > max_chars else output + def get_main_pr_language(languages, files) -> str: """ @@ -326,6 +329,8 @@ def get_main_pr_language(languages, files) -> str: return main_language_str + + class IncrementalPR: def __init__(self, is_incremental: bool = False): self.is_incremental = is_incremental diff --git a/pr_agent/git_providers/github_provider.py b/pr_agent/git_providers/github_provider.py index e97f93398..e4cc20203 100644 --- a/pr_agent/git_providers/github_provider.py +++ b/pr_agent/git_providers/github_provider.py @@ -26,6 +26,7 @@ def __init__(self, pr_url: Optional[str] = None): self.installation_id = context.get("installation_id", None) except Exception: self.installation_id = None + self.max_comment_chars = 65000 self.base_url = get_settings().get("GITHUB.BASE_URL", "https://api.github.com").rstrip("/") self.base_url_html = self.base_url.split("api/")[0].rstrip("/") if "api/" in self.base_url else "https://github.com" self.github_client = self._get_github_client() @@ -254,7 +255,7 @@ def publish_comment(self, pr_comment: str, is_temporary: bool = False): if is_temporary and not get_settings().config.publish_output_progress: get_logger().debug(f"Skipping publish_comment for temporary comment: {pr_comment}") return - + pr_comment = self.limit_output_characters(pr_comment, self.max_comment_chars) response = self.pr.create_issue_comment(pr_comment) if hasattr(response, "user") and hasattr(response.user, "login"): self.github_user_id = response.user.login @@ -265,11 +266,13 @@ def publish_comment(self, pr_comment: str, is_temporary: bool = False): return response def publish_inline_comment(self, body: str, relevant_file: str, relevant_line_in_file: str): + body = self.limit_output_characters(body, self.max_comment_chars) self.publish_inline_comments([self.create_inline_comment(body, relevant_file, relevant_line_in_file)]) def create_inline_comment(self, body: str, relevant_file: str, relevant_line_in_file: str, absolute_position: int = None): + body = self.limit_output_characters(body, self.max_comment_chars) position, absolute_position = find_line_number_of_relevant_line_in_file(self.diff_files, relevant_file.strip('`'), relevant_line_in_file, @@ -442,10 +445,12 @@ def publish_code_suggestions(self, code_suggestions: list) -> bool: return False def edit_comment(self, comment, body: str): + body = self.limit_output_characters(body, self.max_comment_chars) comment.edit(body=body) 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) headers, data_patch = self.pr._requester.requestJsonAndCheck( "PATCH", f"{self.base_url}/repos/{self.repo}/issues/comments/{comment_id}", @@ -456,6 +461,7 @@ def edit_comment_from_comment_id(self, comment_id: int, body: str): 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) headers, data_patch = self.pr._requester.requestJsonAndCheck( "POST", f"{self.base_url}/repos/{self.repo}/pulls/{self.pr_num}/comments/{comment_id}/replies", diff --git a/pr_agent/git_providers/gitlab_provider.py b/pr_agent/git_providers/gitlab_provider.py index d414f9d31..dee263494 100644 --- a/pr_agent/git_providers/gitlab_provider.py +++ b/pr_agent/git_providers/gitlab_provider.py @@ -33,6 +33,7 @@ def __init__(self, merge_request_url: Optional[str] = None, incremental: Optiona url=gitlab_url, oauth_token=gitlab_access_token ) + self.max_comment_chars = 65000 self.id_project = None self.id_mr = None self.mr = None @@ -188,24 +189,29 @@ def publish_persistent_comment(self, pr_comment: str, self.publish_persistent_comment_full(pr_comment, initial_header, update_header, name, final_update_message) def publish_comment(self, mr_comment: str, is_temporary: bool = False): + mr_comment = self.limit_output_characters(mr_comment, self.max_comment_chars) comment = self.mr.notes.create({'body': mr_comment}) if is_temporary: self.temp_comments.append(comment) return comment def edit_comment(self, comment, body: str): + body = self.limit_output_characters(body, self.max_comment_chars) self.mr.notes.update(comment.id,{'body': body} ) def edit_comment_from_comment_id(self, comment_id: int, body: str): + body = self.limit_output_characters(body, self.max_comment_chars) comment = self.mr.notes.get(comment_id) comment.body = body comment.save() def reply_to_comment_from_comment_id(self, comment_id: int, body: str): + body = self.limit_output_characters(body, self.max_comment_chars) discussion = self.mr.discussions.get(comment_id) discussion.notes.create({'body': body}) def publish_inline_comment(self, body: str, relevant_file: str, relevant_line_in_file: str): + body = self.limit_output_characters(body, self.max_comment_chars) edit_type, found, source_line_no, target_file, target_line_no = self.search_line(relevant_file, relevant_line_in_file) self.send_inline_comment(body, edit_type, found, relevant_file, relevant_line_in_file, source_line_no,