diff --git a/README.md b/README.md index 25ddc715..f8658bdb 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,7 @@ To set up your own PR-Agent, see the [Quickstart](#Quickstart) section | | Ask | :white_check_mark: | :white_check_mark: | | | | Auto-Description | :white_check_mark: | | | | | Improve Code | :white_check_mark: | :white_check_mark: | | +| | Reflect and Review | :white_check_mark: | | | | | | | | | | USAGE | CLI | :white_check_mark: | :white_check_mark: | :white_check_mark: | | | Tagging bot | :white_check_mark: | :white_check_mark: | | @@ -92,6 +93,7 @@ Examples for invoking the different tools via the [CLI](#quickstart): - **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 "" is the url of the relevant PR (for example: https://github.com/Codium-ai/pr-agent/pull/50). @@ -120,12 +122,13 @@ Here are several ways to install and run PR-Agent: ## Usage and Tools -**PR-Agent** provides four types of interactions ("tools"): `"PR Reviewer"`, `"PR Q&A"`, `"PR Description"` and `"PR Code Sueggestions"`. +**PR-Agent** provides five types of interactions ("tools"): `"PR Reviewer"`, `"PR Q&A"`, `"PR Description"`, `"PR Code Sueggestions"` and `"PR Reflect and Review"`. - The "PR Reviewer" tool automatically analyzes PRs, and provides various types of feedback. - The "PR Q&A" tool answers free-text questions about the PR. - The "PR Description" tool automatically sets the PR Title and body. - The "PR Code Suggestion" tool provide inline code suggestions for the PR that can be applied and committed. +- The "PR Reflect and Review" tool first dialog with the user and asks him to reflect on the PR, and then provides a review. ## How it works @@ -138,11 +141,11 @@ Check out the [PR Compression strategy](./PR_COMPRESSION.md) page for more detai - [ ] Support open-source models, as a replacement for openai models. (Note - a minimal requirement for each open-source model is to have 8k+ context, and good support for generating json as an output) - [x] Support other Git providers, such as Gitlab and Bitbucket. - [ ] Develop additional logics for handling large PRs, and compressing git patches -- [ ] Dedicated tools and sub-tools for specific programming languages (Python, Javascript, Java, C++, etc) - [ ] Add additional context to the prompt. For example, repo (or relevant files) summarization, with tools such a [ctags](https://github.com/universal-ctags/ctags) - [ ] Adding more tools. Possible directions: - [x] PR description - [x] Inline code suggestions + - [x] Reflect and review - [ ] Enforcing CONTRIBUTING.md guidelines - [ ] Performance (are there any performance issues) - [ ] Documentation (is the PR properly documented) diff --git a/pr_agent/agent/pr_agent.py b/pr_agent/agent/pr_agent.py index 5d1f5c76..3709db1f 100644 --- a/pr_agent/agent/pr_agent.py +++ b/pr_agent/agent/pr_agent.py @@ -15,8 +15,8 @@ class PRAgent: async def handle_request(self, pr_url, request) -> bool: if any(cmd in request for cmd in ["/answer"]): await PRReviewer(pr_url, is_answer=True).review() - elif any(cmd in request for cmd in ["/review", "/review_pr"]): - if settings.pr_reviewer.ask_and_reflect: + elif any(cmd in request for cmd in ["/review", "/review_pr", "/reflect_and_review"]): + if settings.pr_reviewer.ask_and_reflect or any(cmd in request for cmd in ["/reflect_and_review"]): await PRInformationFromUser(pr_url).generate_questions() else: await PRReviewer(pr_url).review() diff --git a/pr_agent/cli.py b/pr_agent/cli.py index d681776a..ca9d5db0 100644 --- a/pr_agent/cli.py +++ b/pr_agent/cli.py @@ -18,20 +18,22 @@ For example: - cli.py --pr-url=... describe - cli.py --pr-url=... improve - cli.py --pr-url=... ask "write me a poem about this PR" +- cli.py --pr-url=... reflect Supported commands: review / review_pr - Add a review that includes a summary of the PR and specific suggestions for improvement. ask / ask_question [question] - Ask a question about the PR. describe / describe_pr - Modify the PR title and description based on the PR's contents. improve / improve_code - Suggest improvements to the code in the PR as pull request comments ready to commit. +reflect - Ask the PR author questions about the PR. """) parser.add_argument('--pr_url', type=str, help='The URL of the PR to review', required=True) parser.add_argument('command', type=str, help='The', choices=['review', 'review_pr', 'ask', 'ask_question', 'describe', 'describe_pr', 'improve', 'improve_code', - 'user_questions', 'user_answers'], - default='review') + 'reflect', 'review_after_reflect'], + default='review') parser.add_argument('rest', nargs=argparse.REMAINDER, default=[]) args = parser.parse_args() logging.basicConfig(level=os.environ.get("LOGLEVEL", "INFO")) @@ -57,11 +59,11 @@ improve / improve_code - Suggest improvements to the code in the PR as pull requ print(f"Reviewing PR: {args.pr_url}") reviewer = PRReviewer(args.pr_url, cli_mode=True) asyncio.run(reviewer.review()) - elif command in ['user_questions']: + elif command in ['reflect']: print(f"Asking the PR author questions: {args.pr_url}") reviewer = PRInformationFromUser(args.pr_url) asyncio.run(reviewer.generate_questions()) - elif command in ['user_answers']: + elif command in ['review_after_reflect']: print(f"Processing author's answers and sending review: {args.pr_url}") reviewer = PRReviewer(args.pr_url, cli_mode=True, is_answer=True) asyncio.run(reviewer.review()) diff --git a/pr_agent/servers/github_action_runner.py b/pr_agent/servers/github_action_runner.py index a856cc58..56a7bb5e 100644 --- a/pr_agent/servers/github_action_runner.py +++ b/pr_agent/servers/github_action_runner.py @@ -56,8 +56,9 @@ async def run_action(): body = comment_body.strip().lower() if any(cmd in body for cmd in ["/answer"]): await PRReviewer(pr_url, is_answer=True).review() - elif any(cmd in body for cmd in ["/review", "/review_pr", "/answer"]): - if settings.pr_reviewer.ask_and_reflect: + elif any(cmd in body for cmd in ["/review", "/review_pr", "/reflect_and_review"]): + if settings.pr_reviewer.ask_and_reflect or \ + any(cmd in body for cmd in ["/reflect_and_review"]): await PRInformationFromUser(pr_url).generate_questions() else: await PRReviewer(pr_url).review() diff --git a/pr_agent/tools/pr_information_from_user.py b/pr_agent/tools/pr_information_from_user.py index a4120cd4..ff78858f 100644 --- a/pr_agent/tools/pr_information_from_user.py +++ b/pr_agent/tools/pr_information_from_user.py @@ -35,7 +35,7 @@ class PRInformationFromUser: async def generate_questions(self): logging.info('Generating question to the user...') if settings.config.publish_output: - self.git_provider.publish_comment("Preparing answer...", is_temporary=True) + self.git_provider.publish_comment("Preparing questions...", is_temporary=True) logging.info('Getting PR diff...') self.patches_diff = get_pr_diff(self.git_provider, self.token_handler) logging.info('Getting AI prediction...') diff --git a/pr_agent/tools/pr_reviewer.py b/pr_agent/tools/pr_reviewer.py index 12d4df72..b086c9c0 100644 --- a/pr_agent/tools/pr_reviewer.py +++ b/pr_agent/tools/pr_reviewer.py @@ -9,7 +9,7 @@ from pr_agent.algo.pr_processing import get_pr_diff from pr_agent.algo.token_handler import TokenHandler from pr_agent.algo.utils import convert_to_markdown, try_fix_json from pr_agent.config_loader import settings -from pr_agent.git_providers import get_git_provider +from pr_agent.git_providers import get_git_provider, GithubProvider from pr_agent.git_providers.git_provider import get_main_pr_language from pr_agent.servers.help import bot_help_text, actions_help_text @@ -22,6 +22,8 @@ class PRReviewer: self.git_provider.get_languages(), self.git_provider.get_files() ) self.is_answer = is_answer + if self.is_answer and type(self.git_provider) != GithubProvider: + raise Exception("Answer mode is only supported for Github for now") answer_str = question_str = self._get_user_answers() self.ai_handler = AiHandler() self.patches_diff = None