From b2d8dee00a2201c404aee21947bb86d2c598cebc Mon Sep 17 00:00:00 2001 From: ofir-frd Date: Fri, 21 Feb 2025 10:38:18 +0200 Subject: [PATCH 1/8] docs: improve formatting and readability of documentation --- docs/docs/core-abilities/metadata.md | 8 ++++---- docs/docs/tools/analyze.md | 5 ++--- docs/docs/tools/ask.md | 8 ++++---- docs/docs/tools/custom_prompt.md | 6 +++--- docs/docs/tools/describe.md | 2 +- docs/docs/tools/documentation.md | 7 +++---- docs/docs/tools/implement.md | 8 +++++--- docs/docs/tools/improve.md | 16 ++++++---------- docs/docs/tools/improve_component.md | 6 +++--- docs/docs/tools/similar_issues.md | 9 ++++++--- docs/docs/tools/test.md | 6 +++--- docs/docs/usage-guide/automations_and_usage.md | 11 ++++------- docs/docs/usage-guide/changing_a_model.md | 8 ++++---- 13 files changed, 48 insertions(+), 52 deletions(-) diff --git a/docs/docs/core-abilities/metadata.md b/docs/docs/core-abilities/metadata.md index c1eb04c0..b886929e 100644 --- a/docs/docs/core-abilities/metadata.md +++ b/docs/docs/core-abilities/metadata.md @@ -1,5 +1,5 @@ ## Local and global metadata injection with multi-stage analysis -(1) +1\. Qodo Merge initially retrieves for each PR the following data: - PR title and branch name @@ -11,7 +11,7 @@ Qodo Merge initially retrieves for each PR the following data: !!! tip "Tip: Organization-level metadata" In addition to the inputs above, Qodo Merge can incorporate supplementary preferences provided by the user, like [`extra_instructions` and `organization best practices`](https://qodo-merge-docs.qodo.ai/tools/improve/#extra-instructions-and-best-practices). This information can be used to enhance the PR analysis. -(2) +2\. By default, the first command that Qodo Merge executes is [`describe`](https://qodo-merge-docs.qodo.ai/tools/describe/), which generates three types of outputs: - PR Type (e.g. bug fix, feature, refactor, etc) @@ -49,8 +49,8 @@ __old hunk__ ... ``` -(3) The entire PR files that were retrieved are also used to expand and enhance the PR context (see [Dynamic Context](https://qodo-merge-docs.qodo.ai/core-abilities/dynamic_context/)). +3\. The entire PR files that were retrieved are also used to expand and enhance the PR context (see [Dynamic Context](https://qodo-merge-docs.qodo.ai/core-abilities/dynamic_context/)). -(4) All the metadata described above represents several level of cumulative analysis - ranging from hunk level, to file level, to PR level, to organization level. +4\. All the metadata described above represents several level of cumulative analysis - ranging from hunk level, to file level, to PR level, to organization level. This comprehensive approach enables Qodo Merge AI models to generate more precise and contextually relevant suggestions and feedback. diff --git a/docs/docs/tools/analyze.md b/docs/docs/tools/analyze.md index c23d4418..189c20af 100644 --- a/docs/docs/tools/analyze.md +++ b/docs/docs/tools/analyze.md @@ -14,6 +14,5 @@ An example result: ![Analyze 1](https://codium.ai/images/pr_agent/analyze_1.png){width=750} -**Notes** - -- Language that are currently supported: Python, Java, C++, JavaScript, TypeScript, C#. +!!! note "Language that are currently supported:" + Python, Java, C++, JavaScript, TypeScript, C#. diff --git a/docs/docs/tools/ask.md b/docs/docs/tools/ask.md index d29d0319..7a5dad6f 100644 --- a/docs/docs/tools/ask.md +++ b/docs/docs/tools/ask.md @@ -38,20 +38,20 @@ where `https://real_link_to_image` is the direct link to the image. Note that GitHub has a built-in mechanism of pasting images in comments. However, pasted image does not provide a direct link. To get a direct link to an image, we recommend using the following scheme: -1) First, post a comment that contains **only** the image: +1\. First, post a comment that contains **only** the image: ![Ask image1](https://codium.ai/images/pr_agent/ask_images1.png){width=512} -2) Quote reply to that comment: +2\. Quote reply to that comment: ![Ask image2](https://codium.ai/images/pr_agent/ask_images2.png){width=512} -3) In the screen opened, type the question below the image: +3\. In the screen opened, type the question below the image: ![Ask image3](https://codium.ai/images/pr_agent/ask_images3.png){width=512} ![Ask image4](https://codium.ai/images/pr_agent/ask_images4.png){width=512} -4) Post the comment, and receive the answer: +4\. Post the comment, and receive the answer: ![Ask image5](https://codium.ai/images/pr_agent/ask_images5.png){width=512} diff --git a/docs/docs/tools/custom_prompt.md b/docs/docs/tools/custom_prompt.md index 9ec01fd9..7b31a5a5 100644 --- a/docs/docs/tools/custom_prompt.md +++ b/docs/docs/tools/custom_prompt.md @@ -51,8 +51,8 @@ Results obtained with the prompt above: ## Configuration options -`prompt`: the prompt for the tool. It should be a multi-line string. +- `prompt`: the prompt for the tool. It should be a multi-line string. -`num_code_suggestions_per_chunk`: number of code suggestions provided by the 'custom_prompt' tool, per chunk. Default is 4. +- `num_code_suggestions_per_chunk`: number of code suggestions provided by the 'custom_prompt' tool, per chunk. Default is 4. -`enable_help_text`: if set to true, the tool will display a help text in the comment. Default is true. +- `enable_help_text`: if set to true, the tool will display a help text in the comment. Default is true. diff --git a/docs/docs/tools/describe.md b/docs/docs/tools/describe.md index 6e8515b0..d77a645e 100644 --- a/docs/docs/tools/describe.md +++ b/docs/docs/tools/describe.md @@ -143,7 +143,7 @@ The marker `pr_agent:type` will be replaced with the PR type, `pr_agent:summary` ![Describe markers before](https://codium.ai/images/pr_agent/describe_markers_before.png){width=512} -→ +becomes ![Describe markers after](https://codium.ai/images/pr_agent/describe_markers_after.png){width=512} diff --git a/docs/docs/tools/documentation.md b/docs/docs/tools/documentation.md index 12832b8d..1c1e328d 100644 --- a/docs/docs/tools/documentation.md +++ b/docs/docs/tools/documentation.md @@ -27,7 +27,6 @@ You can state a name of a specific component in the PR to get documentation only - `docs_style`: The exact style of the documentation (for python docstring). you can choose between: `google`, `numpy`, `sphinx`, `restructuredtext`, `plain`. Default is `sphinx`. - `extra_instructions`: Optional extra instructions to the tool. For example: "focus on the changes in the file X. Ignore change in ...". -**Notes** - -- Language that are currently fully supported: Python, Java, C++, JavaScript, TypeScript, C#. -- This tool can also be triggered interactively by using the [`analyze`](./analyze.md) tool. +!!! notes "Notes" + - The following languages are currently supported: Python, Java, C++, JavaScript, TypeScript, C#. + - This tool can also be triggered interactively by using the [`analyze`](./analyze.md) tool. diff --git a/docs/docs/tools/implement.md b/docs/docs/tools/implement.md index 3ee1b94b..36843dac 100644 --- a/docs/docs/tools/implement.md +++ b/docs/docs/tools/implement.md @@ -10,8 +10,9 @@ It leverages LLM technology to transform PR comments and review suggestions into ### For Reviewers -Reviewers can request code changes by:
-1. Selecting the code block to be modified.
+Reviewers can request code changes by: + +1. Selecting the code block to be modified. 2. Adding a comment with the syntax: ``` /implement @@ -46,7 +47,8 @@ You can reference and implement changes from any comment by: Note that the implementation will occur within the review discussion thread. -**Configuration options**
+**Configuration options** + - Use `/implement` to implement code change within and based on the review discussion.
- Use `/implement ` inside a review discussion to implement specific instructions.
- Use `/implement ` to indirectly call the tool from any comment.
diff --git a/docs/docs/tools/improve.md b/docs/docs/tools/improve.md index b00ea66c..1f9a7b6d 100644 --- a/docs/docs/tools/improve.md +++ b/docs/docs/tools/improve.md @@ -9,9 +9,9 @@ The tool can be triggered automatically every time a new PR is [opened](../usage ![code_suggestions_as_comment_open.png](https://codium.ai/images/pr_agent/code_suggestions_as_comment_open.png){width=512} -Note that the following features are available only for Qodo MergeπŸ’Ž users: -- The `Apply this suggestion` checkbox, which interactively converts a suggestion into a committable code comment -- The `More` checkbox to generate additional suggestions +!!! note "The following features are available only for Qodo Merge πŸ’Ž users:" + - The `Apply this suggestion` checkbox, which interactively converts a suggestion into a committable code comment + - The `More` checkbox to generate additional suggestions ## Example usage @@ -196,7 +196,7 @@ And the label will be: `{organization_name} best practice`. >`Platforms supported: GitHub` -'Auto best practices' is a novel Qodo Merge capability that: +`Auto best practices` is a novel Qodo Merge capability that: 1. Identifies recurring patterns from accepted suggestions 2. **Automatically** generates [best practices page](https://github.com/qodo-ai/pr-agent/wiki/.pr_agent_auto_best_practices) based on what your team consistently values @@ -315,17 +315,13 @@ code_suggestions_self_review_text = "... (your text here) ..." ### How many code suggestions are generated? Qodo Merge uses a dynamic strategy to generate code suggestions based on the size of the pull request (PR). Here's how it works: -1) Chunking large PRs: - +#### 1. Chunking large PRs - Qodo Merge divides large PRs into 'chunks'. - Each chunk contains up to `pr_code_suggestions.max_context_tokens` tokens (default: 14,000). - -2) Generating suggestions: - +#### 2. Generating suggestions - For each chunk, Qodo Merge generates up to `pr_code_suggestions.num_code_suggestions_per_chunk` suggestions (default: 4). - This approach has two main benefits: - Scalability: The number of suggestions scales with the PR size, rather than being fixed. diff --git a/docs/docs/tools/improve_component.md b/docs/docs/tools/improve_component.md index b3aac539..da79c65c 100644 --- a/docs/docs/tools/improve_component.md +++ b/docs/docs/tools/improve_component.md @@ -18,9 +18,9 @@ The tool will generate code suggestions for the selected component (if no compon ![improve_component2](https://codium.ai/images/pr_agent/improve_component2.png){width=768} -**Notes** -- Language that are currently supported by the tool: Python, Java, C++, JavaScript, TypeScript, C#. -- This tool can also be triggered interactively by using the [`analyze`](./analyze.md) tool. +!!! note "Notes" + - Language that are currently supported by the tool: Python, Java, C++, JavaScript, TypeScript, C#. + - This tool can also be triggered interactively by using the [`analyze`](./analyze.md) tool. ## Configuration options - `num_code_suggestions`: number of code suggestions to provide. Default is 4 diff --git a/docs/docs/tools/similar_issues.md b/docs/docs/tools/similar_issues.md index d701c1c6..c974507f 100644 --- a/docs/docs/tools/similar_issues.md +++ b/docs/docs/tools/similar_issues.md @@ -16,14 +16,17 @@ It can be invoked manually by commenting on any PR: Note that to perform retrieval, the `similar_issue` tool indexes all the repo previous issues (once). +### Selecting a Vector Database +Configure your preferred database by changing the `pr_similar_issue` parameter in `configuration.toml` file. -**Select VectorDBs** by changing `pr_similar_issue` parameter in `configuration.toml` file +#### Available Options +Choose from the following Vector Databases: -2 VectorDBs are available to switch in 1. LanceDB 2. Pinecone -To enable usage of the '**similar issue**' tool for Pinecone, you need to set the following keys in `.secrets.toml` (or in the relevant environment variables): +#### Pinecone Configuration +To use Pinecone with the `similar issue` tool, add these credentials to `.secrets.toml` (or set as environment variables): ``` [pinecone] diff --git a/docs/docs/tools/test.md b/docs/docs/tools/test.md index fa5c533e..2d5652ae 100644 --- a/docs/docs/tools/test.md +++ b/docs/docs/tools/test.md @@ -17,9 +17,9 @@ The tool will generate tests for the selected component (if no component is stat (Example taken from [here](https://github.com/Codium-ai/pr-agent/pull/598#issuecomment-1913679429)): -**Notes**
-- The following languages are currently supported: Python, Java, C++, JavaScript, TypeScript, C#.
-- This tool can also be triggered interactively by using the [`analyze`](./analyze.md) tool. +!!! notes "Notes" + - The following languages are currently supported: Python, Java, C++, JavaScript, TypeScript, C#. + - This tool can also be triggered interactively by using the [`analyze`](./analyze.md) tool. ## Configuration options diff --git a/docs/docs/usage-guide/automations_and_usage.md b/docs/docs/usage-guide/automations_and_usage.md index c38481cc..f9004109 100644 --- a/docs/docs/usage-guide/automations_and_usage.md +++ b/docs/docs/usage-guide/automations_and_usage.md @@ -14,12 +14,12 @@ Examples of invoking the different tools via the CLI: **Notes:** -(1) in addition to editing your local configuration file, you can also change any configuration value by adding it to the command line: +1. in addition to editing your local configuration file, you can also change any configuration value by adding it to the command line: ``` python -m pr_agent.cli --pr_url= /review --pr_reviewer.extra_instructions="focus on the file: ..." ``` -(2) You can print results locally, without publishing them, by setting in `configuration.toml`: +2. You can print results locally, without publishing them, by setting in `configuration.toml`: ``` [config] publish_output=false @@ -27,14 +27,11 @@ verbosity_level=2 ``` This is useful for debugging or experimenting with different tools. -(3) - -**git provider**: The [git_provider](https://github.com/Codium-ai/pr-agent/blob/main/pr_agent/settings/configuration.toml#L5) field in a configuration file determines the GIT provider that will be used by Qodo Merge. Currently, the following providers are supported: +3. **git provider**: The [git_provider](https://github.com/Codium-ai/pr-agent/blob/main/pr_agent/settings/configuration.toml#L5) field in a configuration file determines the GIT provider that will be used by Qodo Merge. Currently, the following providers are supported: ` "github", "gitlab", "bitbucket", "azure", "codecommit", "local", "gerrit" -` +`. -Default is "github". ### CLI Health Check To verify that Qodo Merge has been configured correctly, you can run this health check command from the repository root: diff --git a/docs/docs/usage-guide/changing_a_model.md b/docs/docs/usage-guide/changing_a_model.md index d221b953..c4928e19 100644 --- a/docs/docs/usage-guide/changing_a_model.md +++ b/docs/docs/usage-guide/changing_a_model.md @@ -189,18 +189,18 @@ key = ... If the relevant model doesn't appear [here](https://github.com/Codium-ai/pr-agent/blob/main/pr_agent/algo/__init__.py), you can still use it as a custom model: -(1) Set the model name in the configuration file: +1. Set the model name in the configuration file: ``` [config] model="custom_model_name" fallback_models=["custom_model_name"] ``` -(2) Set the maximal tokens for the model: +2. Set the maximal tokens for the model: ``` [config] custom_model_max_tokens= ... ``` -(3) Go to [litellm documentation](https://litellm.vercel.app/docs/proxy/quick_start#supported-llms), find the model you want to use, and set the relevant environment variables. +3. Go to [litellm documentation](https://litellm.vercel.app/docs/proxy/quick_start#supported-llms), find the model you want to use, and set the relevant environment variables. -(4) Most reasoning models do not support chat-style inputs (`system` and `user` messages) or temperature settings. +4. Most reasoning models do not support chat-style inputs (`system` and `user` messages) or temperature settings. To bypass chat templates and temperature controls, set `config.custom_reasoning_model = true` in your configuration file. From 5bace4ddc6a99ae571effcfd24b223358efeb3a4 Mon Sep 17 00:00:00 2001 From: ofir-frd Date: Fri, 21 Feb 2025 10:47:19 +0200 Subject: [PATCH 2/8] docs: final touches --- docs/docs/tools/implement.md | 6 +++--- docs/docs/usage-guide/automations_and_usage.md | 4 +--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/docs/docs/tools/implement.md b/docs/docs/tools/implement.md index 36843dac..4151fde7 100644 --- a/docs/docs/tools/implement.md +++ b/docs/docs/tools/implement.md @@ -49,6 +49,6 @@ Note that the implementation will occur within the review discussion thread. **Configuration options** -- Use `/implement` to implement code change within and based on the review discussion.
-- Use `/implement ` inside a review discussion to implement specific instructions.
-- Use `/implement ` to indirectly call the tool from any comment.
+- Use `/implement` to implement code change within and based on the review discussion. +- Use `/implement ` inside a review discussion to implement specific instructions. +- Use `/implement ` to indirectly call the tool from any comment. diff --git a/docs/docs/usage-guide/automations_and_usage.md b/docs/docs/usage-guide/automations_and_usage.md index f9004109..04e9a13f 100644 --- a/docs/docs/usage-guide/automations_and_usage.md +++ b/docs/docs/usage-guide/automations_and_usage.md @@ -28,9 +28,7 @@ verbosity_level=2 This is useful for debugging or experimenting with different tools. 3. **git provider**: The [git_provider](https://github.com/Codium-ai/pr-agent/blob/main/pr_agent/settings/configuration.toml#L5) field in a configuration file determines the GIT provider that will be used by Qodo Merge. Currently, the following providers are supported: -` -"github", "gitlab", "bitbucket", "azure", "codecommit", "local", "gerrit" -`. +`github` **(default)**, `gitlab`, `bitbucket`, `azure`, `codecommit`, `local`, and `gerrit`. ### CLI Health Check From af72b45593e3defbb77afc7de3d56509bf93d351 Mon Sep 17 00:00:00 2001 From: ofir-frd Date: Sat, 22 Feb 2025 11:01:54 +0200 Subject: [PATCH 3/8] docs: update repository URLs and name --- docs/mkdocs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 28692206..3e462fc3 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -1,6 +1,6 @@ site_name: Qodo Merge (and open-source PR-Agent) -repo_url: https://github.com/Codium-ai/pr-agent -repo_name: Codium-ai/pr-agent +repo_url: https://github.com/qodo-ai/pr-agent +repo_name: Qodo-ai/pr-agent nav: - Overview: From 01cd66f4f50bcdcc5c5cbb237f352edffd892289 Mon Sep 17 00:00:00 2001 From: mrT23 Date: Sat, 22 Feb 2025 16:06:30 +0200 Subject: [PATCH 4/8] chore: comment out test_fetching_sub_issues.py due to API calls --- tests/unittest/test_fetching_sub_issues.py | 235 +++++++++++---------- 1 file changed, 119 insertions(+), 116 deletions(-) diff --git a/tests/unittest/test_fetching_sub_issues.py b/tests/unittest/test_fetching_sub_issues.py index 48795866..43ab68f8 100644 --- a/tests/unittest/test_fetching_sub_issues.py +++ b/tests/unittest/test_fetching_sub_issues.py @@ -1,118 +1,121 @@ -import unittest -import asyncio -from unittest.mock import AsyncMock, patch -from pr_agent.tools.ticket_pr_compliance_check import extract_tickets, extract_and_cache_pr_tickets -from pr_agent.git_providers.github_provider import GithubProvider - - -class TestTicketCompliance(unittest.TestCase): - - @patch.object(GithubProvider, 'get_user_description', return_value="Fixes #1 and relates to #2") - @patch.object(GithubProvider, '_parse_issue_url', side_effect=lambda url: ("WonOfAKind/KimchiBot", int(url.split('#')[-1]))) - @patch.object(GithubProvider, 'repo_obj') - async def test_extract_tickets(self, mock_repo, mock_parse_issue_url, mock_user_desc): - """ - Test extract_tickets() to ensure it extracts tickets correctly - and fetches their content. - """ - github_provider = GithubProvider() - github_provider.repo = "WonOfAKind/KimchiBot" - github_provider.base_url_html = "https://github.com" - - # Mock issue retrieval - mock_issue = AsyncMock() - mock_issue.number = 1 - mock_issue.title = "Sample Issue" - mock_issue.body = "This is a test issue body." - mock_issue.labels = ["bug", "high priority"] - - # Mock repo object - mock_repo.get_issue.return_value = mock_issue - - tickets = await extract_tickets(github_provider) - - # Verify tickets were extracted correctly - self.assertIsInstance(tickets, list) - self.assertGreater(len(tickets), 0, "Expected at least one ticket!") - - # Verify ticket structure - first_ticket = tickets[0] - self.assertIn("ticket_id", first_ticket) - self.assertIn("ticket_url", first_ticket) - self.assertIn("title", first_ticket) - self.assertIn("body", first_ticket) - self.assertIn("labels", first_ticket) - - print("\n Test Passed: extract_tickets() successfully retrieved ticket info!") - - @patch.object(GithubProvider, 'get_user_description', return_value="Fixes #1 and relates to #2") - @patch.object(GithubProvider, '_parse_issue_url', side_effect=lambda url: ("WonOfAKind/KimchiBot", int(url.split('#')[-1]))) - @patch.object(GithubProvider, 'repo_obj') - async def test_extract_and_cache_pr_tickets(self, mock_repo, mock_parse_issue_url, mock_user_desc): - """ - Test extract_and_cache_pr_tickets() to ensure tickets are extracted and cached correctly. - """ - github_provider = GithubProvider() - github_provider.repo = "WonOfAKind/KimchiBot" - github_provider.base_url_html = "https://github.com" - - vars = {} # Simulate the dictionary to store results - - # Mock issue retrieval - mock_issue = AsyncMock() - mock_issue.number = 1 - mock_issue.title = "Sample Issue" - mock_issue.body = "This is a test issue body." - mock_issue.labels = ["bug", "high priority"] - - # Mock repo object - mock_repo.get_issue.return_value = mock_issue - - # Run function - await extract_and_cache_pr_tickets(github_provider, vars) - - # Ensure tickets are cached - self.assertIn("related_tickets", vars) - self.assertIsInstance(vars["related_tickets"], list) - self.assertGreater(len(vars["related_tickets"]), 0, "Expected at least one cached ticket!") - - print("\n Test Passed: extract_and_cache_pr_tickets() successfully cached ticket data!") - - def test_fetch_sub_issues(self): - """ - Test fetch_sub_issues() to ensure sub-issues are correctly retrieved. - """ - github_provider = GithubProvider() - issue_url = "https://github.com/WonOfAKind/KimchiBot/issues/1" # Known issue with sub-issues - result = github_provider.fetch_sub_issues(issue_url) - - print("Fetched sub-issues:", result) - - self.assertIsInstance(result, set) # Ensure result is a set - self.assertGreater(len(result), 0, "Expected at least one sub-issue but found none!") - - print("\n Test Passed: fetch_sub_issues() retrieved sub-issues correctly!") - - def test_fetch_sub_issues_with_no_results(self): - """ - Test fetch_sub_issues() to ensure an empty set is returned for an issue with no sub-issues. - """ - github_provider = GithubProvider() - issue_url = "https://github.com/qodo-ai/pr-agent/issues/1499" # Likely non-existent issue - result = github_provider.fetch_sub_issues(issue_url) - - print("Fetched sub-issues for non-existent issue:", result) - - self.assertIsInstance(result, set) # Ensure result is a set - self.assertEqual(len(result), 0, "Expected no sub-issues but some were found!") - - print("\n Test Passed: fetch_sub_issues_with_no_results() correctly returned an empty set!") - - -if __name__ == "__main__": - asyncio.run(unittest.main()) - - - +# Currently doing API calls - wrong ! +# import unittest +# import asyncio +# from unittest.mock import AsyncMock, patch +# from pr_agent.tools.ticket_pr_compliance_check import extract_tickets, extract_and_cache_pr_tickets +# from pr_agent.git_providers.github_provider import GithubProvider +# +# +# class TestTicketCompliance(unittest.TestCase): +# +# @patch.object(GithubProvider, 'get_user_description', return_value="Fixes #1 and relates to #2") +# @patch.object(GithubProvider, '_parse_issue_url', side_effect=lambda url: ("WonOfAKind/KimchiBot", int(url.split('#')[-1]))) +# @patch.object(GithubProvider, 'repo_obj') +# async def test_extract_tickets(self, mock_repo, mock_parse_issue_url, mock_user_desc): +# """ +# Test extract_tickets() to ensure it extracts tickets correctly +# and fetches their content. +# """ +# github_provider = GithubProvider() +# github_provider.repo = "WonOfAKind/KimchiBot" +# github_provider.base_url_html = "https://github.com" +# +# # Mock issue retrieval +# mock_issue = AsyncMock() +# mock_issue.number = 1 +# mock_issue.title = "Sample Issue" +# mock_issue.body = "This is a test issue body." +# mock_issue.labels = ["bug", "high priority"] +# +# # Mock repo object +# mock_repo.get_issue.return_value = mock_issue +# +# tickets = await extract_tickets(github_provider) +# +# # Verify tickets were extracted correctly +# self.assertIsInstance(tickets, list) +# self.assertGreater(len(tickets), 0, "Expected at least one ticket!") +# +# # Verify ticket structure +# first_ticket = tickets[0] +# self.assertIn("ticket_id", first_ticket) +# self.assertIn("ticket_url", first_ticket) +# self.assertIn("title", first_ticket) +# self.assertIn("body", first_ticket) +# self.assertIn("labels", first_ticket) +# +# print("\n Test Passed: extract_tickets() successfully retrieved ticket info!") +# +# @patch.object(GithubProvider, 'get_user_description', return_value="Fixes #1 and relates to #2") +# @patch.object(GithubProvider, '_parse_issue_url', side_effect=lambda url: ("WonOfAKind/KimchiBot", int(url.split('#')[-1]))) +# @patch.object(GithubProvider, 'repo_obj') +# async def test_extract_and_cache_pr_tickets(self, mock_repo, mock_parse_issue_url, mock_user_desc): +# """ +# Test extract_and_cache_pr_tickets() to ensure tickets are extracted and cached correctly. +# """ +# github_provider = GithubProvider() +# github_provider.repo = "WonOfAKind/KimchiBot" +# github_provider.base_url_html = "https://github.com" +# +# vars = {} # Simulate the dictionary to store results +# +# # Mock issue retrieval +# mock_issue = AsyncMock() +# mock_issue.number = 1 +# mock_issue.title = "Sample Issue" +# mock_issue.body = "This is a test issue body." +# mock_issue.labels = ["bug", "high priority"] +# +# # Mock repo object +# mock_repo.get_issue.return_value = mock_issue +# +# # Run function +# await extract_and_cache_pr_tickets(github_provider, vars) +# +# # Ensure tickets are cached +# self.assertIn("related_tickets", vars) +# self.assertIsInstance(vars["related_tickets"], list) +# self.assertGreater(len(vars["related_tickets"]), 0, "Expected at least one cached ticket!") +# +# print("\n Test Passed: extract_and_cache_pr_tickets() successfully cached ticket data!") +# +# def test_fetch_sub_issues(self): +# """ +# Test fetch_sub_issues() to ensure sub-issues are correctly retrieved. +# """ +# github_provider = GithubProvider() +# issue_url = "https://github.com/WonOfAKind/KimchiBot/issues/1" # Known issue with sub-issues +# result = github_provider.fetch_sub_issues(issue_url) +# +# print("Fetched sub-issues:", result) +# +# self.assertIsInstance(result, set) # Ensure result is a set +# self.assertGreater(len(result), 0, "Expected at least one sub-issue but found none!") +# +# print("\n Test Passed: fetch_sub_issues() retrieved sub-issues correctly!") +# +# def test_fetch_sub_issues_with_no_results(self): +# """ +# Test fetch_sub_issues() to ensure an empty set is returned for an issue with no sub-issues. +# """ +# github_provider = GithubProvider() +# issue_url = "https://github.com/qodo-ai/pr-agent/issues/1499" # Likely non-existent issue +# result = github_provider.fetch_sub_issues(issue_url) +# +# print("Fetched sub-issues for non-existent issue:", result) +# +# self.assertIsInstance(result, set) # Ensure result is a set +# self.assertEqual(len(result), 0, "Expected no sub-issues but some were found!") +# +# print("\n Test Passed: fetch_sub_issues_with_no_results() correctly returned an empty set!") +# +# +# if __name__ == "__main__": +# asyncio.run(unittest.main()) +# +# +# +# +# From 020ef212c1ab549a956fd558377b4dbfd40bb62b Mon Sep 17 00:00:00 2001 From: ofir-frd Date: Sat, 22 Feb 2025 16:46:31 +0200 Subject: [PATCH 5/8] docs: fix notes admonition syntax in documentation --- docs/docs/tools/documentation.md | 2 +- docs/docs/tools/test.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/docs/tools/documentation.md b/docs/docs/tools/documentation.md index 1c1e328d..b09eda3e 100644 --- a/docs/docs/tools/documentation.md +++ b/docs/docs/tools/documentation.md @@ -27,6 +27,6 @@ You can state a name of a specific component in the PR to get documentation only - `docs_style`: The exact style of the documentation (for python docstring). you can choose between: `google`, `numpy`, `sphinx`, `restructuredtext`, `plain`. Default is `sphinx`. - `extra_instructions`: Optional extra instructions to the tool. For example: "focus on the changes in the file X. Ignore change in ...". -!!! notes "Notes" +!!! note "Notes" - The following languages are currently supported: Python, Java, C++, JavaScript, TypeScript, C#. - This tool can also be triggered interactively by using the [`analyze`](./analyze.md) tool. diff --git a/docs/docs/tools/test.md b/docs/docs/tools/test.md index 2d5652ae..0d3da4ff 100644 --- a/docs/docs/tools/test.md +++ b/docs/docs/tools/test.md @@ -17,7 +17,7 @@ The tool will generate tests for the selected component (if no component is stat (Example taken from [here](https://github.com/Codium-ai/pr-agent/pull/598#issuecomment-1913679429)): -!!! notes "Notes" +!!! note "Notes" - The following languages are currently supported: Python, Java, C++, JavaScript, TypeScript, C#. - This tool can also be triggered interactively by using the [`analyze`](./analyze.md) tool. From 7e32a08f00838ccb17a44f18937a8c64e33994ab Mon Sep 17 00:00:00 2001 From: ofir-frd <85901822+ofir-frd@users.noreply.github.com> Date: Sun, 23 Feb 2025 08:05:17 +0200 Subject: [PATCH 6/8] Refresh implement image in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 92455515..8065f7c5 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ to New tool [/Implement](https://qodo-merge-docs.qodo.ai/tools/implement/) (πŸ’Ž), which converts human code review discussions and feedback into ready-to-commit code changes. - + ### Jan 1, 2025 From a0dc9deb30e8c0ec3acaab27e9c6a50bf80ab5d4 Mon Sep 17 00:00:00 2001 From: mrT23 Date: Sun, 23 Feb 2025 08:15:14 +0200 Subject: [PATCH 7/8] docs: add auto-approval configuration documentation --- docs/docs/tools/improve.md | 38 ++++++++++++++++++++++++++++ docs/docs/tools/review.md | 27 -------------------- pr_agent/settings/configuration.toml | 8 +++--- 3 files changed, 43 insertions(+), 30 deletions(-) diff --git a/docs/docs/tools/improve.md b/docs/docs/tools/improve.md index b00ea66c..ab1e6bb9 100644 --- a/docs/docs/tools/improve.md +++ b/docs/docs/tools/improve.md @@ -311,6 +311,44 @@ code_suggestions_self_review_text = "... (your text here) ..." To prevent unauthorized approvals, this configuration defaults to false, and cannot be altered through online comments; enabling requires a direct update to the configuration file and a commit to the repository. This ensures that utilizing the feature demands a deliberate documented decision by the repository owner. +### Auto-approval + +Under specific conditions, Qodo Merge can auto-approve a PR when a specific comment is invoked, or when the PR meets certain criteria. + +To ensure safety, the auto-approval feature is disabled by default. To enable auto-approval, you need to actively set, in a pre-defined _configuration file_, the following: +```toml +[config] +enable_auto_approval = true +``` +Note that this specific flag cannot be set with a command line argument, only in the configuration file, committed to the repository. +This ensures that enabling auto-approval is a deliberate decision by the repository owner. + +**(1) Auto-approval by commenting** + +After enabling, by commenting on a PR: +``` +/review auto_approve +``` +Qodo Merge will automatically approve the PR, and add a comment with the approval. + +**(2) Auto-approval when the PR meets certain criteria** + +There are two criteria that can be set for auto-approval: + +- **Review effort score** +```toml +[config] +auto_approve_for_low_review_effort = X # X is a number between 1 to 5 +``` +When the [review effort score](https://www.qodo.ai/images/pr_agent/review3.png) is lower or equal to X, the PR will be auto-approved. + +___ +- **No code suggestions** +```toml +[config] +auto_approve_for_no_suggestions = true +``` +When no [code suggestion](https://www.qodo.ai/images/pr_agent/code_suggestions_as_comment_closed.png) were found for the PR, the PR will be auto-approved. ### How many code suggestions are generated? Qodo Merge uses a dynamic strategy to generate code suggestions based on the size of the pull request (PR). Here's how it works: diff --git a/docs/docs/tools/review.md b/docs/docs/tools/review.md index 6ce96696..e3c3c3c6 100644 --- a/docs/docs/tools/review.md +++ b/docs/docs/tools/review.md @@ -114,16 +114,6 @@ You can enable\disable the `review` tool to add specific labels to the PR: -!!! example "Auto-approval" - -If enabled, the `review` tool can approve a PR when a specific comment, `/review auto_approve`, is invoked. - - - - - - -
enable_auto_approvalIf set to true, the tool will approve the PR when invoked with the 'auto_approve' command. Default is false. This flag can be changed only from a configuration file.
## Usage Tips @@ -175,23 +165,6 @@ If enabled, the `review` tool can approve a PR when a specific comment, `/review Use triple quotes to write multi-line instructions. Use bullet points to make the instructions more readable. -!!! tip "Auto-approval" - - Qodo Merge can approve a PR when a specific comment is invoked. - - To ensure safety, the auto-approval feature is disabled by default. To enable auto-approval, you need to actively set in a pre-defined configuration file the following: - ``` - [pr_reviewer] - enable_auto_approval = true - ``` - (this specific flag cannot be set with a command line argument, only in the configuration file, committed to the repository) - - - After enabling, by commenting on a PR: - ``` - /review auto_approve - ``` - Qodo Merge will automatically approve the PR, and add a comment with the approval. !!! tip "Code suggestions" diff --git a/pr_agent/settings/configuration.toml b/pr_agent/settings/configuration.toml index ad09243a..890cff35 100644 --- a/pr_agent/settings/configuration.toml +++ b/pr_agent/settings/configuration.toml @@ -48,6 +48,11 @@ ignore_pr_authors = [] # authors to ignore from PR agent when an PR is created # is_auto_command = false # will be auto-set to true if the command is triggered by an automation enable_ai_metadata = false # will enable adding ai metadata +# auto approval πŸ’Ž +enable_auto_approval=false # Set to true to enable auto-approval of PRs under certain conditions +auto_approve_for_low_review_effort=-1 # -1 to disable, [1-5] to set the threshold for auto-approval +auto_approve_for_no_suggestions=false # If true, the PR will be auto-approved if there are no suggestions + [pr_reviewer] # /review # # enable/disable features @@ -70,9 +75,6 @@ minimal_commits_for_incremental_review=0 minimal_minutes_for_incremental_review=0 enable_intro_text=true enable_help_text=false # Determines whether to include help text in the PR review. Enabled by default. -# auto approval -enable_auto_approval=false - [pr_description] # /describe # publish_labels=false From f0b52870a228af00cb3232a8e9d22d6ddf63e6e9 Mon Sep 17 00:00:00 2001 From: mrT23 Date: Sun, 23 Feb 2025 08:34:16 +0200 Subject: [PATCH 8/8] docs: update auto-approval feature documentation and configuration --- docs/docs/tools/improve.md | 25 ++++++++++++++----------- pr_agent/tools/pr_reviewer.py | 10 +++++----- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/docs/docs/tools/improve.md b/docs/docs/tools/improve.md index ab1e6bb9..975df691 100644 --- a/docs/docs/tools/improve.md +++ b/docs/docs/tools/improve.md @@ -53,9 +53,10 @@ num_code_suggestions_per_chunk = ... - The `pr_commands` lists commands that will be executed automatically when a PR is opened. - The `[pr_code_suggestions]` section contains the configurations for the `improve` tool you want to edit (if any) -### Assessing Impact πŸ’Ž +### Assessing Impact +>`πŸ’Ž feature` -Note that Qodo Merge tracks two types of implementations: +Qodo Merge tracks two types of implementations for tracking implemented suggestions: - Direct implementation - when the user directly applies the suggestion by clicking the `Apply` checkbox. - Indirect implementation - when the user implements the suggestion in their IDE environment. In this case, Qodo Merge will utilize, after each commit, a dedicated logic to identify if a suggestion was implemented, and will mark it as implemented. @@ -68,8 +69,8 @@ In post-process, Qodo Merge counts the number of suggestions that were implement ![code_suggestions_asses_impact_stats_2](https://codium.ai/images/pr_agent/code_suggestions_asses_impact_stats_2.png){width=512} -## Suggestion tracking πŸ’Ž -`Platforms supported: GitHub, GitLab` +## Suggestion tracking +>`πŸ’Ž feature. Platforms supported: GitHub, GitLab` Qodo Merge employs a novel detection system to automatically [identify](https://qodo-merge-docs.qodo.ai/core-abilities/impact_evaluation/) AI code suggestions that PR authors have accepted and implemented. @@ -102,8 +103,6 @@ The `improve` tool can be further customized by providing additional instruction ### Extra instructions ->`Platforms supported: GitHub, GitLab, Bitbucket, Azure DevOps` - You can use the `extra_instructions` configuration option to give the AI model additional instructions for the `improve` tool. Be specific, clear, and concise in the instructions. With extra instructions, you are the prompter. @@ -119,9 +118,9 @@ extra_instructions="""\ ``` Use triple quotes to write multi-line instructions. Use bullet points or numbers to make the instructions more readable. -### Best practices πŸ’Ž +### Best practices ->`Platforms supported: GitHub, GitLab, Bitbucket` +> `πŸ’Ž feature. Platforms supported: GitHub, GitLab, Bitbucket` Another option to give additional guidance to the AI model is by creating a `best_practices.md` file, either in your repository's root directory or as a [**wiki page**](https://github.com/Codium-ai/pr-agent/wiki) (we recommend the wiki page, as editing and maintaining it over time is easier). This page can contain a list of best practices, coding standards, and guidelines that are specific to your repo/organization. @@ -192,9 +191,9 @@ And the label will be: `{organization_name} best practice`. ![best_practice](https://codium.ai/images/pr_agent/org_best_practice.png){width=512} -### Auto best practices πŸ’Ž +### Auto best practices ->`Platforms supported: GitHub` +>`πŸ’Ž feature. Platforms supported: GitHub.` 'Auto best practices' is a novel Qodo Merge capability that: @@ -229,7 +228,8 @@ max_patterns = 5 ``` -### Combining `extra instructions` and `best practices` πŸ’Ž +### Combining 'extra instructions' and 'best practices' +> `πŸ’Ž feature` The `extra instructions` configuration is more related to the `improve` tool prompt. It can be used, for example, to avoid specific suggestions ("Don't suggest to add try-except block", "Ignore changes in toml files", ...) or to emphasize specific aspects or formats ("Answer in Japanese", "Give only short suggestions", ...) @@ -268,6 +268,8 @@ dual_publishing_score_threshold = x Where x represents the minimum score threshold (>=) for suggestions to be presented as commitable PR comments in addition to the table. Default is -1 (disabled). ### Self-review +> `πŸ’Ž feature` + If you set in a configuration file: ```toml [pr_code_suggestions] @@ -312,6 +314,7 @@ code_suggestions_self_review_text = "... (your text here) ..." To prevent unauthorized approvals, this configuration defaults to false, and cannot be altered through online comments; enabling requires a direct update to the configuration file and a commit to the repository. This ensures that utilizing the feature demands a deliberate documented decision by the repository owner. ### Auto-approval +> `πŸ’Ž feature` Under specific conditions, Qodo Merge can auto-approve a PR when a specific comment is invoked, or when the PR meets certain criteria. diff --git a/pr_agent/tools/pr_reviewer.py b/pr_agent/tools/pr_reviewer.py index 8725c843..0f4eff22 100644 --- a/pr_agent/tools/pr_reviewer.py +++ b/pr_agent/tools/pr_reviewer.py @@ -123,10 +123,10 @@ class PRReviewer: if self.incremental.is_incremental and not self._can_run_incremental_review(): return None - if isinstance(self.args, list) and self.args and self.args[0] == 'auto_approve': - get_logger().info(f'Auto approve flow PR: {self.pr_url} ...') - self.auto_approve_logic() - return None + # if isinstance(self.args, list) and self.args and self.args[0] == 'auto_approve': + # get_logger().info(f'Auto approve flow PR: {self.pr_url} ...') + # self.auto_approve_logic() + # return None get_logger().info(f'Reviewing PR: {self.pr_url} ...') relevant_configs = {'pr_reviewer': dict(get_settings().pr_reviewer), @@ -402,7 +402,7 @@ class PRReviewer: """ Auto-approve a pull request if it meets the conditions for auto-approval. """ - if get_settings().pr_reviewer.enable_auto_approval: + if get_settings().config.enable_auto_approval: is_auto_approved = self.git_provider.auto_approve() if is_auto_approved: get_logger().info("Auto-approved PR")