-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
121 lines (93 loc) · 3.85 KB
/
Copy pathmain.py
File metadata and controls
121 lines (93 loc) · 3.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import os, hmac, hashlib, json
from fastapi import FastAPI, Request, HTTPException, BackgroundTasks
from dotenv import load_dotenv
from core.debate import run_debate
from core.github import get_pr_diff, post_comment
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
load_dotenv()
app = FastAPI(title="CodeCouncil", version="1.0.0")
WEBHOOK_SECRET = os.getenv("WEBHOOK_SECRET", "codecouncil123")
def verify_signature(payload: bytes, signature: str) -> bool:
expected = "sha256=" + hmac.new(
WEBHOOK_SECRET.encode(), payload, hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature)
def process_pr(repo: str, pr_number: int):
try:
print(f"\n🔍 Fetching PR #{pr_number} from {repo}...")
diff = get_pr_diff(repo, pr_number)
if len(diff) > 8000:
diff = diff[:8000]
print("⚠️ Diff truncated to 8000 chars")
print(f"📄 Diff fetched ({len(diff)} chars). Starting debate...")
verdict = run_debate(diff)
print("💬 Posting comment to GitHub...")
success = post_comment(repo, pr_number, verdict)
if success:
print(f"✅ Comment posted to PR #{pr_number}")
else:
print(f"❌ Failed to post comment to PR #{pr_number}")
except Exception as e:
print(f"❌ Error processing PR #{pr_number}: {e}")
@app.get("/")
def health():
return {
"status": "CodeCouncil running",
"version": "1.0.0",
"agents": ["SecurityAuditor", "PerfEngineer", "CleanCodeReviewer", "TechLead"]
}
@app.post("/webhook")
async def github_webhook(request: Request, background_tasks: BackgroundTasks):
payload = await request.body()
signature = request.headers.get("X-Hub-Signature-256", "")
if not verify_signature(payload, signature):
raise HTTPException(status_code=401, detail="Invalid signature")
event = request.headers.get("X-GitHub-Event")
data = json.loads(payload)
if event == "pull_request" and data.get("action") in ["opened", "synchronize"]:
repo = data["repository"]["full_name"]
pr_number = data["pull_request"]["number"]
pr_title = data["pull_request"]["title"]
print(f"\n📥 PR received: #{pr_number} — {pr_title}")
background_tasks.add_task(process_pr, repo, pr_number)
return {
"status": "processing",
"pr": pr_number,
"repo": repo,
"message": "Debate started in background"
}
return {"status": "ignored", "event": event}
@app.post("/review")
async def manual_review(request: Request):
data = await request.json()
repo = data.get("repo")
pr_number = data.get("pr_number")
if not repo or not pr_number:
raise HTTPException(status_code=400, detail="repo and pr_number required")
diff = get_pr_diff(repo, pr_number)
if len(diff) > 8000:
diff = diff[:8000]
verdict = run_debate(diff)
post_comment(repo, pr_number, verdict)
return verdict
@app.get("/dashboard", response_class=HTMLResponse)
async def dashboard():
with open("frontend/index.html", "r", encoding="utf-8") as f:
return f.read()
@app.post("/api/review")
async def api_review(request: Request):
data = await request.json()
repo = data.get("repo")
pr_number = data.get("pr_number")
if not repo or not pr_number:
raise HTTPException(status_code=400, detail="repo and pr_number required")
try:
diff = get_pr_diff(repo, int(pr_number))
if len(diff) > 8000:
diff = diff[:8000]
verdict = run_debate(diff)
post_comment(repo, int(pr_number), verdict)
return verdict
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))