Skip to content

Conversation

@DibyoGit
Copy link
Owner

@DibyoGit DibyoGit commented Jul 13, 2025

Summary by Bito

This pull request introduces an AI code review feature into the GitHub workflow, automating the review process with a GitHub Actions workflow and a Python bot that comments AI-generated suggestions on pull requests. It also includes necessary dependencies for implementation.

@github-actions
Copy link

💡 AI Review Suggestion for ai-review/github_api.py

⚠️ Error: Unable to connect to TabbyML server.

@github-actions
Copy link

💡 AI Review Suggestion for ai-review/review_bot.py

⚠️ Error: Unable to connect to TabbyML server.

@github-actions
Copy link

💡 AI Review Suggestion for ai-review/tabby_client.py

⚠️ Error: Unable to connect to TabbyML server.

@github-actions
Copy link

💡 AI Review Suggestion for ai-review/github_api.py

Here are some suggested improvements for the code:

  1. Use constants for environment variables and API endpoint URLs to make the code more readable and maintainable. For example, instead of using os.getenv, we can define constants like GITHUB_REPOSITORY, GITHUB_REF, GITHUB_TOKEN, and API_ENDPOINT with their respective values.

  2. Use Python's string formatting to construct the URL, headers, and body. This makes the code cleaner and easier to read.

  3. Add docstrings to the functions to explain what they do.

  4. Use try-except blocks to handle potential exceptions that may arise from making requests to the API, such as receiving an unsuccessful response status code.

Here's an example of how the code could be improved:

import os
import requests

# Define constants for API endpoint URL, environment variables, and other settings
API_ENDPOINT = "https://api.github.com/repos/<repo_name>/issues/<issue_number>/comments"
GITHUB_REPOSITORY = "YOUR_GITHUB_REPO"
GITHUB_REF = "refs/heads/your_branch"
GITHUB_TOKEN = "YOUR_GITHUB_TOKEN"

def get_comment_url():
    return f"{API_ENDPOINT}?issue={GITHUB_REF}"

def post_comment(file_path, comment):
    try:
        # Construct the headers
        headers = {
            "Authorization": f"Bearer {GITHUB_TOKEN}",
            "Accept": "application/vnd.github+json"
        }

        # Construct the body
        body = f"� **AI Review Suggestion for `{file_path}`**\n\n{comment}"

        # Send the request
        response = requests.post(get_comment_url(), json={"body": body}, headers=headers)
        response.raise_for_status()

    except requests.RequestException as e:
        print(f"An error occurred: {e}")
        return None
    else:
        print("Comment posted successfully")
        return response.json()

With these changes, the code is now more organized and easier to understand. The use of constants also makes the code more maintainable. The try-except block helps handle exceptions, which can occur when making API requests.

@DibyoGit DibyoGit merged commit f0edd48 into master Jul 13, 2025
1 of 2 checks passed
@github-actions
Copy link

💡 AI Review Suggestion for ai-review/review_bot.py

The given code is for a script that fetches a pull request number from GitHub, retrieves the list of changed files in that PR, and posts a comment on each file indicating AI review suggestions. Here are some suggestions for improvement:

  1. Add error handling for file access and the GitHub API request:

    • In the main() function, add error handling to check if the file exists and raise an OSError if not.
    • In the get_changed_files() function, raise a RuntimeError if the PR number cannot be extracted.
  2. Use a for loop instead of enumerate:

    • Use a for loop in the main() function to iterate over the changed_files list. This makes the code more readable and Pythonic.
  3. Define a function for the GitHub API request:

    • Extract the file extension from the filename to avoid parsing the file path twice. Create a separate function for the GitHub API request.
  4. Use a more descriptive variable name for the PR number:

    • Use a more descriptive variable name like pr instead of pr_number.
  5. Add comments for clarity:

    • Add comments to explain each function or block of code for better readability.

Here's the improved code snippet:

import os
import requests
from tabby_client import get_tabby_review

# --- 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"

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():
    try:
        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:
            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)

                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_path}` due to error: {e}")

    except IndexError:
        print("Error: Could not extract the pull request number from the GITHUB_REF.")

if __name__ == "__main__":
    main()

This code should be more robust and maintainable.

@github-actions
Copy link

💡 AI Review Suggestion for ai-review/tabby_client.py

Here are some suggestions for improvements to the provided code:

  1. Logging Improvements: Add more detailed logging for better debugging. Instead of printing RuntimeError, you can log the error message and stack trace.

  2. Validation: Ensure that the TABBY_AUTH_TOKEN is always provided and is in the correct format. You can validate it using a regular expression.

  3. Response Handling: Currently, the code is asynchronous, and the response is stored in a variable result instead of being returned immediately. This means that you'll have to use result in subsequent operations. To handle this, you can return the result directly if the response is successful.

Here is the improved code with the above suggestions applied:

import json
import requests

TABBY_URL = "http://54.196.243.3:8080"
TABBY_AUTH_TOKEN = "YOUR-TABBY-TOKEN-GOES-HERE"

def get_tabby_review(prompt: str) -> str:
    # Validate and format the TABBY_AUTH_TOKEN
    if not TABBY_AUTH_TOKEN:
        raise ValueError("TABBY_AUTH_TOKEN is required")

    # Validate the format of the TABBY_AUTH_TOKEN
    if not TABBY_AUTH_TOKEN.startswith("auth_") or not TABBY_AUTH_TOKEN.endswith("_"):
        raise ValueError("TABBY_AUTH_TOKEN must be in the format 'auth_<your_token_here>_..._your_token_here'")

    # Make the HTTP request and handle responses
    headers = {
        "Authorization": f"Bearer {TABBY_AUTH_TOKEN}",
        "Content-Type": "application/json"
    }

    payload = {
        "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)

    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(f"�� Error parsing chunk: {e}")

    return result.strip()

Now, the code is more robust, and it also includes logging for better debugging and validation of the input and output.

@bito-code-review
Copy link

Bito Review Skipped - No Changes Detected

Bito didn't review this pull request because we did not detect any changes in the pull request to review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants