From abeec4db33addea71ee42422281826a52ffcdc98 Mon Sep 17 00:00:00 2001 From: cicdguy <26552821+cicdguy@users.noreply.github.com> Date: Thu, 16 Nov 2023 09:43:45 -0600 Subject: [PATCH 1/5] Add GPT-based code review Signed-off-by: cicdguy <26552821+cicdguy@users.noreply.github.com> --- .github/workflows/code-review.yaml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .github/workflows/code-review.yaml diff --git a/.github/workflows/code-review.yaml b/.github/workflows/code-review.yaml new file mode 100644 index 0000000..984cf7f --- /dev/null +++ b/.github/workflows/code-review.yaml @@ -0,0 +1,23 @@ +name: GPT Code Review 🤖 + +permissions: + contents: read + pull-requests: write + +on: + pull_request: + types: + - opened + - reopened + - synchronize + +jobs: + review: + name: GPT Code Review 🤖 + runs-on: ubuntu-latest + steps: + - name: GPT Code Review 🤖 + uses: anc95/ChatGPT-CodeReview@main + env: + GITHUB_TOKEN: "${{ secrets.REPO_GITHUB_TOKEN }}" + OPENAI_API_KEY: "${{ secrets.OPENAI_API_KEY }}" From 79598f5923e9b83daa478d749382706d03948443 Mon Sep 17 00:00:00 2001 From: cicdguy <26552821+cicdguy@users.noreply.github.com> Date: Thu, 16 Nov 2023 09:47:25 -0600 Subject: [PATCH 2/5] Add model and other params Signed-off-by: cicdguy <26552821+cicdguy@users.noreply.github.com> --- .github/workflows/code-review.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/code-review.yaml b/.github/workflows/code-review.yaml index 984cf7f..406115d 100644 --- a/.github/workflows/code-review.yaml +++ b/.github/workflows/code-review.yaml @@ -21,3 +21,6 @@ jobs: env: GITHUB_TOKEN: "${{ secrets.REPO_GITHUB_TOKEN }}" OPENAI_API_KEY: "${{ secrets.OPENAI_API_KEY }}" + MODEL: gpt-3.5-turbo + top_p: 1 + temperature: 1 From 24b2d7a58d721df47a7f78a0733b5c3f7ae72581 Mon Sep 17 00:00:00 2001 From: cicdguy <26552821+cicdguy@users.noreply.github.com> Date: Thu, 16 Nov 2023 09:52:38 -0600 Subject: [PATCH 3/5] Use Microsoft's action Signed-off-by: cicdguy <26552821+cicdguy@users.noreply.github.com> --- .github/workflows/code-review.yaml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/code-review.yaml b/.github/workflows/code-review.yaml index 406115d..2071c4a 100644 --- a/.github/workflows/code-review.yaml +++ b/.github/workflows/code-review.yaml @@ -17,10 +17,7 @@ jobs: runs-on: ubuntu-latest steps: - name: GPT Code Review 🤖 - uses: anc95/ChatGPT-CodeReview@main + uses: microsoft/gpt-review@v0.9.5 env: GITHUB_TOKEN: "${{ secrets.REPO_GITHUB_TOKEN }}" OPENAI_API_KEY: "${{ secrets.OPENAI_API_KEY }}" - MODEL: gpt-3.5-turbo - top_p: 1 - temperature: 1 From 6bb540f85594c71c84933995e58a62ff471c08eb Mon Sep 17 00:00:00 2001 From: cicdguy <26552821+cicdguy@users.noreply.github.com> Date: Thu, 16 Nov 2023 09:57:15 -0600 Subject: [PATCH 4/5] Try mattzcarey's action Signed-off-by: cicdguy <26552821+cicdguy@users.noreply.github.com> --- .github/workflows/code-review.yaml | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/.github/workflows/code-review.yaml b/.github/workflows/code-review.yaml index 2071c4a..ed92b5c 100644 --- a/.github/workflows/code-review.yaml +++ b/.github/workflows/code-review.yaml @@ -16,8 +16,14 @@ jobs: name: GPT Code Review 🤖 runs-on: ubuntu-latest steps: + - name: Checkout Repo 🛎️ + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: GPT Code Review 🤖 - uses: microsoft/gpt-review@v0.9.5 - env: - GITHUB_TOKEN: "${{ secrets.REPO_GITHUB_TOKEN }}" - OPENAI_API_KEY: "${{ secrets.OPENAI_API_KEY }}" + uses: mattzcarey/code-review-gpt@v0.1.4-alpha + with: + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} + MODEL: 'gpt-3.5-turbo' + GITHUB_TOKEN: ${{ github.token }} From 5f1c07f20b121d9595dd5bef9298b4701256d2da Mon Sep 17 00:00:00 2001 From: cicdguy <26552821+cicdguy@users.noreply.github.com> Date: Thu, 16 Nov 2023 10:02:07 -0600 Subject: [PATCH 5/5] Add test file --- randomfile.ts | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 randomfile.ts diff --git a/randomfile.ts b/randomfile.ts new file mode 100644 index 0000000..d436b29 --- /dev/null +++ b/randomfile.ts @@ -0,0 +1,97 @@ +/* eslint-disable max-depth */ +/* eslint-disable complexity */ +// Reviewing multiple files inline > prioritising them > adding review comments +// Answer questions > get the comments on the PR (by me and the questioner) as context > answer the question as comment + +import jsesc from "jsesc"; + +import { modelInfo } from "../constants"; +import { AIModel } from "../llm/ai"; +import { buildReviewPrompt } from "../prompts/buildPrompt"; +import { ReviewFile } from "../types"; + +export class Chat { + ai: AIModel; + modelName: string; + constructor( + openaiApiKey: string, + openaiModelName?: string, + temperature?: string + ) { + this.modelName = openaiModelName ?? "gpt-4-1106-preview"; + this.ai = new AIModel({ + modelName: this.modelName, + apiKey: openaiApiKey, + temperature: temperature ? parseFloat(temperature) : 0, + }); + } + + private getMaxPromptLength = (modelName: string): number => { + const model = modelInfo.find((info) => info.model === modelName); + if (!model) { + throw new Error(`Model ${modelName} not found`); + } + + return model.maxPromptLength; + }; + + public getReview = async ( + patch: string + ): Promise => { + const prompt = buildReviewPrompt(patch); + const maxPromptLength = this.getMaxPromptLength(this.modelName); + + if (prompt.length > maxPromptLength) { + console.error( + `File ${prompt} is too large to review, skipping review for this file` + ); + + return undefined; + } + + try { + let jsonResponse = await this.ai.callModel(prompt); + jsonResponse = removeMarkdownJsonQuotes(jsonResponse); + + try { + return JSON.parse(jsonResponse) as ReviewFile[]; + } catch (parseError) { + console.error( + `Error parsing JSON: ${ + (parseError as Error).message + }. Escaping special characters and retrying.` + ); + + try { + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call + const escapedJsonResponse: string = jsesc(jsonResponse, { + json: true, + }); + + return JSON.parse(escapedJsonResponse) as ReviewFile[]; + } catch (escapeParseError) { + console.error( + `Error parsing escaped JSON: ${ + (escapeParseError as Error).message + }. Returning undefined.` + ); + + return undefined; + } + } + } catch (error) { + console.error( + `Error processing review data: ${(error as Error).message}` + ); + + return undefined; + } + }; +} + +const removeMarkdownJsonQuotes = (jsonString: string): string => { + return jsonString + .replace(/^`+\s*json\s*/, "") + .replace(/\s*`+$/, "") + .trim(); +}; \ No newline at end of file