Added OPEN_AI_BASE_URL variable to plug into the openai library

This commit is contained in:
Jimmy Royer 2024-09-01 18:27:52 -04:00
parent 415823ed2c
commit cb0db573b8
6 changed files with 266 additions and 168 deletions

1
.gitignore vendored
View file

@ -1,3 +1,4 @@
node_modules
.idea
lib/**/*
.secrets

View file

@ -11,6 +11,9 @@ inputs:
description: "OpenAI API model."
required: false
default: "gpt-4"
OPEN_AI_BASE_URL:
description: "Base URL to the API model (Open AI or Azure portal)."
required: false
exclude:
description: "Glob patterns to exclude files from the diff analysis"
required: false

167
dist/index.js vendored
View file

@ -6,41 +6,88 @@ require('./sourcemap-register.js');/******/ (() => { // webpackBootstrap
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
var __createBinding =
(this && this.__createBinding) ||
(Object.create
? function (o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
if (
!desc ||
("get" in desc ? !m.__esModule : desc.writable || desc.configurable)
) {
desc = {
enumerable: true,
get: function () {
return m[k];
},
};
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
}
: function (o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
});
var __setModuleDefault =
(this && this.__setModuleDefault) ||
(Object.create
? function (o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
}
: function (o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
});
var __importStar =
(this && this.__importStar) ||
function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
if (mod != null)
for (var k in mod)
if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k))
__createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
};
var __awaiter =
(this && this.__awaiter) ||
function (thisArg, _arguments, P, generator) {
function adopt(value) {
return value instanceof P
? value
: new P(function (resolve) {
resolve(value);
});
}
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
function fulfilled(value) {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
}
function rejected(value) {
try {
step(generator["throw"](value));
} catch (e) {
reject(e);
}
}
function step(result) {
result.done
? resolve(result.value)
: adopt(result.value).then(fulfilled, rejected);
}
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
};
var __importDefault =
(this && this.__importDefault) ||
function (mod) {
return mod && mod.__esModule ? mod : { default: mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
const fs_1 = __nccwpck_require__(7147);
const core = __importStar(__nccwpck_require__(2186));
@ -48,17 +95,22 @@ const openai_1 = __importDefault(__nccwpck_require__(47));
const rest_1 = __nccwpck_require__(5375);
const parse_diff_1 = __importDefault(__nccwpck_require__(4833));
const minimatch_1 = __importDefault(__nccwpck_require__(2002));
// import { OpenAI as AzureOpenAI } from "@azure/openai";
const GITHUB_TOKEN = core.getInput("GITHUB_TOKEN");
const OPENAI_API_KEY = core.getInput("OPENAI_API_KEY");
const OPENAI_API_MODEL = core.getInput("OPENAI_API_MODEL");
const OPEN_AI_BASE_URL = core.getInput("OPEN_AI_BASE_URL") || undefined; // Keep the default value as undefined instead of empty strings.
const octokit = new rest_1.Octokit({ auth: GITHUB_TOKEN });
const openai = new openai_1.default({
apiKey: OPENAI_API_KEY,
baseURL: OPEN_AI_BASE_URL || undefined,
});
function getPRDetails() {
var _a, _b;
return __awaiter(this, void 0, void 0, function* () {
const { repository, number } = JSON.parse((0, fs_1.readFileSync)(process.env.GITHUB_EVENT_PATH || "", "utf8"));
const { repository, number } = JSON.parse(
(0, fs_1.readFileSync)(process.env.GITHUB_EVENT_PATH || "", "utf8")
);
const prResponse = yield octokit.pulls.get({
owner: repository.owner.login,
repo: repository.name,
@ -69,7 +121,8 @@ function getPRDetails() {
repo: repository.name,
pull_number: number,
title: (_a = prResponse.data.title) !== null && _a !== void 0 ? _a : "",
description: (_b = prResponse.data.body) !== null && _b !== void 0 ? _b : "",
description:
(_b = prResponse.data.body) !== null && _b !== void 0 ? _b : "",
};
});
}
@ -89,8 +142,7 @@ function analyzeCode(parsedDiff, prDetails) {
return __awaiter(this, void 0, void 0, function* () {
const comments = [];
for (const file of parsedDiff) {
if (file.to === "/dev/null")
continue; // Ignore deleted files
if (file.to === "/dev/null") continue; // Ignore deleted files
for (const chunk of file.chunks) {
const prompt = createPrompt(file, chunk, prDetails);
const aiResponse = yield getAIResponse(prompt);
@ -114,7 +166,9 @@ function createPrompt(file, chunk, prDetails) {
- Use the given description only for the overall context and only comment the code.
- IMPORTANT: NEVER suggest adding comments to the code.
Review the following code diff in the file "${file.to}" and take the pull request title and description into account when writing the response.
Review the following code diff in the file "${
file.to
}" and take the pull request title and description into account when writing the response.
Pull request title: ${prDetails.title}
Pull request description:
@ -146,18 +200,33 @@ function getAIResponse(prompt) {
presence_penalty: 0,
};
try {
const response = yield openai.chat.completions.create(Object.assign(Object.assign(Object.assign({}, queryConfig), (OPENAI_API_MODEL === "gpt-4-1106-preview"
const response = yield openai.chat.completions.create(
Object.assign(
Object.assign(
Object.assign({}, queryConfig),
OPENAI_API_MODEL === "gpt-4-1106-preview"
? { response_format: { type: "json_object" } }
: {})), { messages: [
: {}
),
{
messages: [
{
role: "system",
content: prompt,
},
] }));
const res = ((_b = (_a = response.choices[0].message) === null || _a === void 0 ? void 0 : _a.content) === null || _b === void 0 ? void 0 : _b.trim()) || "{}";
return JSON.parse(res).reviews;
],
}
catch (error) {
)
);
const res =
((_b =
(_a = response.choices[0].message) === null || _a === void 0
? void 0
: _a.content) === null || _b === void 0
? void 0
: _b.trim()) || "{}";
return JSON.parse(res).reviews;
} catch (error) {
console.error("Error:", error);
return null;
}
@ -191,11 +260,21 @@ function main() {
return __awaiter(this, void 0, void 0, function* () {
const prDetails = yield getPRDetails();
let diff;
const eventData = JSON.parse((0, fs_1.readFileSync)((_a = process.env.GITHUB_EVENT_PATH) !== null && _a !== void 0 ? _a : "", "utf8"));
const eventData = JSON.parse(
(0, fs_1.readFileSync)(
(_a = process.env.GITHUB_EVENT_PATH) !== null && _a !== void 0
? _a
: "",
"utf8"
)
);
if (eventData.action === "opened") {
diff = yield getDiff(prDetails.owner, prDetails.repo, prDetails.pull_number);
}
else if (eventData.action === "synchronize") {
diff = yield getDiff(
prDetails.owner,
prDetails.repo,
prDetails.pull_number
);
} else if (eventData.action === "synchronize") {
const newBaseSha = eventData.before;
const newHeadSha = eventData.after;
const response = yield octokit.repos.compareCommits({
@ -208,8 +287,7 @@ function main() {
head: newHeadSha,
});
diff = String(response.data);
}
else {
} else {
console.log("Unsupported event:", process.env.GITHUB_EVENT_NAME);
return;
}
@ -223,11 +301,22 @@ function main() {
.split(",")
.map((s) => s.trim());
const filteredDiff = parsedDiff.filter((file) => {
return !excludePatterns.some((pattern) => { var _a; return (0, minimatch_1.default)((_a = file.to) !== null && _a !== void 0 ? _a : "", pattern); });
return !excludePatterns.some((pattern) => {
var _a;
return (0, minimatch_1.default)(
(_a = file.to) !== null && _a !== void 0 ? _a : "",
pattern
);
});
});
const comments = yield analyzeCode(filteredDiff, prDetails);
if (comments.length > 0) {
yield createReviewComment(prDetails.owner, prDetails.repo, prDetails.pull_number, comments);
yield createReviewComment(
prDetails.owner,
prDetails.repo,
prDetails.pull_number,
comments
);
}
});
}

2
dist/index.js.map vendored

File diff suppressed because one or more lines are too long

View file

@ -13,7 +13,7 @@
},
"dependencies": {
"@actions/core": "^1.10.0",
"@azure/openai" :"2.0.0-beta.1",
"@azure/openai": "2.0.0-beta.1",
"@octokit/rest": "^19.0.7",
"minimatch": "^7.4.2",
"openai": "^4.20.1",

View file

@ -5,14 +5,19 @@ import { Octokit } from "@octokit/rest";
import parseDiff, { Chunk, File } from "parse-diff";
import minimatch from "minimatch";
// import { OpenAI as AzureOpenAI } from "@azure/openai";
const GITHUB_TOKEN: string = core.getInput("GITHUB_TOKEN");
const OPENAI_API_KEY: string = core.getInput("OPENAI_API_KEY");
const OPENAI_API_MODEL: string = core.getInput("OPENAI_API_MODEL");
const OPEN_AI_BASE_URL: string | undefined =
core.getInput("OPEN_AI_BASE_URL") || undefined; // Keep the default value as undefined instead of empty strings.
const octokit = new Octokit({ auth: GITHUB_TOKEN });
const openai = new OpenAI({
apiKey: OPENAI_API_KEY,
baseURL: OPEN_AI_BASE_URL || undefined,
});
interface PRDetails {