From df8290a29045997f580155a689d29c60fdf65a0f Mon Sep 17 00:00:00 2001 From: Abhinav Kumar Date: Wed, 2 Jul 2025 18:07:54 +0530 Subject: [PATCH 01/53] add support for PR sequence diagram in description markers --- docs/docs/tools/describe.md | 6 +++++- pr_agent/servers/help.py | 1 + pr_agent/settings/pr_description_prompts.toml | 2 +- pr_agent/tools/pr_description.py | 4 ++++ 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/docs/docs/tools/describe.md b/docs/docs/tools/describe.md index f00903d1..627e6dcf 100644 --- a/docs/docs/tools/describe.md +++ b/docs/docs/tools/describe.md @@ -177,9 +177,12 @@ pr_agent:summary ## PR Walkthrough: pr_agent:walkthrough + +## PR Diagram: +pr_agent:diagram ``` -The marker `pr_agent:type` will be replaced with the PR type, `pr_agent:summary` will be replaced with the PR summary, and `pr_agent:walkthrough` will be replaced with the PR walkthrough. +The marker `pr_agent:type` will be replaced with the PR type, `pr_agent:summary` will be replaced with the PR summary, `pr_agent:walkthrough` will be replaced with the PR walkthrough, and `pr_agent:diagram` will be replaced with the sequence diagram (if enabled). ![Describe markers before](https://codium.ai/images/pr_agent/describe_markers_before.png){width=512} @@ -191,6 +194,7 @@ becomes - `use_description_markers`: if set to true, the tool will use markers template. It replaces every marker of the form `pr_agent:marker_name` with the relevant content. Default is false. - `include_generated_by_header`: if set to true, the tool will add a dedicated header: 'Generated by PR Agent at ...' to any automatic content. Default is true. +- `diagram`: if present as a marker, will be replaced by the PR sequence diagram (if enabled). ## Custom labels diff --git a/pr_agent/servers/help.py b/pr_agent/servers/help.py index e3cdf0de..85e2d286 100644 --- a/pr_agent/servers/help.py +++ b/pr_agent/servers/help.py @@ -81,6 +81,7 @@ the tool will replace every marker of the form `pr_agent:marker_name` in the PR - `type`: the PR type. - `summary`: the PR summary. - `walkthrough`: the PR walkthrough. + - `diagram`: the PR sequence diagram (if enabled). Note that when markers are enabled, if the original PR description does not contain any markers, the tool will not alter the description at all. diff --git a/pr_agent/settings/pr_description_prompts.toml b/pr_agent/settings/pr_description_prompts.toml index d8954052..19b8f185 100644 --- a/pr_agent/settings/pr_description_prompts.toml +++ b/pr_agent/settings/pr_description_prompts.toml @@ -48,7 +48,7 @@ class PRDescription(BaseModel): description: str = Field(description="summarize the PR changes in up to four bullet points, each up to 8 words. For large PRs, add sub-bullets if needed. Order bullets by importance, with each bullet highlighting a key change group.") title: str = Field(description="a concise and descriptive title that captures the PR's main theme") {%- if enable_pr_diagram %} - changes_diagram: str = Field(description="a horizontal diagram that represents the main PR changes, in the format of a valid mermaid LR flowchart. The diagram should be concise and easy to read. Leave empty if no diagram is relevant. To create robust Mermaid diagrams, follow this two-step process: (1) Declare the nodes: nodeID["node description"]. (2) Then define the links: nodeID1 -- "link text" --> nodeID2. Node description must always be surrounded with quotation marks.") + changes_diagram: str = Field(description="a horizontal diagram that represents the main PR changes, in the format of a valid mermaid LR flowchart. The diagram should be concise and easy to read. Leave empty if no diagram is relevant. To create robust Mermaid diagrams, follow this two-step process: (1) Declare the nodes: nodeID[\"node description\"]. (2) Then define the links: nodeID1 -- \"link text\" --> nodeID2. Node description must always be surrounded with quotation marks. This field is used for the pr_agent:diagram marker if markers are enabled.") {%- endif %} {%- if enable_semantic_files_types %} pr_files: List[FileDescription] = Field(max_items=20, description="a list of all the files that were changed in the PR, and summary of their changes. Each file must be analyzed regardless of change size.") diff --git a/pr_agent/tools/pr_description.py b/pr_agent/tools/pr_description.py index c4595140..41cc4006 100644 --- a/pr_agent/tools/pr_description.py +++ b/pr_agent/tools/pr_description.py @@ -538,6 +538,10 @@ class PRDescription: get_logger().error(f"Failing to process walkthrough {self.pr_id}: {e}") body = body.replace('pr_agent:walkthrough', "") + ai_diagram = self.data.get('changes_diagram') + if ai_diagram and not re.search(r'', body): + body = body.replace('pr_agent:diagram', ai_diagram) + return title, body, walkthrough_gfm, pr_file_changes def _prepare_pr_answer(self) -> Tuple[str, str, str, List[dict]]: From aeb1bd8dbcde2a4e9c9b5a0fb758dd6afacb713b Mon Sep 17 00:00:00 2001 From: Abhinav Kumar Date: Wed, 2 Jul 2025 18:11:19 +0530 Subject: [PATCH 02/53] fix suggestions --- pr_agent/tools/pr_description.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pr_agent/tools/pr_description.py b/pr_agent/tools/pr_description.py index 41cc4006..3ce633dd 100644 --- a/pr_agent/tools/pr_description.py +++ b/pr_agent/tools/pr_description.py @@ -538,9 +538,10 @@ class PRDescription: get_logger().error(f"Failing to process walkthrough {self.pr_id}: {e}") body = body.replace('pr_agent:walkthrough', "") + # Add support for pr_agent:diagram marker (plain and HTML comment formats) ai_diagram = self.data.get('changes_diagram') - if ai_diagram and not re.search(r'', body): - body = body.replace('pr_agent:diagram', ai_diagram) + if ai_diagram: + body = re.sub(r'|pr_agent:diagram', ai_diagram, body) return title, body, walkthrough_gfm, pr_file_changes From 822a253eb593192b9f5d9a2061a49cc336445d70 Mon Sep 17 00:00:00 2001 From: Abhinav Kumar Date: Wed, 2 Jul 2025 18:49:58 +0530 Subject: [PATCH 03/53] clarify that Fetching Ticket Context affects Ask tool --- README.md | 6 +++--- docs/docs/core-abilities/fetching_ticket_context.md | 9 +++++++++ docs/docs/index.md | 2 +- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 0ee113a8..f6e24e18 100644 --- a/README.md +++ b/README.md @@ -141,7 +141,7 @@ Supported commands per platform: | | [Chat on code suggestions](https://qodo-merge-docs.qodo.ai/core-abilities/chat_on_code_suggestions/) | βœ… | βœ… | | | | | | [Code Validation πŸ’Ž](https://qodo-merge-docs.qodo.ai/core-abilities/code_validation/) | βœ… | βœ… | βœ… | βœ… | | | | [Dynamic context](https://qodo-merge-docs.qodo.ai/core-abilities/dynamic_context/) | βœ… | βœ… | βœ… | βœ… | | -| | [Fetching ticket context](https://qodo-merge-docs.qodo.ai/core-abilities/fetching_ticket_context/) | βœ… | βœ… | βœ… | | | +| | [Fetching ticket context](https://qodo-merge-docs.qodo.ai/core-abilities/fetching_ticket_context/) | βœ… | βœ… | βœ… | βœ… | | | | [Global and wiki configurations](https://qodo-merge-docs.qodo.ai/usage-guide/configuration_options/) πŸ’Ž | βœ… | βœ… | βœ… | | | | | [Impact Evaluation](https://qodo-merge-docs.qodo.ai/core-abilities/impact_evaluation/) πŸ’Ž | βœ… | βœ… | | | | | | [Incremental Update](https://qodo-merge-docs.qodo.ai/core-abilities/incremental_update/) | βœ… | | | | | @@ -249,9 +249,9 @@ https://openai.com/enterprise-privacy - When using Qodo Merge πŸ’Ž, hosted by Qodo, we will not store any of your data, nor will we use it for training. You will also benefit from an OpenAI account with zero data retention. -- For certain clients, Qodo-hosted Qodo Merge will use Qodo’s proprietary models β€” if this is the case, you will be notified. +- For certain clients, Qodo-hosted Qodo Merge will use Qodo's proprietary models β€” if this is the case, you will be notified. -- No passive collection of Code and Pull Requests’ data β€” Qodo Merge will be active only when you invoke it, and it will then extract and analyze only data relevant to the executed command and queried pull request. +- No passive collection of Code and Pull Requests' data β€” Qodo Merge will be active only when you invoke it, and it will then extract and analyze only data relevant to the executed command and queried pull request. ### Qodo Merge Chrome extension diff --git a/docs/docs/core-abilities/fetching_ticket_context.md b/docs/docs/core-abilities/fetching_ticket_context.md index 63cd65f4..ed8c81f0 100644 --- a/docs/docs/core-abilities/fetching_ticket_context.md +++ b/docs/docs/core-abilities/fetching_ticket_context.md @@ -50,6 +50,15 @@ Each ticket will be assigned a label (Compliance/Alignment level), Indicates the A `PR Code Verified` label indicates the PR code meets ticket requirements, but requires additional manual testing beyond the code scope. For example - validating UI display across different environments (Mac, Windows, mobile, etc.). +### Ask tool + +The `ask` tool will also leverage the ticket content (title, description, labels, etc.) to provide additional context when answering questions about the PR. This means that when you use the Ask tool, it can: + +- Use ticket context to provide more relevant and accurate answers to your questions about the PR. +- Directly answer questions related to the ticket itself, such as its requirements, acceptance criteria, or intent. +- Help clarify how the code changes relate to the ticket, or whether the PR fulfills the ticket's goals. + +By including ticket context, the Ask tool ensures that responses are as informed and useful as those from the Describe and Review tools. #### Configuration options diff --git a/docs/docs/index.md b/docs/docs/index.md index 46f49ff2..8f0af294 100644 --- a/docs/docs/index.md +++ b/docs/docs/index.md @@ -60,7 +60,7 @@ PR-Agent and Qodo Merge offers extensive pull request functionalities across var | | [Chat on code suggestions](https://qodo-merge-docs.qodo.ai/core-abilities/chat_on_code_suggestions/) | βœ… | βœ… | | | | | | [Code Validation πŸ’Ž](https://qodo-merge-docs.qodo.ai/core-abilities/code_validation/) | βœ… | βœ… | βœ… | βœ… | | | | [Dynamic context](https://qodo-merge-docs.qodo.ai/core-abilities/dynamic_context/) | βœ… | βœ… | βœ… | βœ… | | -| | [Fetching ticket context](https://qodo-merge-docs.qodo.ai/core-abilities/fetching_ticket_context/) | βœ… | βœ… | βœ… | | | +| | [Fetching ticket context](https://qodo-merge-docs.qodo.ai/core-abilities/fetching_ticket_context/) | βœ… | βœ… | βœ… | βœ… | | | | [Global and wiki configurations](https://qodo-merge-docs.qodo.ai/usage-guide/configuration_options/) πŸ’Ž | βœ… | βœ… | βœ… | | | | | [Impact Evaluation](https://qodo-merge-docs.qodo.ai/core-abilities/impact_evaluation/) πŸ’Ž | βœ… | βœ… | | | | | | [Incremental Update πŸ’Ž](https://qodo-merge-docs.qodo.ai/core-abilities/incremental_update/) | βœ… | | | | | From 3b071ccb4e8a5d9ba64456b379185dffbed7372e Mon Sep 17 00:00:00 2001 From: Abhinav Kumar Date: Wed, 2 Jul 2025 19:11:53 +0530 Subject: [PATCH 04/53] apply repository settings before processing push commands in GitLab webhook --- pr_agent/servers/gitlab_webhook.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pr_agent/servers/gitlab_webhook.py b/pr_agent/servers/gitlab_webhook.py index af777a9a..a699f190 100644 --- a/pr_agent/servers/gitlab_webhook.py +++ b/pr_agent/servers/gitlab_webhook.py @@ -234,6 +234,8 @@ async def gitlab_webhook(background_tasks: BackgroundTasks, request: Request): get_logger().info(f"Skipping draft MR: {url}") return JSONResponse(status_code=status.HTTP_200_OK, content=jsonable_encoder({"message": "success"})) + # Apply repo settings before checking push commands or handle_push_trigger + apply_repo_settings(url) commands_on_push = get_settings().get(f"gitlab.push_commands", {}) handle_push_trigger = get_settings().get(f"gitlab.handle_push_trigger", False) if not commands_on_push or not handle_push_trigger: From 8a7b37ab4cd735bb20116f48e967dbb2a914b911 Mon Sep 17 00:00:00 2001 From: Abhinav Kumar Date: Wed, 2 Jul 2025 19:13:01 +0530 Subject: [PATCH 05/53] Revert "clarify that Fetching Ticket Context affects Ask tool" This reverts commit 822a253eb593192b9f5d9a2061a49cc336445d70. --- README.md | 6 +++--- docs/docs/core-abilities/fetching_ticket_context.md | 9 --------- docs/docs/index.md | 2 +- 3 files changed, 4 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index f6e24e18..0ee113a8 100644 --- a/README.md +++ b/README.md @@ -141,7 +141,7 @@ Supported commands per platform: | | [Chat on code suggestions](https://qodo-merge-docs.qodo.ai/core-abilities/chat_on_code_suggestions/) | βœ… | βœ… | | | | | | [Code Validation πŸ’Ž](https://qodo-merge-docs.qodo.ai/core-abilities/code_validation/) | βœ… | βœ… | βœ… | βœ… | | | | [Dynamic context](https://qodo-merge-docs.qodo.ai/core-abilities/dynamic_context/) | βœ… | βœ… | βœ… | βœ… | | -| | [Fetching ticket context](https://qodo-merge-docs.qodo.ai/core-abilities/fetching_ticket_context/) | βœ… | βœ… | βœ… | βœ… | | +| | [Fetching ticket context](https://qodo-merge-docs.qodo.ai/core-abilities/fetching_ticket_context/) | βœ… | βœ… | βœ… | | | | | [Global and wiki configurations](https://qodo-merge-docs.qodo.ai/usage-guide/configuration_options/) πŸ’Ž | βœ… | βœ… | βœ… | | | | | [Impact Evaluation](https://qodo-merge-docs.qodo.ai/core-abilities/impact_evaluation/) πŸ’Ž | βœ… | βœ… | | | | | | [Incremental Update](https://qodo-merge-docs.qodo.ai/core-abilities/incremental_update/) | βœ… | | | | | @@ -249,9 +249,9 @@ https://openai.com/enterprise-privacy - When using Qodo Merge πŸ’Ž, hosted by Qodo, we will not store any of your data, nor will we use it for training. You will also benefit from an OpenAI account with zero data retention. -- For certain clients, Qodo-hosted Qodo Merge will use Qodo's proprietary models β€” if this is the case, you will be notified. +- For certain clients, Qodo-hosted Qodo Merge will use Qodo’s proprietary models β€” if this is the case, you will be notified. -- No passive collection of Code and Pull Requests' data β€” Qodo Merge will be active only when you invoke it, and it will then extract and analyze only data relevant to the executed command and queried pull request. +- No passive collection of Code and Pull Requests’ data β€” Qodo Merge will be active only when you invoke it, and it will then extract and analyze only data relevant to the executed command and queried pull request. ### Qodo Merge Chrome extension diff --git a/docs/docs/core-abilities/fetching_ticket_context.md b/docs/docs/core-abilities/fetching_ticket_context.md index ed8c81f0..63cd65f4 100644 --- a/docs/docs/core-abilities/fetching_ticket_context.md +++ b/docs/docs/core-abilities/fetching_ticket_context.md @@ -50,15 +50,6 @@ Each ticket will be assigned a label (Compliance/Alignment level), Indicates the A `PR Code Verified` label indicates the PR code meets ticket requirements, but requires additional manual testing beyond the code scope. For example - validating UI display across different environments (Mac, Windows, mobile, etc.). -### Ask tool - -The `ask` tool will also leverage the ticket content (title, description, labels, etc.) to provide additional context when answering questions about the PR. This means that when you use the Ask tool, it can: - -- Use ticket context to provide more relevant and accurate answers to your questions about the PR. -- Directly answer questions related to the ticket itself, such as its requirements, acceptance criteria, or intent. -- Help clarify how the code changes relate to the ticket, or whether the PR fulfills the ticket's goals. - -By including ticket context, the Ask tool ensures that responses are as informed and useful as those from the Describe and Review tools. #### Configuration options diff --git a/docs/docs/index.md b/docs/docs/index.md index 8f0af294..46f49ff2 100644 --- a/docs/docs/index.md +++ b/docs/docs/index.md @@ -60,7 +60,7 @@ PR-Agent and Qodo Merge offers extensive pull request functionalities across var | | [Chat on code suggestions](https://qodo-merge-docs.qodo.ai/core-abilities/chat_on_code_suggestions/) | βœ… | βœ… | | | | | | [Code Validation πŸ’Ž](https://qodo-merge-docs.qodo.ai/core-abilities/code_validation/) | βœ… | βœ… | βœ… | βœ… | | | | [Dynamic context](https://qodo-merge-docs.qodo.ai/core-abilities/dynamic_context/) | βœ… | βœ… | βœ… | βœ… | | -| | [Fetching ticket context](https://qodo-merge-docs.qodo.ai/core-abilities/fetching_ticket_context/) | βœ… | βœ… | βœ… | βœ… | | +| | [Fetching ticket context](https://qodo-merge-docs.qodo.ai/core-abilities/fetching_ticket_context/) | βœ… | βœ… | βœ… | | | | | [Global and wiki configurations](https://qodo-merge-docs.qodo.ai/usage-guide/configuration_options/) πŸ’Ž | βœ… | βœ… | βœ… | | | | | [Impact Evaluation](https://qodo-merge-docs.qodo.ai/core-abilities/impact_evaluation/) πŸ’Ž | βœ… | βœ… | | | | | | [Incremental Update πŸ’Ž](https://qodo-merge-docs.qodo.ai/core-abilities/incremental_update/) | βœ… | | | | | From 23ce79589cbecf4242b3138bbd31d0305381d34f Mon Sep 17 00:00:00 2001 From: Abhinav Kumar <113254225+abhinav-1305@users.noreply.github.com> Date: Sat, 5 Jul 2025 11:27:38 +0530 Subject: [PATCH 06/53] Update pr_agent/settings/pr_description_prompts.toml Co-authored-by: qodo-merge-for-open-source[bot] <189517486+qodo-merge-for-open-source[bot]@users.noreply.github.com> --- pr_agent/settings/pr_description_prompts.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pr_agent/settings/pr_description_prompts.toml b/pr_agent/settings/pr_description_prompts.toml index 19b8f185..cc789c94 100644 --- a/pr_agent/settings/pr_description_prompts.toml +++ b/pr_agent/settings/pr_description_prompts.toml @@ -48,7 +48,7 @@ class PRDescription(BaseModel): description: str = Field(description="summarize the PR changes in up to four bullet points, each up to 8 words. For large PRs, add sub-bullets if needed. Order bullets by importance, with each bullet highlighting a key change group.") title: str = Field(description="a concise and descriptive title that captures the PR's main theme") {%- if enable_pr_diagram %} - changes_diagram: str = Field(description="a horizontal diagram that represents the main PR changes, in the format of a valid mermaid LR flowchart. The diagram should be concise and easy to read. Leave empty if no diagram is relevant. To create robust Mermaid diagrams, follow this two-step process: (1) Declare the nodes: nodeID[\"node description\"]. (2) Then define the links: nodeID1 -- \"link text\" --> nodeID2. Node description must always be surrounded with quotation marks. This field is used for the pr_agent:diagram marker if markers are enabled.") + changes_diagram: str = Field(description="a horizontal diagram that represents the main PR changes, in the format of a valid mermaid LR flowchart. The diagram should be concise and easy to read. Leave empty if no diagram is relevant. To create robust Mermaid diagrams, follow this two-step process: (1) Declare the nodes: nodeID[\"node description\"]. (2) Then define the links: nodeID1 -- \"link text\" --> nodeID2. Node description must always be surrounded with quotation marks.") {%- endif %} {%- if enable_semantic_files_types %} pr_files: List[FileDescription] = Field(max_items=20, description="a list of all the files that were changed in the PR, and summary of their changes. Each file must be analyzed regardless of change size.") From a3d52f9cc7dde525fc377ef58d522534c0ddbcaf Mon Sep 17 00:00:00 2001 From: Tal Date: Sat, 5 Jul 2025 09:05:23 +0300 Subject: [PATCH 07/53] Update pr_agent/servers/gitlab_webhook.py Co-authored-by: qodo-merge-for-open-source[bot] <189517486+qodo-merge-for-open-source[bot]@users.noreply.github.com> --- pr_agent/servers/gitlab_webhook.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pr_agent/servers/gitlab_webhook.py b/pr_agent/servers/gitlab_webhook.py index a699f190..c020ec44 100644 --- a/pr_agent/servers/gitlab_webhook.py +++ b/pr_agent/servers/gitlab_webhook.py @@ -236,6 +236,8 @@ async def gitlab_webhook(background_tasks: BackgroundTasks, request: Request): # Apply repo settings before checking push commands or handle_push_trigger apply_repo_settings(url) + + commands_on_push = get_settings().get(f"gitlab.push_commands", {}) commands_on_push = get_settings().get(f"gitlab.push_commands", {}) handle_push_trigger = get_settings().get(f"gitlab.handle_push_trigger", False) if not commands_on_push or not handle_push_trigger: From 34cc434459e555f651aa6c6536c632a7e305b7f6 Mon Sep 17 00:00:00 2001 From: Tal Date: Sat, 5 Jul 2025 09:07:47 +0300 Subject: [PATCH 08/53] Update gitlab_webhook.py --- pr_agent/servers/gitlab_webhook.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pr_agent/servers/gitlab_webhook.py b/pr_agent/servers/gitlab_webhook.py index c020ec44..60f13501 100644 --- a/pr_agent/servers/gitlab_webhook.py +++ b/pr_agent/servers/gitlab_webhook.py @@ -237,7 +237,6 @@ async def gitlab_webhook(background_tasks: BackgroundTasks, request: Request): # Apply repo settings before checking push commands or handle_push_trigger apply_repo_settings(url) - commands_on_push = get_settings().get(f"gitlab.push_commands", {}) commands_on_push = get_settings().get(f"gitlab.push_commands", {}) handle_push_trigger = get_settings().get(f"gitlab.handle_push_trigger", False) if not commands_on_push or not handle_push_trigger: @@ -286,8 +285,8 @@ def handle_ask_line(body, data): question = body.replace('/ask', '').strip() path = data['object_attributes']['position']['new_path'] side = 'RIGHT' # if line_range_['start']['type'] == 'new' else 'LEFT' - comment_id = data['object_attributes']["discussion_id"] - get_logger().info("Handling line comment") + _id = data['object_attributes']["discussion_id"] + get_logger().info("Handling line ") body = f"/ask_line --line_start={start_line} --line_end={end_line} --side={side} --file_name={path} --comment_id={comment_id} {question}" except Exception as e: get_logger().error(f"Failed to handle ask line comment: {e}") From 38dc9a8fe572262aa4c7f6f27c0accf1a99c5f64 Mon Sep 17 00:00:00 2001 From: mrT23 Date: Sun, 6 Jul 2025 08:52:34 +0300 Subject: [PATCH 09/53] docs: clarify behavior of Qodo Merge regarding original PR descriptions --- docs/docs/tools/describe.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/docs/tools/describe.md b/docs/docs/tools/describe.md index 627e6dcf..d929679c 100644 --- a/docs/docs/tools/describe.md +++ b/docs/docs/tools/describe.md @@ -47,11 +47,16 @@ publish_labels = true ## Preserving the original user description -By default, Qodo Merge preserves your original PR description by placing it above the generated content. +By default, Qodo Merge tries to preserve your original PR description by placing it above the generated content. This requires including your description during the initial PR creation. -Be aware that if you edit the description while the automated tool is running, a race condition may occur, potentially causing your original description to be lost. -When updating PR descriptions, the `/describe` tool considers everything above the "PR Type" field as user content and will preserve it. +"Qodo removed the original description from the PR. Why"? + +From our experience, there are two possible reasons: + +- If you edit the description _while_ the automated tool is running, a race condition may occur, potentially causing your original description to be lost. Hence, create a description before launching the PR. + +- When _updating_ PR descriptions, the `/describe` tool considers everything above the "PR Type" field as user content and will preserve it. Everything below this marker is treated as previously auto-generated content and will be replaced. ![Describe comment](https://codium.ai/images/pr_agent/pr_description_user_description.png){width=512} From ef2e69dbf317d77619441fdd9b786e735f356d99 Mon Sep 17 00:00:00 2001 From: ofir-frd <85901822+ofir-frd@users.noreply.github.com> Date: Sun, 6 Jul 2025 16:03:30 +0300 Subject: [PATCH 10/53] Hide outdated compression strategy --- docs/docs/core-abilities/index.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/docs/core-abilities/index.md b/docs/docs/core-abilities/index.md index e26640dc..f8ac0f63 100644 --- a/docs/docs/core-abilities/index.md +++ b/docs/docs/core-abilities/index.md @@ -6,8 +6,7 @@ Qodo Merge utilizes a variety of core abilities to provide a comprehensive and e - [Auto best practices](https://qodo-merge-docs.qodo.ai/core-abilities/auto_best_practices/) - [Chat on code suggestions](https://qodo-merge-docs.qodo.ai/core-abilities/chat_on_code_suggestions/) - [Chrome extension](https://qodo-merge-docs.qodo.ai/chrome-extension/) -- [Code validation](https://qodo-merge-docs.qodo.ai/core-abilities/code_validation/) -- [Compression strategy](https://qodo-merge-docs.qodo.ai/core-abilities/compression_strategy/) +- [Code validation](https://qodo-merge-docs.qodo.ai/core-abilities/code_validation/) - [Dynamic context](https://qodo-merge-docs.qodo.ai/core-abilities/dynamic_context/) - [Fetching ticket context](https://qodo-merge-docs.qodo.ai/core-abilities/fetching_ticket_context/) - [Impact evaluation](https://qodo-merge-docs.qodo.ai/core-abilities/impact_evaluation/) From 17a90c536f134693846334097813d06776e9634d Mon Sep 17 00:00:00 2001 From: mrT23 Date: Sun, 6 Jul 2025 21:47:22 +0300 Subject: [PATCH 11/53] docs: add Claude-4 Opus evaluation section with strengths and weaknesses --- docs/docs/pr_benchmark/index.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/docs/docs/pr_benchmark/index.md b/docs/docs/pr_benchmark/index.md index af193411..ace90650 100644 --- a/docs/docs/pr_benchmark/index.md +++ b/docs/docs/pr_benchmark/index.md @@ -82,6 +82,12 @@ A list of the models used for generating the baseline suggestions, and example r 33.5 + + Claude-4-opus-20250514 + 2025-05-14 + + 32.8 + Claude-3.7-sonnet 2025-02-19 @@ -240,6 +246,22 @@ weaknesses: - **Introduces new problems:** Several suggestions add unsupported APIs, undeclared variables, wrong types, or break compilation, hurting trust in the recommendations. - **Rule violations:** It often edits lines outside the diff, exceeds the 3-suggestion cap, or labels cosmetic tweaks as β€œcritical”, showing inconsistent guideline compliance. +### Claude-4 Opus + +final score: **32.8** + +strengths: + +- **Format & rule adherence:** Almost always returns valid YAML, stays within the ≀3-suggestion limit, and usually restricts edits to newly-added lines, so its output is easy to apply automatically. +- **Concise, focused patches:** When it does find a real bug it gives short, well-scoped explanations plus minimal diff snippets, often outperforming verbose baselines in clarity. +- **Able to catch subtle edge-cases:** In several examples it detected overflow, race-condition or enum-mismatch issues that many other models missed, showing solid code‐analysis capability. + +weaknesses: + +- **Low recall / narrow coverage:** In a large share of the 399 examples the model produced an empty list or only one minor tip while more serious defects were present, causing it to be rated inferior to most baselines. +- **Frequent incorrect or no-op fixes:** It sometimes supplies identical β€œbefore/after” code, flags non-issues, or suggests changes that would break compilation or logic, reducing reviewer trust. +- **Shaky guideline consistency:** Although generally compliant, it still occasionally violates rules (touches unchanged lines, offers stylistic advice, adds imports) and duplicates suggestions, indicating unstable internal checks. + ## Appendix - Example Results Some examples of benchmarked PRs and their results: From 34594e54365e6f0da226a83db166e6d5fc772872 Mon Sep 17 00:00:00 2001 From: Abhinav Kumar Date: Mon, 7 Jul 2025 20:11:10 +0530 Subject: [PATCH 12/53] fix: correct typo in configuration comments --- .../code_suggestions/pr_code_suggestions_reflect_prompts.toml | 2 +- pr_agent/settings/configuration.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pr_agent/settings/code_suggestions/pr_code_suggestions_reflect_prompts.toml b/pr_agent/settings/code_suggestions/pr_code_suggestions_reflect_prompts.toml index e3035d12..9e528682 100644 --- a/pr_agent/settings/code_suggestions/pr_code_suggestions_reflect_prompts.toml +++ b/pr_agent/settings/code_suggestions/pr_code_suggestions_reflect_prompts.toml @@ -5,7 +5,7 @@ In addition to evaluating the suggestion correctness and importance, another sub Examine each suggestion meticulously, assessing its quality, relevance, and accuracy within the context of PR. Keep in mind that the suggestions may vary in their correctness, accuracy and impact. Consider the following components of each suggestion: - 1. 'one_sentence_summary' - A one-liner summary summary of the suggestion's purpose + 1. 'one_sentence_summary' - A one-liner summary of the suggestion's purpose 2. 'suggestion_content' - The suggestion content, explaining the proposed modification 3. 'existing_code' - a code snippet from a __new hunk__ section in the PR code diff that the suggestion addresses 4. 'improved_code' - a code snippet demonstrating how the 'existing_code' should be after the suggestion is applied diff --git a/pr_agent/settings/configuration.toml b/pr_agent/settings/configuration.toml index 8c9de39c..e75cfa56 100644 --- a/pr_agent/settings/configuration.toml +++ b/pr_agent/settings/configuration.toml @@ -8,7 +8,7 @@ # models model="o4-mini" fallback_models=["gpt-4.1"] -#model_reasoning="o4-mini" # dedictated reasoning model for self-reflection +#model_reasoning="o4-mini" # dedicated reasoning model for self-reflection #model_weak="gpt-4o" # optional, a weaker model to use for some easier tasks # CLI git_provider="github" From 12af211c13450a025e106afd1a10296c17b899fa Mon Sep 17 00:00:00 2001 From: Abhinav Kumar Date: Mon, 7 Jul 2025 21:14:45 +0530 Subject: [PATCH 13/53] feat: support OpenAI Flex Processing via [litellm] extra_body config --- docs/docs/usage-guide/changing_a_model.md | 10 ++++++++++ pr_agent/algo/ai_handlers/litellm_ai_handler.py | 10 ++++++++++ pr_agent/settings/.secrets_template.toml | 4 ++++ 3 files changed, 24 insertions(+) diff --git a/docs/docs/usage-guide/changing_a_model.md b/docs/docs/usage-guide/changing_a_model.md index 9648e6cf..361abbca 100644 --- a/docs/docs/usage-guide/changing_a_model.md +++ b/docs/docs/usage-guide/changing_a_model.md @@ -32,6 +32,16 @@ OPENAI__API_BASE=https://api.openai.com/v1 OPENAI__KEY=sk-... ``` +### OpenAI Flex Processing + +To reduce costs for non-urgent/background tasks, enable Flex Processing: + +```toml +[litellm] +extra_body='{"processing_mode": "flex"}' +``` + +See [OpenAI Flex Processing docs](https://platform.openai.com/docs/guides/flex-processing) for details. ### Azure diff --git a/pr_agent/algo/ai_handlers/litellm_ai_handler.py b/pr_agent/algo/ai_handlers/litellm_ai_handler.py index ec96d952..ecb84ea7 100644 --- a/pr_agent/algo/ai_handlers/litellm_ai_handler.py +++ b/pr_agent/algo/ai_handlers/litellm_ai_handler.py @@ -364,6 +364,16 @@ class LiteLLMAIHandler(BaseAiHandler): raise ValueError(f"LITELLM.EXTRA_HEADERS contains invalid JSON: {str(e)}") kwargs["extra_headers"] = litellm_extra_headers + # Support for custom OpenAI body fields (e.g., Flex Processing) + if get_settings().get("LITELLM.EXTRA_BODY", None): + try: + litellm_extra_body = json.loads(get_settings().litellm.extra_body) + if not isinstance(litellm_extra_body, dict): + raise ValueError("LITELLM.EXTRA_BODY must be a JSON object") + kwargs.update(litellm_extra_body) + except json.JSONDecodeError as e: + raise ValueError(f"LITELLM.EXTRA_BODY contains invalid JSON: {str(e)}") + get_logger().debug("Prompts", artifact={"system": system, "user": user}) if get_settings().config.verbosity_level >= 2: diff --git a/pr_agent/settings/.secrets_template.toml b/pr_agent/settings/.secrets_template.toml index 350abe5c..c3d7a3f9 100644 --- a/pr_agent/settings/.secrets_template.toml +++ b/pr_agent/settings/.secrets_template.toml @@ -16,6 +16,10 @@ key = "" # Acquire through https://platform.openai.com #deployment_id = "" # The deployment name you chose when you deployed the engine #fallback_deployments = [] # For each fallback model specified in configuration.toml in the [config] section, specify the appropriate deployment_id +# OpenAI Flex Processing (optional, for cost savings) +# [litellm] +# extra_body='{"processing_mode": "flex"}' + [pinecone] api_key = "..." environment = "gcp-starter" From 6a55bbcd2332278e277888a0d2e5111ecc2e25d5 Mon Sep 17 00:00:00 2001 From: Abhinav Kumar Date: Mon, 7 Jul 2025 21:20:25 +0530 Subject: [PATCH 14/53] fix: prevent LITELLM.EXTRA_BODY from overriding existing parameters in LiteLLMAIHandler --- pr_agent/algo/ai_handlers/litellm_ai_handler.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pr_agent/algo/ai_handlers/litellm_ai_handler.py b/pr_agent/algo/ai_handlers/litellm_ai_handler.py index ecb84ea7..14d98546 100644 --- a/pr_agent/algo/ai_handlers/litellm_ai_handler.py +++ b/pr_agent/algo/ai_handlers/litellm_ai_handler.py @@ -365,11 +365,14 @@ class LiteLLMAIHandler(BaseAiHandler): kwargs["extra_headers"] = litellm_extra_headers # Support for custom OpenAI body fields (e.g., Flex Processing) - if get_settings().get("LITELLM.EXTRA_BODY", None): + if get_settings().litellm.extra_body: try: litellm_extra_body = json.loads(get_settings().litellm.extra_body) if not isinstance(litellm_extra_body, dict): raise ValueError("LITELLM.EXTRA_BODY must be a JSON object") + colliding_keys = kwargs.keys() & litellm_extra_body.keys() + if colliding_keys: + raise ValueError(f"LITELLM.EXTRA_BODY cannot override existing parameters: {', '.join(colliding_keys)}") kwargs.update(litellm_extra_body) except json.JSONDecodeError as e: raise ValueError(f"LITELLM.EXTRA_BODY contains invalid JSON: {str(e)}") From 8127d52ab3035bfc0c8358a133e94f66ee8c38a6 Mon Sep 17 00:00:00 2001 From: Abhinav Kumar Date: Mon, 7 Jul 2025 21:26:13 +0530 Subject: [PATCH 15/53] fix: security checks --- pr_agent/algo/ai_handlers/litellm_ai_handler.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/pr_agent/algo/ai_handlers/litellm_ai_handler.py b/pr_agent/algo/ai_handlers/litellm_ai_handler.py index 14d98546..cececc60 100644 --- a/pr_agent/algo/ai_handlers/litellm_ai_handler.py +++ b/pr_agent/algo/ai_handlers/litellm_ai_handler.py @@ -365,11 +365,17 @@ class LiteLLMAIHandler(BaseAiHandler): kwargs["extra_headers"] = litellm_extra_headers # Support for custom OpenAI body fields (e.g., Flex Processing) - if get_settings().litellm.extra_body: + # Only allow whitelisted keys for security + allowed_extra_body_keys = {"processing_mode", "service_tier"} + extra_body = getattr(getattr(get_settings(), "litellm", None), "extra_body", None) + if extra_body: try: - litellm_extra_body = json.loads(get_settings().litellm.extra_body) + litellm_extra_body = json.loads(extra_body) if not isinstance(litellm_extra_body, dict): raise ValueError("LITELLM.EXTRA_BODY must be a JSON object") + unsupported_keys = set(litellm_extra_body.keys()) - allowed_extra_body_keys + if unsupported_keys: + raise ValueError(f"LITELLM.EXTRA_BODY contains unsupported keys: {', '.join(unsupported_keys)}. Allowed keys: {', '.join(allowed_extra_body_keys)}") colliding_keys = kwargs.keys() & litellm_extra_body.keys() if colliding_keys: raise ValueError(f"LITELLM.EXTRA_BODY cannot override existing parameters: {', '.join(colliding_keys)}") From e2d71acb9d28ed26282c3196c9f5b34cb880c59b Mon Sep 17 00:00:00 2001 From: Abhinav Kumar Date: Mon, 7 Jul 2025 21:27:35 +0530 Subject: [PATCH 16/53] fix: remove comments --- pr_agent/algo/ai_handlers/litellm_ai_handler.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pr_agent/algo/ai_handlers/litellm_ai_handler.py b/pr_agent/algo/ai_handlers/litellm_ai_handler.py index cececc60..2dd4ad31 100644 --- a/pr_agent/algo/ai_handlers/litellm_ai_handler.py +++ b/pr_agent/algo/ai_handlers/litellm_ai_handler.py @@ -365,7 +365,6 @@ class LiteLLMAIHandler(BaseAiHandler): kwargs["extra_headers"] = litellm_extra_headers # Support for custom OpenAI body fields (e.g., Flex Processing) - # Only allow whitelisted keys for security allowed_extra_body_keys = {"processing_mode", "service_tier"} extra_body = getattr(getattr(get_settings(), "litellm", None), "extra_body", None) if extra_body: From 3f632835c5705085ce775e1af0d93c08b50c29b8 Mon Sep 17 00:00:00 2001 From: Abhinav Kumar Date: Mon, 7 Jul 2025 21:51:35 +0530 Subject: [PATCH 17/53] fix: Remove trailing comma in gerrit provider prepare_repo function --- pr_agent/git_providers/gerrit_provider.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pr_agent/git_providers/gerrit_provider.py b/pr_agent/git_providers/gerrit_provider.py index ba587656..ced150c9 100644 --- a/pr_agent/git_providers/gerrit_provider.py +++ b/pr_agent/git_providers/gerrit_provider.py @@ -103,7 +103,7 @@ def prepare_repo(url: urllib3.util.Url, project, refspec): repo_url = (f"{url.scheme}://{url.auth}@{url.host}:{url.port}/{project}") directory = pathlib.Path(mkdtemp()) - clone(repo_url, directory), + clone(repo_url, directory) fetch(repo_url, refspec, cwd=directory) checkout(cwd=directory) return directory From 017db5b63c96bf122d28eb5a9918b92fa2dbdbba Mon Sep 17 00:00:00 2001 From: Abhinav Kumar Date: Tue, 8 Jul 2025 01:51:59 +0530 Subject: [PATCH 18/53] fix: Correct resultsContainer handling --- docs/docs/ai_search/index.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/docs/ai_search/index.md b/docs/docs/ai_search/index.md index b80d0d6d..e240e0b4 100644 --- a/docs/docs/ai_search/index.md +++ b/docs/docs/ai_search/index.md @@ -19,7 +19,6 @@