-
Notifications
You must be signed in to change notification settings - Fork 0
/
comment-pr-changes.js
159 lines (148 loc) · 4.74 KB
/
comment-pr-changes.js
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
const axios = require("axios");
const { GoogleGenerativeAI } = require("@google/generative-ai");
const fs = require("fs");
// const { OpenAI } = require("openai");
const genAI = new GoogleGenerativeAI(process.env.GOOGLE_API_KEY);
const githubToken = process.env.GITHUB_TOKEN;
const prNumber = process.env.PR_NUMBER;
const repo = process.env.GITHUB_REPOSITORY;
const [owner, repoName] = repo.split("/");
async function getPullRequestFiles() {
const url = `https://api.github.com/repos/${owner}/${repoName}/pulls/${prNumber}/files`;
const response = await axios.get(url, {
headers: {
Authorization: `token ${githubToken}`,
},
});
return response.data;
}
async function commentOnPullRequest(body) {
const url = `https://api.github.com/repos/${owner}/${repoName}/issues/${prNumber}/comments`;
await axios.post(
url,
{ body },
{
headers: {
Authorization: `token ${githubToken}`,
},
}
);
}
// async function getReviewFromApiChatGpt(changes) {
// const baseURL = "https://api.aimlapi.com/v1";
// const apiKey = "6ebf6933be6e4defa5d4e980a09dce86";
// const systemPrompt = "You are a senior developer. Be descriptive and helpful";
// const userPrompt = "Tell me a joke about javascript";
// const api = new OpenAI({
// apiKey,
// baseURL,
// });
// try {
// const completion = await api.chat.completions.create({
// model: "mistralai/Mistral-7B-Instruct-v0.2",
// messages: [
// {
// role: "system",
// content: systemPrompt,
// },
// {
// role: "user",
// content: userPrompt,
// },
// ],
// temperature: 0.7,
// max_tokens: 256,
// });
// const response = completion.choices[0].message.content;
// return response;
// } catch (error) {
// console.error(`AI API Error: ${error.message}`);
// }
// }
function readRules() {
return new Promise((resolve, reject) => {
fs.readFile("rules.txt", "utf8", (err, data) => {
if (err) {
reject(err);
} else {
resolve(data);
}
});
});
}
async function getReviewFromApiGemini(changes) {
const model = genAI.getGenerativeModel({
model: "gemini-1.5-flash",
});
const generationConfig = {
temperature: 1,
topP: 0.95,
topK: 64,
maxOutputTokens: 8192,
responseMimeType: "text/plain",
};
const rules = await readRules();
try {
const chatSession = model.startChat({
generationConfig,
history: [
{
role: "user",
parts: [
{
text:
"You are a senior developer who has a lot of experience in web and app development. You like to review code, especially github pull requests and give a positive feedback with constructive criticism. From now on I will give you some code snippets and you should review it based on the rules below: \n" +
rules +
"\nIf you have suggestion then use ONLY github suggestion format to paste the code and reply with a description of the suggestion.\nGithub suggestion format: \n```suggestion\n${suggested code} //replace this with your code\n```\n${description} //replace this with your description." +
"And Please write every review comment in Japanese",
},
],
},
{
role: "model",
parts: [
{
text: "Okay, I'm ready to review your code snippets. Please provide the code, and I'll give you feedback based on the criteria you outlined. Let's make it the best code it can be! \n",
},
],
},
],
});
const result = await chatSession.sendMessage(
'before: "' + changes.before + '"\nafter: "' + changes.after + '"'
);
return result.response.text();
} catch (error) {
console.error(`AI API Error: ${error.message}`);
}
}
function separateAndCleanCode(input) {
const lines = input.split("\n");
const before = [];
const after = [];
lines.forEach((line) => {
if (line.startsWith("-")) {
before.push(line.substring(1).trim());
} else if (line.startsWith("+")) {
after.push(line.substring(1).trim());
}
});
return {
before: before.join("\n"),
after: after.join("\n"),
};
}
(async () => {
try {
const files = await getPullRequestFiles();
for (const file of files) {
const changes = `Changes in \`${file.filename}\`:\n\n\`\`\`${file.patch}\`\`\``;
const cleanChanges = separateAndCleanCode(changes);
const review = await getReviewFromApiGemini(cleanChanges);
const body = `Review for changes in \`${file.filename}\`:\n\n${review}`;
await commentOnPullRequest(body);
}
} catch (error) {
console.error(`Error: ${error.message}`);
}
})();