From e67e6638225240c16c35eb1306fa57604542af8f Mon Sep 17 00:00:00 2001 From: DibyoGit <64616330+DibyoGit@users.noreply.github.com> Date: Fri, 11 Jul 2025 11:49:46 +0530 Subject: [PATCH 01/22] Create tabby-ai-review.yaml --- .github/workflows/tabby-ai-review.yaml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 .github/workflows/tabby-ai-review.yaml diff --git a/.github/workflows/tabby-ai-review.yaml b/.github/workflows/tabby-ai-review.yaml new file mode 100644 index 00000000..793c0551 --- /dev/null +++ b/.github/workflows/tabby-ai-review.yaml @@ -0,0 +1,26 @@ +name: AI Code Review with Tabby + +on: + pull_request: + types: [opened, synchronize] + +jobs: + tabby-review: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: 3.11 + + - name: Install dependencies + run: pip install -r ai-review/requirements.txt + + - name: Run Tabby PR review + env: + TABBY_URL: ${{ secrets.TABBY_URL }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: python ai-review/review_bot.py From c1879a61fdcc04b7bbdd4312d2eac0f937809fc6 Mon Sep 17 00:00:00 2001 From: DibyoGit <64616330+DibyoGit@users.noreply.github.com> Date: Fri, 11 Jul 2025 11:52:15 +0530 Subject: [PATCH 02/22] Create review-bot.py --- ai-review/review-bot.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 ai-review/review-bot.py diff --git a/ai-review/review-bot.py b/ai-review/review-bot.py new file mode 100644 index 00000000..1ddcaae4 --- /dev/null +++ b/ai-review/review-bot.py @@ -0,0 +1,23 @@ +import os +import subprocess +from github_api import post_comment +from tabby_client import get_tabby_review + +def get_changed_files(): + output = subprocess.check_output(["git", "diff", "--name-only", "origin/main...HEAD"]) + return output.decode().splitlines() + +def main(): + tabby_url = os.getenv("TABBY_URL", "http://54.196.243.3:8080") + changed_files = get_changed_files() + + for file_path in changed_files: + with open(file_path, "r") as f: + code = f.read() + + prompt = f"Review this code for issues:\n\n{code}" + suggestion = get_tabby_review(prompt, tabby_url) + post_comment(file_path, suggestion) + +if __name__ == "__main__": + main() From 56a4bb8cf4c1a02d0dac568df2e9054df2ff9f6e Mon Sep 17 00:00:00 2001 From: DibyoGit <64616330+DibyoGit@users.noreply.github.com> Date: Fri, 11 Jul 2025 11:52:59 +0530 Subject: [PATCH 03/22] Create githin-api.py --- ai-review/githin-api.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 ai-review/githin-api.py diff --git a/ai-review/githin-api.py b/ai-review/githin-api.py new file mode 100644 index 00000000..6cc8a99f --- /dev/null +++ b/ai-review/githin-api.py @@ -0,0 +1,17 @@ +import os +import requests + +def post_comment(file_path, comment): + repo = os.getenv("GITHUB_REPOSITORY") + pr_number = os.getenv("GITHUB_REF").split("/")[-1] + token = os.getenv("GITHUB_TOKEN") + + url = f"https://api.github.com/repos/{repo}/issues/{pr_number}/comments" + headers = { + "Authorization": f"Bearer {token}", + "Accept": "application/vnd.github+json" + } + + body = f"💡 **AI Review Suggestion for `{file_path}`**\n\n{comment}" + response = requests.post(url, json={"body": body}, headers=headers) + response.raise_for_status() From 392e740c1ec7d52ad7b523e4dd1ca83b9e4743d0 Mon Sep 17 00:00:00 2001 From: DibyoGit <64616330+DibyoGit@users.noreply.github.com> Date: Fri, 11 Jul 2025 11:59:30 +0530 Subject: [PATCH 04/22] Create requirements.txt --- ai-review/requirements.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 ai-review/requirements.txt diff --git a/ai-review/requirements.txt b/ai-review/requirements.txt new file mode 100644 index 00000000..f79c0da7 --- /dev/null +++ b/ai-review/requirements.txt @@ -0,0 +1,2 @@ +requests +rich From 975794684f9ed2a1453ac532616015dcf08d5242 Mon Sep 17 00:00:00 2001 From: DibyoGit <64616330+DibyoGit@users.noreply.github.com> Date: Fri, 11 Jul 2025 12:00:51 +0530 Subject: [PATCH 05/22] Rename review-bot.py to review_bot.py --- ai-review/{review-bot.py => review_bot.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ai-review/{review-bot.py => review_bot.py} (100%) diff --git a/ai-review/review-bot.py b/ai-review/review_bot.py similarity index 100% rename from ai-review/review-bot.py rename to ai-review/review_bot.py From 3380a94814ffa51184c0a9440a804ef5404d8c84 Mon Sep 17 00:00:00 2001 From: DibyoGit <64616330+DibyoGit@users.noreply.github.com> Date: Fri, 11 Jul 2025 12:01:07 +0530 Subject: [PATCH 06/22] Rename githin-api.py to githhub_api.py --- ai-review/{githin-api.py => githhub_api.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ai-review/{githin-api.py => githhub_api.py} (100%) diff --git a/ai-review/githin-api.py b/ai-review/githhub_api.py similarity index 100% rename from ai-review/githin-api.py rename to ai-review/githhub_api.py From ed20c624922e665958215ae646839ffa2bead13d Mon Sep 17 00:00:00 2001 From: DibyoGit <64616330+DibyoGit@users.noreply.github.com> Date: Fri, 11 Jul 2025 12:02:11 +0530 Subject: [PATCH 07/22] Rename githhub_api.py to github_api.py --- ai-review/{githhub_api.py => github_api.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ai-review/{githhub_api.py => github_api.py} (100%) diff --git a/ai-review/githhub_api.py b/ai-review/github_api.py similarity index 100% rename from ai-review/githhub_api.py rename to ai-review/github_api.py From 817e17862601fe2da86324f0955dfea1025d6d64 Mon Sep 17 00:00:00 2001 From: DibyoGit <64616330+DibyoGit@users.noreply.github.com> Date: Fri, 11 Jul 2025 12:03:27 +0530 Subject: [PATCH 08/22] Create tabby_client.py --- ai-review/tabby_client.py | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 ai-review/tabby_client.py diff --git a/ai-review/tabby_client.py b/ai-review/tabby_client.py new file mode 100644 index 00000000..a254cd7a --- /dev/null +++ b/ai-review/tabby_client.py @@ -0,0 +1,31 @@ +import requests + +def get_tabby_review(prompt: str, tabby_url="http://54.196.243.3:8080") -> str: + """ + Sends a prompt to the TabbyML chat model and returns the response. + + Args: + prompt (str): The prompt text to analyze. + tabby_url (str): Base URL of the TabbyML server. + + Returns: + str: AI-generated response from TabbyML. + """ + try: + response = requests.post( + f"{tabby_url}/v1/chat/completions", + json={ + "messages": [ + {"role": "user", "content": prompt} + ], + "temperature": 0.4, + }, + timeout=30 + ) + response.raise_for_status() + result = response.json() + return result["choices"][0]["message"]["content"] + + except requests.exceptions.RequestException as e: + print(f"[ERROR] Failed to communicate with TabbyML: {e}") + return "⚠️ Error: Unable to connect to TabbyML server." From 2919dba1045f494de59e66255e351415794563b3 Mon Sep 17 00:00:00 2001 From: DibyoGit <64616330+DibyoGit@users.noreply.github.com> Date: Fri, 11 Jul 2025 12:05:21 +0530 Subject: [PATCH 09/22] Update review_bot.py --- ai-review/review_bot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ai-review/review_bot.py b/ai-review/review_bot.py index 1ddcaae4..9c946c7d 100644 --- a/ai-review/review_bot.py +++ b/ai-review/review_bot.py @@ -4,7 +4,7 @@ from tabby_client import get_tabby_review def get_changed_files(): - output = subprocess.check_output(["git", "diff", "--name-only", "origin/main...HEAD"]) + output = subprocess.check_output(["git", "diff", "--name-only", "origin/master...HEAD"]) return output.decode().splitlines() def main(): From c319fa84f50756a3c08b8ab60473b0dceebcc07c Mon Sep 17 00:00:00 2001 From: DibyoGit <64616330+DibyoGit@users.noreply.github.com> Date: Fri, 11 Jul 2025 12:07:55 +0530 Subject: [PATCH 10/22] Update review_bot.py --- ai-review/review_bot.py | 76 ++++++++++++++++++++++++++++++++++------- 1 file changed, 64 insertions(+), 12 deletions(-) diff --git a/ai-review/review_bot.py b/ai-review/review_bot.py index 9c946c7d..8f46eada 100644 --- a/ai-review/review_bot.py +++ b/ai-review/review_bot.py @@ -1,23 +1,75 @@ import os -import subprocess -from github_api import post_comment +import requests from tabby_client import get_tabby_review -def get_changed_files(): - output = subprocess.check_output(["git", "diff", "--name-only", "origin/master...HEAD"]) - return output.decode().splitlines() +# --- Config --- +GITHUB_TOKEN = os.getenv("GITHUB_TOKEN") +GITHUB_REPOSITORY = os.getenv("GITHUB_REPOSITORY") # e.g., "myuser/myrepo" +GITHUB_REF = os.getenv("GITHUB_REF", "") # e.g., "refs/pull/42/merge" +TABBY_URL = os.getenv("TABBY_URL", "http://54.196.243.3:8080") + + +def get_pull_request_number(): + """ + Extract the pull request number from GITHUB_REF (e.g. "refs/pull/42/merge"). + """ + try: + return GITHUB_REF.split("/")[2] + except IndexError: + raise RuntimeError(f"Cannot extract PR number from GITHUB_REF='{GITHUB_REF}'") + + +def get_changed_files(pr_number): + """ + Fetch the list of changed files in the PR using GitHub API. + """ + url = f"https://api.github.com/repos/{GITHUB_REPOSITORY}/pulls/{pr_number}/files" + headers = {"Authorization": f"Bearer {GITHUB_TOKEN}"} + response = requests.get(url, headers=headers) + response.raise_for_status() + files = response.json() + return [f["filename"] for f in files if f["filename"].endswith((".py", ".js", ".ts", ".java", ".go", ".rb"))] + + +def post_comment(pr_number, body): + """ + Post a comment on the pull request. + """ + url = f"https://api.github.com/repos/{GITHUB_REPOSITORY}/issues/{pr_number}/comments" + headers = { + "Authorization": f"Bearer {GITHUB_TOKEN}", + "Accept": "application/vnd.github+json" + } + response = requests.post(url, headers=headers, json={"body": body}) + response.raise_for_status() + def main(): - tabby_url = os.getenv("TABBY_URL", "http://54.196.243.3:8080") - changed_files = get_changed_files() + pr_number = get_pull_request_number() + print(f"🔍 Pull Request #{pr_number}") + + changed_files = get_changed_files(pr_number) + if not changed_files: + print("✅ No code files changed. Skipping review.") + return + + print(f"📂 Changed files: {changed_files}") for file_path in changed_files: - with open(file_path, "r") as f: - code = f.read() + try: + with open(file_path, "r", encoding="utf-8") as f: + code = f.read() + + prompt = f"Review this code and suggest improvements:\n\n{code}" + suggestion = get_tabby_review(prompt, tabby_url=TABBY_URL) + + comment_body = f"💡 **AI Review Suggestion for `{file_path}`**\n\n{suggestion}" + post_comment(pr_number, comment_body) + print(f"✅ Comment posted for {file_path}") + + except Exception as e: + print(f"⚠️ Skipping file `{file_path}` due to error: {e}") - prompt = f"Review this code for issues:\n\n{code}" - suggestion = get_tabby_review(prompt, tabby_url) - post_comment(file_path, suggestion) if __name__ == "__main__": main() From f537a98281b35e66103ec974d04e66dfb2c01337 Mon Sep 17 00:00:00 2001 From: DibyoGit <64616330+DibyoGit@users.noreply.github.com> Date: Mon, 14 Jul 2025 00:09:10 +0530 Subject: [PATCH 11/22] Update tabby-ai-review.yaml --- .github/workflows/tabby-ai-review.yaml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/workflows/tabby-ai-review.yaml b/.github/workflows/tabby-ai-review.yaml index 793c0551..b8d72b57 100644 --- a/.github/workflows/tabby-ai-review.yaml +++ b/.github/workflows/tabby-ai-review.yaml @@ -4,12 +4,19 @@ on: pull_request: types: [opened, synchronize] +permissions: + contents: read + pull-requests: write # 🔑 Needed to post PR comments + jobs: tabby-review: runs-on: ubuntu-latest + steps: - name: Checkout code uses: actions/checkout@v3 + with: + fetch-depth: 0 # 🔁 Ensures full git history for diff - name: Set up Python uses: actions/setup-python@v4 @@ -22,5 +29,9 @@ jobs: - name: Run Tabby PR review env: TABBY_URL: ${{ secrets.TABBY_URL }} + TABBY_USERNAME: ${{ secrets.TABBY_USERNAME }} + TABBY_PASSWORD: ${{ secrets.TABBY_PASSWORD }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_REPOSITORY: ${{ github.repository }} + GITHUB_EVENT_PATH: ${{ github.event_path }} run: python ai-review/review_bot.py From 4fecd011164d1498d37b661db059e0b0489ffad9 Mon Sep 17 00:00:00 2001 From: DibyoGit <64616330+DibyoGit@users.noreply.github.com> Date: Mon, 14 Jul 2025 00:11:35 +0530 Subject: [PATCH 12/22] Update tabby_client.py --- ai-review/tabby_client.py | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/ai-review/tabby_client.py b/ai-review/tabby_client.py index a254cd7a..05a58d52 100644 --- a/ai-review/tabby_client.py +++ b/ai-review/tabby_client.py @@ -1,16 +1,12 @@ import requests +import os +from requests.auth import HTTPBasicAuth + +def get_tabby_review(prompt: str, tabby_url=None) -> str: + tabby_url = tabby_url or os.getenv("TABBY_URL", "http://localhost:8080") + username = os.getenv("TABBY_USERNAME") + password = os.getenv("TABBY_PASSWORD") -def get_tabby_review(prompt: str, tabby_url="http://54.196.243.3:8080") -> str: - """ - Sends a prompt to the TabbyML chat model and returns the response. - - Args: - prompt (str): The prompt text to analyze. - tabby_url (str): Base URL of the TabbyML server. - - Returns: - str: AI-generated response from TabbyML. - """ try: response = requests.post( f"{tabby_url}/v1/chat/completions", @@ -20,12 +16,13 @@ def get_tabby_review(prompt: str, tabby_url="http://54.196.243.3:8080") -> str: ], "temperature": 0.4, }, - timeout=30 + timeout=30, + auth=HTTPBasicAuth(username, password) if username and password else None ) response.raise_for_status() result = response.json() return result["choices"][0]["message"]["content"] - + except requests.exceptions.RequestException as e: - print(f"[ERROR] Failed to communicate with TabbyML: {e}") + print(f"Error: Failed to communicate with TabbyML: {e}") return "⚠️ Error: Unable to connect to TabbyML server." From 3c621ac2d030f08b9f82e17f883d6f3f5d28bcfc Mon Sep 17 00:00:00 2001 From: DibyoGit <64616330+DibyoGit@users.noreply.github.com> Date: Mon, 14 Jul 2025 00:16:43 +0530 Subject: [PATCH 13/22] Update tabby_client.py --- ai-review/tabby_client.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/ai-review/tabby_client.py b/ai-review/tabby_client.py index 05a58d52..84a2b5dc 100644 --- a/ai-review/tabby_client.py +++ b/ai-review/tabby_client.py @@ -3,7 +3,7 @@ from requests.auth import HTTPBasicAuth def get_tabby_review(prompt: str, tabby_url=None) -> str: - tabby_url = tabby_url or os.getenv("TABBY_URL", "http://localhost:8080") + tabby_url = tabby_url or os.getenv("TABBY_URL", "http://54.196.243.3:8080/") username = os.getenv("TABBY_USERNAME") password = os.getenv("TABBY_PASSWORD") @@ -11,17 +11,14 @@ def get_tabby_review(prompt: str, tabby_url=None) -> str: response = requests.post( f"{tabby_url}/v1/chat/completions", json={ - "messages": [ - {"role": "user", "content": prompt} - ], + "messages": [{"role": "user", "content": prompt}], "temperature": 0.4, }, timeout=30, - auth=HTTPBasicAuth(username, password) if username and password else None + auth=HTTPBasicAuth(username, password) ) response.raise_for_status() - result = response.json() - return result["choices"][0]["message"]["content"] + return response.json()["choices"][0]["message"]["content"] except requests.exceptions.RequestException as e: print(f"Error: Failed to communicate with TabbyML: {e}") From e8d732fc66a49f7b80950e99364cb710424cd9c3 Mon Sep 17 00:00:00 2001 From: DibyoGit <64616330+DibyoGit@users.noreply.github.com> Date: Mon, 14 Jul 2025 00:17:48 +0530 Subject: [PATCH 14/22] Update tabby_client.py --- ai-review/tabby_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ai-review/tabby_client.py b/ai-review/tabby_client.py index 84a2b5dc..1f9dab97 100644 --- a/ai-review/tabby_client.py +++ b/ai-review/tabby_client.py @@ -3,7 +3,7 @@ from requests.auth import HTTPBasicAuth def get_tabby_review(prompt: str, tabby_url=None) -> str: - tabby_url = tabby_url or os.getenv("TABBY_URL", "http://54.196.243.3:8080/") + tabby_url = tabby_url or os.getenv("TABBY_URL", "http://54.196.243.3:8080") username = os.getenv("TABBY_USERNAME") password = os.getenv("TABBY_PASSWORD") From 045a18d8fdd4ca858efe9bd54544ecc666778011 Mon Sep 17 00:00:00 2001 From: DibyoGit <64616330+DibyoGit@users.noreply.github.com> Date: Mon, 14 Jul 2025 00:20:57 +0530 Subject: [PATCH 15/22] Update tabby_client.py --- ai-review/tabby_client.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ai-review/tabby_client.py b/ai-review/tabby_client.py index 1f9dab97..f88bcdfd 100644 --- a/ai-review/tabby_client.py +++ b/ai-review/tabby_client.py @@ -7,6 +7,10 @@ def get_tabby_review(prompt: str, tabby_url=None) -> str: username = os.getenv("TABBY_USERNAME") password = os.getenv("TABBY_PASSWORD") + if not username or not password: + print("⚠️ Missing TabbyML credentials. Set TABBY_USERNAME and TABBY_PASSWORD.") + return "⚠️ Error: Missing credentials for TabbyML." + try: response = requests.post( f"{tabby_url}/v1/chat/completions", @@ -21,5 +25,5 @@ def get_tabby_review(prompt: str, tabby_url=None) -> str: return response.json()["choices"][0]["message"]["content"] except requests.exceptions.RequestException as e: - print(f"Error: Failed to communicate with TabbyML: {e}") + print(f"Error: Failed to communicate with TabbyML: {e}") return "⚠️ Error: Unable to connect to TabbyML server." From a4e9b7218f2374f6a9173e41fa0d5a3dde96bb75 Mon Sep 17 00:00:00 2001 From: DibyoGit <64616330+DibyoGit@users.noreply.github.com> Date: Mon, 14 Jul 2025 01:02:19 +0530 Subject: [PATCH 16/22] Update tabby_client.py --- ai-review/tabby_client.py | 45 ++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/ai-review/tabby_client.py b/ai-review/tabby_client.py index f88bcdfd..254db9ad 100644 --- a/ai-review/tabby_client.py +++ b/ai-review/tabby_client.py @@ -1,29 +1,26 @@ import requests -import os -from requests.auth import HTTPBasicAuth -def get_tabby_review(prompt: str, tabby_url=None) -> str: - tabby_url = tabby_url or os.getenv("TABBY_URL", "http://54.196.243.3:8080") - username = os.getenv("TABBY_USERNAME") - password = os.getenv("TABBY_PASSWORD") +TABBY_URL = "http://54.196.243.3:8080/v1/chat/completions" +JWT_TOKEN = "auth_9675f108605f42f8bad46e5324d756ab" # Replace with your current token - if not username or not password: - print("⚠️ Missing TabbyML credentials. Set TABBY_USERNAME and TABBY_PASSWORD.") - return "⚠️ Error: Missing credentials for TabbyML." +def get_tabby_completion(user_input): + headers = { + "Authorization": f"Bearer {JWT_TOKEN}", + "Content-Type": "application/json" + } - try: - response = requests.post( - f"{tabby_url}/v1/chat/completions", - json={ - "messages": [{"role": "user", "content": prompt}], - "temperature": 0.4, - }, - timeout=30, - auth=HTTPBasicAuth(username, password) - ) - response.raise_for_status() - return response.json()["choices"][0]["message"]["content"] + data = { + "model": "Qwen2-1.5B-Instruct", + "stream": False, # unless you're streaming token-by-token + "messages": [ + {"role": "user", "content": user_input} + ] + } - except requests.exceptions.RequestException as e: - print(f"Error: Failed to communicate with TabbyML: {e}") - return "⚠️ Error: Unable to connect to TabbyML server." + response = requests.post(TABBY_URL, headers=headers, json=data) + + if response.status_code == 200: + result = response.json() + return result['choices'][0]['message']['content'] + else: + raise Exception(f"Tabby error {response.status_code}: {response.text}") From 3e9abbe870d3668f8c100f5e7a83d568bc38ff41 Mon Sep 17 00:00:00 2001 From: DibyoGit <64616330+DibyoGit@users.noreply.github.com> Date: Mon, 14 Jul 2025 01:03:36 +0530 Subject: [PATCH 17/22] Update tabby_client.py --- ai-review/tabby_client.py | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/ai-review/tabby_client.py b/ai-review/tabby_client.py index 254db9ad..d6a9552a 100644 --- a/ai-review/tabby_client.py +++ b/ai-review/tabby_client.py @@ -1,26 +1,23 @@ import requests TABBY_URL = "http://54.196.243.3:8080/v1/chat/completions" -JWT_TOKEN = "auth_9675f108605f42f8bad46e5324d756ab" # Replace with your current token +JWT_TOKEN = "auth_9675f108605f42f8bad46e5324d756ab" # Replace with your actual token if it changes -def get_tabby_completion(user_input): +def get_tabby_review(code_snippet: str) -> str: headers = { "Authorization": f"Bearer {JWT_TOKEN}", "Content-Type": "application/json" } - data = { + payload = { "model": "Qwen2-1.5B-Instruct", - "stream": False, # unless you're streaming token-by-token + "stream": False, "messages": [ - {"role": "user", "content": user_input} + {"role": "user", "content": f"Please review the following code:\n\n{code_snippet}"} ] } - response = requests.post(TABBY_URL, headers=headers, json=data) + response = requests.post(TABBY_URL, headers=headers, json=payload) + response.raise_for_status() - if response.status_code == 200: - result = response.json() - return result['choices'][0]['message']['content'] - else: - raise Exception(f"Tabby error {response.status_code}: {response.text}") + return response.json()["choices"][0]["message"]["content"] From aee83908127341e6573d69b7a11e6fb6c971369d Mon Sep 17 00:00:00 2001 From: DibyoGit <64616330+DibyoGit@users.noreply.github.com> Date: Mon, 14 Jul 2025 01:04:48 +0530 Subject: [PATCH 18/22] Update review_bot.py --- ai-review/review_bot.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ai-review/review_bot.py b/ai-review/review_bot.py index 8f46eada..f7cfa7db 100644 --- a/ai-review/review_bot.py +++ b/ai-review/review_bot.py @@ -16,7 +16,7 @@ def get_pull_request_number(): try: return GITHUB_REF.split("/")[2] except IndexError: - raise RuntimeError(f"Cannot extract PR number from GITHUB_REF='{GITHUB_REF}'") + raise RuntimeError(f"❌ Cannot extract PR number from GITHUB_REF='{GITHUB_REF}'") def get_changed_files(pr_number): @@ -60,15 +60,15 @@ def main(): with open(file_path, "r", encoding="utf-8") as f: code = f.read() - prompt = f"Review this code and suggest improvements:\n\n{code}" + prompt = f"Please review and suggest improvements for the following code:\n\n{code}" suggestion = get_tabby_review(prompt, tabby_url=TABBY_URL) comment_body = f"💡 **AI Review Suggestion for `{file_path}`**\n\n{suggestion}" post_comment(pr_number, comment_body) - print(f"✅ Comment posted for {file_path}") + print(f"✅ Comment posted for `{file_path}`") except Exception as e: - print(f"⚠️ Skipping file `{file_path}` due to error: {e}") + print(f"⚠️ Skipping `{file_path}` due to error: {e}") if __name__ == "__main__": From 3bb2c1865772f13d4495c4c0b893e15d7f3d7f98 Mon Sep 17 00:00:00 2001 From: DibyoGit <64616330+DibyoGit@users.noreply.github.com> Date: Mon, 14 Jul 2025 01:20:47 +0530 Subject: [PATCH 19/22] Update tabby_client.py --- ai-review/tabby_client.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ai-review/tabby_client.py b/ai-review/tabby_client.py index d6a9552a..29f69b07 100644 --- a/ai-review/tabby_client.py +++ b/ai-review/tabby_client.py @@ -1,11 +1,12 @@ +import os import requests -TABBY_URL = "http://54.196.243.3:8080/v1/chat/completions" -JWT_TOKEN = "auth_9675f108605f42f8bad46e5324d756ab" # Replace with your actual token if it changes +def get_tabby_review(prompt: str) -> str: + tabby_url = os.getenv("TABBY_URL", "http://localhost:8080") + jwt_token = os.getenv("TABBY_API_TOKEN", "auth_9675f108605f42f8bad46e5324d756ab") -def get_tabby_review(code_snippet: str) -> str: headers = { - "Authorization": f"Bearer {JWT_TOKEN}", + "Authorization": f"Bearer {jwt_token}", "Content-Type": "application/json" } @@ -13,11 +14,10 @@ def get_tabby_review(code_snippet: str) -> str: "model": "Qwen2-1.5B-Instruct", "stream": False, "messages": [ - {"role": "user", "content": f"Please review the following code:\n\n{code_snippet}"} + { "role": "user", "content": prompt } ] } - response = requests.post(TABBY_URL, headers=headers, json=payload) + response = requests.post(f"{tabby_url}/v1/chat/completions", headers=headers, json=payload) response.raise_for_status() - return response.json()["choices"][0]["message"]["content"] From 518ff2036cf1bd49c2c68a7dea2626ccdd957d8f Mon Sep 17 00:00:00 2001 From: DibyoGit <64616330+DibyoGit@users.noreply.github.com> Date: Mon, 14 Jul 2025 01:21:12 +0530 Subject: [PATCH 20/22] Update review_bot.py --- ai-review/review_bot.py | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/ai-review/review_bot.py b/ai-review/review_bot.py index f7cfa7db..cb2d8b61 100644 --- a/ai-review/review_bot.py +++ b/ai-review/review_bot.py @@ -6,8 +6,6 @@ GITHUB_TOKEN = os.getenv("GITHUB_TOKEN") GITHUB_REPOSITORY = os.getenv("GITHUB_REPOSITORY") # e.g., "myuser/myrepo" GITHUB_REF = os.getenv("GITHUB_REF", "") # e.g., "refs/pull/42/merge" -TABBY_URL = os.getenv("TABBY_URL", "http://54.196.243.3:8080") - def get_pull_request_number(): """ @@ -16,8 +14,7 @@ def get_pull_request_number(): try: return GITHUB_REF.split("/")[2] except IndexError: - raise RuntimeError(f"❌ Cannot extract PR number from GITHUB_REF='{GITHUB_REF}'") - + raise RuntimeError(f"Cannot extract PR number from GITHUB_REF='{GITHUB_REF}'") def get_changed_files(pr_number): """ @@ -30,7 +27,6 @@ def get_changed_files(pr_number): files = response.json() return [f["filename"] for f in files if f["filename"].endswith((".py", ".js", ".ts", ".java", ".go", ".rb"))] - def post_comment(pr_number, body): """ Post a comment on the pull request. @@ -43,7 +39,6 @@ def post_comment(pr_number, body): response = requests.post(url, headers=headers, json={"body": body}) response.raise_for_status() - def main(): pr_number = get_pull_request_number() print(f"🔍 Pull Request #{pr_number}") @@ -60,16 +55,15 @@ def main(): with open(file_path, "r", encoding="utf-8") as f: code = f.read() - prompt = f"Please review and suggest improvements for the following code:\n\n{code}" - suggestion = get_tabby_review(prompt, tabby_url=TABBY_URL) + prompt = f"Review this code and suggest improvements:\n\n{code}" + suggestion = get_tabby_review(prompt) comment_body = f"💡 **AI Review Suggestion for `{file_path}`**\n\n{suggestion}" post_comment(pr_number, comment_body) - print(f"✅ Comment posted for `{file_path}`") + print(f"✅ Comment posted for {file_path}") except Exception as e: print(f"⚠️ Skipping `{file_path}` due to error: {e}") - if __name__ == "__main__": main() From 4ccd293d2103b79650c7f87acad87a6c5c813a56 Mon Sep 17 00:00:00 2001 From: DibyoGit <64616330+DibyoGit@users.noreply.github.com> Date: Mon, 14 Jul 2025 01:23:11 +0530 Subject: [PATCH 21/22] Update tabby_client.py --- ai-review/tabby_client.py | 45 +++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/ai-review/tabby_client.py b/ai-review/tabby_client.py index 29f69b07..3a08c43c 100644 --- a/ai-review/tabby_client.py +++ b/ai-review/tabby_client.py @@ -1,23 +1,46 @@ import os import requests -def get_tabby_review(prompt: str) -> str: - tabby_url = os.getenv("TABBY_URL", "http://localhost:8080") - jwt_token = os.getenv("TABBY_API_TOKEN", "auth_9675f108605f42f8bad46e5324d756ab") +TABBY_URL = os.getenv("TABBY_URL", "http://localhost:8080") +TABBY_AUTH_TOKEN = os.getenv("TABBY_AUTH_TOKEN", "") # Optional +def get_tabby_review(prompt: str) -> str: headers = { - "Authorization": f"Bearer {jwt_token}", "Content-Type": "application/json" } + if TABBY_AUTH_TOKEN: + headers["Authorization"] = f"Bearer {TABBY_AUTH_TOKEN}" payload = { - "model": "Qwen2-1.5B-Instruct", - "stream": False, + "model": "Qwen2-1.5B-Instruct", # or "StarCoder-1B" if Qwen2 fails "messages": [ - { "role": "user", "content": prompt } - ] + {"role": "user", "content": prompt} + ], + "stream": True # ✅ Required to avoid the invalid args error } - response = requests.post(f"{tabby_url}/v1/chat/completions", headers=headers, json=payload) - response.raise_for_status() - return response.json()["choices"][0]["message"]["content"] + response = requests.post( + f"{TABBY_URL}/v1/chat/completions", + headers=headers, + json=payload, + stream=True # ✅ Required to handle streaming properly + ) + + if response.status_code != 200: + raise RuntimeError(f"Tabby Error: {response.status_code} - {response.text}") + + result = "" + for line in response.iter_lines(decode_unicode=True): + if line and line.startswith("data: "): + chunk = line.removeprefix("data: ").strip() + if chunk == "[DONE]": + break + try: + json_chunk = json.loads(chunk) + delta = json_chunk["choices"][0]["delta"] + result += delta.get("content", "") + except Exception as e: + print("⚠️ Error parsing chunk:", e) + continue + + return result.strip() From e65d2bf7b8400b904b7d57053e4291b0a49e9fb0 Mon Sep 17 00:00:00 2001 From: DibyoGit <64616330+DibyoGit@users.noreply.github.com> Date: Mon, 14 Jul 2025 01:25:59 +0530 Subject: [PATCH 22/22] Update tabby_client.py --- ai-review/tabby_client.py | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/ai-review/tabby_client.py b/ai-review/tabby_client.py index 3a08c43c..fbb0f523 100644 --- a/ai-review/tabby_client.py +++ b/ai-review/tabby_client.py @@ -1,30 +1,25 @@ -import os +import json import requests -TABBY_URL = os.getenv("TABBY_URL", "http://localhost:8080") -TABBY_AUTH_TOKEN = os.getenv("TABBY_AUTH_TOKEN", "") # Optional +TABBY_URL = "http://54.196.243.3:8080" +TABBY_AUTH_TOKEN = "auth_9675f108605f42f8bad46e5324d756ab" # <-- your manual token def get_tabby_review(prompt: str) -> str: headers = { + "Authorization": f"Bearer {TABBY_AUTH_TOKEN}", "Content-Type": "application/json" } - if TABBY_AUTH_TOKEN: - headers["Authorization"] = f"Bearer {TABBY_AUTH_TOKEN}" payload = { - "model": "Qwen2-1.5B-Instruct", # or "StarCoder-1B" if Qwen2 fails - "messages": [ - {"role": "user", "content": prompt} - ], - "stream": True # ✅ Required to avoid the invalid args error + "model": "Qwen2-1.5B-Instruct", + "messages": [{"role": "user", "content": prompt}], + "stream": True } - response = requests.post( - f"{TABBY_URL}/v1/chat/completions", - headers=headers, - json=payload, - stream=True # ✅ Required to handle streaming properly - ) + response = requests.post(f"{TABBY_URL}/v1/chat/completions", + headers=headers, + json=payload, + stream=True) if response.status_code != 200: raise RuntimeError(f"Tabby Error: {response.status_code} - {response.text}") @@ -40,7 +35,6 @@ def get_tabby_review(prompt: str) -> str: delta = json_chunk["choices"][0]["delta"] result += delta.get("content", "") except Exception as e: - print("⚠️ Error parsing chunk:", e) - continue + print(f"⚠️ Error parsing chunk: {e}") return result.strip()