-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbot_engine.py
More file actions
94 lines (82 loc) · 3.67 KB
/
bot_engine.py
File metadata and controls
94 lines (82 loc) · 3.67 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
#!/usr/bin/env python3
"""
Fleet Bot Engine — auto-replies, auto-labels, auto-assigns.
Uses Groq for rapid decisions, DeepSeek for complex ones.
"""
import json, os, urllib.request, ssl, time
GROQ_KEY = os.environ.get("GROQ_KEY", "")
GITHUB_TOKEN = os.environ.get("GITHUB_TOKEN", "")
ctx = ssl.create_default_context()
def gh_api(method, url, data=None):
headers = {"Authorization": f"Bearer {GITHUB_TOKEN}", "Content-Type": "application/json"}
if data: data = json.dumps(data).encode()
req = urllib.request.Request(url, data=data, headers=headers, method=method)
resp = urllib.request.urlopen(req, timeout=15, context=ctx)
return json.loads(resp.read()) if resp.status < 300 else {}
def groq(prompt, max_tokens=100):
body = json.dumps({"model": "llama-3.3-70b-versatile", "messages": [{"role": "user", "content": prompt}],
"max_tokens": max_tokens, "temperature": 0.3}).encode()
req = urllib.request.Request("https://api.groq.com/openai/v1/chat/completions", data=body,
headers={"Authorization": f"Bearer {GROQ_KEY}", "Content-Type": "application/json", "User-Agent": "curl/7.88"})
resp = urllib.request.urlopen(req, timeout=15)
return json.loads(resp.read())["choices"][0]["message"]["content"]
def auto_label(repo, issue_number, title, body):
"""Auto-label an issue based on content."""
prompt = f"""Classify this GitHub issue into labels. Return ONLY a JSON array of label strings.
Available labels: bug, enhancement, fleet, flux, documentation, good-first-issue, help-wanted, question, marine, hardware
Title: {title}
Body: {(body or "")[:200]}"""
reply = groq(prompt, max_tokens=50)
import re
match = re.search(r"\[.*?\]", reply)
if match:
labels = json.loads(match.group())
if labels:
try:
gh_api("POST", f"https://api.github.com/repos/{repo}/issues/{issue_number}/labels",
{"labels": labels})
return labels
except:
pass
return []
def auto_comment(repo, issue_number, title, author):
"""Auto-comment on new issues."""
# Fleet welcome message
comment = f"""Thanks @{author} for opening this issue.
> **Fleet GitHub App** has processed this issue.
> - Repository: {repo}
> - Auto-assigned: pending
> - Dockside score: checking...
The lighthouse keeper is watching. 🔮
---
*This comment was generated by the Fleet GitHub App (@oracle1-bot).*"""
try:
gh_api("POST", f"https://api.github.com/repos/{repo}/issues/{issue_number}/comments",
{"body": comment})
return True
except:
return False
def dockside_check(repo):
"""Run dockside exam on a repo via GitHub API."""
try:
tree = gh_api("GET", f"https://api.github.com/repos/{repo}/git/trees/main?recursive=1")
files = [t["path"] for t in tree.get("tree", []) if t["type"] == "blob"]
checks = {
"README": "README.md" in files,
"LICENSE": any(f.startswith("LICENSE") for f in files),
"tests": any("test" in f.lower() for f in files),
"CI": any(f.startswith(".github/workflows") for f in files),
"CHARTER": "CHARTER.md" in files,
"ABSTRACTION": "ABSTRACTION.md" in files,
"STATE": "STATE.md" in files,
}
total = sum(checks.values())
pct = round(total / len(checks) * 100)
grade = "🟢" if pct >= 80 else "🟡" if pct >= 60 else "⚠️"
return total, len(checks), pct, grade, checks
except:
return 0, 7, 0, "❌", {}
if __name__ == "__main__":
# Test
print("Bot engine ready")
print("Available: auto_label, auto_comment, dockside_check")