Skip to content
Merged
5 changes: 5 additions & 0 deletions agent/indexing/chunker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
def chunk_code(code: str, chunk_size=300):
chunks = []
for i in range(0, len(code), chunk_size):
chunks.append(code[i:i+chunk_size])
return chunks
9 changes: 9 additions & 0 deletions agent/indexing/parser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import os

def get_code_files(root_dir="."):
code_files = []
for root, _, files in os.walk(root_dir):
for file in files:
if file.endswith(".py"):
code_files.append(os.path.join(root, file))
return code_files
40 changes: 33 additions & 7 deletions agent/llm/groq_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,37 @@

client = Groq(api_key=os.getenv("GROQ_API_KEY"))
model = MODEL
def generate_review(diff: str) -> str:
def generate_review(diff: str,context : list = None) -> str:
from agent.llm.prompts import REVIEW_PROMPT

if not diff.strip():
return "No changes found to review."

prompt = REVIEW_PROMPT.format(diff=diff[:8000])
# prompt = REVIEW_PROMPT.format(diff=diff[:8000])
MAX_CONTEXT_CHARS = 5000

'''preparing context'''
context_text = ""
if context:
combined = "\n\n".join(context) # Include up to 5 context items(limitting)
context_text = combined[:MAX_CONTEXT_CHARS]
prompt = f"""
You are an AI code reviewer. Use the provided repository context (if available) to give better insights.

---CONTEXT---
{context_text}

---DIFF---
{diff[:8000]}

---TASK---
{REVIEW_PROMPT}

"""

try:
response = client.chat.completions.create(
model="llama-3.3-70b-versatile",
model=model,
messages=[
{"role": "user", "content": prompt}
],
Expand All @@ -28,12 +48,18 @@ def generate_review(diff: str) -> str:
except Exception as e:
return f"Error generating review: {str(e)}"

#local test for generate review function
if __name__ == "__main__":
test_diff = """
diff --git a/app.py b/app.py
+ def add(a, b):
+ return a + b
+ def divide(a, b):
+ return a / b
"""

result = generate_review(test_diff)
print(result)
test_context = [
"def safe_divide(a, b): return a / b if b != 0 else 0",
"Utility functions for math operations"
]

result = generate_review(test_diff, context=test_context) #added conetxt parameter (kindly see @pleasingsunlight)
print(result)
21 changes: 10 additions & 11 deletions agent/llm/prompts.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
REVIEW_PROMPT = """
You are a senior code reviewer.
Analyze the following git diff and respond STRICTLY in this format:
REVIEW_PROMPT = """
Analyze the code changes using the provided DIFF and CONTEXT.

Return output STRICTLY in this format:

### Bugs
- List any bugs (or write "None")
Expand All @@ -9,13 +10,11 @@
- Code quality improvements

### Suggestions
- Better practices or optimizations

If everything looks good, say: "Code looks good ✅"
format output clearly using bullet points.

Keep it concise.
- Best practices or optimizations

Diff:
{diff}
Rules:
- Be concise
- Do NOT repeat the diff
- Use context if helpful
- If everything looks good, say: "Code looks good ✅"
"""
71 changes: 61 additions & 10 deletions agent/main.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,78 @@
from agent.indexing.parser import get_code_files
from agent.indexing.chunker import chunk_code
from agent.indexing.embedder import get_embeddings
from agent.indexing.vector_store import store_embeddings, query_embeddings

import subprocess
from agent.llm.groq_client import generate_review
from agent.github.commenter import post_comment
def get_pr_diff():
try:
diff = subprocess.check_output(
["git","diff","origin/main...HEAD"],
text = True
["git", "diff", "HEAD~1", "HEAD"],
text=True
)
return diff
except Exception as e:
print(f"Error getting PR diff: {e}")
print("Error getting diff:", e)
return ""


def build_context():
files = get_code_files()
all_chunks = []

for file in files:
try:
with open(file, "r", encoding="utf-8") as f:
code = f.read()
chunks = chunk_code(code)
all_chunks.extend(chunks)
except:
continue

return all_chunks


def main():
print("Agent is started...")
print("Agent started")

# 1. Get diff
diff = get_pr_diff()

if not diff.strip():
print("No changes detected in the PR.")
print("No changes found")
return
print("Generating review based on the PR diff...")
review = generate_review(diff)
print("Review generated, posting to github...")
# Here you would add code to post the review back to GitHub using their API

# 2. Build full codebase context
print("Building context...")
chunks = build_context()

# 3. Convert to embeddings
print("Generating embeddings...")
embeddings = get_embeddings(chunks)

# 4. Store embeddings
print("Storing embeddings...")
store_embeddings(chunks, embeddings)

# 5. Convert diff to embedding
print("Embedding diff...")
query_embedding = get_embeddings([diff])[0]

# 6. Retrieve relevant chunks
print("Retrieving relevant context...")
relevant_chunks = query_embeddings(query_embedding)

# 7. Generate review
print("Generating review...")
review = generate_review(diff, context=relevant_chunks)

# 8. Post comment
print("Posting comment...")
post_comment(review)
print("Review posted successfully.")

print("Done")

if __name__ == "__main__":
main()
Loading