Autoreview-AI / main.py
Krishp1's picture
Update main.py
09fa7ad verified
Raw
History Blame Contribute Delete
5.94 kB
# main.py β€” AutoReview AI
# LangChain-based autonomous GitHub PR reviewer
import os
import re
from dotenv import load_dotenv
from langchain_groq import ChatGroq
from langchain.agents import AgentExecutor, create_tool_calling_agent
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.messages import HumanMessage, SystemMessage
from tools import fetch_pr_diff, analyze_diff, post_inline_comment, post_overall_review
load_dotenv()
# ── LLM ──────────────────────────────────
llm = ChatGroq(model="openai/gpt-oss-120b", temperature=0)
# ── TOOLS ─────────────────────────────────
tools = [fetch_pr_diff, analyze_diff, post_inline_comment, post_overall_review]
# ── PROMPT ────────────────────────────────
prompt = ChatPromptTemplate.from_messages([
("system", """You are AutoReview AI β€” an expert autonomous GitHub PR reviewer.
Your job when given a PR URL:
1. Use fetch_pr_diff to get the PR details and code changes
2. Use analyze_diff for each changed file to find bugs, security issues, style problems
3. Use post_inline_comment to post specific comments on problematic lines
4. Use post_overall_review to post a final APPROVE or REQUEST_CHANGES verdict
Be thorough but concise. Focus on real issues that matter.
Always complete all 4 steps β€” don't stop after fetching.
If GitHub token is not available, still analyze and return the review as text.
"""),
("human", "{input}"),
("placeholder", "{agent_scratchpad}")
])
# ── AGENT ─────────────────────────────────
agent = create_tool_calling_agent(llm, tools, prompt)
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
verbose=True,
max_iterations=10,
handle_parsing_errors=True
)
# ─────────────────────────────────────────
# MAIN REVIEW FUNCTION
# ─────────────────────────────────────────
def review_pr(pr_url: str) -> dict:
"""
Main function to review a GitHub PR.
Returns structured review result.
"""
print(f"\n{'='*60}")
print(f"πŸ” AutoReview AI starting review...")
print(f"πŸ“Ž PR: {pr_url}")
print("="*60)
try:
result = agent_executor.invoke({
"input": f"""
Please review this GitHub Pull Request: {pr_url}
Steps to follow:
1. Fetch the PR diff using fetch_pr_diff
2. Analyze each changed file using analyze_diff
3. Post inline comments for specific issues using post_inline_comment
4. Post overall verdict using post_overall_review
Provide a thorough code review focusing on:
- Bugs and logic errors
- Security vulnerabilities
- Code style and best practices
- Performance issues
"""
})
output = result.get("output", "")
print(f"\nβœ… Review complete!")
print(f"\nOutput:\n{output}")
return {
"success": True,
"pr_url": pr_url,
"review": output,
"error": None
}
except Exception as e:
error_msg = str(e)
print(f"\n❌ Error: {error_msg}")
return {
"success": False,
"pr_url": pr_url,
"review": None,
"error": error_msg
}
# ─────────────────────────────────────────
# SIMPLE REVIEW (no GitHub token needed)
# For demo purposes
# ─────────────────────────────────────────
def review_pr_simple(pr_url: str) -> dict:
"""
Reviews PR without posting comments to GitHub.
Returns full analysis as text β€” good for demo.
"""
print(f"\nπŸ” Fetching PR data...")
# Step 1: Fetch diff
diff_result = fetch_pr_diff.invoke(pr_url)
if diff_result.startswith("ERROR"):
return {"success": False, "error": diff_result, "review": None}
print("βœ… PR fetched!")
print(f"\nπŸ€– Analyzing code...")
# Step 2: Analyze
analysis = analyze_diff.invoke(diff_result[:4000])
print("βœ… Analysis complete!")
# Step 3: Generate final verdict
verdict_response = llm.invoke([
SystemMessage("You are a senior engineer. Give a final PR review verdict."),
HumanMessage(f"""
Based on this PR analysis, write a complete review report:
PR DATA:
{diff_result[:2000]}
ANALYSIS:
{analysis}
Write a professional review with:
1. Overall verdict (APPROVE / REQUEST CHANGES)
2. Key issues found
3. Positive aspects
4. Specific suggestions
""")
])
return {
"success": True,
"pr_url": pr_url,
"pr_data": diff_result,
"analysis": analysis,
"verdict": verdict_response.content,
"error": None
}
# ─────────────────────────────────────────
# RUN
# ─────────────────────────────────────────
if __name__ == "__main__":
# Test with a real public PR
test_pr = "https://github.com/langchain-ai/langchain/pull/1"
print("Mode: Simple review (no GitHub token needed for demo)")
result = review_pr_simple(test_pr)
if result["success"]:
print(f"\n{'='*60}")
print("πŸ“‹ PR DATA SUMMARY:")
print(result["pr_data"][:500])
print(f"\nπŸ” ANALYSIS:")
print(result["analysis"])
print(f"\nβœ… FINAL VERDICT:")
print(result["verdict"])
else:
print(f"❌ Failed: {result['error']}")