From 4f7b08bde333dcefdae6cfc32240f7c578332a6a Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 21:21:24 -0300 Subject: [PATCH 01/17] Update entrypoint.py --- entrypoint.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/entrypoint.py b/entrypoint.py index e0fae1f..1cc42b9 100755 --- a/entrypoint.py +++ b/entrypoint.py @@ -136,10 +136,10 @@ def format_review_comment(summarized_review: str, chunked_reviews: List[str]) -> if len(chunked_reviews) == 1: return summarized_review unioned_reviews = "\n".join(chunked_reviews) - review = f"""
- {summarized_review} + review = f""" + {summarized_review} + {unioned_reviews} -
""" return review From 27dcaf50be5cb51e357d59af1e2b451d19cade8f Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 21:22:13 -0300 Subject: [PATCH 02/17] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8fe76f8..81ea46f 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ jobs: git diff "origin/${{ env.PULL_REQUEST_HEAD_REF }}" > "diff.txt" # shellcheck disable=SC2086 echo "diff=$(cat "diff.txt")" >> $GITHUB_ENV - - uses: rubensflinco/gemini-code-review-action@1.0.4 + - uses: rubensflinco/gemini-code-review-action@1.0.5 name: "Code Review by Gemini AI" id: review with: From 5d5a86532d43ae692d714d5d775b8e9de98a7f05 Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 21:25:16 -0300 Subject: [PATCH 03/17] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 81ea46f..552abcc 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,7 @@ jobs: github_repository: ${{ github.repository }} github_pull_request_number: ${{ github.event.pull_request.number }} git_commit_hash: ${{ github.event.pull_request.head.sha }} - model: "gemini-1.0-pro-latest" + model: "gemini-1.5-pro-latest" pull_request_diff: |- ${{ steps.get_diff.outputs.pull_request_diff }} pull_request_chunk_size: "3500" From 6a6ae731051111a0410a6f44f57dc3a6293f8df2 Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 21:25:48 -0300 Subject: [PATCH 04/17] Update ai-code-review.yml --- .github/workflows/ai-code-review.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ai-code-review.yml b/.github/workflows/ai-code-review.yml index 226acd8..f7a5a92 100644 --- a/.github/workflows/ai-code-review.yml +++ b/.github/workflows/ai-code-review.yml @@ -53,7 +53,7 @@ jobs: github_repository: ${{ github.repository }} github_pull_request_number: ${{ github.event.pull_request.number }} git_commit_hash: ${{ github.event.pull_request.head.sha }} - model: "gemini-1.0-pro-latest" + model: "gemini-1.5-pro-latest" pull_request_diff: |- ${{ steps.get_diff.outputs.pull_request_diff }} pull_request_chunk_size: "3500" From d70ca5bedb2538e171c80d966abf24fa7747dc52 Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 21:28:44 -0300 Subject: [PATCH 05/17] Update entrypoint.py --- entrypoint.py | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/entrypoint.py b/entrypoint.py index 1cc42b9..3881a7b 100755 --- a/entrypoint.py +++ b/entrypoint.py @@ -99,18 +99,14 @@ def get_review( ): """Get a review""" # Chunk the prompt - genai_model = genai.GenerativeModel(model) review_prompt = get_review_prompt(extra_prompt=extra_prompt) chunked_diff_list = chunk_string(input_string=diff, chunk_size=prompt_chunk_size) # Get summary by chunk chunked_reviews = [] for chunked_diff in chunked_diff_list: - prompt = str(f""" - {str(review_prompt)} - - ```{str(chunked_diff)}```""") - - response = genai_model.generate_content(prompt) + system_instruction = review_prompt + genai_model = genai.GenerativeModel(model_name=model,system_instruction=system_instruction) + response = genai_model.generate_content(chunked_diff) review_result = response.text chunked_reviews.append(review_result) # If the chunked reviews are only one, return it @@ -119,14 +115,10 @@ def get_review( # Summarize the chunked reviews summarize_prompt = get_summarize_prompt() - chunked_reviews_JOIN = str("\n".join(chunked_reviews)) - prompt = str(f""" - {summarize_prompt} - {extra_prompt} - - ```{str(chunked_reviews_JOIN)}```""") - - response = genai_model.generate_content(prompt) + chunked_reviews_join = str("\n".join(chunked_reviews)) + system_instruction = summarize_prompt + genai_model = genai.GenerativeModel(model_name=model,system_instruction=system_instruction)) + response = genai_model.generate_content(chunked_reviews_join) summarized_review = response.text return chunked_reviews, summarized_review From 7411bafd2133524917b704e4253ae6cf77f6fde6 Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 21:32:19 -0300 Subject: [PATCH 06/17] Update entrypoint.py --- entrypoint.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/entrypoint.py b/entrypoint.py index 3881a7b..48b4ffc 100755 --- a/entrypoint.py +++ b/entrypoint.py @@ -117,7 +117,7 @@ def get_review( summarize_prompt = get_summarize_prompt() chunked_reviews_join = str("\n".join(chunked_reviews)) system_instruction = summarize_prompt - genai_model = genai.GenerativeModel(model_name=model,system_instruction=system_instruction)) + genai_model = genai.GenerativeModel(model_name=model,system_instruction=system_instruction) response = genai_model.generate_content(chunked_reviews_join) summarized_review = response.text return chunked_reviews, summarized_review From 2005b838b0060959864a9080b4ecf390685196cf Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 21:42:59 -0300 Subject: [PATCH 07/17] Update entrypoint.py --- entrypoint.py | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/entrypoint.py b/entrypoint.py index 48b4ffc..2cfc34a 100755 --- a/entrypoint.py +++ b/entrypoint.py @@ -101,12 +101,23 @@ def get_review( # Chunk the prompt review_prompt = get_review_prompt(extra_prompt=extra_prompt) chunked_diff_list = chunk_string(input_string=diff, chunk_size=prompt_chunk_size) + generation_config = { + "temperature": 1, + "top_p": 0.95, + "top_k": 0, + "max_output_tokens": 8192, + } + genai_model = genai.GenerativeModel(model_name=model,generation_config=generation_config,system_instruction=extra_prompt) # Get summary by chunk chunked_reviews = [] for chunked_diff in chunked_diff_list: - system_instruction = review_prompt - genai_model = genai.GenerativeModel(model_name=model,system_instruction=system_instruction) - response = genai_model.generate_content(chunked_diff) + prompt = str(f""" + {str(review_prompt)} + + ```txt + {str(chunked_diff)} + ```""") + response = genai_model.generate_content(prompt) review_result = response.text chunked_reviews.append(review_result) # If the chunked reviews are only one, return it @@ -116,9 +127,11 @@ def get_review( # Summarize the chunked reviews summarize_prompt = get_summarize_prompt() chunked_reviews_join = str("\n".join(chunked_reviews)) - system_instruction = summarize_prompt - genai_model = genai.GenerativeModel(model_name=model,system_instruction=system_instruction) - response = genai_model.generate_content(chunked_reviews_join) + prompt2 = str(f""" + {summarize_prompt} + + {str(chunked_reviews_JOIN)}""") + response = genai_model.generate_content(prompt2) summarized_review = response.text return chunked_reviews, summarized_review From 0a103f0c3dd9762da1b6e65f811e6bea3746d21a Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 21:43:56 -0300 Subject: [PATCH 08/17] Update entrypoint.py --- entrypoint.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/entrypoint.py b/entrypoint.py index 2cfc34a..ee80a72 100755 --- a/entrypoint.py +++ b/entrypoint.py @@ -130,7 +130,7 @@ def get_review( prompt2 = str(f""" {summarize_prompt} - {str(chunked_reviews_JOIN)}""") + {str(chunked_reviews_join)}""") response = genai_model.generate_content(prompt2) summarized_review = response.text return chunked_reviews, summarized_review From 783fd4ced34991d47fd72e8eefdb1bc884e9308d Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 21:50:31 -0300 Subject: [PATCH 09/17] Update entrypoint.py --- entrypoint.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/entrypoint.py b/entrypoint.py index ee80a72..693d795 100755 --- a/entrypoint.py +++ b/entrypoint.py @@ -36,12 +36,12 @@ def check_required_env_vars(): def get_review_prompt(extra_prompt: str = "") -> str: """Get a prompt template""" template = f""" - This is a pull request or a part of a pull request if the pull request is too large. - Please assume you review this PR as a great software engineer and a great security engineer. + This is a pull request or part of a pull request if the pull request is very large. + Suppose you review this PR as an excellent software engineer and an excellent security engineer. Can you tell me the issues with differences in a pull request and provide suggestions to improve it? - You can provide a summary of the review and comments about issues by file, if any important issues are found. - - {extra_prompt} + You can provide a review summary and comments on issues per file if any major issues are found. + Always put the name of the file that is citing the improvement or problem. + You will find the diff below so you can analyze: """ return template @@ -49,10 +49,10 @@ def get_review_prompt(extra_prompt: str = "") -> str: def get_summarize_prompt() -> str: """Get a prompt template""" template = """ - This is a pull request of a set of reviews of a pull request. - Those are generated by Gemini AI. - Can you summarized them? - It would be good to focus on highlighting issues and providing suggestions to improve the pull request. + This is a pull request from a set of revisions of a pull request. + Can you summarize them? + It would be good to focus on highlighting pressing issues and providing code suggestions to improve the pull request. + Always put the name of the file that is citing the improvement or problem. """ return template @@ -114,7 +114,7 @@ def get_review( prompt = str(f""" {str(review_prompt)} - ```txt + ``` {str(chunked_diff)} ```""") response = genai_model.generate_content(prompt) From 91f75433d3200a9102207d76a7cfc31c3aaef5e5 Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 22:01:01 -0300 Subject: [PATCH 10/17] Update entrypoint.py --- entrypoint.py | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/entrypoint.py b/entrypoint.py index 693d795..ffed654 100755 --- a/entrypoint.py +++ b/entrypoint.py @@ -39,9 +39,9 @@ def get_review_prompt(extra_prompt: str = "") -> str: This is a pull request or part of a pull request if the pull request is very large. Suppose you review this PR as an excellent software engineer and an excellent security engineer. Can you tell me the issues with differences in a pull request and provide suggestions to improve it? - You can provide a review summary and comments on issues per file if any major issues are found. - Always put the name of the file that is citing the improvement or problem. - You will find the diff below so you can analyze: + You can provide a review summary and issue comments per file if any major issues are found. + Always include the name of the file that is citing the improvement or problem. + In the next messages I will be sending you the difference between the GitHub file codes, okay? """ return template @@ -49,10 +49,9 @@ def get_review_prompt(extra_prompt: str = "") -> str: def get_summarize_prompt() -> str: """Get a prompt template""" template = """ - This is a pull request from a set of revisions of a pull request. - Can you summarize them? - It would be good to focus on highlighting pressing issues and providing code suggestions to improve the pull request. - Always put the name of the file that is citing the improvement or problem. + Can you summarize this for me? + It would be good to stick to highlighting pressing issues and providing code suggestions to improve the pull request. + Here's what you need to summarize: """ return template @@ -111,14 +110,9 @@ def get_review( # Get summary by chunk chunked_reviews = [] for chunked_diff in chunked_diff_list: - prompt = str(f""" - {str(review_prompt)} - - ``` - {str(chunked_diff)} - ```""") - response = genai_model.generate_content(prompt) - review_result = response.text + convo = model.start_chat(history=[]) + convo.send_message(review_prompt+"\n\n"+chunked_diff) + review_result = convo.last.text chunked_reviews.append(review_result) # If the chunked reviews are only one, return it if len(chunked_reviews) == 1: @@ -126,13 +120,19 @@ def get_review( # Summarize the chunked reviews summarize_prompt = get_summarize_prompt() - chunked_reviews_join = str("\n".join(chunked_reviews)) - prompt2 = str(f""" - {summarize_prompt} - - {str(chunked_reviews_join)}""") - response = genai_model.generate_content(prompt2) - summarized_review = response.text + chunked_reviews_join = "\n".join(chunked_reviews) + convo = model.start_chat(history=[ + { + "role": "user", + "parts": [summarize_prompt] + }, + { + "role": "model", + "parts": ["Ok"] + }, + ]) + convo.send_message(chunked_reviews_join) + summarized_review = convo.last.text return chunked_reviews, summarized_review From 2f3b3b8e1c5418b96c8143e3343f334ac84f4ba3 Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 22:05:38 -0300 Subject: [PATCH 11/17] Update entrypoint.py --- entrypoint.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/entrypoint.py b/entrypoint.py index ffed654..6c0b7e0 100755 --- a/entrypoint.py +++ b/entrypoint.py @@ -110,8 +110,17 @@ def get_review( # Get summary by chunk chunked_reviews = [] for chunked_diff in chunked_diff_list: - convo = model.start_chat(history=[]) - convo.send_message(review_prompt+"\n\n"+chunked_diff) + convo = genai_model.start_chat(history=[ + { + "role": "user", + "parts": [review_prompt] + }, + { + "role": "model", + "parts": ["Ok"] + }, + ]) + convo.send_message(chunked_diff) review_result = convo.last.text chunked_reviews.append(review_result) # If the chunked reviews are only one, return it @@ -121,17 +130,8 @@ def get_review( # Summarize the chunked reviews summarize_prompt = get_summarize_prompt() chunked_reviews_join = "\n".join(chunked_reviews) - convo = model.start_chat(history=[ - { - "role": "user", - "parts": [summarize_prompt] - }, - { - "role": "model", - "parts": ["Ok"] - }, - ]) - convo.send_message(chunked_reviews_join) + convo = genai_model.start_chat(history=[]) + convo.send_message(summarize_prompt+"\n\n"+chunked_reviews_join) summarized_review = convo.last.text return chunked_reviews, summarized_review From 09e46e896b83fb1eb3e7f3f3d3b2c6c1f0f8b922 Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 22:10:21 -0300 Subject: [PATCH 12/17] Update entrypoint.py --- entrypoint.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/entrypoint.py b/entrypoint.py index 6c0b7e0..ff4831f 100755 --- a/entrypoint.py +++ b/entrypoint.py @@ -122,6 +122,7 @@ def get_review( ]) convo.send_message(chunked_diff) review_result = convo.last.text + logger.debug(f"Response AI: {review_result}") chunked_reviews.append(review_result) # If the chunked reviews are only one, return it if len(chunked_reviews) == 1: @@ -133,6 +134,7 @@ def get_review( convo = genai_model.start_chat(history=[]) convo.send_message(summarize_prompt+"\n\n"+chunked_reviews_join) summarized_review = convo.last.text + logger.debug(f"Response AI: {summarized_review}") return chunked_reviews, summarized_review From d6a5219dce3ea910577dcb1edf9f5a28eea3191f Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 22:14:34 -0300 Subject: [PATCH 13/17] Update entrypoint.py --- entrypoint.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/entrypoint.py b/entrypoint.py index ff4831f..010f7db 100755 --- a/entrypoint.py +++ b/entrypoint.py @@ -125,11 +125,15 @@ def get_review( logger.debug(f"Response AI: {review_result}") chunked_reviews.append(review_result) # If the chunked reviews are only one, return it + if len(chunked_reviews) == 1: return chunked_reviews, chunked_reviews[0] - # Summarize the chunked reviews - summarize_prompt = get_summarize_prompt() + if len(chunked_reviews) == 0: + summarize_prompt = "Say that you didn't find any relevant changes to comment on any file" + else + summarize_prompt = get_summarize_prompt() + chunked_reviews_join = "\n".join(chunked_reviews) convo = genai_model.start_chat(history=[]) convo.send_message(summarize_prompt+"\n\n"+chunked_reviews_join) From a595ffc9278c61c91d2d9a514ac5a61d2227e64d Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 22:20:34 -0300 Subject: [PATCH 14/17] Update action.yml --- action.yml | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/action.yml b/action.yml index 4c2ca26..5ffc2a3 100644 --- a/action.yml +++ b/action.yml @@ -37,11 +37,31 @@ inputs: model: description: "GPT model" required: true - default: "gemini-1.5-pro-latest" + default: "text-davinci-003" extra_prompt: description: "Extra prompt for GPT" required: false default: "" + temperature: + description: "Temperature for GPT" + required: false + default: "0.7" + max_tokens: + description: "Max tokens for GPT" + required: false + default: "256" + top_p: + description: "Top p for GPT" + required: false + default: "1" + frequency_penalty: + description: "Frequency penalty for GPT" + required: false + default: "0.0" + presence_penalty: + description: "Presence penalty for GPT" + required: false + default: "0.0" pull_request_diff: description: "Pull request diff" required: true @@ -78,5 +98,10 @@ runs: args: - "--model=${{ inputs.model }}" - "--extra-prompt=${{ inputs.extra_prompt }}" + - "--temperature=${{ inputs.temperature }}" + - "--max-tokens=${{ inputs.max_tokens }}" + - "--top-p=${{ inputs.top_p }}" + - "--frequency-penalty=${{ inputs.frequency_penalty }}" + - "--presence-penalty=${{ inputs.presence_penalty }}" - "--diff-chunk-size=${{ inputs.pull_request_chunk_size }}" - "--diff=${{ inputs.pull_request_diff }}" From f45b0f7cf368558b92db21c38974ee74c624e890 Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 22:21:48 -0300 Subject: [PATCH 15/17] Update entrypoint.py --- entrypoint.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/entrypoint.py b/entrypoint.py index 010f7db..aaaacae 100755 --- a/entrypoint.py +++ b/entrypoint.py @@ -131,7 +131,7 @@ def get_review( if len(chunked_reviews) == 0: summarize_prompt = "Say that you didn't find any relevant changes to comment on any file" - else + else: summarize_prompt = get_summarize_prompt() chunked_reviews_join = "\n".join(chunked_reviews) From 72dafca06fc7e57133b3c1d377830baa757252ce Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 22:28:35 -0300 Subject: [PATCH 16/17] Update entrypoint.py --- entrypoint.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/entrypoint.py b/entrypoint.py index aaaacae..1627f69 100755 --- a/entrypoint.py +++ b/entrypoint.py @@ -147,10 +147,10 @@ def format_review_comment(summarized_review: str, chunked_reviews: List[str]) -> if len(chunked_reviews) == 1: return summarized_review unioned_reviews = "\n".join(chunked_reviews) - review = f""" - {summarized_review} - + review = f"""
+ {summarized_review} {unioned_reviews} +
""" return review @@ -167,7 +167,8 @@ def format_review_comment(summarized_review: str, chunked_reviews: List[str]) -> @click.option("--presence-penalty", type=click.FLOAT, required=False, default=0.0, help="Presence penalty") @click.option("--log-level", type=click.STRING, required=False, default="INFO", help="Presence penalty") def main( - diff: str, + + : str, diff_chunk_size: int, model: str, extra_prompt: str, From b26aa1968704b2d7acf424bc5ee6fe76d315fdfb Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 22:30:07 -0300 Subject: [PATCH 17/17] Update entrypoint.py --- entrypoint.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/entrypoint.py b/entrypoint.py index 1627f69..9335720 100755 --- a/entrypoint.py +++ b/entrypoint.py @@ -167,8 +167,7 @@ def format_review_comment(summarized_review: str, chunked_reviews: List[str]) -> @click.option("--presence-penalty", type=click.FLOAT, required=False, default=0.0, help="Presence penalty") @click.option("--log-level", type=click.STRING, required=False, default="INFO", help="Presence penalty") def main( - - : str, + diff: str, diff_chunk_size: int, model: str, extra_prompt: str,