Compare commits

..

24 Commits

Author SHA1 Message Date
2fc0e462c4 docs: update describe tool configuration table with missing options 2025-02-16 15:36:18 +02:00
3f1987248e docs: add override title config by tag name option to describe tool table 2025-02-16 15:21:42 +02:00
778d00d1a0 Merge remote-tracking branch 'origin/main' 2025-02-15 11:32:43 +02:00
cc8d5a6c50 docs: fix broken links in GitLab Server installation section 2025-02-15 11:32:32 +02:00
Tal
62c47f9cb5 Merge pull request #1536 from PeterDaveHelloKitchen/OptimizeDockerfile
Use `pip install` with `--no-cache-dir` in `Dockerfile.github_action`
2025-02-15 11:25:41 +02:00
bb31b0c66b docs: update Qodo Merge installation guide with GitLab Server details 2025-02-15 11:23:52 +02:00
Tal
359c963ad1 Merge pull request #1531 from hi120ki/add-pull-request-target-event
Add : pull_request_target event on GitHub Actions integration
2025-02-15 08:08:20 +02:00
130b1ff4fb Use pip install with --no-cache-dir in Dockerfile.github_action 2025-02-15 00:17:02 +08:00
Tal
605a4b99ad Merge pull request #1534 from qodo-ai/tr/help_r
feat: improve help tool with markdown header formatting and error han…
2025-02-13 11:50:59 +02:00
b989f41b96 fix: correct typo in help tool message ("be" -> "can be") 2025-02-13 11:48:07 +02:00
26168a605b fix: correct typo in help tool message ("be" -> "can be") 2025-02-13 11:47:21 +02:00
2c37b02aa0 feat: improve help tool with markdown header formatting and error handling 2025-02-13 11:44:50 +02:00
Tal
a2550870c2 Merge pull request #1532 from qodo-ai/tr/review_effort
fix: update review effort label format to use X/5 notation
2025-02-13 09:25:53 +02:00
279c6ead8f fix: update review effort label format to use X/5 notation 2025-02-13 08:41:25 +02:00
c9500cf796 Add : pull_request_target event on GitHub Actions integration
Signed-off-by: Hi120ki <12624257+hi120ki@users.noreply.github.com>
2025-02-13 12:03:30 +09:00
77204faa51 docs: clarify open-source models usage scope in model selection guide 2025-02-11 10:24:16 +02:00
43fb8ff433 docs: fix broken link to Qodo Merge models documentation 2025-02-11 08:49:05 +02:00
cd129d8b27 docs: fix broken link to Qodo Merge models documentation 2025-02-11 08:47:04 +02:00
Tal
04aff0d3b2 Update README.md 2025-02-07 20:51:21 +02:00
Tal
be1dd4bd20 Update README.md 2025-02-06 18:10:37 +02:00
Tal
b3b89e7138 Merge pull request #1522 from qodo-ai/tr/readme_34
docs: update README with new design and remove outdated news
2025-02-06 18:06:17 +02:00
9045723084 docs: adjust Qodo Merge link formatting in README 2025-02-06 18:04:31 +02:00
34e22a2c8e docs: update image URL in README for /improve tool screenshot 2025-02-06 18:02:40 +02:00
1d784c60cb docs: update README with new design and remove outdated news 2025-02-06 17:59:40 +02:00
14 changed files with 104 additions and 106 deletions

View File

@ -3,7 +3,7 @@ FROM python:3.12 as base
WORKDIR /app
ADD pyproject.toml .
ADD requirements.txt .
RUN pip install . && rm pyproject.toml requirements.txt
RUN pip install --no-cache-dir . && rm pyproject.toml requirements.txt
ENV PYTHONPATH=/app
ADD docs docs
ADD pr_agent pr_agent

View File

@ -1,48 +0,0 @@
## 📌 Pull Request Template
### 1⃣ Short Description
<!-- Provide a concise summary of the changes in this PR. -->
---
### 2⃣ Related Open Issue
<!-- Link the related issue(s) this PR is addressing, e.g., Fixes #123 or Closes #456. -->
Fixes #
---
### 3⃣ PR Type
<!-- Select one of the following by marking `[x]` -->
- [ ] 🐞 Bug Fix
- [ ] ✨ New Feature
- [ ] 🔄 Refactoring
- [ ] 📖 Documentation Update
---
### 4⃣ Does this PR Introduce a Breaking Change?
<!-- Mark the applicable option -->
- [ ] ❌ No
- [ ] ⚠️ Yes (Explain below)
If **yes**, describe the impact and necessary migration steps:
<!-- Provide a short explanation of what needs to be changed. -->
---
### 5⃣ Current Behavior (Before Changes)
<!-- Describe the existing behavior before applying the changes in this PR. -->
---
### 6⃣ New Behavior (After Changes)
<!-- Explain how the behavior changes with this PR. -->
---
### ✅ Checklist
- [ ] Code follows the project's coding guidelines.
- [ ] Tests have been added or updated (if applicable).
- [ ] Documentation has been updated (if applicable).
- [ ] Ready for review and approval.

View File

@ -10,6 +10,12 @@
</picture>
<br/>
[Installation Guide](https://qodo-merge-docs.qodo.ai/installation/) |
[Usage Guide](https://qodo-merge-docs.qodo.ai/usage-guide/) |
[Tools Guide](https://qodo-merge-docs.qodo.ai/tools/) |
[Qodo Merge](https://qodo-merge-docs.qodo.ai/overview/pr_agent_pro/) 💎
PR-Agent aims to help efficiently review and handle pull requests, by providing AI feedback and suggestions
</div>
@ -22,13 +28,16 @@ PR-Agent aims to help efficiently review and handle pull requests, by providing
</a>
</div>
### [Documentation](https://qodo-merge-docs.qodo.ai/)
[//]: # (### [Documentation]&#40;https://qodo-merge-docs.qodo.ai/&#41;)
- See the [Installation Guide](https://qodo-merge-docs.qodo.ai/installation/) for instructions on installing PR-Agent on different platforms.
[//]: # ()
[//]: # (- See the [Installation Guide]&#40;https://qodo-merge-docs.qodo.ai/installation/&#41; for instructions on installing PR-Agent on different platforms.)
- See the [Usage Guide](https://qodo-merge-docs.qodo.ai/usage-guide/) for instructions on running PR-Agent tools via different interfaces, such as CLI, PR Comments, or by automatically triggering them when a new PR is opened.
[//]: # ()
[//]: # (- See the [Usage Guide]&#40;https://qodo-merge-docs.qodo.ai/usage-guide/&#41; for instructions on running PR-Agent tools via different interfaces, such as CLI, PR Comments, or by automatically triggering them when a new PR is opened.)
- See the [Tools Guide](https://qodo-merge-docs.qodo.ai/tools/) for a detailed description of the different tools, and the available configurations for each tool.
[//]: # ()
[//]: # (- See the [Tools Guide]&#40;https://qodo-merge-docs.qodo.ai/tools/&#41; for a detailed description of the different tools, and the available configurations for each tool.)
## Table of Contents
@ -37,12 +46,17 @@ PR-Agent aims to help efficiently review and handle pull requests, by providing
- [Overview](#overview)
- [Example results](#example-results)
- [Try it now](#try-it-now)
- [Qodo Merge 💎](https://qodo-merge-docs.qodo.ai/overview/pr_agent_pro/)
- [Qodo Merge](https://qodo-merge-docs.qodo.ai/overview/pr_agent_pro/)
- [How it works](#how-it-works)
- [Why use PR-Agent?](#why-use-pr-agent)
## News and Updates
### Feb 6, 2025
New design for the `/improve` tool:
<kbd><img src="https://github.com/user-attachments/assets/26506430-550e-469a-adaa-af0a09b70c6d" width="512"></kbd>
### Jan 25, 2025
The open-source GitHub organization was updated:
@ -69,40 +83,7 @@ Update logic and [documentation](https://qodo-merge-docs.qodo.ai/usage-guide/cha
### December 30, 2024
Following feedback from the community, we have addressed two vulnerabilities identified in the open-source PR-Agent project. The fixes are now included in the newly released version (v0.26), available as of today.
### December 25, 2024
The `review` tool previously included a legacy feature for providing code suggestions (controlled by '--pr_reviewer.num_code_suggestion'). This functionality has been deprecated. Use instead the [`improve`](https://qodo-merge-docs.qodo.ai/tools/improve/) tool, which offers higher quality and more actionable code suggestions.
### December 2, 2024
Open-source repositories can now freely use Qodo Merge, and enjoy easy one-click installation using a marketplace [app](https://github.com/apps/qodo-merge-pro-for-open-source).
<kbd><img src="https://github.com/user-attachments/assets/b0838724-87b9-43b0-ab62-73739a3a855c" width="512"></kbd>
See [here](https://qodo-merge-docs.qodo.ai/installation/pr_agent_pro/) for more details about installing Qodo Merge for private repositories.
### November 18, 2024
A new mode was enabled by default for code suggestions - `--pr_code_suggestions.focus_only_on_problems=true`:
- This option reduces the number of code suggestions received
- The suggestions will focus more on identifying and fixing code problems, rather than style considerations like best practices, maintainability, or readability.
- The suggestions will be categorized into just two groups: "Possible Issues" and "General".
Still, if you prefer the previous mode, you can set `--pr_code_suggestions.focus_only_on_problems=false` in the [configuration file](https://qodo-merge-docs.qodo.ai/usage-guide/configuration_options/).
**Example results:**
Original mode
<kbd><img src="https://qodo.ai/images/pr_agent/code_suggestions_original_mode.png" width="512"></kbd>
Focused mode
<kbd><img src="https://qodo.ai/images/pr_agent/code_suggestions_focused_mode.png" width="512"></kbd>
Following feedback from the community, we have addressed two vulnerabilities identified in the open-source PR-Agent project. The [fixes](https://github.com/qodo-ai/pr-agent/pull/1425) are now included in the newly released version (v0.26), available as of today.
## Overview

View File

@ -15,7 +15,7 @@ Qodo Merge for GitHub cloud is available for installation through the [GitHub Ma
### GitHub Enterprise Server
To use Qodo Merge application on your private GitHub Enterprise Server, you will need to contact us for starting an [Enterprise](https://www.codium.ai/pricing/) trial.
To use Qodo Merge application on your private GitHub Enterprise Server, you will need to [contact](https://www.qodo.ai/contact/#pricing) Qodo for starting an Enterprise trial.
### GitHub Open Source Projects
@ -34,7 +34,9 @@ Qodo Merge for Bitbucket Cloud is available for installation through the followi
To use Qodo Merge application on your private Bitbucket Server, you will need to contact us for starting an [Enterprise](https://www.qodo.ai/pricing/) trial.
## Install Qodo Merge for GitLab (Teams & Enterprise)
## Install Qodo Merge for GitLab
### GitLab Cloud
Since GitLab platform does not support apps, installing Qodo Merge for GitLab is a bit more involved, and requires the following steps:
@ -79,3 +81,7 @@ Enable SSL verification: Check the box.
Youre all set!
Open a new merge request or add a MR comment with one of Qodo Merges commands such as /review, /describe or /improve.
### GitLab Server
For a trial period of two weeks on your private GitLab Server, the same [installation steps](#gitlab-cloud) as for GitLab Cloud apply. After the trial period, you will need to [contact](https://www.qodo.ai/contact/#pricing) Qodo for moving to an Enterprise account.

View File

@ -1,6 +1,6 @@
### Overview
[Qodo Merge](https://www.codium.ai/pricing/){:target="_blank"} is a hosted version of open-source [PR-Agent](https://github.com/Codium-ai/pr-agent){:target="_blank"}. A complimentary two-week trial is offered, followed by a monthly subscription fee.
[Qodo Merge](https://www.codium.ai/pricing/){:target="_blank"} is a paid, hosted version of open-source [PR-Agent](https://github.com/Codium-ai/pr-agent){:target="_blank"}. A complimentary two-week trial is offered, followed by a monthly subscription fee.
Qodo Merge is designed for companies and teams that require additional features and capabilities. It provides the following benefits:
1. **Fully managed** - We take care of everything for you - hosting, models, regular updates, and more. Installation is as simple as signing up and adding the Qodo Merge app to your GitHub\GitLab\BitBucket repo.

View File

@ -85,7 +85,19 @@ publish_labels = true
</tr>
<tr>
<td><b>collapsible_file_list</b></td>
<td>If set to true, the file list in the "Changes walkthrough" section will be collapsible. If set to "adaptive", the file list will be collapsible only if there are more than 8 files. Default is "adaptive".</td>
<td>If set to true, the file list in the "Changes walkthrough" section will be collapsible. If set to "adaptive", the file list will be collapsible only if the number of files exceeds the threshold defined by `collapsible_file_list_threshold`. Default is "adaptive".</td>
</tr>
<tr>
<td><b>collapsible_file_list_threshold</b></td>
<td>The number of files threshold for when to make the file list collapsible when using 'adaptive' mode. Default is 8.</td>
</tr>
<tr>
<td><b>inline_file_summary</b></td>
<td>Controls where and how file summaries are displayed:
<br>- 'table': Displays file changes walkthrough table on both "Files changed" and "Conversation" tabs
<br>- true: Adds a collapsible file comment with changes title and summary for each file
<br>- false: Shows file changes walkthrough only in the "Conversation" tab
<br>Default is false.</td>
</tr>
<tr>
<td><b>enable_large_pr_handling</b></td>
@ -95,6 +107,14 @@ publish_labels = true
<td><b>enable_help_text</b></td>
<td>If set to true, the tool will display a help text in the comment. Default is false.</td>
</tr>
<tr>
<td><b>enable_help_comment</b></td>
<td>If set to true, the help guidance text is displayed in the comment. Default is true.</td>
</tr>
<tr>
<td><b>enable_override_title_with_parent_tag</b></td>
<td>If set to true, the tool will set the PR title to the next patch version from the latest tag in the target branch, with an RC suffix (e.g., v1.0.1-rc.1). Default is false.</td>
</tr>
</table>

View File

@ -51,7 +51,7 @@ api_base = "http://localhost:11434" # or whatever port you're running Ollama on
Commercial models such as GPT-4, Claude Sonnet, and Gemini have demonstrated robust capabilities in generating structured output for code analysis tasks with large input. In contrast, most open-source models currently available (as of January 2025) face challenges with these complex tasks.
Based on our testing, local open-source models are suitable for experimentation and learning purposes, but they are not suitable for production-level code analysis tasks.
Based on our testing, local open-source models are suitable for experimentation and learning purposes (mainly for the `ask` command), but they are not suitable for production-level code analysis tasks.
Hence, for production workflows and real-world usage, we recommend using commercial models.

View File

@ -24,4 +24,4 @@ It includes information on how to adjust Qodo Merge configurations, define which
- [Changing a model](./additional_configurations.md#changing-a-model)
- [Patch Extra Lines](./additional_configurations.md#patch-extra-lines)
- [Editing the prompts](./additional_configurations.md#editing-the-prompts)
- [Qodo Merge Models](./PR_agent_pro_models.md)
- [Qodo Merge Models](./qodo_merge_models)

View File

@ -1,4 +1,3 @@
## Qodo Merge Models
The default models used by Qodo Merge are a combination of Claude-3.5-sonnet and OpenAI's GPT-4 models.

View File

@ -20,7 +20,7 @@ nav:
- Managing Mail Notifications: 'usage-guide/mail_notifications.md'
- Changing a Model: 'usage-guide/changing_a_model.md'
- Additional Configurations: 'usage-guide/additional_configurations.md'
- 💎 Qodo Merge Models: 'usage-guide/PR_agent_pro_models'
- 💎 Qodo Merge Models: 'usage-guide/qodo_merge_models.md'
- Tools:
- 'tools/index.md'
- Describe: 'tools/describe.md'

View File

@ -81,7 +81,7 @@ async def run_action():
get_logger().info(f"github action: failed to apply repo settings: {e}")
# Handle pull request opened event
if GITHUB_EVENT_NAME == "pull_request":
if GITHUB_EVENT_NAME == "pull_request" or GITHUB_EVENT_NAME == "pull_request_target":
action = event_payload.get("action")
# Retrieve the list of actions from the configuration

View File

@ -13,7 +13,7 @@ The output must be a YAML object equivalent to type $DocHelper, according to the
=====
class relevant_section(BaseModel):
file_name: str = Field(description="The name of the relevant file")
relevant_section_header_string: str = Field(description="From the relevant file, exact text of the relevant section heading. If no markdown heading is relevant, return empty string")
relevant_section_header_string: str = Field(description="The exact text of the relevant markdown section heading from the relevant file (starting with '#', '##', etc.). Return empty string if the entire file is the relevant section, or if the relevant section has no heading")
class DocHelper(BaseModel):
user_question: str = Field(description="The user's question")

View File

@ -1,4 +1,5 @@
import copy
import re
from functools import partial
from pathlib import Path
@ -9,10 +10,9 @@ from pr_agent.algo.ai_handlers.base_ai_handler import BaseAiHandler
from pr_agent.algo.ai_handlers.litellm_ai_handler import LiteLLMAIHandler
from pr_agent.algo.pr_processing import retry_with_fallback_models
from pr_agent.algo.token_handler import TokenHandler
from pr_agent.algo.utils import ModelType, clip_tokens, load_yaml
from pr_agent.algo.utils import ModelType, clip_tokens, load_yaml, get_max_tokens
from pr_agent.config_loader import get_settings
from pr_agent.git_providers import (BitbucketServerProvider, GithubProvider,
get_git_provider_with_context)
from pr_agent.git_providers import BitbucketServerProvider, GithubProvider, get_git_provider_with_context
from pr_agent.log import get_logger
@ -30,10 +30,11 @@ def extract_header(snippet):
return res
class PRHelpMessage:
def __init__(self, pr_url: str, args=None, ai_handler: partial[BaseAiHandler,] = LiteLLMAIHandler):
def __init__(self, pr_url: str, args=None, ai_handler: partial[BaseAiHandler,] = LiteLLMAIHandler, return_as_string=False):
self.git_provider = get_git_provider_with_context(pr_url)
self.ai_handler = ai_handler()
self.question_str = self.parse_args(args)
self.return_as_string = return_as_string
self.num_retrieved_snippets = get_settings().get('pr_help.num_retrieved_snippets', 5)
if self.question_str:
self.vars = {
@ -65,6 +66,34 @@ class PRHelpMessage:
question_str = ""
return question_str
def format_markdown_header(self, header: str) -> str:
try:
# First, strip common characters from both ends
cleaned = header.strip('# 💎\n')
# Define all characters to be removed/replaced in a single pass
replacements = {
"'": '',
"`": '',
'(': '',
')': '',
',': '',
'.': '',
'?': '',
'!': '',
' ': '-'
}
# Compile regex pattern for characters to remove
pattern = re.compile('|'.join(map(re.escape, replacements.keys())))
# Perform replacements in a single pass and convert to lowercase
return pattern.sub(lambda m: replacements[m.group()], cleaned).lower()
except Exception:
get_logger().exception(f"Error while formatting markdown header", artifacts={'header': header})
return ""
async def run(self):
try:
if self.question_str:
@ -106,7 +135,10 @@ class PRHelpMessage:
get_logger().debug(f"Token count of full documentation website: {token_count}")
model = get_settings().config.model
max_tokens_full = MAX_TOKENS[model] # note - here we take the actual max tokens, without any reductions. we do aim to get the full documentation website in the prompt
if model in MAX_TOKENS:
max_tokens_full = MAX_TOKENS[model] # note - here we take the actual max tokens, without any reductions. we do aim to get the full documentation website in the prompt
else:
max_tokens_full = get_max_tokens(model)
delta_output = 2000
if token_count > max_tokens_full - delta_output:
get_logger().info(f"Token count {token_count} exceeds the limit {max_tokens_full - delta_output}. Skipping the PR Help message.")
@ -114,8 +146,16 @@ class PRHelpMessage:
self.vars['snippets'] = docs_prompt.strip()
# run the AI model
response = await retry_with_fallback_models(self._prepare_prediction, model_type=ModelType.WEAK)
response = await retry_with_fallback_models(self._prepare_prediction, model_type=ModelType.REGULAR)
response_yaml = load_yaml(response)
if isinstance(response_yaml, str):
get_logger().warning(f"failing to parse response: {response_yaml}, publishing the response as is")
if get_settings().config.publish_output:
answer_str = f"### Question: \n{self.question_str}\n\n"
answer_str += f"### Answer:\n\n"
answer_str += response_yaml
self.git_provider.publish_comment(answer_str)
return ""
response_str = response_yaml.get('response')
relevant_sections = response_yaml.get('relevant_sections')
@ -138,7 +178,7 @@ class PRHelpMessage:
for section in relevant_sections:
file = section.get('file_name').strip().removesuffix('.md')
if str(section['relevant_section_header_string']).strip():
markdown_header = section['relevant_section_header_string'].strip().strip('#').strip().lower().replace(' ', '-').replace("'", '').replace('(', '').replace(')', '').replace(',', '').replace('.', '').replace('?', '').replace('!', '')
markdown_header = self.format_markdown_header(section['relevant_section_header_string'])
answer_str += f"> - {base_path}{file}#{markdown_header}\n"
else:
answer_str += f"> - {base_path}{file}\n"

View File

@ -371,7 +371,7 @@ class PRReviewer:
else:
get_logger().warning(f"Unexpected type for estimated_effort: {type(estimated_effort)}")
if 1 <= estimated_effort_number <= 5: # 1, because ...
review_labels.append(f'Review effort [1-5]: {estimated_effort_number}')
review_labels.append(f'Review effort {estimated_effort_number}/5')
if get_settings().pr_reviewer.enable_review_labels_security and get_settings().pr_reviewer.require_security_review:
security_concerns = data['review']['security_concerns'] # yes, because ...
security_concerns_bool = 'yes' in security_concerns.lower() or 'true' in security_concerns.lower()