From 9c8bc6c86a43f9e49ea9a4db4af2f9bea9893e58 Mon Sep 17 00:00:00 2001 From: mrT23 Date: Sun, 9 Jun 2024 14:29:32 +0300 Subject: [PATCH 1/5] Update PR review prompts and terminology for clarity and consistency --- pr_agent/algo/utils.py | 9 +++++---- pr_agent/git_providers/github_provider.py | 4 ++-- pr_agent/settings/configuration.toml | 2 +- pr_agent/settings/pr_reviewer_prompts.toml | 8 ++++---- pr_agent/tools/pr_reviewer.py | 11 ++++++++--- tests/unittest/test_convert_to_markdown.py | 2 +- 6 files changed, 21 insertions(+), 15 deletions(-) diff --git a/pr_agent/algo/utils.py b/pr_agent/algo/utils.py index 8c6bf673..7162c1ae 100644 --- a/pr_agent/algo/utils.py +++ b/pr_agent/algo/utils.py @@ -39,7 +39,7 @@ def emphasize_header(text: str) -> str: # Splitting the string and wrapping the first part in tags if colon_position != -1: # Everything before the colon (inclusive) is wrapped in tags - transformed_string = "" + text[:colon_position + 1] + "" + text[colon_position + 1:] + transformed_string = "" + text[:colon_position + 1] + "" +'
' + text[colon_position + 1:] else: # If there's no ": ", return the original string transformed_string = text @@ -74,6 +74,7 @@ def convert_to_markdown(output_data: dict, gfm_supported: bool = True, increment emojis = { "Can be split": "๐Ÿ”€", "Possible issues": "โšก", + "Key issues to review": "โšก", "Score": "๐Ÿ…", "Relevant tests": "๐Ÿงช", "Focused PR": "โœจ", @@ -85,9 +86,9 @@ def convert_to_markdown(output_data: dict, gfm_supported: bool = True, increment } markdown_text = "" if not incremental_review: - markdown_text += f"## PR Review ๐Ÿ”\n\n" + markdown_text += f"## PR Reviewer Guide ๐Ÿ”\n\n" else: - markdown_text += f"## Incremental PR Review ๐Ÿ”\n\n" + markdown_text += f"## Incremental PR Reviewer Guide ๐Ÿ”\n\n" markdown_text += f"โฎ๏ธ Review for commits since previous PR-Agent review {incremental_review}.\n\n" if gfm_supported: markdown_text += "\n\n" @@ -110,7 +111,7 @@ def convert_to_markdown(output_data: dict, gfm_supported: bool = True, increment markdown_text += f"\n" elif 'can be split' in key_nice.lower(): markdown_text += process_can_be_split(emoji, value) - elif 'possible issues' in key_nice.lower(): + elif 'key issues to review' in key_nice.lower(): value = value.strip() issues = value.split('\n- ') for i, _ in enumerate(issues): diff --git a/pr_agent/git_providers/github_provider.py b/pr_agent/git_providers/github_provider.py index 99b8521b..f2be54a3 100644 --- a/pr_agent/git_providers/github_provider.py +++ b/pr_agent/git_providers/github_provider.py @@ -92,9 +92,9 @@ class GithubProvider(GitProvider): self.comments = list(self.pr.get_issue_comments()) prefixes = [] if full: - prefixes.append("## PR Review") + prefixes.append("## PR Reviewer Guide") if incremental: - prefixes.append("## Incremental PR Review") + prefixes.append("## Incremental PR Reviewer Guide") for index in range(len(self.comments) - 1, -1, -1): if any(self.comments[index].body.startswith(prefix) for prefix in prefixes): return self.comments[index] diff --git a/pr_agent/settings/configuration.toml b/pr_agent/settings/configuration.toml index 5051ee06..0fa85013 100644 --- a/pr_agent/settings/configuration.toml +++ b/pr_agent/settings/configuration.toml @@ -33,7 +33,7 @@ require_security_review=true require_soc2_ticket=false soc2_ticket_prompt="Does the PR description include a link to ticket in a project management system (e.g., Jira, Asana, Trello, etc.) ?" # general options -num_code_suggestions=4 +num_code_suggestions=0 inline_code_comments = false ask_and_reflect=false #automatic_review=true diff --git a/pr_agent/settings/pr_reviewer_prompts.toml b/pr_agent/settings/pr_reviewer_prompts.toml index d7d06f41..9f4d73f1 100644 --- a/pr_agent/settings/pr_reviewer_prompts.toml +++ b/pr_agent/settings/pr_reviewer_prompts.toml @@ -57,7 +57,7 @@ class SubPR(BaseModel): class Review(BaseModel): {%- if require_estimate_effort_to_review %} - estimated_effort_to_review_[1-5]: str = Field(description="Estimate, on a scale of 1-5 (inclusive), the time and effort required to review this PR by an experienced and knowledgeable developer. 1 means short and easy review , 5 means long and hard review. Take into account the size, complexity, quality, and the needed changes of the PR code diff. Explain your answer in a short and concise manner.") + estimated_effort_to_review_[1-5]: int = Field(description="Estimate, on a scale of 1-5 (inclusive), the time and effort required to review this PR by an experienced and knowledgeable developer. 1 means short and easy review , 5 means long and hard review. Take into account the size, complexity, quality, and the needed changes of the PR code diff.") {%- endif %} {%- if require_score %} score: str = Field(description="Rate this PR on a scale of 0-100 (inclusive), where 0 means the worst possible PR code, and 100 means PR code of the highest quality, without any bugs or performance issues, that is ready to be merged immediately and run in production at scale.") @@ -68,7 +68,7 @@ class Review(BaseModel): {%- if question_str %} insights_from_user_answers: str = Field(description="shortly summarize the insights you gained from the user's answers to the questions") {%- endif %} - possible_issues: str = Field(description="Does this PR code introduce clear issues, bugs, or major performance concerns? If there are no apparent issues, respond with 'No'. If there are any issues, describe them briefly. Use bullet points if more than one issue. Be specific, and provide examples if possible. Start each bullet point with a short specific header, such as: "- Possible Bug: ...", etc.") + key_issues_to_review: str = Field(description="Does this PR code introduce issues, bugs, or major performance concerns, which the PR reviewer should further investigate ? If there are no apparent issues, respond with 'No'. If there are any issues, describe them briefly. Use bullet points if more than one issue. Be specific, and provide examples if possible. Start each bullet point with a short specific header, such as: "- Possible Bug: ...", etc.") {%- if require_security_review %} security_concerns: str = Field(description="does this PR code introduce possible vulnerabilities such as exposure of sensitive information (e.g., API keys, secrets, passwords), or security concerns like SQL injection, XSS, CSRF, and others ? Answer 'No' if there are no possible issues. If there are security concerns or issues, start your answer with a short header, such as: 'Sensitive information exposure: ...', 'SQL injection: ...' etc. Explain your answer. Be specific and give examples if possible") {%- endif %} @@ -101,14 +101,14 @@ Example output: review: {%- if require_estimate_effort_to_review %} estimated_effort_to_review_[1-5]: | - 3, because ... + 3 {%- endif %} {%- if require_score %} score: 89 {%- endif %} relevant_tests: | No - possible_issues: | + key_issues_to_review: | No security_concerns: | No diff --git a/pr_agent/tools/pr_reviewer.py b/pr_agent/tools/pr_reviewer.py index baa0ccc4..68267232 100644 --- a/pr_agent/tools/pr_reviewer.py +++ b/pr_agent/tools/pr_reviewer.py @@ -140,7 +140,7 @@ class PRReviewer: if get_settings().pr_reviewer.persistent_comment and not self.incremental.is_incremental: final_update_message = get_settings().pr_reviewer.final_update_message self.git_provider.publish_persistent_comment(pr_review, - initial_header="## PR Review ๐Ÿ”", + initial_header="## PR Reviewer Guide ๐Ÿ”", update_header=True, final_update_message=final_update_message, ) else: @@ -193,10 +193,15 @@ class PRReviewer: the feedback. """ data = load_yaml(self.prediction.strip(), - keys_fix_yaml=["estimated_effort_to_review_[1-5]:", "security_concerns:", "possible_issues:", + keys_fix_yaml=["estimated_effort_to_review_[1-5]:", "security_concerns:", "key_issues_to_review:", "relevant_file:", "relevant_line:", "suggestion:"]) github_action_output(data, 'review') + # move data['review'] 'key_issues_to_review' key to the end of the dictionary + if 'key_issues_to_review' in data['review']: + key_issues_to_review = data['review'].pop('key_issues_to_review') + data['review']['key_issues_to_review'] = key_issues_to_review + if 'code_feedback' in data: code_feedback = data['code_feedback'] @@ -260,7 +265,7 @@ class PRReviewer: return data = load_yaml(self.prediction.strip(), - keys_fix_yaml=["estimated_effort_to_review_[1-5]:", "security_concerns:", "possible_issues:", + keys_fix_yaml=["estimated_effort_to_review_[1-5]:", "security_concerns:", "key_issues_to_review:", "relevant_file:", "relevant_line:", "suggestion:"]) comments: List[str] = [] for suggestion in data.get('code_feedback', []): diff --git a/tests/unittest/test_convert_to_markdown.py b/tests/unittest/test_convert_to_markdown.py index 676d0eea..3b0ce3ea 100644 --- a/tests/unittest/test_convert_to_markdown.py +++ b/tests/unittest/test_convert_to_markdown.py @@ -52,7 +52,7 @@ class TestConvertToMarkdown: 'suggestion': "Consider raising an exception or logging a warning when 'pr_url' attribute is not found. This can help in debugging issues related to the absence of 'pr_url' in instances where it's expected. [important]\n", 'relevant_line': '[return ""](https://github.com/Codium-ai/pr-agent-pro/pull/102/files#diff-52d45f12b836f77ed1aef86e972e65404634ea4e2a6083fb71a9b0f9bb9e062fR199)'}]} - expected_output = '## PR Review ๐Ÿ”\n\n
{emoji} {key_nice}\n\n{value}\n\n
\n\n\n\n\n\n
โฑ๏ธ Estimated effort to review [1-5]\n\n1, because the changes are minimal and straightforward, focusing on a single functionality addition.\n\n\n
๐Ÿงช Relevant tests\n\nNo\n\n\n
โšก Possible issues\n\nNo\n\n
๐Ÿ”’ Security concerns\n\nNo\n\n
\n\n\n
Code feedback:\n\n
relevant filepr_agent/git_providers/git_provider.py\n
suggestion      \n\n\n\nConsider raising an exception or logging a warning when \'pr_url\' attribute is not found. This can help in debugging issues related to the absence of \'pr_url\' in instances where it\'s expected. [important]\n\n\n
relevant linereturn ""

\n\n
' + expected_output = '## PR Reviewer Guide ๐Ÿ”\n\n\n\n\n\n\n\n
โฑ๏ธ Estimated effort to review [1-5]\n\n1, because the changes are minimal and straightforward, focusing on a single functionality addition.\n\n\n
๐Ÿงช Relevant tests\n\nNo\n\n\n
โšก Possible issues\n\nNo\n\n
๐Ÿ”’ Security concerns\n\nNo\n\n
\n\n\n
Code feedback:\n\n
relevant filepr_agent/git_providers/git_provider.py\n
suggestion      \n\n\n\nConsider raising an exception or logging a warning when \'pr_url\' attribute is not found. This can help in debugging issues related to the absence of \'pr_url\' in instances where it\'s expected. [important]\n\n\n
relevant linereturn ""

\n\n
' assert convert_to_markdown(input_data).strip() == expected_output.strip() From e5f269040e3b8288297518b7776c39a08f8e37f9 Mon Sep 17 00:00:00 2001 From: mrT23 Date: Sun, 9 Jun 2024 14:32:50 +0300 Subject: [PATCH 2/5] Update PR review prompts and terminology for clarity and consistency --- tests/unittest/test_convert_to_markdown.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unittest/test_convert_to_markdown.py b/tests/unittest/test_convert_to_markdown.py index 3b0ce3ea..e4918beb 100644 --- a/tests/unittest/test_convert_to_markdown.py +++ b/tests/unittest/test_convert_to_markdown.py @@ -52,7 +52,7 @@ class TestConvertToMarkdown: 'suggestion': "Consider raising an exception or logging a warning when 'pr_url' attribute is not found. This can help in debugging issues related to the absence of 'pr_url' in instances where it's expected. [important]\n", 'relevant_line': '[return ""](https://github.com/Codium-ai/pr-agent-pro/pull/102/files#diff-52d45f12b836f77ed1aef86e972e65404634ea4e2a6083fb71a9b0f9bb9e062fR199)'}]} - expected_output = '## PR Reviewer Guide ๐Ÿ”\n\n\n\n\n\n\n\n
โฑ๏ธ Estimated effort to review [1-5]\n\n1, because the changes are minimal and straightforward, focusing on a single functionality addition.\n\n\n
๐Ÿงช Relevant tests\n\nNo\n\n\n
โšก Possible issues\n\nNo\n\n
๐Ÿ”’ Security concerns\n\nNo\n\n
\n\n\n
Code feedback:\n\n
relevant filepr_agent/git_providers/git_provider.py\n
suggestion      \n\n\n\nConsider raising an exception or logging a warning when \'pr_url\' attribute is not found. This can help in debugging issues related to the absence of \'pr_url\' in instances where it\'s expected. [important]\n\n\n
relevant linereturn ""

\n\n
' + expected_output = '## PR Reviewer Guide ๐Ÿ”\n\n\n\n\n\n\n\n
โฑ๏ธ Estimated effort to review [1-5]\n\n1, because the changes are minimal and straightforward, focusing on a single functionality addition.\n\n\n
๐Ÿงช Relevant tests\n\nNo\n\n\n
โšก Possible issues\n\nNo\n\n\n
๐Ÿ”’ Security concerns\n\nNo\n\n
\n\n\n
Code feedback:\n\n
relevant filepr_agent/git_providers/git_provider.py\n
suggestion      \n\n\n\nConsider raising an exception or logging a warning when \'pr_url\' attribute is not found. This can help in debugging issues related to the absence of \'pr_url\' in instances where it\'s expected. [important]\n\n\n
relevant linereturn ""

\n\n
' assert convert_to_markdown(input_data).strip() == expected_output.strip() From 1106dccc4f86730b76cf195f652fdc73582de75e Mon Sep 17 00:00:00 2001 From: mrT23 Date: Sun, 9 Jun 2024 14:34:51 +0300 Subject: [PATCH 3/5] Update PR review prompts and terminology for clarity and consistency --- pr_agent/settings/pr_reviewer_prompts.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pr_agent/settings/pr_reviewer_prompts.toml b/pr_agent/settings/pr_reviewer_prompts.toml index 9f4d73f1..5c717b0f 100644 --- a/pr_agent/settings/pr_reviewer_prompts.toml +++ b/pr_agent/settings/pr_reviewer_prompts.toml @@ -68,7 +68,7 @@ class Review(BaseModel): {%- if question_str %} insights_from_user_answers: str = Field(description="shortly summarize the insights you gained from the user's answers to the questions") {%- endif %} - key_issues_to_review: str = Field(description="Does this PR code introduce issues, bugs, or major performance concerns, which the PR reviewer should further investigate ? If there are no apparent issues, respond with 'No'. If there are any issues, describe them briefly. Use bullet points if more than one issue. Be specific, and provide examples if possible. Start each bullet point with a short specific header, such as: "- Possible Bug: ...", etc.") + key_issues_to_review: str = Field(description="Does this PR code introduce issues, bugs, or major performance concerns, which the PR reviewer should further investigate ? If there are no apparent issues, respond with 'None'. If there are any issues, describe them briefly. Use bullet points if more than one issue. Be specific, and provide examples if possible. Start each bullet point with a short specific header, such as: "- Possible Bug: ...", etc.") {%- if require_security_review %} security_concerns: str = Field(description="does this PR code introduce possible vulnerabilities such as exposure of sensitive information (e.g., API keys, secrets, passwords), or security concerns like SQL injection, XSS, CSRF, and others ? Answer 'No' if there are no possible issues. If there are security concerns or issues, start your answer with a short header, such as: 'Sensitive information exposure: ...', 'SQL injection: ...' etc. Explain your answer. Be specific and give examples if possible") {%- endif %} From 306fd3d064707a2b4eee78d8734a2d939306c636 Mon Sep 17 00:00:00 2001 From: mrT23 Date: Mon, 10 Jun 2024 08:13:48 +0300 Subject: [PATCH 4/5] Update PR review prompts and terminology for clarity and consistency --- docs/docs/tools/review.md | 51 +++++++++++++------- pr_agent/git_providers/bitbucket_provider.py | 2 +- pr_agent/git_providers/github_provider.py | 2 +- pr_agent/git_providers/gitlab_provider.py | 2 +- 4 files changed, 36 insertions(+), 21 deletions(-) diff --git a/docs/docs/tools/review.md b/docs/docs/tools/review.md index 3f69186e..f0a3c057 100644 --- a/docs/docs/tools/review.md +++ b/docs/docs/tools/review.md @@ -1,10 +1,13 @@ ## Overview -The `review` tool scans the PR code changes, and automatically generates a PR review. +The `review` tool scans the PR code changes, and generates a list of feedbacks about the PR, aiming to aid the reviewing process. +
The tool can be triggered automatically every time a new PR is [opened](../usage-guide/automations_and_usage.md#github-app-automatic-tools-when-a-new-pr-is-opened), or can be invoked manually by commenting on any PR: ``` /review ``` +Note that the main purpose of the `review` tool is to provide the **PR reviewer** with useful feedbacks and insights. The PR author, in contrast, may prefer to save time and focus on the output of the [improve](./improve.md) tool, which provides actionable code suggestions. + ## Example usage ### Manual triggering @@ -50,19 +53,27 @@ Note that the incremental mode is only available for GitHub. ![incremental review](https://codium.ai/images/pr_agent/incremental_review_2.png){width=512} -### PR Reflection +[//]: # (### PR Reflection) -By invoking: -``` -/reflect_and_review -``` -The tool will first ask the author questions about the PR, and will guide the review based on their answers. +[//]: # () +[//]: # (By invoking:) -![reflection questions](https://codium.ai/images/pr_agent/reflection_questions.png){width=512} +[//]: # (```) -![reflection answers](https://codium.ai/images/pr_agent/reflection_answers.png){width=512} +[//]: # (/reflect_and_review) -![reflection insights](https://codium.ai/images/pr_agent/reflection_insights.png){width=512} +[//]: # (```) + +[//]: # (The tool will first ask the author questions about the PR, and will guide the review based on their answers.) + +[//]: # () +[//]: # (![reflection questions](https://codium.ai/images/pr_agent/reflection_questions.png){width=512}) + +[//]: # () +[//]: # (![reflection answers](https://codium.ai/images/pr_agent/reflection_answers.png){width=512}) + +[//]: # () +[//]: # (![reflection insights](https://codium.ai/images/pr_agent/reflection_insights.png){width=512}) @@ -167,7 +178,7 @@ If enabled, the `review` tool can approve a PR when a specific comment, `/review !!! tip "General guidelines" - The `review` tool provides a collection of possible feedbacks about a PR. + The `review` tool provides a collection of configurable feedbacks about a PR. It is recommended to review the [Configuration options](#configuration-options) section, and choose the relevant options for your use case. Some of the features that are disabled by default are quite useful, and should be considered for enabling. For example: @@ -183,13 +194,6 @@ If enabled, the `review` tool can approve a PR when a specific comment, `/review Meaning the `review` tool will run automatically on every PR, without providing code suggestions. Edit this field to enable/disable the tool, or to change the used configurations. -!!! tip "Code suggestions" - - If you set `num_code_suggestions`>0 , the `review` tool will also provide code suggestions. - - Notice If you are interested **only** in the code suggestions, it is recommended to use the [`improve`](./improve.md) feature instead, since it is a dedicated only to code suggestions, and usually gives better results. - Use the `review` tool if you want to get more comprehensive feedback, which includes code suggestions as well. - !!! tip "Possible labels from the review tool" The `review` tool can auto-generate two specific types of labels for a PR: @@ -244,3 +248,14 @@ If enabled, the `review` tool can approve a PR when a specific comment, `/review [pr_reviewer] maximal_review_effort = 5 ``` + +[//]: # (!!! tip "Code suggestions") + +[//]: # () +[//]: # ( If you set `num_code_suggestions`>0 , the `review` tool will also provide code suggestions.) + +[//]: # ( ) +[//]: # ( Notice If you are interested **only** in the code suggestions, it is recommended to use the [`improve`](./improve.md) feature instead, since it is a dedicated only to code suggestions, and usually gives better results.) + +[//]: # ( Use the `review` tool if you want to get more comprehensive feedback, which includes code suggestions as well.) + diff --git a/pr_agent/git_providers/bitbucket_provider.py b/pr_agent/git_providers/bitbucket_provider.py index 3516516c..27a88a76 100644 --- a/pr_agent/git_providers/bitbucket_provider.py +++ b/pr_agent/git_providers/bitbucket_provider.py @@ -172,7 +172,7 @@ class BitbucketProvider(GitProvider): latest_commit_url = self.get_latest_commit_url() comment_url = self.get_comment_url(comment) if update_header: - updated_header = f"{initial_header}\n\n### ({name.capitalize()} updated until commit {latest_commit_url})\n" + updated_header = f"{initial_header}\n\n#### ({name.capitalize()} updated until commit {latest_commit_url})\n" pr_comment_updated = pr_comment.replace(initial_header, updated_header) else: pr_comment_updated = pr_comment diff --git a/pr_agent/git_providers/github_provider.py b/pr_agent/git_providers/github_provider.py index f2be54a3..36f15201 100644 --- a/pr_agent/git_providers/github_provider.py +++ b/pr_agent/git_providers/github_provider.py @@ -217,7 +217,7 @@ class GithubProvider(GitProvider): latest_commit_url = self.get_latest_commit_url() comment_url = self.get_comment_url(comment) if update_header: - updated_header = f"{initial_header}\n\n### ({name.capitalize()} updated until commit {latest_commit_url})\n" + updated_header = f"{initial_header}\n\n#### ({name.capitalize()} updated until commit {latest_commit_url})\n" pr_comment_updated = pr_comment.replace(initial_header, updated_header) else: pr_comment_updated = pr_comment diff --git a/pr_agent/git_providers/gitlab_provider.py b/pr_agent/git_providers/gitlab_provider.py index 3a2e1c85..ad18ba1d 100644 --- a/pr_agent/git_providers/gitlab_provider.py +++ b/pr_agent/git_providers/gitlab_provider.py @@ -160,7 +160,7 @@ class GitLabProvider(GitProvider): latest_commit_url = self.get_latest_commit_url() comment_url = self.get_comment_url(comment) if update_header: - updated_header = f"{initial_header}\n\n### ({name.capitalize()} updated until commit {latest_commit_url})\n" + updated_header = f"{initial_header}\n\n#### ({name.capitalize()} updated until commit {latest_commit_url})\n" pr_comment_updated = pr_comment.replace(initial_header, updated_header) else: pr_comment_updated = pr_comment From 55b52ad6b243a01ea35bd69f579b4ba362f737ac Mon Sep 17 00:00:00 2001 From: mrT23 Date: Thu, 13 Jun 2024 09:28:51 +0300 Subject: [PATCH 5/5] Add exception handling to process_can_be_split function and update pr_reviewer_prompts.toml formatting --- pr_agent/algo/utils.py | 60 ++++++++++++---------- pr_agent/settings/pr_reviewer_prompts.toml | 10 ++-- 2 files changed, 37 insertions(+), 33 deletions(-) diff --git a/pr_agent/algo/utils.py b/pr_agent/algo/utils.py index 7162c1ae..e0ea2134 100644 --- a/pr_agent/algo/utils.py +++ b/pr_agent/algo/utils.py @@ -163,34 +163,38 @@ def convert_to_markdown(output_data: dict, gfm_supported: bool = True, increment def process_can_be_split(emoji, value): - # key_nice = "Can this PR be split?" - key_nice = "Multiple PR themes" - markdown_text = "" - if not value or isinstance(value, list) and len(value) == 1: - value = "No" - markdown_text += f" {emoji} {key_nice}\n\n{value}\n\n\n" - else: - number_of_splits = len(value) - markdown_text += f" {emoji} {key_nice}\n" - for i, split in enumerate(value): - title = split.get('title', '') - relevant_files = split.get('relevant_files', []) - if i == 0: - markdown_text += f"
\nSub-PR theme: {title}\n\n" - markdown_text += f"
\n" - markdown_text += f"Relevant files:\n" - markdown_text += f"
    \n" - for file in relevant_files: - markdown_text += f"
  • {file}
  • \n" - markdown_text += f"
\n\n
\n" - else: - markdown_text += f"\n
\nSub-PR theme: {title}\n\n" - markdown_text += f"
\n" - markdown_text += f"Relevant files:\n" - markdown_text += f"
    \n" - for file in relevant_files: - markdown_text += f"
  • {file}
  • \n" - markdown_text += f"
\n\n
\n" + try: + # key_nice = "Can this PR be split?" + key_nice = "Multiple PR themes" + markdown_text = "" + if not value or isinstance(value, list) and len(value) == 1: + value = "No" + markdown_text += f" {emoji} {key_nice}\n\n{value}\n\n\n" + else: + number_of_splits = len(value) + markdown_text += f" {emoji} {key_nice}\n" + for i, split in enumerate(value): + title = split.get('title', '') + relevant_files = split.get('relevant_files', []) + if i == 0: + markdown_text += f"
\nSub-PR theme:
{title}
\n\n" + markdown_text += f"
\n" + markdown_text += f"Relevant files:\n" + markdown_text += f"
    \n" + for file in relevant_files: + markdown_text += f"
  • {file}
  • \n" + markdown_text += f"
\n\n
\n" + else: + markdown_text += f"\n
\nSub-PR theme:
{title}
\n\n" + markdown_text += f"
\n" + markdown_text += f"Relevant files:\n" + markdown_text += f"
    \n" + for file in relevant_files: + markdown_text += f"
  • {file}
  • \n" + markdown_text += f"
\n\n
\n" + except Exception as e: + get_logger().exception(f"Failed to process can be split: {e}") + return "" return markdown_text diff --git a/pr_agent/settings/pr_reviewer_prompts.toml b/pr_agent/settings/pr_reviewer_prompts.toml index 5c717b0f..cd24233a 100644 --- a/pr_agent/settings/pr_reviewer_prompts.toml +++ b/pr_agent/settings/pr_reviewer_prompts.toml @@ -113,12 +113,12 @@ review: security_concerns: | No {%- if require_can_be_split_review %} - can_be_split: | - - relevant_files: - - ... - - ... - title: ... + can_be_split: + - relevant_files: - ... + - ... + title: ... + - ... {%- endif %} {%- if num_code_suggestions > 0 %} code_feedback