diff --git a/CONFIGURATION.md b/CONFIGURATION.md deleted file mode 100644 index 66ec4f06..00000000 --- a/CONFIGURATION.md +++ /dev/null @@ -1,80 +0,0 @@ -## Configuration - -The different tools and sub-tools used by CodiumAI PR-Agent are adjustable via the **[configuration file](pr_agent/settings/configuration.toml)** - -### Working from CLI -When running from source (CLI), your local configuration file will be initially used. - -Example for invoking the 'review' tools via the CLI: - -``` -python cli.py --pr-url= review -``` -In addition to general configurations, the 'review' tool will use parameters from the `[pr_reviewer]` section (every tool has a dedicated section in the configuration file). - -Note that you can print results locally, without publishing them, by setting in `configuration.toml`: - -``` -[config] -publish_output=true -verbosity_level=2 -``` -This is useful for debugging or experimenting with the different tools. - -### Working from GitHub App (pre-built repo) -When running PR-Agent from GitHub App, the default configuration file (`configuration.toml`) will be loaded. - -#### GitHub app default tools -The `[github_app]` section of the configuration file defines GitHub app specific configurations. -The important parameter is `pr_commands`, which is a list of tools that will be run automatically when a new PR is opened: -``` -[github_app] -pr_commands = [ - "/describe --pr_description.add_original_user_description=true --pr_description.keep_original_user_title=true", - "/auto_review", -] -``` -This means that when a new PR is opened, PR-Agent will run the `describe` and `auto_review` tools. -For the describe tool, the `add_original_user_description` and `keep_original_user_title` parameters will be set to `true`. - -However, you can override the default tool parameters by uploading a local configuration file called `.pr_agent.toml` to the root of your repo. -For example, if your local `.pr_agent.toml` file contains: -``` -[pr_description] -add_original_user_description = false -keep_original_user_title = false -``` -Then when a new PR is opened, PR-Agent will run the `describe` tool with the above parameters. - -Note that a local `.pr_agent.toml` file enables you to edit and customize the default parameters of any tool, not just the ones that are run automatically. - -#### Online usage -For online usage (calling tools by comments on a PR like `/ask ...`), just add `--config_path=` to any command, to edit a specific configuration value. -For example if you want to edit `pr_reviewer` configurations, you can run: -``` -/review --pr_reviewer.extra_instructions="..." --pr_reviewer.require_score_review=false ... -``` -Any configuration value in `configuration.toml` file can be similarly edited. - - -### General configuration walkthrough - -#### Changing a model -See [here](pr_agent/algo/__init__.py) for the list of available models. - -To use Llama2 model, for example, set: -``` -[config] -model = "replicate/llama-2-70b-chat:2c1608e18606fad2812020dc541930f2d0495ce32eee50074220b87300bc16e1" -[replicate] -key = ... -``` -(you can obtain a Llama2 key from [here](https://replicate.com/replicate/llama-2-70b-chat/api)) - -Also review the [AiHandler](pr_agent/algo/ai_handler.py) file for instruction how to set keys for other models. - -#### Extra instructions -All PR-Agent tools have a parameter called `extra_instructions`, that enables to add free-text extra instructions. Example usage: -``` -/update_changelog --pr_update_changelog.extra_instructions="Make sure to update also the version ..." -``` \ No newline at end of file diff --git a/INSTALL.md b/INSTALL.md index ba2547b1..74368ac0 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -9,8 +9,8 @@ To get started with PR-Agent quickly, you first need to acquire two tokens: There are several ways to use PR-Agent: - [Method 1: Use Docker image (no installation required)](INSTALL.md#method-1-use-docker-image-no-installation-required) -- [Method 2: Run as a GitHub Action](INSTALL.md#method-2-run-as-a-github-action) -- [Method 3: Run from source](INSTALL.md#method-3-run-from-source) +- [Method 2: Run from source](INSTALL.md#method-2-run-from-source) +- [Method 3: Run as a GitHub Action](INSTALL.md#method-3-run-as-a-github-action) - [Method 4: Run as a polling server](INSTALL.md#method-4-run-as-a-polling-server) - [Method 5: Run as a GitHub App](INSTALL.md#method-5-run-as-a-github-app) - [Method 6: Deploy as a Lambda Function](INSTALL.md#method-6---deploy-as-a-lambda-function) @@ -55,7 +55,41 @@ Possible questions you can ask include: --- -### Method 2: Run as a GitHub Action +### Method 2: Run from source + +1. Clone this repository: + +``` +git clone https://github.com/Codium-ai/pr-agent.git +``` + +2. Install the requirements in your favorite virtual environment: + +``` +pip install -r requirements.txt +``` + +3. Copy the secrets template file and fill in your OpenAI key and your GitHub user token: + +``` +cp pr_agent/settings/.secrets_template.toml pr_agent/settings/.secrets.toml +chmod 600 pr_agent/settings/.secrets.toml +# Edit .secrets.toml file +``` + +4. Add the pr_agent folder to your PYTHONPATH, then run the cli.py script: + +``` +export PYTHONPATH=[$PYTHONPATH:] +python pr_agent/cli.py --pr_url /review +python pr_agent/cli.py --pr_url /ask +python pr_agent/cli.py --pr_url /describe +python pr_agent/cli.py --pr_url /improve +``` + +--- + +### Method 3: Run as a GitHub Action You can use our pre-built Github Action Docker image to run PR-Agent as a Github Action. @@ -114,7 +148,7 @@ The GITHUB_TOKEN secret is automatically created by GitHub. 3. Merge this change to your main branch. When you open your next PR, you should see a comment from `github-actions` bot with a review of your PR, and instructions on how to use the rest of the tools. -4. You may configure PR-Agent by adding environment variables under the env section corresponding to any configurable property in the [configuration](./CONFIGURATION.md) file. Some examples: +4. You may configure PR-Agent by adding environment variables under the env section corresponding to any configurable property in the [configuration](./Usage.md) file. Some examples: ```yaml env: # ... previous environment values @@ -125,40 +159,6 @@ When you open your next PR, you should see a comment from `github-actions` bot w --- -### Method 3: Run from source - -1. Clone this repository: - -``` -git clone https://github.com/Codium-ai/pr-agent.git -``` - -2. Install the requirements in your favorite virtual environment: - -``` -pip install -r requirements.txt -``` - -3. Copy the secrets template file and fill in your OpenAI key and your GitHub user token: - -``` -cp pr_agent/settings/.secrets_template.toml pr_agent/settings/.secrets.toml -chmod 600 pr_agent/settings/.secrets.toml -# Edit .secrets.toml file -``` - -4. Add the pr_agent folder to your PYTHONPATH, then run the cli.py script: - -``` -export PYTHONPATH=[$PYTHONPATH:] -python pr_agent/cli.py --pr_url review -python pr_agent/cli.py --pr_url ask -python pr_agent/cli.py --pr_url describe -python pr_agent/cli.py --pr_url improve -``` - ---- - ### Method 4: Run as a polling server Request reviews by tagging your Github user on a PR @@ -251,6 +251,9 @@ docker push codiumai/pr-agent:github_app # Push to your Docker repository 9. Install the app by navigating to the "Install App" tab and selecting your desired repositories. +> **Note:** When running PR-Agent from GitHub App, the default configuration file (configuration.toml) will be loaded.
+> However, you can override the default tool parameters by uploading a local configuration file
+> For more information please check out [CONFIGURATION.md](Usage.md#working-from-github-app-pre-built-repo) --- ### Method 6 - Deploy as a Lambda Function diff --git a/README.md b/README.md index fa9bd89b..31de5d6e 100644 --- a/README.md +++ b/README.md @@ -17,17 +17,20 @@ Making pull requests less painful with an AI agent CodiumAI `PR-Agent` is an open-source tool aiming to help developers review pull requests faster and more efficiently. It automatically analyzes the pull request and can provide several types of PR feedback: -**Auto-Description**: Automatically generating [PR description](https://github.com/Codium-ai/pr-agent/pull/229#issue-1860711415) - title, type, summary, code walkthrough and labels. +**Auto Description (/describe)**: Automatically generating [PR description](https://github.com/Codium-ai/pr-agent/pull/229#issue-1860711415) - title, type, summary, code walkthrough and labels. \ -**Auto Review**: [Adjustable feedback](https://github.com/Codium-ai/pr-agent/pull/229#issuecomment-1695022908) about the PR main theme, type, relevant tests, security issues, score, and various suggestions for the PR content. +**Auto Review (/review)**: [Adjustable feedback](https://github.com/Codium-ai/pr-agent/pull/229#issuecomment-1695022908) about the PR main theme, type, relevant tests, security issues, score, and various suggestions for the PR content. \ -**Question Answering**: Answering [free-text questions](https://github.com/Codium-ai/pr-agent/pull/229#issuecomment-1695021332) about the PR. +**Question Answering (/ask ...)**: Answering [free-text questions](https://github.com/Codium-ai/pr-agent/pull/229#issuecomment-1695021332) about the PR. \ -**Code Suggestions**: [Committable code suggestions](https://github.com/Codium-ai/pr-agent/pull/229#discussion_r1306919276) for improving the PR. +**Code Suggestions (/improve)**: [Committable code suggestions](https://github.com/Codium-ai/pr-agent/pull/229#discussion_r1306919276) for improving the PR. \ -**Update Changelog**: Automatically updating the CHANGELOG.md file with the [PR changes](https://github.com/Codium-ai/pr-agent/pull/168#discussion_r1282077645). +**Update Changelog (/update_changelog)**: Automatically updating the CHANGELOG.md file with the [PR changes](https://github.com/Codium-ai/pr-agent/pull/168#discussion_r1282077645). -

Example results:

+ +See the [usage guide](./Usage.md) for instructions how to run the different tools from [CLI](./Usage.md#working-from-a-local-repo-cli), or by [online usage](./Usage.md#online-usage). + +

Example results:

/describe:

@@ -35,89 +38,100 @@ CodiumAI `PR-Agent` is an open-source tool aiming to help developers review pull

+

/review:

-

/reflect_and_review:

-
-

- -

-
-

/ask:

-
-

- -

-
-

/improve:

-
-

- -

-
+ +[//]: # (

/reflect_and_review:

) + +[//]: # (
) + +[//]: # (

) + +[//]: # () + +[//]: # (

) + +[//]: # (
) + +[//]: # (

/ask:

) + +[//]: # (
) + +[//]: # (

) + +[//]: # () + +[//]: # (

) + +[//]: # (
) + +[//]: # (

/improve:

) + +[//]: # (
) + +[//]: # (

) + +[//]: # () + +[//]: # (

) + +[//]: # (
)
- +## Table of Contents - [Overview](#overview) - [Try it now](#try-it-now) - [Installation](#installation) -- [Configuration](./CONFIGURATION.md) +- [Usage guide](./Usage.md) - [How it works](#how-it-works) - [Why use PR-Agent](#why-use-pr-agent) - [Roadmap](#roadmap) -- [Similar projects](#similar-projects)
## Overview `PR-Agent` offers extensive pull request functionalities across various git providers: -| | | GitHub | Gitlab | Bitbucket | CodeCommit | -|-------|---------------------------------------------|:------:|:------:|:---------:|:----------:| -| TOOLS | Review | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| | ⮑ Inline review | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| | Ask | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| | Auto-Description | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| | Improve Code | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| | Reflect and Review | :white_check_mark: | | :white_check_mark: | -| | Update CHANGELOG.md | :white_check_mark: | | :white_check_mark: | -| | | | | | | -| USAGE | CLI | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| | App / webhook | :white_check_mark: | :white_check_mark: | | | -| | Tagging bot | :white_check_mark: | | | | -| | Actions | :white_check_mark: | | | | -| | | | | | | -| CORE | PR compression | :white_check_mark: | :white_check_mark: | :white_check_mark: | | -| | Repo language prioritization | :white_check_mark: | :white_check_mark: | :white_check_mark: | | -| | Adaptive and token-aware
file patch fitting | :white_check_mark: | :white_check_mark: | :white_check_mark: | | -| | Multiple models support | :white_check_mark: | :white_check_mark: | :white_check_mark: | | -| | Incremental PR Review | :white_check_mark: | | | | +| | | GitHub | Gitlab | Bitbucket | CodeCommit | Azure DevOps | +|-------|---------------------------------------------|:------:|:------:|:---------:|:----------:|:----------:| +| TOOLS | Review | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| | Ask | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: +| | Auto-Description | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| | Improve Code | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | | +| | ⮑ Extended | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | | +| | Reflect and Review | :white_check_mark: | | :white_check_mark: | | :white_check_mark: | +| | Update CHANGELOG.md | :white_check_mark: | | :white_check_mark: | | | +| | | | | | | | +| USAGE | CLI | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| | App / webhook | :white_check_mark: | :white_check_mark: | | | | +| | Tagging bot | :white_check_mark: | | | | | +| | Actions | :white_check_mark: | | | | | +| | | | | | | | +| CORE | PR compression | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| | Repo language prioritization | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| | Adaptive and token-aware
file patch fitting | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| | Multiple models support | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| | Incremental PR Review | :white_check_mark: | | | | | -Examples for invoking the different tools via the CLI: -- **Review**: python cli.py --pr_url= review -- **Describe**: python cli.py --pr_url= describe -- **Improve**: python cli.py --pr_url= improve -- **Ask**: python cli.py --pr_url= ask "Write me a poem about this PR" -- **Reflect**: python cli.py --pr_url= reflect -- **Update Changelog**: python cli.py --pr_url= update_changelog - -"" is the url of the relevant PR (for example: https://github.com/Codium-ai/pr-agent/pull/50). - -In the [configuration](./CONFIGURATION.md) file you can select your git provider (GitHub, Gitlab, Bitbucket), and further configure the different tools. -Options that are available in the configuration file can be specified at run time when calling actions. Two examples: -- /review --pr_reviewer.extra_instructions="focus on the file: ..." -- /describe --pr_description.add_original_user_description=false -pr_description.extra_instructions="make sure to mention: ..." +Review the **[usage guide](./Usage.md)** section for detailed instructions how to use the different tools, select the relevant git provider (GitHub, Gitlab, Bitbucket,...), and adjust the configuration file to your needs. ## Try it now -Try GPT-4 powered PR-Agent on your public GitHub repository for free. Just mention `@CodiumAI-Agent` and add the desired command in any PR comment! The agent will generate a response based on your command. +You can try GPT-4 powered PR-Agent, on your public GitHub repository, instantly. Just mention `@CodiumAI-Agent` and add the desired command in any PR comment. The agent will generate a response based on your command. +For example, add a comment to any pull request with the following text: +``` +@CodiumAI-Agent /review +``` +and the agent will respond with a review of your PR ![Review generation process](https://www.codium.ai/images/demo-2.gif) -To set up your own PR-Agent, see the [Installation](#installation) section + +To set up your own PR-Agent, see the [Installation](#installation) section below. --- @@ -131,8 +145,8 @@ To get started with PR-Agent quickly, you first need to acquire two tokens: There are several ways to use PR-Agent: - [Method 1: Use Docker image (no installation required)](INSTALL.md#method-1-use-docker-image-no-installation-required) -- [Method 2: Run as a GitHub Action](INSTALL.md#method-2-run-as-a-github-action) -- [Method 3: Run from source](INSTALL.md#method-3-run-from-source) +- [Method 2: Run from source](INSTALL.md#method-2-run-from-source) +- [Method 3: Run as a GitHub Action](INSTALL.md#method-3-run-as-a-github-action) - [Method 4: Run as a polling server](INSTALL.md#method-4-run-as-a-polling-server) - Request reviews by tagging your GitHub user on a PR - [Method 5: Run as a GitHub App](INSTALL.md#method-5-run-as-a-github-app) @@ -156,7 +170,7 @@ Here are some advantages of PR-Agent: - We emphasize **real-life practical usage**. Each tool (review, improve, ask, ...) has a single GPT-4 call, no more. We feel that this is critical for realistic team usage - obtaining an answer quickly (~30 seconds) and affordably. - Our [PR Compression strategy](./PR_COMPRESSION.md) is a core ability that enables to effectively tackle both short and long PRs. -- Our JSON prompting strategy enables to have **modular, customizable tools**. For example, the '/review' tool categories can be controlled via the [configuration](./CONFIGURATION.md) file. Adding additional categories is easy and accessible. +- Our JSON prompting strategy enables to have **modular, customizable tools**. For example, the '/review' tool categories can be controlled via the [configuration](pr_agent/settings/configuration.toml) file. Adding additional categories is easy and accessible. - We support **multiple git providers** (GitHub, Gitlab, Bitbucket, CodeCommit), **multiple ways** to use the tool (CLI, GitHub Action, GitHub App, Docker, ...), and **multiple models** (GPT-4, GPT-3.5, Anthropic, Cohere, Llama2). - We are open-source, and welcome contributions from the community. @@ -183,4 +197,4 @@ Here are some advantages of PR-Agent: - [Aider - GPT powered coding in your terminal](https://github.com/paul-gauthier/aider) - [openai-pr-reviewer](https://github.com/coderabbitai/openai-pr-reviewer) - [CodeReview BOT](https://github.com/anc95/ChatGPT-CodeReview) -- [AI-Maintainer](https://github.com/merwanehamadi/AI-Maintainer) +- [AI-Maintainer](https://github.com/merwanehamadi/AI-Maintainer) \ No newline at end of file diff --git a/Usage.md b/Usage.md new file mode 100644 index 00000000..336de974 --- /dev/null +++ b/Usage.md @@ -0,0 +1,182 @@ +## Usage guide + +### Table of Contents +- [Introduction](#introduction) +- [Working from a local repo (CLI)](#working-from-a-local-repo-cli) +- [Online usage](#online-usage) +- [Working with GitHub App](#working-with-github-app) +- [Working with GitHub Action](#working-with-github-action) +- [Appendix - additional configurations walkthrough](#appendix---additional-configurations-walkthrough) + +### Introduction + +There are 3 basic ways to invoke CodiumAI PR-Agent: +1. Locally running a CLI command +2. Online usage - by [commenting](https://github.com/Codium-ai/pr-agent/pull/229#issuecomment-1695021901) on a PR +3. Enabling PR-Agent tools to run automatically when a new PR is opened + +See the [installation guide](/INSTALL.md) for instructions on how to setup your own PR-Agent. + +Specifically, CLI commands can be issued by invoking a pre-built [docker image](/INSTALL.md#running-from-source), or by invoking a [locally cloned repo](INSTALL.md#method-2-run-from-source). + +For online usage, you will need to setup either a [GitHub App](INSTALL.md#method-5-run-as-a-github-app), or a [GitHub Action](INSTALL.md#method-3-run-as-a-github-action). +GitHub App and GitHub Action also enable to run PR-Agent specific tool automatically when a new PR is opened. + + +#### The configuration file +The different tools and sub-tools used by CodiumAI PR-Agent are adjustable via the **[configuration file](pr_agent/settings/configuration.toml)**. +In addition to general configuration options, each tool has its own configurations. For example, the `review` tool will use parameters from the [pr_reviewer](/pr_agent/settings/configuration.toml#L16) section in the configuration file. + +**git provider:** +The [git_provider](pr_agent/settings/configuration.toml#L4) field in the configuration file determines the GIT provider that will be used by PR-Agent. Currently, the following providers are supported: +` +"github", "gitlab", "azure", "codecommit", "local" +` + +[//]: # (** online usage:**) + +[//]: # (Options that are available in the configuration file can be specified at run time when calling actions. Two examples:) + +[//]: # (```) + +[//]: # (- /review --pr_reviewer.extra_instructions="focus on the file: ...") + +[//]: # (- /describe --pr_description.add_original_user_description=false -pr_description.extra_instructions="make sure to mention: ...") + +[//]: # (```) + +### Working from a local repo (CLI) +When running from your local repo (CLI), your local configuration file will be used. + +Examples for invoking the different tools via the CLI: + +- **Review**: `python cli.py --pr_url= /review` +- **Describe**: `python cli.py --pr_url= /describe` +- **Improve**: `python cli.py --pr_url= /improve` +- **Ask**: `python cli.py --pr_url= /ask "Write me a poem about this PR"` +- **Reflect**: `python cli.py --pr_url= /reflect` +- **Update Changelog**: `python cli.py --pr_url= /update_changelog` + +`` is the url of the relevant PR (for example: https://github.com/Codium-ai/pr-agent/pull/50). + +**Notes:** + +(1) in addition to editing your local configuration file, you can also change any configuration value by adding it to the command line: +``` +python cli.py --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`: +``` +[config] +publish_output=true +verbosity_level=2 +``` +This is useful for debugging or experimenting with the different tools. + + +### Online usage + +Online usage means invoking PR-Agent tools by [comments](https://github.com/Codium-ai/pr-agent/pull/229#issuecomment-1695021901) on a PR. +Commands for invoking the different tools via comments: + +- **Review**: `/review` +- **Describe**: `/describe` +- **Improve**: `/improve` +- **Ask**: `/ask "..."` +- **Reflect**: `/reflect` +- **Update Changelog**: `/update_changelog` + + +To edit a specific configuration value, just add `--config_path=` to any command. +For example if you want to edit the `review` tool configurations, you can run: +``` +/review --pr_reviewer.extra_instructions="..." --pr_reviewer.require_score_review=false +``` +Any configuration value in [configuration file](pr_agent/settings/configuration.toml) file can be similarly edited. + + +### Working with GitHub App +When running PR-Agent from [GitHub App](INSTALL.md#method-5-run-as-a-github-app), the default configurations from a pre-built repo will be initially loaded. + +#### GitHub app automatic tools +The [github_app](pr_agent/settings/configuration.toml#L56) section defines GitHub app specific configurations. +An important parameter is `pr_commands`, which is a list of tools that will be **run automatically when a new PR is opened**: +``` +[github_app] +pr_commands = [ + "/describe --pr_description.add_original_user_description=true --pr_description.keep_original_user_title=true", + "/auto_review", +] +``` +This means that when a new PR is opened, PR-Agent will run the `describe` and `auto_review` tools. +For the describe tool, the `add_original_user_description` and `keep_original_user_title` parameters will be set to true. + +However, you can override the default tool parameters by uploading a local configuration file called `.pr_agent.toml` to the root of your repo. +For example, if your local `.pr_agent.toml` file contains: +``` +[pr_description] +add_original_user_description = false +keep_original_user_title = false +``` +When a new PR is opened, PR-Agent will run the `describe` tool with the above parameters. + +Note that a local `.pr_agent.toml` file enables you to edit and customize the default parameters of any tool, not just the ones that are run automatically. + +#### Editing the prompts +The prompts for the various PR-Agent tools are defined in the `pr_agent/settings` folder. + +In practice, the prompts are loaded and stored as a standard setting object. +Hence, editing them is similar to editing any other configuration value - just place the relevant key in `.pr_agent.toml`file, and override the default value. + +For example, if you want to edit the prompts of the [describe](./pr_agent/settings/pr_description_prompts.toml) tool, you can add the following to your `.pr_agent.toml` file: +``` +[pr_description_prompt] +system=""" +... +""" +user=""" +... +""" +``` +Note that the new prompt will need to generate an output compatible with the relevant [post-process function](./pr_agent/tools/pr_description.py#L137). + +### Working with GitHub Action +TBD + +### Appendix - additional configurations walkthrough + +#### Changing a model +See [here](pr_agent/algo/__init__.py) for the list of available models. + +To use Llama2 model, for example, set: +``` +[config] +model = "replicate/llama-2-70b-chat:2c1608e18606fad2812020dc541930f2d0495ce32eee50074220b87300bc16e1" +[replicate] +key = ... +``` +(you can obtain a Llama2 key from [here](https://replicate.com/replicate/llama-2-70b-chat/api)) + +Also review the [AiHandler](pr_agent/algo/ai_handler.py) file for instruction how to set keys for other models. + +#### Extra instructions +All PR-Agent tools have a parameter called `extra_instructions`, that enables to add free-text extra instructions. Example usage: +``` +/update_changelog --pr_update_changelog.extra_instructions="Make sure to update also the version ..." +``` + +#### Azure DevOps provider +To use Azure DevOps provider use the following settings in configuration.toml: +``` +[config] +git_provider="azure" +use_repo_settings_file=false +``` + +And use the following settings (you have to replace the values) in .secrets.toml: +``` +[azure_devops] +org = "https://dev.azure.com/YOUR_ORGANIZATION/" +pat = "YOUR_PAT_TOKEN" +``` \ No newline at end of file diff --git a/pr_agent/git_providers/codecommit_client.py b/pr_agent/git_providers/codecommit_client.py index 6200340d..1112ee22 100644 --- a/pr_agent/git_providers/codecommit_client.py +++ b/pr_agent/git_providers/codecommit_client.py @@ -90,7 +90,11 @@ class CodeCommitClient: ): differences.extend(page.get("differences", [])) except botocore.exceptions.ClientError as e: - raise ValueError(f"Failed to retrieve differences from CodeCommit PR #{self.pr_num}") from e + if e.response["Error"]["Code"] == 'RepositoryDoesNotExistException': + raise ValueError(f"CodeCommit cannot retrieve differences: Repository does not exist: {repo_name}") from e + raise ValueError(f"CodeCommit cannot retrieve differences for {source_commit}..{destination_commit}") from e + except Exception as e: + raise ValueError(f"CodeCommit cannot retrieve differences for {source_commit}..{destination_commit}") from e output = [] for json in differences: @@ -122,6 +126,8 @@ class CodeCommitClient: try: response = self.boto_client.get_file(repositoryName=repo_name, commitSpecifier=sha_hash, filePath=file_path) except botocore.exceptions.ClientError as e: + if e.response["Error"]["Code"] == 'RepositoryDoesNotExistException': + raise ValueError(f"CodeCommit cannot retrieve PR: Repository does not exist: {repo_name}") from e # if the file does not exist, but is flagged as optional, then return an empty string if optional and e.response["Error"]["Code"] == 'FileDoesNotExistException': return "" @@ -133,11 +139,12 @@ class CodeCommitClient: return response.get("fileContent", "") - def get_pr(self, pr_number: int): + def get_pr(self, repo_name: str, pr_number: int): """ Get a information about a CodeCommit PR. Args: + - repo_name: Name of the repository - pr_number: The PR number you are requesting Returns: @@ -155,6 +162,8 @@ class CodeCommitClient: except botocore.exceptions.ClientError as e: if e.response["Error"]["Code"] == 'PullRequestDoesNotExistException': raise ValueError(f"CodeCommit cannot retrieve PR: PR number does not exist: {pr_number}") from e + if e.response["Error"]["Code"] == 'RepositoryDoesNotExistException': + raise ValueError(f"CodeCommit cannot retrieve PR: Repository does not exist: {repo_name}") from e raise ValueError(f"CodeCommit cannot retrieve PR: {pr_number}: boto client error") from e except Exception as e: raise ValueError(f"CodeCommit cannot retrieve PR: {pr_number}") from e @@ -201,7 +210,7 @@ class CodeCommitClient: except Exception as e: raise ValueError(f"Error calling publish_description") from e - def publish_comment(self, repo_name: str, pr_number: int, destination_commit: str, source_commit: str, comment: str): + def publish_comment(self, repo_name: str, pr_number: int, destination_commit: str, source_commit: str, comment: str, annotation_file: str = None, annotation_line: int = None): """ Publish a comment to a pull request @@ -210,7 +219,13 @@ class CodeCommitClient: - pr_number: number of the pull request - destination_commit: The commit hash you want to merge into (the "before" hash) (usually on the main or master branch) - source_commit: The commit hash of the code you are adding (the "after" branch) - - pr_comment: comment + - comment: The comment you want to publish + - annotation_file: The file you want to annotate (optional) + - annotation_line: The line number you want to annotate (optional) + + Comment annotations for CodeCommit are different than GitHub. + CodeCommit only designates the starting line number for the comment. + It does not support the ending line number to highlight a range of lines. Returns: - None @@ -223,13 +238,30 @@ class CodeCommitClient: self._connect_boto_client() try: - self.boto_client.post_comment_for_pull_request( - pullRequestId=str(pr_number), - repositoryName=repo_name, - beforeCommitId=destination_commit, - afterCommitId=source_commit, - content=comment, - ) + # If the comment has code annotations, + # then set the file path and line number in the location dictionary + if annotation_file and annotation_line: + self.boto_client.post_comment_for_pull_request( + pullRequestId=str(pr_number), + repositoryName=repo_name, + beforeCommitId=destination_commit, + afterCommitId=source_commit, + content=comment, + location={ + "filePath": annotation_file, + "filePosition": annotation_line, + "relativeFileVersion": "AFTER", + }, + ) + else: + # The comment does not have code annotations + self.boto_client.post_comment_for_pull_request( + pullRequestId=str(pr_number), + repositoryName=repo_name, + beforeCommitId=destination_commit, + afterCommitId=source_commit, + content=comment, + ) except botocore.exceptions.ClientError as e: if e.response["Error"]["Code"] == 'RepositoryDoesNotExistException': raise ValueError(f"Repository does not exist: {repo_name}") from e diff --git a/pr_agent/git_providers/codecommit_provider.py b/pr_agent/git_providers/codecommit_provider.py index d43409c3..1f570a1a 100644 --- a/pr_agent/git_providers/codecommit_provider.py +++ b/pr_agent/git_providers/codecommit_provider.py @@ -180,10 +180,37 @@ class CodeCommitProvider(GitProvider): comment=pr_comment, ) except Exception as e: - raise ValueError(f"CodeCommit Cannot post comment for PR: {self.pr_num}") from e + raise ValueError(f"CodeCommit Cannot publish comment for PR: {self.pr_num}") from e def publish_code_suggestions(self, code_suggestions: list) -> bool: - return [""] # not implemented yet + counter = 1 + for suggestion in code_suggestions: + # Verify that each suggestion has the required keys + if not all(key in suggestion for key in ["body", "relevant_file", "relevant_lines_start"]): + logging.warning(f"Skipping code suggestion #{counter}: Each suggestion must have 'body', 'relevant_file', 'relevant_lines_start' keys") + continue + + # Publish the code suggestion to CodeCommit + try: + logging.debug(f"Code Suggestion #{counter} in file: {suggestion['relevant_file']}: {suggestion['relevant_lines_start']}") + self.codecommit_client.publish_comment( + repo_name=self.repo_name, + pr_number=self.pr_num, + destination_commit=self.pr.destination_commit, + source_commit=self.pr.source_commit, + comment=suggestion["body"], + annotation_file=suggestion["relevant_file"], + annotation_line=suggestion["relevant_lines_start"], + ) + except Exception as e: + raise ValueError(f"CodeCommit Cannot publish code suggestions for PR: {self.pr_num}") from e + + counter += 1 + + # The calling function passes in a list of code suggestions, and this function publishes each suggestion one at a time. + # If we were to return False here, the calling function will attempt to publish the same list of code suggestions again, one at a time. + # Since this function publishes the suggestions one at a time anyway, we always return True here to avoid the retry. + return True def publish_labels(self, labels): return [""] # not implemented yet @@ -195,6 +222,7 @@ class CodeCommitProvider(GitProvider): return "" # not implemented yet def publish_inline_comment(self, body: str, relevant_file: str, relevant_line_in_file: str): + # https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/codecommit/client/post_comment_for_compared_commit.html raise NotImplementedError("CodeCommit provider does not support publishing inline comments yet") def create_inline_comment(self, body: str, relevant_file: str, relevant_line_in_file: str): @@ -255,9 +283,11 @@ class CodeCommitProvider(GitProvider): return self.codecommit_client.get_file(self.repo_name, settings_filename, self.pr.source_commit, optional=True) def add_eyes_reaction(self, issue_comment_id: int) -> Optional[int]: + logging.info("CodeCommit provider does not support eyes reaction yet") return True def remove_reaction(self, issue_comment_id: int, reaction_id: int) -> bool: + logging.info("CodeCommit provider does not support removing reactions yet") return True @staticmethod @@ -315,16 +345,16 @@ class CodeCommitProvider(GitProvider): return re.match(r"^[a-z]{2}-(gov-)?[a-z]+-\d\.console\.aws\.amazon\.com$", hostname) is not None def _get_pr(self): - response = self.codecommit_client.get_pr(self.pr_num) + response = self.codecommit_client.get_pr(self.repo_name, self.pr_num) if len(response.targets) == 0: raise ValueError(f"No files found in CodeCommit PR: {self.pr_num}") - # TODO: implement support for multiple commits in one CodeCommit PR - # for now, we are only using the first commit in the PR + # TODO: implement support for multiple targets in one CodeCommit PR + # for now, we are only using the first target in the PR if len(response.targets) > 1: logging.warning( - "Multiple commits in one PR is not supported for CodeCommit yet. Continuing, using the first commit only..." + "Multiple targets in one PR is not supported for CodeCommit yet. Continuing, using the first target only..." ) # Return our object that mimics PullRequest class from the PyGithub library diff --git a/pr_agent/git_providers/git_provider.py b/pr_agent/git_providers/git_provider.py index 4651d47d..330590a1 100644 --- a/pr_agent/git_providers/git_provider.py +++ b/pr_agent/git_providers/git_provider.py @@ -161,7 +161,6 @@ def get_main_pr_language(languages, files) -> str: most_common_extension == 'scala' and top_language == 'scala' or \ most_common_extension == 'kt' and top_language == 'kotlin' or \ most_common_extension == 'pl' and top_language == 'perl' or \ - most_common_extension == 'swift' and top_language == 'swift' or \ most_common_extension == top_language: main_language_str = top_language diff --git a/pr_agent/settings/pr_code_suggestions_prompts.toml b/pr_agent/settings/pr_code_suggestions_prompts.toml index f60b9cc2..6867a883 100644 --- a/pr_agent/settings/pr_code_suggestions_prompts.toml +++ b/pr_agent/settings/pr_code_suggestions_prompts.toml @@ -68,12 +68,17 @@ Code suggestions: type: string description: |- a code snippet showing the relevant code lines from a '__new hunk__' section. - It must be continuous, correctly formatted and indented, and without line numbers. - relevant lines: - type: string + It must be contiguous, correctly formatted and indented, and without line numbers. + relevant lines start: + type: integer description: |- - the relevant lines from a '__new hunk__' section, in the format of 'start_line-end_line'. - For example: '10-15'. They should be derived from the hunk line numbers, and correspond to the 'existing code' snippet above. + The relevant line number from a '__new hunk__' section where the suggestion starts (inclusive). + Should be derived from the hunk line numbers, and correspond to the 'existing code' snippet above. + relevant lines end: + type: integer + description: |- + The relevant line number from a '__new hunk__' section where the suggestion ends (inclusive). + Should be derived from the hunk line numbers, and correspond to the 'existing code' snippet above. improved code: type: string description: |- @@ -90,7 +95,8 @@ Code suggestions: Add a docstring to func1() existing code: |- def func1(): - relevant lines: '12-12' + relevant lines start: 12 + relevant lines end: 12 improved code: |- ... ``` diff --git a/pr_agent/tools/pr_code_suggestions.py b/pr_agent/tools/pr_code_suggestions.py index d9fb3051..ba45598e 100644 --- a/pr_agent/tools/pr_code_suggestions.py +++ b/pr_agent/tools/pr_code_suggestions.py @@ -113,11 +113,8 @@ class PRCodeSuggestions: if get_settings().config.verbosity_level >= 2: logging.info(f"suggestion: {d}") relevant_file = d['relevant file'].strip() - relevant_lines_str = d['relevant lines'].strip() - if ',' in relevant_lines_str: # handling 'relevant lines': '181, 190' or '178-184, 188-194' - relevant_lines_str = relevant_lines_str.split(',')[0] - relevant_lines_start = int(relevant_lines_str.split('-')[0]) # absolute position - relevant_lines_end = int(relevant_lines_str.split('-')[-1]) + relevant_lines_start = int(d['relevant lines start']) # absolute position + relevant_lines_end = int(d['relevant lines end']) content = d['suggestion content'] new_code_snippet = d['improved code'] diff --git a/requirements.txt b/requirements.txt index 2441b1c1..99efa846 100644 --- a/requirements.txt +++ b/requirements.txt @@ -17,3 +17,5 @@ litellm~=0.1.504 boto3~=1.28.25 google-cloud-storage==2.10.0 ujson==5.8.0 +azure-devops==7.1.0b3 +msrest==0.7.1 \ No newline at end of file diff --git a/tests/unittest/test_codecommit_client.py b/tests/unittest/test_codecommit_client.py index 5d09bdd1..0aa1ffa6 100644 --- a/tests/unittest/test_codecommit_client.py +++ b/tests/unittest/test_codecommit_client.py @@ -125,7 +125,7 @@ class TestCodeCommitProvider: } } - pr = api.get_pr(321) + pr = api.get_pr("my_test_repo", 321) assert pr.title == "My PR" assert pr.description == "My PR description"