-
Notifications
You must be signed in to change notification settings - Fork 13
/
main.py
135 lines (114 loc) · 5.54 KB
/
main.py
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import os
import json
import requests
from flask import Flask, request
import openai
app = Flask(__name__)
openai.api_key = os.environ.get("OPENAI_API_KEY")
gitlab_token = os.environ.get("GITLAB_TOKEN")
gitlab_url = os.environ.get("GITLAB_URL")
api_base = os.environ.get("AZURE_OPENAI_API_BASE")
if api_base != None:
openai.api_base = api_base
openai.api_version = os.environ.get("AZURE_OPENAI_API_VERSION")
if openai.api_version != None:
openai.api_type = "azure"
@app.route('/webhook', methods=['POST'])
def webhook():
if request.headers.get("X-Gitlab-Token") != os.environ.get("EXPECTED_GITLAB_TOKEN"):
return "Unauthorized", 403
payload = request.json
if payload.get("object_kind") == "merge_request":
if payload["object_attributes"]["action"] != "open":
return "Not a PR open", 200
project_id = payload["project"]["id"]
mr_id = payload["object_attributes"]["iid"]
changes_url = f"{gitlab_url}/projects/{project_id}/merge_requests/{mr_id}/changes"
headers = {"Private-Token": gitlab_token}
response = requests.get(changes_url, headers=headers)
mr_changes = response.json()
diffs = [change["diff"] for change in mr_changes["changes"]]
pre_prompt = "Review the following git diff code changes, focusing on structure, security, and clarity."
questions = """
Questions:
1. Summarize key changes.
2. Is the new/modified code clear?
3. Are comments and names descriptive?
4. Can complexity be reduced? Examples?
5. Any bugs? Where?
6. Potential security issues?
7. Suggestions for best practices alignment?
"""
messages = [
{"role": "system", "content": "You are a senior developer reviewing code changes."},
{"role": "user", "content": f"{pre_prompt}\n\n{''.join(diffs)}{questions}"},
{"role": "assistant", "content": "Respond in GitLab-friendly markdown. Include a concise version of each question in your response."},
]
try:
completions = openai.ChatCompletion.create(
deployment_id=os.environ.get("OPENAI_API_MODEL"),
model=os.environ.get("OPENAI_API_MODEL") or "gpt-3.5-turbo",
temperature=0.2,
stream=False,
messages=messages
)
answer = completions.choices[0].message["content"].strip()
answer += "\n\nThis comment was generated by an artificial intelligence duck."
except Exception as e:
print(e)
answer = "I'm sorry, I'm not feeling well today. Please ask a human to review this PR."
answer += "\n\nThis comment was generated by an artificial intelligence duck."
answer += "\n\nError: " + str(e)
print(answer)
comment_url = f"{gitlab_url}/projects/{project_id}/merge_requests/{mr_id}/notes"
comment_payload = {"body": answer}
comment_response = requests.post(comment_url, headers=headers, json=comment_payload)
elif payload.get("object_kind") == "push":
project_id = payload["project_id"]
commit_id = payload["after"]
commit_url = f"{gitlab_url}/projects/{project_id}/repository/commits/{commit_id}/diff"
headers = {"Private-Token": gitlab_token}
response = requests.get(commit_url, headers=headers)
changes = response.json()
changes_string = ''.join([str(change) for change in changes])
pre_prompt = "Review the git diff of a recent commit, focusing on clarity, structure, and security."
questions = """
Questions:
1. Summarize changes (Changelog style).
2. Clarity of added/modified code?
3. Comments and naming adequacy?
4. Simplification without breaking functionality? Examples?
5. Any bugs? Where?
6. Potential security issues?
"""
messages = [
{"role": "system", "content": "You are a senior developer reviewing code changes from a commit."},
{"role": "user", "content": f"{pre_prompt}\n\n{changes_string}{questions}"},
{"role": "assistant", "content": "Respond in markdown for GitLab. Include concise versions of questions in the response."},
]
print(messages)
try:
completions = openai.ChatCompletion.create(
deployment_id=os.environ.get("OPENAI_API_MODEL"),
model=os.environ.get("OPENAI_API_MODEL") or "gpt-3.5-turbo",
temperature=0.7,
stream=False,
messages=messages
)
answer = completions.choices[0].message["content"].strip()
answer += "\n\nFor reference, i was given the following questions: \n"
for question in questions.split("\n"):
answer += f"\n{question}"
answer += "\n\nThis comment was generated by an artificial intelligence duck."
except Exception as e:
print(e)
answer = "I'm sorry, I'm not feeling well today. Please ask a human to review this code change."
answer += "\n\nThis comment was generated by an artificial intelligence duck."
answer += "\n\nError: " + str(e)
print(answer)
comment_url = f"{gitlab_url}/projects/{project_id}/repository/commits/{commit_id}/comments"
comment_payload = {"note": answer}
comment_response = requests.post(comment_url, headers=headers, json=comment_payload)
return "OK", 200
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080)