Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pr advanced display #124

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Open

Pr advanced display #124

wants to merge 15 commits into from

Conversation

nithilanimraka
Copy link
Owner

No description provided.

@pr-respond-test
Copy link

Hi, I am a code reviewer bot. I will analyze the PR and provide detailed review comments.

Comment on lines +70 to +77
completion = client.beta.chat.completions.parse(
model="gpt-4o-2024-08-06",
messages=[
{"role": "system", "content": "You are an experienced code reviewer."},
{"role": "user", "content": prompt}
],
response_format=ReviewModel,
)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue: Missing error handling for API call. Add try/catch block around the API call and log any exceptions.

Severity: error

Suggestion: Wrap the API call in a try/except block to handle potential exceptions and log them appropriately.

try:
    completion = client.beta.chat.completions.parse(
        model="gpt-4o-2024-08-06",
        messages=[
            {"role": "system", "content": "You are an experienced code reviewer."},
            {"role": "user", "content": prompt}
        ],
        response_format=ReviewModel,
    )
except Exception as e:
    print(f"Error during API call: {str(e)}")
    raise

Comment on lines +65 to +112
def parse_diff_file_line_numbers(diff_content: str) -> List[Dict]:
"""
Parse a unified diff string and return a structured list of changes using
actual file line numbers.

Returns a list of dicts, each representing a file change:
{
"file_name": str,
"changes": [
{
"type": "added" | "removed" | "context",
"line_number": int, # For added or context lines, this is target_line_no.
# For removed lines, use source_line_no.
"content": str
},
...
]
}
"""
patch = PatchSet(diff_content)
parsed_files = []

for patched_file in patch:
file_info = {
"file_name": patched_file.path,
"changes": []
}
for hunk in patched_file:
for line in hunk:
# Decide which line number to use based on change type.
if line.is_added or not line.is_removed:
line_num = line.target_line_no
else:
line_num = line.source_line_no

if line_num is None:
continue # Skip lines without a valid number

# Append each changed line along with its file-based line number.
file_info["changes"].append({
"type": "added" if line.is_added else "removed" if line.is_removed else "context",
"line_number": line_num,
"content": line.value.rstrip("\n")
})
parsed_files.append(file_info)

return parsed_files

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue: Missing error handling for diff parsing. Add try/catch block around the parsing logic and log any exceptions.

Severity: error

Suggestion: Wrap the parsing logic in a try/except block to handle exceptions and log them.

def parse_diff_file_line_numbers(diff_content: str) -> List[Dict]:
    """
    Parse a unified diff string and return a structured list of changes using
    actual file line numbers.
    """
    try:
        patch = PatchSet(diff_content)
        parsed_files = []
        
        for patched_file in patch:
            file_info = {
                "file_name": patched_file.path,
                "changes": []
            }
            for hunk in patched_file:
                for line in hunk:
                    # Decide which line number to use based on change type.
                    if line.is_added or not line.is_removed:
                        line_num = line.target_line_no
                    else:
                        line_num = line.source_line_no
                    
                    if line_num is None:
                        continue  # Skip lines without a valid number
                    
                    # Append each changed line along with its file-based line number.
                    file_info["changes"].append({
                        "type": "added" if line.is_added else "removed" if line.is_removed else "context",
                        "line_number": line_num,
                        "content": line.value.rstrip("\n")
                    })
            parsed_files.append(file_info)
        
        return parsed_files
    except Exception as e:
        print(f"Error parsing diff content: {str(e)}")
        raise

Comment on lines +12 to +14
WEBHOOK_SECRET = os.environ.get("WEBHOOK_SECRET")
if not WEBHOOK_SECRET:
raise ValueError("WEBHOOK_SECRET not set")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue: Missing logging for critical exceptions. Add logging to capture when environment variables are missing.

Severity: warning

Suggestion: Add logging to capture when critical environment variables are missing.

if not WEBHOOK_SECRET:
    print("Critical: WEBHOOK_SECRET environment variable is not set.")
    raise ValueError("WEBHOOK_SECRET not set")

Comment on lines +28 to +35
def generate_hash_signature(secret: bytes, payload: bytes, digest_method=hashlib.sha1):
return hmac.new(secret, payload, digest_method).hexdigest()

def verify_signature(payload: bytes, x_hub_signature: str):
secret = WEBHOOK_SECRET.encode("utf-8")
expected_signature = f"sha1={generate_hash_signature(secret, payload)}"
if not hmac.compare_digest(expected_signature, x_hub_signature):
raise HTTPException(status_code=401, detail="Invalid webhook signature")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue: Unused functions - These functions are defined but not used within the module, potentially leading to dead code.

Severity: info

Suggestion: Remove unused functions or ensure they are called appropriately within the module.

Comment on lines +5 to +16
def create_check_run(repo, sha):
"""Create a check run using the modern PyGithub API"""
return repo.create_check_run(
name="AI Code Review",
head_sha=sha,
status="queued", # Initial status should be 'queued'
output={
"title": "Analyzing Changes",
"summary": "🔍 Scanning code changes with AI...",
"text": "This may take 20-30 seconds"
}
)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue: Initial check run status - The initial status is set to 'queued' but should consider starting with 'in_progress' for better status transition clarity.

Severity: info

Suggestion: Consider starting the initial check run status with 'in_progress' for better clarity in status transitions.

def create_check_run(repo, sha):
    """Create a check run using the modern PyGithub API"""
    return repo.create_check_run(
        name="AI Code Review",
        head_sha=sha,
        status="in_progress",  # Initial status should be 'in_progress'
        output={
            "title": "Analyzing Changes",
            "summary": "🔍 Scanning code changes with AI...",
            "text": "This may take 20-30 seconds"
        }
    )

Comment on lines +35 to +65
# Prepare the prompt for the LLM
prompt = f"""
Analyze the following code changes and provide detailed review comments.
Focus on:
- Code quality and best practices
- Potential security vulnerabilities
- Performance implications

Important:
- Provide insights in the comment section for each code segment. Provide improvements in suggestions when necessary.
- Always output the codeSegmentToFix in the diff format (e.g., '+ added code', '- removed code', 'or nothing for normal code').
- If there is a new line in the codeSegmentToFix (when there are multiple lines), you MUST indicate it with the new line symbol.
- Ensure that you provide all the necessary code lines in the codeSegmentToFix field.
- If there are multiple comments for the same code segment, provide the comments separated by commas.

CRITICAL REQUIREMENTS:
- Precisely mention the position where the comment should be placed.
- The codeSegmentToFix should exactly start from the start_line_with_prefix and end at the end_line_with_prefix.
- Use the file-based line numbers provided in the structured diff below.
- You MUST provide exact start_line_with_prefix and end_line_with_prefix numbers for each comment.
- Never omit line numbers or the system will fail.

Examples for start_line_with_prefix when the start_line is from new file: "+5, +2, +51, +61"
Examples for start_line_with_prefix when the start_line is from old file: "-8, -1, -56, -20"

Examples for end_line_with_prefix when the start_line is from new file: "+10, +2, +77, +65"
Examples for end_line_with_prefix when the start_line is from old file: "-1, -5, -22, -44"

Diff content:
{structured_diff_text}
"""

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue: Complex prompt string - The prompt string is very long and complex, making it hard to maintain and modify. Consider breaking it into smaller parts or using a different approach to build the prompt.

Severity: info

Suggestion: Break the prompt string into smaller parts or use a different approach to build the prompt for better maintainability.

prompt_intro = """
    Analyze the following code changes and provide detailed review comments.
    Focus on:
    - Code quality and best practices
    - Potential security vulnerabilities
    - Performance implications
    
    Important:
    - Provide insights in the comment section for each code segment. Provide improvements in suggestions when necessary.
    - Always output the codeSegmentToFix in the diff format (e.g., '+ added code', '- removed code', 'or nothing for normal code').
    - If there is a new line in the codeSegmentToFix (when there are multiple lines), you MUST indicate it with the new line symbol.
    - Ensure that you provide all the necessary code lines in the codeSegmentToFix field.
    - If there are multiple comments for the same code segment, provide the comments separated by commas.
    """

prompt_critical = """
    CRITICAL REQUIREMENTS:
    - Precisely mention the position where the comment should be placed.
    - The codeSegmentToFix should exactly start from the start_line_with_prefix and end at the end_line_with_prefix.
    - Use the file-based line numbers provided in the structured diff below.
    - You MUST provide exact start_line_with_prefix and end_line_with_prefix numbers for each comment.
    - Never omit line numbers or the system will fail.
    """

prompt_examples = """
    Examples for start_line_with_prefix when the start_line is from new file: "+5, +2, +51, +61" 
    Examples for start_line_with_prefix when the start_line is from old file: "-8, -1, -56, -20" 
    
    Examples for end_line_with_prefix when the start_line is from new file: "+10, +2, +77, +65" 
    Examples for end_line_with_prefix when the start_line is from old file: "-1, -5, -22, -44" 
    
    Diff content:
    {structured_diff_text}
    """

prompt = f"{prompt_intro}{prompt_critical}{prompt_examples}"

installation_id = github_integration.get_installation(owner, repo_name).id
access_token = github_integration.get_access_token(installation_id).token
return Github(login_or_token=access_token).get_repo(f"{owner}/{repo_name}")

@app.post("/webhook")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue: Missing docstring - The webhook function lacks a docstring, making it harder for developers to understand its purpose and functionality.

Severity: info

Suggestion: Add a docstring to the webhook function to describe its purpose and functionality.

@app.post("/webhook")
async def webhook(request: Request, x_hub_signature: str = Header(None)):
    """
    Handle incoming webhook requests from GitHub.

    This function verifies the webhook signature, processes the payload to
    determine if it is a pull request event, and initiates a code review
    process if applicable.

    Args:
        request (Request): The incoming request object.
        x_hub_signature (str): The signature header from GitHub for verification.

    Returns:
        dict: An empty dictionary as a response.
    """

print("Before API CALL...")

# Get analysis from OpenAI
completion = client.beta.chat.completions.parse(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue: The OpenAI model name is incorrect. The correct model name should be 'gpt-4o' or another valid OpenAI model name. The current name 'gpt-4o-2024-08-06' is not a valid model name provided by OpenAI.

Severity: error

Suggestion: Update the model name to a valid OpenAI model name such as 'gpt-4o'.

model="gpt-4o"

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.

1 participant