From 3d38759519c31e845b084d7e487daae2eb603e76 Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 16:44:53 -0300 Subject: [PATCH 01/25] Update entrypoint.py --- entrypoint.py | 1 + 1 file changed, 1 insertion(+) diff --git a/entrypoint.py b/entrypoint.py index 0f376d8..bc3aac2 100755 --- a/entrypoint.py +++ b/entrypoint.py @@ -216,3 +216,4 @@ def main( if __name__ == "__main__": # pylint: disable=no-value-for-parameter main() + From 0f9d78d4c09082dd8c35d1cfa51a72f394e5132d Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 16:52:48 -0300 Subject: [PATCH 02/25] api_base --- entrypoint.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/entrypoint.py b/entrypoint.py index bc3aac2..426c3a2 100755 --- a/entrypoint.py +++ b/entrypoint.py @@ -182,7 +182,7 @@ def main( check_required_env_vars() # Set the OpenAI API key - openai.base_url = "https://my-openai-gemini-demo.vercel.app" + openai.api_base = "https://my-openai-gemini-demo.vercel.app" openai.api_key = os.getenv("GEMINI_API_KEY") # Request a code review From cd51bf34794a0981cf08eef620df38139c35169c Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 16:55:29 -0300 Subject: [PATCH 03/25] change api_base --- entrypoint.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/entrypoint.py b/entrypoint.py index 426c3a2..05e9b30 100755 --- a/entrypoint.py +++ b/entrypoint.py @@ -182,7 +182,7 @@ def main( check_required_env_vars() # Set the OpenAI API key - openai.api_base = "https://my-openai-gemini-demo.vercel.app" + openai.api_base = "https://my-openai-gemini-demo.vercel.app/v1" openai.api_key = os.getenv("GEMINI_API_KEY") # Request a code review From 71271ff157cd67958a046fab851a130abce4a29c Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 17:12:51 -0300 Subject: [PATCH 04/25] Update entrypoint.py --- entrypoint.py | 1 + 1 file changed, 1 insertion(+) diff --git a/entrypoint.py b/entrypoint.py index 05e9b30..807d57b 100755 --- a/entrypoint.py +++ b/entrypoint.py @@ -183,6 +183,7 @@ def main( # Set the OpenAI API key openai.api_base = "https://my-openai-gemini-demo.vercel.app/v1" + openai.api_type = "azure" openai.api_key = os.getenv("GEMINI_API_KEY") # Request a code review From a1ee03b99eb018f7167496a97bfb023e27588495 Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 17:15:48 -0300 Subject: [PATCH 05/25] Update entrypoint.py --- entrypoint.py | 1 + 1 file changed, 1 insertion(+) diff --git a/entrypoint.py b/entrypoint.py index 807d57b..79a6ab5 100755 --- a/entrypoint.py +++ b/entrypoint.py @@ -183,6 +183,7 @@ def main( # Set the OpenAI API key openai.api_base = "https://my-openai-gemini-demo.vercel.app/v1" + openai.api_version = "2022-12-01" openai.api_type = "azure" openai.api_key = os.getenv("GEMINI_API_KEY") From c0dcba2d859c82291a96b4255994456d61237ce9 Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 17:39:01 -0300 Subject: [PATCH 06/25] Update entrypoint.py --- entrypoint.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/entrypoint.py b/entrypoint.py index 79a6ab5..fd273fc 100755 --- a/entrypoint.py +++ b/entrypoint.py @@ -105,6 +105,7 @@ def get_review( chunked_reviews = [] for chunked_diff in chunked_diff_list: response = openai.ChatCompletion.create( + engine="deployment-name", model=model, messages=[ {"role": "system", "content": review_prompt}, @@ -125,6 +126,7 @@ def get_review( # Summarize the chunked reviews summarize_prompt = get_summarize_prompt() response = openai.ChatCompletion.create( + engine="deployment-name", model=model, messages=[ {"role": "system", "content": summarize_prompt}, From 3d3049aa086a37d5f09c85e4407d227c08f62330 Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 18:35:56 -0300 Subject: [PATCH 07/25] Gemini Package --- entrypoint.py | 189 ++++++++++++++++++++------------------------------ 1 file changed, 76 insertions(+), 113 deletions(-) diff --git a/entrypoint.py b/entrypoint.py index fd273fc..41a7536 100755 --- a/entrypoint.py +++ b/entrypoint.py @@ -1,23 +1,26 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this code except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + import json import os from typing import List import click -import openai import requests from loguru import logger +# Import Gemini API client library (assuming it's available) +from google_generativeai import GeminiClient + def check_required_env_vars(): """Check required environment variables""" @@ -50,7 +53,7 @@ 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 OpenAI's GPT. + Those are generated by Google Generative AI's model. Can you summarized them? It would be good to focus on highlighting issues and providing suggestions to improve the pull request. """ @@ -58,21 +61,14 @@ def get_summarize_prompt() -> str: def create_a_comment_to_pull_request( - github_token: str, - github_repository: str, - pull_request_number: int, - git_commit_hash: str, - body: str): + github_token: str, github_repository: str, pull_request_number: int, git_commit_hash: str, body: str +): """Create a comment to a pull request""" headers = { "Accept": "application/vnd.github.v3.patch", - "authorization": f"Bearer {github_token}" - } - data = { - "body": body, - "commit_id": git_commit_hash, - "event": "COMMENT" + "authorization": f"Bearer {github_token}", } + data = {"body": body, "commit_id": git_commit_hash, "event": "COMMENT"} url = f"https://api.github.com/repos/{github_repository}/pulls/{pull_request_number}/reviews" response = requests.post(url, headers=headers, data=json.dumps(data)) return response @@ -82,142 +78,109 @@ def chunk_string(input_string: str, chunk_size) -> List[str]: """Chunk a string""" chunked_inputs = [] for i in range(0, len(input_string), chunk_size): - chunked_inputs.append(input_string[i:i + chunk_size]) + chunked_inputs.append(input_string[i : i + chunk_size]) return chunked_inputs def get_review( - model: str, - diff: str, - extra_prompt: str, - temperature: float, - max_tokens: int, - top_p: float, - frequency_penalty: float, - presence_penalty: float, - prompt_chunk_size: int + client: GeminiClient, + diff: str, + extra_prompt: str, + temperature: float, + max_tokens: int, ): - """Get a 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) - # Get summary by chunk + """Get a review using the Gemini API + + This function chunks the diff, sends each chunk along with the prompt to + the Gemini API for review, and summarizes the individual reviews. + + Args: + client (GeminiClient): An initialized GeminiClient object. + diff (str): The pull request diff content. + extra_prompt (str): Additional prompt text for Gemini. + temperature (float): Temperature for controlling randomness. + max_tokens (int): Maximum number of tokens for response generation. + + Returns: + tuple: A tuple containing (chunked_reviews, summarized_review). + - chunked_reviews (List[str]): List of individual review responses. + - summarized_review (str): Summarized review of the entire diff. + """ + + # Chunk the diff + prompt_chunk_size = 3500 # Adjust as needed for Gemini's capabilities + chunked_diff_list = chunk_string(diff, chunk_size=prompt_chunk_size) + + # Get review by chunk chunked_reviews = [] for chunked_diff in chunked_diff_list: - response = openai.ChatCompletion.create( - engine="deployment-name", - model=model, - messages=[ - {"role": "system", "content": review_prompt}, - {"role": "user", "content": chunked_diff}, - ], + review_prompt = get_review_prompt(extra_prompt=extra_prompt) + response = client.text_generate( + prompt=review_prompt + chunked_diff, temperature=temperature, max_tokens=max_tokens, - top_p=top_p, - frequency_penalty=frequency_penalty, - presence_penalty=presence_penalty ) - review_result = response.choices[0].message["content"] + review_result = response.text 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() - response = openai.ChatCompletion.create( - engine="deployment-name", - model=model, - messages=[ - {"role": "system", "content": summarize_prompt}, - {"role": "user", "content": "\n".join(chunked_reviews)}, - ], + response = client.text_generate( + prompt=summarize_prompt + "\n".join(chunked_reviews), temperature=temperature, max_tokens=max_tokens, - top_p=top_p, - frequency_penalty=frequency_penalty, - presence_penalty=presence_penalty ) - summarized_review = response.choices[0].message["content"] - return chunked_reviews, summarized_review + summarized_review = response.text - -def format_review_comment(summarized_review: str, chunked_reviews: List[str]) -> str: - """Format reviews""" - if len(chunked_reviews) == 1: - return summarized_review - unioned_reviews = "\n".join(chunked_reviews) - review = f"""
- {summarized_review} - {unioned_reviews} -
- """ - return review + return chunked_reviews, summarized_review @click.command() @click.option("--diff", type=click.STRING, required=True, help="Pull request diff") -@click.option("--diff-chunk-size", type=click.INT, required=False, default=3500, help="Pull request diff") -@click.option("--model", type=click.STRING, required=False, default="gpt-3.5-turbo", help="Model") @click.option("--extra-prompt", type=click.STRING, required=False, default="", help="Extra prompt") -@click.option("--temperature", type=click.FLOAT, required=False, default=0.1, help="Temperature") -@click.option("--max-tokens", type=click.INT, required=False, default=512, help="Max tokens") -@click.option("--top-p", type=click.FLOAT, required=False, default=1.0, help="Top N") -@click.option("--frequency-penalty", type=click.FLOAT, required=False, default=0.0, help="Frequency penalty") -@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") +@click.option("--temperature", type=click.FLOAT, required=False, default=0.7, help="Temperature") +@click.option("--max-tokens", type=click.INT, required=False, default=1024, help="Max tokens") +@click.option("--log-level", type=click.STRING, required=False, default="INFO", help="Log level") def main( - diff: str, - diff_chunk_size: int, - model: str, - extra_prompt: str, - temperature: float, - max_tokens: int, - top_p: float, - frequency_penalty: float, - presence_penalty: float, - log_level: str + diff: str, + extra_prompt: str, + temperature: float, + max_tokens: int, + log_level: str, ): # Set log level logger.level(log_level) + # Check if necessary environment variables are set or not check_required_env_vars() - # Set the OpenAI API key - openai.api_base = "https://my-openai-gemini-demo.vercel.app/v1" - openai.api_version = "2022-12-01" - openai.api_type = "azure" - openai.api_key = os.getenv("GEMINI_API_KEY") + # Authenticate with Gemini API (assuming API key is stored in environment variable) + api_key = os.getenv("GEMINI_API_KEY") + client = GeminiClient(api_key=api_key) # Request a code review chunked_reviews, summarized_review = get_review( + client=client, diff=diff, extra_prompt=extra_prompt, - model=model, temperature=temperature, max_tokens=max_tokens, - top_p=top_p, - frequency_penalty=frequency_penalty, - presence_penalty=presence_penalty, - prompt_chunk_size=diff_chunk_size ) logger.debug(f"Summarized review: {summarized_review}") logger.debug(f"Chunked reviews: {chunked_reviews}") - # Format reviews - review_comment = format_review_comment(summarized_review=summarized_review, - chunked_reviews=chunked_reviews) - # Create a comment to a pull request + # Format reviews (same logic as before) + review_comment = format_review_comment(summarized_review=summarized_review, chunked_reviews=chunked_reviews) + + # Create a comment to a pull request (same logic as before) create_a_comment_to_pull_request( github_token=os.getenv("GITHUB_TOKEN"), github_repository=os.getenv("GITHUB_REPOSITORY"), pull_request_number=int(os.getenv("GITHUB_PULL_REQUEST_NUMBER")), git_commit_hash=os.getenv("GIT_COMMIT_HASH"), - body=review_comment + body=review_comment, ) if __name__ == "__main__": - # pylint: disable=no-value-for-parameter - main() - + # pylint: disable=no-value-for From 015a314f3899c5865240857678ae0016efdc0394 Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 18:38:41 -0300 Subject: [PATCH 08/25] install google-generativeai --- requirements.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 8f4221f..ba1f538 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,5 +15,4 @@ loguru==0.7.0 requests==2.28.2 -langchain[openai]==0.0.144 -openai==0.27.0 +google-generativeai==0.5.2 From 423d99bec378140a7ae168d8946c08632cb752b1 Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 19:33:05 -0300 Subject: [PATCH 09/25] Update entrypoint.py --- entrypoint.py | 170 ++++++++++++++++++++++++++------------------------ 1 file changed, 90 insertions(+), 80 deletions(-) diff --git a/entrypoint.py b/entrypoint.py index 41a7536..1cd8908 100755 --- a/entrypoint.py +++ b/entrypoint.py @@ -1,26 +1,23 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this code except in compliance with the License. -# You may obtain a copy of the License at - -# http://www.apache.org/licenses/LICENSE-2.0 - -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import json import os from typing import List import click +import google.generativeai as genai import requests from loguru import logger -# Import Gemini API client library (assuming it's available) -from google_generativeai import GeminiClient - def check_required_env_vars(): """Check required environment variables""" @@ -53,7 +50,7 @@ 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 Google Generative AI's model. + 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. """ @@ -61,14 +58,21 @@ def get_summarize_prompt() -> str: def create_a_comment_to_pull_request( - github_token: str, github_repository: str, pull_request_number: int, git_commit_hash: str, body: str -): + github_token: str, + github_repository: str, + pull_request_number: int, + git_commit_hash: str, + body: str): """Create a comment to a pull request""" headers = { "Accept": "application/vnd.github.v3.patch", - "authorization": f"Bearer {github_token}", + "authorization": f"Bearer {github_token}" + } + data = { + "body": body, + "commit_id": git_commit_hash, + "event": "COMMENT" } - data = {"body": body, "commit_id": git_commit_hash, "event": "COMMENT"} url = f"https://api.github.com/repos/{github_repository}/pulls/{pull_request_number}/reviews" response = requests.post(url, headers=headers, data=json.dumps(data)) return response @@ -78,109 +82,115 @@ def chunk_string(input_string: str, chunk_size) -> List[str]: """Chunk a string""" chunked_inputs = [] for i in range(0, len(input_string), chunk_size): - chunked_inputs.append(input_string[i : i + chunk_size]) + chunked_inputs.append(input_string[i:i + chunk_size]) return chunked_inputs def get_review( - client: GeminiClient, - diff: str, - extra_prompt: str, - temperature: float, - max_tokens: int, + model: str, + diff: str, + extra_prompt: str, + temperature: float, + max_tokens: int, + top_p: float, + frequency_penalty: float, + presence_penalty: float, + prompt_chunk_size: int ): - """Get a review using the Gemini API - - This function chunks the diff, sends each chunk along with the prompt to - the Gemini API for review, and summarizes the individual reviews. - - Args: - client (GeminiClient): An initialized GeminiClient object. - diff (str): The pull request diff content. - extra_prompt (str): Additional prompt text for Gemini. - temperature (float): Temperature for controlling randomness. - max_tokens (int): Maximum number of tokens for response generation. - - Returns: - tuple: A tuple containing (chunked_reviews, summarized_review). - - chunked_reviews (List[str]): List of individual review responses. - - summarized_review (str): Summarized review of the entire diff. - """ - - # Chunk the diff - prompt_chunk_size = 3500 # Adjust as needed for Gemini's capabilities - chunked_diff_list = chunk_string(diff, chunk_size=prompt_chunk_size) - - # Get review by chunk + """Get a review""" + # Chunk the prompt + genaiModel = 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: - review_prompt = get_review_prompt(extra_prompt=extra_prompt) - response = client.text_generate( - prompt=review_prompt + chunked_diff, - temperature=temperature, - max_tokens=max_tokens, - ) + response = model.generate_content("".review_prompt."```".chunked_diff."```") review_result = response.text 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() - response = client.text_generate( - prompt=summarize_prompt + "\n".join(chunked_reviews), - temperature=temperature, - max_tokens=max_tokens, - ) + response = model.generate_content("".summarize_prompt."```".join(chunked_reviews)."```") summarized_review = response.text - return chunked_reviews, summarized_review +def format_review_comment(summarized_review: str, chunked_reviews: List[str]) -> str: + """Format reviews""" + if len(chunked_reviews) == 1: + return summarized_review + unioned_reviews = "\n".join(chunked_reviews) + review = f"""
+ {summarized_review} + {unioned_reviews} +
+ """ + return review + + @click.command() @click.option("--diff", type=click.STRING, required=True, help="Pull request diff") +@click.option("--diff-chunk-size", type=click.INT, required=False, default=3500, help="Pull request diff") +@click.option("--model", type=click.STRING, required=False, default="gpt-3.5-turbo", help="Model") @click.option("--extra-prompt", type=click.STRING, required=False, default="", help="Extra prompt") -@click.option("--temperature", type=click.FLOAT, required=False, default=0.7, help="Temperature") -@click.option("--max-tokens", type=click.INT, required=False, default=1024, help="Max tokens") -@click.option("--log-level", type=click.STRING, required=False, default="INFO", help="Log level") +@click.option("--temperature", type=click.FLOAT, required=False, default=0.1, help="Temperature") +@click.option("--max-tokens", type=click.INT, required=False, default=512, help="Max tokens") +@click.option("--top-p", type=click.FLOAT, required=False, default=1.0, help="Top N") +@click.option("--frequency-penalty", type=click.FLOAT, required=False, default=0.0, help="Frequency penalty") +@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, - extra_prompt: str, - temperature: float, - max_tokens: int, - log_level: str, + diff: str, + diff_chunk_size: int, + model: str, + extra_prompt: str, + temperature: float, + max_tokens: int, + top_p: float, + frequency_penalty: float, + presence_penalty: float, + log_level: str ): # Set log level logger.level(log_level) - # Check if necessary environment variables are set or not check_required_env_vars() - # Authenticate with Gemini API (assuming API key is stored in environment variable) - api_key = os.getenv("GEMINI_API_KEY") - client = GeminiClient(api_key=api_key) + # Set the Gemini API key + genai.configure(api_key=os.getenv("GEMINI_API_KEY")) # Request a code review chunked_reviews, summarized_review = get_review( - client=client, diff=diff, extra_prompt=extra_prompt, + model=model, temperature=temperature, max_tokens=max_tokens, + top_p=top_p, + frequency_penalty=frequency_penalty, + presence_penalty=presence_penalty, + prompt_chunk_size=diff_chunk_size ) logger.debug(f"Summarized review: {summarized_review}") logger.debug(f"Chunked reviews: {chunked_reviews}") - # Format reviews (same logic as before) - review_comment = format_review_comment(summarized_review=summarized_review, chunked_reviews=chunked_reviews) - - # Create a comment to a pull request (same logic as before) + # Format reviews + review_comment = format_review_comment(summarized_review=summarized_review, + chunked_reviews=chunked_reviews) + # Create a comment to a pull request create_a_comment_to_pull_request( github_token=os.getenv("GITHUB_TOKEN"), github_repository=os.getenv("GITHUB_REPOSITORY"), pull_request_number=int(os.getenv("GITHUB_PULL_REQUEST_NUMBER")), git_commit_hash=os.getenv("GIT_COMMIT_HASH"), - body=review_comment, + body=review_comment ) if __name__ == "__main__": - # pylint: disable=no-value-for + # pylint: disable=no-value-for-parameter + main() From 2539bb381b8cc707856f02d65fd04c0496a65ef1 Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 19:33:10 -0300 Subject: [PATCH 10/25] Update action.yml --- action.yml | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/action.yml b/action.yml index 6bba1b6..4c2ca26 100644 --- a/action.yml +++ b/action.yml @@ -42,26 +42,6 @@ inputs: 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 @@ -98,10 +78,5 @@ 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 09c36342a80b54f928f6f926faf7b21ec3c1da30 Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 19:37:07 -0300 Subject: [PATCH 11/25] Update entrypoint.py --- entrypoint.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/entrypoint.py b/entrypoint.py index 1cd8908..e39e1f6 100755 --- a/entrypoint.py +++ b/entrypoint.py @@ -105,7 +105,7 @@ def get_review( # Get summary by chunk chunked_reviews = [] for chunked_diff in chunked_diff_list: - response = model.generate_content("".review_prompt."```".chunked_diff."```") + response = model.generate_content(review_prompt + "\n\n```" + chunked_diff + "```") review_result = response.text chunked_reviews.append(review_result) # If the chunked reviews are only one, return it @@ -114,7 +114,7 @@ def get_review( # Summarize the chunked reviews summarize_prompt = get_summarize_prompt() - response = model.generate_content("".summarize_prompt."```".join(chunked_reviews)."```") + response = model.generate_content(summarize_prompt + "\n\n```" + "\n".join(chunked_reviews) + "```") summarized_review = response.text return chunked_reviews, summarized_review From 7d7cea93014b6bac2c6966f60da372e33ff5b7e5 Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 19:38:28 -0300 Subject: [PATCH 12/25] Update entrypoint.py --- entrypoint.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/entrypoint.py b/entrypoint.py index e39e1f6..ba2cb63 100755 --- a/entrypoint.py +++ b/entrypoint.py @@ -105,7 +105,7 @@ def get_review( # Get summary by chunk chunked_reviews = [] for chunked_diff in chunked_diff_list: - response = model.generate_content(review_prompt + "\n\n```" + chunked_diff + "```") + response = model.generate_content("" + review_prompt + "\n\n```" + chunked_diff + "```") review_result = response.text chunked_reviews.append(review_result) # If the chunked reviews are only one, return it @@ -114,7 +114,7 @@ def get_review( # Summarize the chunked reviews summarize_prompt = get_summarize_prompt() - response = model.generate_content(summarize_prompt + "\n\n```" + "\n".join(chunked_reviews) + "```") + response = model.generate_content("" + summarize_prompt + "\n\n```" + "\n".join(chunked_reviews) + "```") summarized_review = response.text return chunked_reviews, summarized_review From dcefe5cc2eb443e60e73eed89984379e5f67661c Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 19:40:56 -0300 Subject: [PATCH 13/25] Update entrypoint.py --- entrypoint.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/entrypoint.py b/entrypoint.py index ba2cb63..20d98c4 100755 --- a/entrypoint.py +++ b/entrypoint.py @@ -105,7 +105,7 @@ def get_review( # Get summary by chunk chunked_reviews = [] for chunked_diff in chunked_diff_list: - response = model.generate_content("" + review_prompt + "\n\n```" + chunked_diff + "```") + response = model.generate_content(str(review_prompt + "\n\n```" + chunked_diff + "```")) review_result = response.text chunked_reviews.append(review_result) # If the chunked reviews are only one, return it @@ -114,7 +114,7 @@ def get_review( # Summarize the chunked reviews summarize_prompt = get_summarize_prompt() - response = model.generate_content("" + summarize_prompt + "\n\n```" + "\n".join(chunked_reviews) + "```") + response = model.generate_content(str(summarize_prompt + "\n\n```" + "\n".join(chunked_reviews) + "```")) summarized_review = response.text return chunked_reviews, summarized_review From 8f5d99ff8755d0bd023736890553e5c181c8d67d Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 19:43:03 -0300 Subject: [PATCH 14/25] Update entrypoint.py --- entrypoint.py | 1 + 1 file changed, 1 insertion(+) diff --git a/entrypoint.py b/entrypoint.py index 20d98c4..7557650 100755 --- a/entrypoint.py +++ b/entrypoint.py @@ -105,6 +105,7 @@ def get_review( # Get summary by chunk chunked_reviews = [] for chunked_diff in chunked_diff_list: + logger.debug(str(review_prompt + "\n\n```" + chunked_diff + "```")) response = model.generate_content(str(review_prompt + "\n\n```" + chunked_diff + "```")) review_result = response.text chunked_reviews.append(review_result) From 69c9508f054687f093f145d8e46f5c0e5246148f Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 19:47:44 -0300 Subject: [PATCH 15/25] Update entrypoint.py --- entrypoint.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/entrypoint.py b/entrypoint.py index 7557650..f8c487d 100755 --- a/entrypoint.py +++ b/entrypoint.py @@ -105,8 +105,8 @@ def get_review( # Get summary by chunk chunked_reviews = [] for chunked_diff in chunked_diff_list: - logger.debug(str(review_prompt + "\n\n```" + chunked_diff + "```")) - response = model.generate_content(str(review_prompt + "\n\n```" + chunked_diff + "```")) + logger.debug(review_prompt + "\n\n```" + chunked_diff + "```") + response = model.generate_content(f"""{review_prompt}\n\n```{chunked_diff}```""") review_result = response.text chunked_reviews.append(review_result) # If the chunked reviews are only one, return it @@ -115,7 +115,7 @@ def get_review( # Summarize the chunked reviews summarize_prompt = get_summarize_prompt() - response = model.generate_content(str(summarize_prompt + "\n\n```" + "\n".join(chunked_reviews) + "```")) + response = model.generate_content(f"""{summarize_prompt}\n\n```{"\n".join(chunked_reviews)}```""") summarized_review = response.text return chunked_reviews, summarized_review From 816d831edf030ea434dfe610bb733ee930e9fc46 Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 19:50:08 -0300 Subject: [PATCH 16/25] Update entrypoint.py --- entrypoint.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/entrypoint.py b/entrypoint.py index f8c487d..582c208 100755 --- a/entrypoint.py +++ b/entrypoint.py @@ -105,8 +105,9 @@ def get_review( # Get summary by chunk chunked_reviews = [] for chunked_diff in chunked_diff_list: - logger.debug(review_prompt + "\n\n```" + chunked_diff + "```") - response = model.generate_content(f"""{review_prompt}\n\n```{chunked_diff}```""") + prompt = f"""{review_prompt}\n\n```{chunked_diff}```""" + logger.debug(f"Prompt: {prompt}") + response = model.generate_content(prompt) review_result = response.text chunked_reviews.append(review_result) # If the chunked reviews are only one, return it @@ -115,7 +116,9 @@ def get_review( # Summarize the chunked reviews summarize_prompt = get_summarize_prompt() - response = model.generate_content(f"""{summarize_prompt}\n\n```{"\n".join(chunked_reviews)}```""") + prompt = f"""{summarize_prompt}\n\n```{"\n".join(chunked_reviews)}```""" + logger.debug(f"Prompt: {prompt}") + response = model.generate_content(prompt) summarized_review = response.text return chunked_reviews, summarized_review From 3c80e278c23bc53e064040a5d978581ab3c79439 Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 19:52:14 -0300 Subject: [PATCH 17/25] Update entrypoint.py --- entrypoint.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/entrypoint.py b/entrypoint.py index 582c208..18e32ca 100755 --- a/entrypoint.py +++ b/entrypoint.py @@ -105,7 +105,11 @@ def get_review( # Get summary by chunk chunked_reviews = [] for chunked_diff in chunked_diff_list: - prompt = f"""{review_prompt}\n\n```{chunked_diff}```""" + prompt = f""" + {review_prompt} + + ```{chunked_diff}```""" + logger.debug(f"Prompt: {prompt}") response = model.generate_content(prompt) review_result = response.text @@ -116,7 +120,11 @@ def get_review( # Summarize the chunked reviews summarize_prompt = get_summarize_prompt() - prompt = f"""{summarize_prompt}\n\n```{"\n".join(chunked_reviews)}```""" + prompt = f""" + {summarize_prompt} + + ```{" ".join(chunked_reviews)}```""" + logger.debug(f"Prompt: {prompt}") response = model.generate_content(prompt) summarized_review = response.text From dcb3b5066839d3cea5c9b9f3133bff28686d9b92 Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 19:55:47 -0300 Subject: [PATCH 18/25] Update entrypoint.py --- entrypoint.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/entrypoint.py b/entrypoint.py index 18e32ca..fb2e87b 100755 --- a/entrypoint.py +++ b/entrypoint.py @@ -106,9 +106,9 @@ def get_review( chunked_reviews = [] for chunked_diff in chunked_diff_list: prompt = f""" - {review_prompt} + {str(review_prompt)} - ```{chunked_diff}```""" + ```{str(chunked_diff)}```""" logger.debug(f"Prompt: {prompt}") response = model.generate_content(prompt) @@ -120,11 +120,12 @@ def get_review( # Summarize the chunked reviews summarize_prompt = get_summarize_prompt() + chunked_reviews_JOIN = str("\n".join(chunked_reviews)) prompt = f""" {summarize_prompt} - ```{" ".join(chunked_reviews)}```""" - + ```{str(chunked_reviews_JOIN)}```""" + logger.debug(f"Prompt: {prompt}") response = model.generate_content(prompt) summarized_review = response.text From bf64f79eb6134760dc05672033a3618a60368111 Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 19:58:33 -0300 Subject: [PATCH 19/25] Update entrypoint.py --- entrypoint.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/entrypoint.py b/entrypoint.py index fb2e87b..1ad5d8f 100755 --- a/entrypoint.py +++ b/entrypoint.py @@ -105,10 +105,10 @@ def get_review( # Get summary by chunk chunked_reviews = [] for chunked_diff in chunked_diff_list: - prompt = f""" + prompt = str(f""" {str(review_prompt)} - ```{str(chunked_diff)}```""" + ```{str(chunked_diff)}```""") logger.debug(f"Prompt: {prompt}") response = model.generate_content(prompt) @@ -121,10 +121,10 @@ def get_review( # Summarize the chunked reviews summarize_prompt = get_summarize_prompt() chunked_reviews_JOIN = str("\n".join(chunked_reviews)) - prompt = f""" + prompt = str(f""" {summarize_prompt} - ```{str(chunked_reviews_JOIN)}```""" + ```{str(chunked_reviews_JOIN)}```""") logger.debug(f"Prompt: {prompt}") response = model.generate_content(prompt) From 13f7f089244458fbee77cdf53de4e74096b71347 Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 20:01:13 -0300 Subject: [PATCH 20/25] Update entrypoint.py --- entrypoint.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/entrypoint.py b/entrypoint.py index 1ad5d8f..530148e 100755 --- a/entrypoint.py +++ b/entrypoint.py @@ -111,7 +111,7 @@ def get_review( ```{str(chunked_diff)}```""") logger.debug(f"Prompt: {prompt}") - response = model.generate_content(prompt) + response = genaiModel.generate_content(prompt) review_result = response.text chunked_reviews.append(review_result) # If the chunked reviews are only one, return it @@ -127,7 +127,7 @@ def get_review( ```{str(chunked_reviews_JOIN)}```""") logger.debug(f"Prompt: {prompt}") - response = model.generate_content(prompt) + response = genaiModel.generate_content(prompt) summarized_review = response.text return chunked_reviews, summarized_review From 279743f0205e5899f71c061279b86ac9853792fa Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 20:05:50 -0300 Subject: [PATCH 21/25] Update test-action.yml --- .github/workflows/test-action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-action.yml b/.github/workflows/test-action.yml index e329be8..118b22c 100644 --- a/.github/workflows/test-action.yml +++ b/.github/workflows/test-action.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.5-pro-latest" + model: "gemini-1.0-pro-latest" temperature: "0.1" max_tokens: "512" top_p: "1" From f73b0be2001f10478c3e78da456a9f1edfab2ad9 Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 20:08:08 -0300 Subject: [PATCH 22/25] Update entrypoint.py --- entrypoint.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/entrypoint.py b/entrypoint.py index 530148e..c0a71b4 100755 --- a/entrypoint.py +++ b/entrypoint.py @@ -99,7 +99,7 @@ def get_review( ): """Get a review""" # Chunk the prompt - genaiModel = genai.GenerativeModel(model) + 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 @@ -110,8 +110,7 @@ def get_review( ```{str(chunked_diff)}```""") - logger.debug(f"Prompt: {prompt}") - response = genaiModel.generate_content(prompt) + response = genai_model.generate_content(prompt) review_result = response.text chunked_reviews.append(review_result) # If the chunked reviews are only one, return it @@ -126,8 +125,7 @@ def get_review( ```{str(chunked_reviews_JOIN)}```""") - logger.debug(f"Prompt: {prompt}") - response = genaiModel.generate_content(prompt) + response = genai_model.generate_content(prompt) summarized_review = response.text return chunked_reviews, summarized_review @@ -175,6 +173,7 @@ def main( # Set the Gemini API key genai.configure(api_key=os.getenv("GEMINI_API_KEY")) + logger.debug(f"api_key: {os.getenv("GEMINI_API_KEY")}") # Request a code review chunked_reviews, summarized_review = get_review( From 74f926acac941154571274d3dff11b617525b3d4 Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 20:09:17 -0300 Subject: [PATCH 23/25] Update entrypoint.py --- entrypoint.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/entrypoint.py b/entrypoint.py index c0a71b4..f4bb39c 100755 --- a/entrypoint.py +++ b/entrypoint.py @@ -172,8 +172,9 @@ def main( check_required_env_vars() # Set the Gemini API key - genai.configure(api_key=os.getenv("GEMINI_API_KEY")) - logger.debug(f"api_key: {os.getenv("GEMINI_API_KEY")}") + api_key = os.getenv("GEMINI_API_KEY") + genai.configure(api_key=api_key) + logger.debug(f"api_key: {api_key}") # Request a code review chunked_reviews, summarized_review = get_review( From 770a93652d4a531ad21403457a6996f295061f52 Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 20:15:43 -0300 Subject: [PATCH 24/25] Answer in Brazilian Portuguese! --- .github/workflows/test-action.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/workflows/test-action.yml b/.github/workflows/test-action.yml index 118b22c..eec642b 100644 --- a/.github/workflows/test-action.yml +++ b/.github/workflows/test-action.yml @@ -54,14 +54,9 @@ jobs: github_pull_request_number: ${{ github.event.pull_request.number }} git_commit_hash: ${{ github.event.pull_request.head.sha }} model: "gemini-1.0-pro-latest" - temperature: "0.1" - max_tokens: "512" - top_p: "1" - frequency_penalty: "0.0" - presence_penalty: "0.0" pull_request_diff: |- ${{ steps.get_diff.outputs.pull_request_diff }} pull_request_chunk_size: "3500" extra_prompt: |- - You are very familiar with python too. + You are very familiar with python too. Answer in Brazilian Portuguese! log_level: "DEBUG" From 33c5cfdff4d42f602410f0677f87654932849227 Mon Sep 17 00:00:00 2001 From: Rubens Flinco Date: Sat, 11 May 2024 20:19:30 -0300 Subject: [PATCH 25/25] Update README.md --- README.md | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/README.md b/README.md index 64878ad..5850dea 100644 --- a/README.md +++ b/README.md @@ -18,11 +18,6 @@ We have to set a GitHub Actions secret `GEMINI_API_KEY` to use the OpenAI API so - `pull_request_diff_chunk_size`: The chunk size of the diff of the pull request to generate a review comment. - `extra_prompt`: The extra prompt to generate a review comment. - `model`: The model to generate a review comment. We can use a model which is available in `openai.ChatCompletion.create`. -- `temperature`: The temperature to generate a review comment. -- `top_p`: The top_p to generate a review comment. -- `max_tokens`: The max_tokens to generate a review comment. -- `frequency_penalty`: The frequency_penalty to generate a review comment. -- `presence_penalty`: The presence_penalty to generate a review comment. - `log_level`: The log level to print logs. As you might know, a model of OpenAI has limitation of the maximum number of input tokens. @@ -77,12 +72,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.5-pro-latest" - temperature: "0.1" - max_tokens: "512" - top_p: "1" - frequency_penalty: "0.0" - presence_penalty: "0.0" + model: "gemini-1.0-pro-latest" pull_request_diff: |- ${{ steps.get_diff.outputs.pull_request_diff }} pull_request_chunk_size: "3500"