From 3daf94954a5416cde0f66db9ea15accc3261aa2e Mon Sep 17 00:00:00 2001 From: mrT23 Date: Sun, 30 Jul 2023 11:43:44 +0300 Subject: [PATCH] update_settings_from_args --- pr_agent/agent/pr_agent.py | 6 +++--- pr_agent/algo/utils.py | 18 ++++++++++++++++++ pr_agent/cli.py | 7 +++++-- pr_agent/servers/help.py | 8 ++++---- pr_agent/settings/configuration.toml | 14 +++++++++----- .../settings/pr_code_suggestions_prompts.toml | 6 ++++++ pr_agent/settings/pr_description_prompts.toml | 6 ++++++ pr_agent/settings/pr_reviewer_prompts.toml | 6 ++++++ pr_agent/tools/pr_code_suggestions.py | 10 +++++++--- pr_agent/tools/pr_description.py | 6 ++++-- pr_agent/tools/pr_information_from_user.py | 2 +- pr_agent/tools/pr_reviewer.py | 6 ++++-- pr_agent/tools/pr_update_changelog.py | 1 + 13 files changed, 74 insertions(+), 22 deletions(-) diff --git a/pr_agent/agent/pr_agent.py b/pr_agent/agent/pr_agent.py index 9f336f64..1a00c977 100644 --- a/pr_agent/agent/pr_agent.py +++ b/pr_agent/agent/pr_agent.py @@ -16,16 +16,16 @@ class PRAgent: async def handle_request(self, pr_url, request) -> bool: action, *args = request.strip().split() if any(cmd == action for cmd in ["/answer"]): - await PRReviewer(pr_url, is_answer=True).review() + await PRReviewer(pr_url, is_answer=True, args=args).review() elif any(cmd == action for cmd in ["/review", "/review_pr", "/reflect_and_review"]): if settings.pr_reviewer.ask_and_reflect or "/reflect_and_review" in request: - await PRInformationFromUser(pr_url).generate_questions() + await PRInformationFromUser(pr_url, args=args).generate_questions() else: await PRReviewer(pr_url, args=args).review() elif any(cmd == action for cmd in ["/describe", "/describe_pr"]): await PRDescription(pr_url, args=args).describe() elif any(cmd == action for cmd in ["/improve", "/improve_code"]): - await PRCodeSuggestions(pr_url).suggest() + await PRCodeSuggestions(pr_url, args=args).suggest() elif any(cmd == action for cmd in ["/ask", "/ask_question"]): await PRQuestions(pr_url, args=args).answer() elif any(cmd == action for cmd in ["/update_changelog"]): diff --git a/pr_agent/algo/utils.py b/pr_agent/algo/utils.py index 23bf8dfd..c939d67a 100644 --- a/pr_agent/algo/utils.py +++ b/pr_agent/algo/utils.py @@ -211,3 +211,21 @@ def load_large_diff(file, new_file_content_str: str, original_file_content_str: except Exception: pass return patch + + +def update_settings_from_args(args): + if args and len(args) >= 1: + for arg in args: + try: + arg = arg.strip('-').strip() + vals = arg.replace('=', '.').replace('=', '.').split('.') + d = settings + for i, v in enumerate(vals[:-1]): + if i == len(vals) - 2: + d[v] = vals[-1] + logging.info(f'Updated setting {vals[:-1]} to: "{vals[-1]}"') + break + else: + d = d[v] + except Exception as e: + logging.error(f'Failed to parse argument {arg}: {e}') \ No newline at end of file diff --git a/pr_agent/cli.py b/pr_agent/cli.py index 2f0a3a28..7a1130c8 100644 --- a/pr_agent/cli.py +++ b/pr_agent/cli.py @@ -29,6 +29,9 @@ describe / describe_pr - Modify the PR title and description based on the PR's c 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. update_changelog - Update the changelog based on the PR's contents. + +To edit any configuration parameter from 'configuration.toml', just add -config_path=. +For example: '- cli.py --pr-url=... review --pr_reviewer.extra_instructions="focus on the file: ...' """) 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', @@ -79,7 +82,7 @@ def _handle_describe_command(pr_url: str, rest: list): def _handle_improve_command(pr_url: str, rest: list): print(f"PR code suggestions: {pr_url}") - reviewer = PRCodeSuggestions(pr_url) + reviewer = PRCodeSuggestions(pr_url, args=rest) asyncio.run(reviewer.suggest()) @@ -97,7 +100,7 @@ def _handle_reflect_command(pr_url: str, rest: list): def _handle_review_after_reflect_command(pr_url: str, rest: list): print(f"Processing author's answers and sending review: {pr_url}") - reviewer = PRReviewer(pr_url, cli_mode=True, is_answer=True) + reviewer = PRReviewer(pr_url, cli_mode=True, is_answer=True, args=rest) asyncio.run(reviewer.review()) def _handle_update_changelog(pr_url: str, rest: list): diff --git a/pr_agent/servers/help.py b/pr_agent/servers/help.py index af5350d2..de5b07ec 100644 --- a/pr_agent/servers/help.py +++ b/pr_agent/servers/help.py @@ -1,11 +1,11 @@ commands_text = "> **/review [-i]**: Request a review of your Pull Request. For an incremental review, which only " \ "considers changes since the last review, include the '-i' option.\n" \ - "> **/describe [-c]**: Modify the PR title and description based on the contents of the PR. " \ - "To get the description as comment instead of modifying the PR description, " \ - "include the '-c' option.\n" \ + "> **/describe**: Modify the PR title and description based on the contents of the PR.\n" \ "> **/improve**: Suggest improvements to the code in the PR. " \ "These will be provided as pull request comments, ready to commit.\n" \ - "> **/ask \\**: Pose a question about the PR.\n" + "> **/ask \\**: Pose a question about the PR.\n\n" \ + "To edit any configuration parameter from 'configuration.toml', just add -config_path=. " \ + "For example: '/review --pr_reviewer.extra_instructions=focus on the file: ...'" \ def bot_help_text(user: str): diff --git a/pr_agent/settings/configuration.toml b/pr_agent/settings/configuration.toml index 58f4ba32..5d9c0846 100644 --- a/pr_agent/settings/configuration.toml +++ b/pr_agent/settings/configuration.toml @@ -7,7 +7,7 @@ publish_output_progress=true verbosity_level=0 # 0,1,2 use_extra_bad_extensions=false -[pr_reviewer] +[pr_reviewer] # /review # require_focused_review=true require_score_review=false require_tests_review=true @@ -15,17 +15,21 @@ require_security_review=true num_code_suggestions=0 inline_code_comments = true ask_and_reflect=false +extra_instructions = "" -[pr_description] +[pr_description] # /describe # publish_description_as_comment=false +extra_instructions = "" -[pr_questions] +[pr_questions] # /ask # -[pr_code_suggestions] +[pr_code_suggestions] # /improve # num_code_suggestions=4 +extra_instructions = "" -[pr_update_changelog] +[pr_update_changelog] # /update_changelog # push_changelog_changes=false +extra_instructions = "" [github] # The type of deployment to create. Valid values are 'app' or 'user'. diff --git a/pr_agent/settings/pr_code_suggestions_prompts.toml b/pr_agent/settings/pr_code_suggestions_prompts.toml index d4aa24a2..b3a63f9a 100644 --- a/pr_agent/settings/pr_code_suggestions_prompts.toml +++ b/pr_agent/settings/pr_code_suggestions_prompts.toml @@ -9,6 +9,12 @@ Your task is to provide meaningfull non-trivial code suggestions to improve the - Make sure not to provide suggestions repeating modifications already implemented in the new PR code (the '+' lines). - Don't output line numbers in the 'improved code' snippets. +{%- if extra_instructions %} + +Extra instructions from the user: +{{ extra_instructions }} +{% endif %} + You must use the following JSON schema to format your answer: ```json { diff --git a/pr_agent/settings/pr_description_prompts.toml b/pr_agent/settings/pr_description_prompts.toml index 8c8df966..16b6bfde 100644 --- a/pr_agent/settings/pr_description_prompts.toml +++ b/pr_agent/settings/pr_description_prompts.toml @@ -3,6 +3,12 @@ system="""You are CodiumAI-PR-Reviewer, a language model designed to review git Your task is to provide full description of the PR content. - Make sure not to focus the new PR code (the '+' lines). +{%- if extra_instructions %} + +Extra instructions from the user: +{{ extra_instructions }} +{% endif %} + You must use the following JSON schema to format your answer: ```json { diff --git a/pr_agent/settings/pr_reviewer_prompts.toml b/pr_agent/settings/pr_reviewer_prompts.toml index 97d12366..87cfa29f 100644 --- a/pr_agent/settings/pr_reviewer_prompts.toml +++ b/pr_agent/settings/pr_reviewer_prompts.toml @@ -8,6 +8,12 @@ Your task is to provide constructive and concise feedback for the PR, and also p - Make sure not to provide suggestions repeating modifications already implemented in the new PR code (the '+' lines). {%- endif %} +{%- if extra_instructions %} + +Extra instructions from the user: +{{ extra_instructions }} +{% endif %} + You must use the following JSON schema to format your answer: ```json { diff --git a/pr_agent/tools/pr_code_suggestions.py b/pr_agent/tools/pr_code_suggestions.py index 6ec80ec0..3c1477cc 100644 --- a/pr_agent/tools/pr_code_suggestions.py +++ b/pr_agent/tools/pr_code_suggestions.py @@ -8,19 +8,21 @@ from jinja2 import Environment, StrictUndefined from pr_agent.algo.ai_handler import AiHandler from pr_agent.algo.pr_processing import get_pr_diff, retry_with_fallback_models from pr_agent.algo.token_handler import TokenHandler -from pr_agent.algo.utils import try_fix_json +from pr_agent.algo.utils import try_fix_json, update_settings_from_args from pr_agent.config_loader import settings from pr_agent.git_providers import BitbucketProvider, get_git_provider from pr_agent.git_providers.git_provider import get_main_pr_language class PRCodeSuggestions: - def __init__(self, pr_url: str, cli_mode=False): + def __init__(self, pr_url: str, cli_mode=False, args: list = None): self.git_provider = get_git_provider()(pr_url) self.main_language = get_main_pr_language( self.git_provider.get_languages(), self.git_provider.get_files() ) + update_settings_from_args(args) + self.ai_handler = AiHandler() self.patches_diff = None self.prediction = None @@ -31,7 +33,8 @@ class PRCodeSuggestions: "description": self.git_provider.get_pr_description(), "language": self.main_language, "diff": "", # empty diff for initial calculation - 'num_code_suggestions': settings.pr_code_suggestions.num_code_suggestions, + "num_code_suggestions": settings.pr_code_suggestions.num_code_suggestions, + "extra_instructions": settings.pr_code_suggestions.extra_instructions, } self.token_handler = TokenHandler(self.git_provider.pr, self.vars, @@ -137,3 +140,4 @@ class PRCodeSuggestions: logging.info(f"Could not dedent code snippet for file {relevant_file}, error: {e}") return new_code_snippet + diff --git a/pr_agent/tools/pr_description.py b/pr_agent/tools/pr_description.py index aa2d2ce1..c9d9f0ec 100644 --- a/pr_agent/tools/pr_description.py +++ b/pr_agent/tools/pr_description.py @@ -8,6 +8,7 @@ from jinja2 import Environment, StrictUndefined from pr_agent.algo.ai_handler import AiHandler from pr_agent.algo.pr_processing import get_pr_diff, retry_with_fallback_models from pr_agent.algo.token_handler import TokenHandler +from pr_agent.algo.utils import update_settings_from_args from pr_agent.config_loader import settings from pr_agent.git_providers import get_git_provider from pr_agent.git_providers.git_provider import get_main_pr_language @@ -21,8 +22,8 @@ class PRDescription: pr_url (str): The URL of the pull request. args (list, optional): List of arguments passed to the PRDescription class. Defaults to None. """ - self.parse_args(args) - + update_settings_from_args(args) + # Initialize the git provider and main PR language self.git_provider = get_git_provider()(pr_url) self.main_pr_language = get_main_pr_language( @@ -39,6 +40,7 @@ class PRDescription: "description": self.git_provider.get_pr_description(), "language": self.main_pr_language, "diff": "", # empty diff for initial calculation + "extra_instructions": settings.pr_description.extra_instructions, } # Initialize the token handler diff --git a/pr_agent/tools/pr_information_from_user.py b/pr_agent/tools/pr_information_from_user.py index 463b434e..feeb0e31 100644 --- a/pr_agent/tools/pr_information_from_user.py +++ b/pr_agent/tools/pr_information_from_user.py @@ -14,7 +14,7 @@ from pr_agent.git_providers.git_provider import get_main_pr_language class PRInformationFromUser: - def __init__(self, pr_url: str): + def __init__(self, pr_url: str, args: list = None): self.git_provider = get_git_provider()(pr_url) self.main_pr_language = get_main_pr_language( self.git_provider.get_languages(), self.git_provider.get_files() diff --git a/pr_agent/tools/pr_reviewer.py b/pr_agent/tools/pr_reviewer.py index ec4b8f03..8e2343d0 100644 --- a/pr_agent/tools/pr_reviewer.py +++ b/pr_agent/tools/pr_reviewer.py @@ -9,7 +9,7 @@ from jinja2 import Environment, StrictUndefined from pr_agent.algo.ai_handler import AiHandler from pr_agent.algo.pr_processing import get_pr_diff, retry_with_fallback_models from pr_agent.algo.token_handler import TokenHandler -from pr_agent.algo.utils import convert_to_markdown, try_fix_json +from pr_agent.algo.utils import convert_to_markdown, try_fix_json, update_settings_from_args from pr_agent.config_loader import settings from pr_agent.git_providers import get_git_provider from pr_agent.git_providers.git_provider import get_main_pr_language, IncrementalPR @@ -30,7 +30,8 @@ class PRReviewer: is_answer (bool, optional): Indicates whether the review is being done in answer mode. Defaults to False. args (list, optional): List of arguments passed to the PRReviewer class. Defaults to None. """ - self.parse_args(args) + update_settings_from_args(args) + self.parse_args(args) # -i command self.git_provider = get_git_provider()(pr_url, incremental=self.incremental) self.main_language = get_main_pr_language( @@ -60,6 +61,7 @@ class PRReviewer: 'num_code_suggestions': settings.pr_reviewer.num_code_suggestions, 'question_str': question_str, 'answer_str': answer_str, + "extra_instructions": settings.pr_reviewer.extra_instructions, } self.token_handler = TokenHandler( diff --git a/pr_agent/tools/pr_update_changelog.py b/pr_agent/tools/pr_update_changelog.py index 1b06c381..eea77e30 100644 --- a/pr_agent/tools/pr_update_changelog.py +++ b/pr_agent/tools/pr_update_changelog.py @@ -37,6 +37,7 @@ class PRUpdateChangelog: "diff": "", # empty diff for initial calculation "changelog_file_str": self.changelog_file_str, "today": date.today(), + "extra_instructions": settings.pr_update_changelog_prompt.extra_instructions, } self.token_handler = TokenHandler(self.git_provider.pr, self.vars,