Skip to content
This repository has been archived by the owner on Sep 19, 2024. It is now read-only.

/review #748

Closed
wants to merge 44 commits into from
Closed
Show file tree
Hide file tree
Changes from 42 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
45a15af
feat(deps): added openai
Keyrxng Aug 23, 2023
bfe3409
feat: added ask command
Keyrxng Aug 23, 2023
9ca0a6b
fix: update prompt
Keyrxng Aug 23, 2023
da4a3f7
fix: update system prompt
Keyrxng Aug 23, 2023
d9cc49b
Merge branch 'ubiquity:development' into ask
Keyrxng Aug 25, 2023
8e6b42b
feat: simple memory
Keyrxng Aug 25, 2023
dd153f4
fix: comments
Keyrxng Aug 25, 2023
5588905
fix: streamlined context
Keyrxng Aug 27, 2023
6d4ff92
chore: pulling context
Keyrxng Aug 31, 2023
6725419
chore: tokenization
Keyrxng Aug 31, 2023
7322a59
chore: diff comparison
Keyrxng Aug 31, 2023
a1343cf
fix: ci and spec check
Keyrxng Sep 4, 2023
d3104df
Merge branch 'development' into ask
Keyrxng Sep 5, 2023
99b8aa2
fix: merge mistake
Keyrxng Sep 5, 2023
4a4d32d
fix: key from config
Keyrxng Sep 5, 2023
8b80e39
fix: set ask to false
Keyrxng Sep 5, 2023
3c669df
fix(deps): langchain
Keyrxng Sep 7, 2023
0dbfde3
Merge branch 'development' into ask
Keyrxng Sep 7, 2023
911952f
fix: apikey undefined
Keyrxng Sep 7, 2023
8cf84b8
fix: using token limit
Keyrxng Sep 7, 2023
d529dd7
Merge branch 'development' into ask
Keyrxng Sep 7, 2023
c7c96aa
chore: improve ask command
Keyrxng Sep 10, 2023
b659fab
Merge branch 'ubiquity:development' into ask
Keyrxng Sep 10, 2023
9ffde17
feat: review command
Keyrxng Sep 10, 2023
75e9438
Merge branch 'ubiquity:development' into review
Keyrxng Sep 10, 2023
e0a50fa
Merge branch 'ubiquity:development' into review
Keyrxng Sep 10, 2023
f9a36b4
fix: using errordiff
Keyrxng Sep 10, 2023
33caf8e
chore: prompt rework
Keyrxng Sep 12, 2023
10c46f6
chore: prompt rework
Keyrxng Sep 13, 2023
13c7578
fix: final sprint
Keyrxng Sep 14, 2023
c447ab5
Update src/handlers/comment/handlers/index.ts
0x4007 Sep 14, 2023
667bff2
fix: flattery gets you no where
Keyrxng Sep 14, 2023
94a80bb
Merge branch 'review' of https://github.com/Keyrxng/ubiquibot into re…
Keyrxng Sep 14, 2023
8ff8538
Update src/helpers/gpt.ts
0x4007 Sep 14, 2023
10a4ff4
fix: nullable api key
Keyrxng Sep 14, 2023
eb0a83f
fix: prompt merge
Keyrxng Sep 14, 2023
31c04b5
Merge branch 'development' into review
Keyrxng Sep 14, 2023
7d63d53
fix: error diff
Keyrxng Sep 14, 2023
403643a
fix: suffix
Keyrxng Sep 16, 2023
ad44658
Merge branch 'development' into review
Keyrxng Sep 16, 2023
28c8b98
chore: prompt working
Keyrxng Sep 20, 2023
f155e9b
Update src/handlers/comment/handlers/review.ts
0x4007 Sep 21, 2023
839fc95
fix: max tokens
Keyrxng Sep 21, 2023
f1400cc
Merge branch 'review' of https://github.com/Keyrxng/ubiquibot into re…
Keyrxng Sep 21, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ SUPABASE_KEY=
AUTO_PAY_MODE=
ANALYTICS_MODE=


# Use `trace` to get verbose logging or `info` to show less
LOG_LEVEL=debug
LOGDNA_INGESTION_KEY=
OPENAI_API_HOST=https://api.openai.com
OPENAI_API_KEY=
OPENAI_TOKEN_LIMIT=
CHATGPT_USER_PROMPT_FOR_IMPORTANT_WORDS="I need your help to find important words (e.g. unique adjectives) from github issue below and I want to parse them easily so please separate them using #(No other contexts needed). Please separate the words by # so I can parse them easily. Please answer simply as I only need the important words. Here is the issue content.\n"
CHATGPT_USER_PROMPT_FOR_MEASURE_SIMILARITY='I have two github issues and I need to measure the possibility of the 2 issues are the same content (No other contents needed and give me only the number in %).\n Give me in number format and add % after the number.\nDo not tell other things since I only need the number (e.g. 85%). Here are two issues:\n 1. "%first%"\n2. "%second%"'
SIMILARITY_THRESHOLD=80
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"node-html-parser": "^6.1.5",
"node-html-to-image": "^3.3.0",
"nodemon": "^2.0.19",
"openai": "^4.2.0",
"parse5": "^7.1.2",
"prettier": "^2.7.1",
"probot": "^12.2.4",
Expand Down
7 changes: 7 additions & 0 deletions src/bindings/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
DEFAULT_PERMIT_BASE_URL,
DEFAULT_TIME_RANGE_FOR_MAX_ISSUE,
DEFAULT_TIME_RANGE_FOR_MAX_ISSUE_ENABLED,
DEFAULT_TOKEN_LIMIT,
} from "../configs";
import { getPayoutConfigByNetworkId } from "../helpers";
import { ajv } from "../utils";
Expand All @@ -34,6 +35,8 @@ export const loadConfig = async (context: Context): Promise<BotConfig> => {
registerWalletWithVerification,
staleBountyTime,
enableAccessControl,
openAIKey,
openAITokenLimit,
} = await getWideConfig(context);

const publicKey = await getScalarKey(process.env.X25519_PRIVATE_KEY);
Expand Down Expand Up @@ -99,6 +102,10 @@ export const loadConfig = async (context: Context): Promise<BotConfig> => {
wallet: {
registerWalletWithVerification: registerWalletWithVerification,
},
review: {
apiKey: openAIKey,
tokenLimit: openAITokenLimit || DEFAULT_TOKEN_LIMIT,
},
accessControl: enableAccessControl,
};

Expand Down
2 changes: 2 additions & 0 deletions src/configs/shared.ts
0xcodercrane marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,5 @@ export const DEFAULT_DISQUALIFY_TIME = "7 days"; // 7 days
export const DEFAULT_NETWORK_ID = 1; // ethereum
export const DEFAULT_RPC_ENDPOINT = "https://rpc-bot.ubq.fi/v1/mainnet";
export const DEFAULT_PERMIT_BASE_URL = "https://pay.ubq.fi";

export const DEFAULT_TOKEN_LIMIT = 6000;
1 change: 1 addition & 0 deletions src/handlers/comment/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export enum IssueCommentCommands {
PAYOUT = "/payout", // request permit payout
MULTIPLIER = "/multiplier", // set bounty multiplier (for treasury)
QUERY = "/query",
REVIEW = "/review", // gpt-3.5-turbo-16k will review the pull request
// Access Controls

ALLOW = "/allow",
Expand Down
8 changes: 8 additions & 0 deletions src/handlers/comment/handlers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { listAvailableCommands } from "./help";
import { unassign } from "./unassign";
import { registerWallet } from "./wallet";
import { setAccess } from "./allow";
import { review } from "./review";
import { multiplier } from "./multiplier";
import { BigNumber, ethers } from "ethers";
import { addPenalty } from "../../../adapters/supabase";
Expand Down Expand Up @@ -36,6 +37,7 @@ export * from "./payout";
export * from "./help";
export * from "./multiplier";
export * from "./query";
export * from "./review";

/**
* Parses the comment body and figure out the command name a user wants
Expand Down Expand Up @@ -251,6 +253,12 @@ export const userCommands = (): UserCommands[] => {
handler: query,
callback: commandCallback,
},
{
id: IssueCommentCommands.REVIEW,
description: `Compares the pull request code diff with the linked issue's specification to perform a review of the current pull request. \n example usage: /review`,
handler: review,
callback: commandCallback,
},
{
id: IssueCommentCommands.MULTIPLIER,
description: `Set the bounty payout multiplier for a specific contributor, and provide the reason for why. \n example usage: "/wallet @user 0.5 'Multiplier reason'"`,
Expand Down
126 changes: 126 additions & 0 deletions src/handlers/comment/handlers/review.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import { getBotContext, getLogger } from "../../../bindings";
import { Payload, StreamlinedComment } from "../../../types";
import { getAllIssueComments, getPullByNumber } from "../../../helpers";
import { CreateChatCompletionRequestMessage } from "openai/resources/chat";
import { askGPT, getPRSpec, specCheckTemplate } from "../../../helpers/gpt";
import { ErrorDiff } from "../../../utils/helpers";

/**
* @notice Three calls to OpenAI are made. First for context, second for review and third for finalization.
* @returns Pull Request Report
*/
export const review = async (body: string) => {
const context = getBotContext();
const logger = getLogger();

const payload = context.payload as Payload;
const issue = payload.issue;

if (!issue) {
return ErrorDiff(`Payload issue is undefined.`);
}

if (!body) {
return ErrorDiff(`Payload body is undefined.`);
}

const isPr = await getPullByNumber(context, issue.number);

if (!isPr) {
return ErrorDiff(`Can only be used on pull requests.`);
}

const reviewRegex = /^\/review/;
const reviewRegexMatch = body.match(reviewRegex);

if (!reviewRegexMatch) {
return ErrorDiff(`Error matching regex for review`);
}

const streamlined: StreamlinedComment[] = [];
let chatHistory: CreateChatCompletionRequestMessage[] = [];
const commentsRaw = await getAllIssueComments(issue.number, "raw");

if (!commentsRaw) {
logger.info(`Error getting issue comments`);
return ErrorDiff(`Error getting issue comments.`);
}

// return a diff of the changes made in the PR
const comparePR = async () => {
const comparePR = await context.octokit.pulls.get({
owner: payload.repository.owner.login,
repo: payload.repository.name,
pull_number: issue.number,
});

const pr = comparePR.data;

const prDiff = await context.octokit.pulls.get({
owner: payload.repository.owner.login,
repo: payload.repository.name,
pull_number: pr.number,
mediaType: {
format: "diff",
},
});

const diffContent = prDiff.data;

return {
pr,
diff: diffContent,
};
};

const isPull = async () => {
if (isPr) {
const diff = await comparePR()
.then(({ diff }) => {
return diff;
})
.catch((error) => {
logger.info(`Error getting diff: ${error}`);
return ErrorDiff(`Error getting diff: ${error}`);
});

const spec = await getPRSpec(context, chatHistory, streamlined);

chatHistory = [];
chatHistory.push(
{
role: "system",
content: specCheckTemplate,
} as CreateChatCompletionRequestMessage,
{
role: "assistant",
content: "Spec for Pr: \n" + JSON.stringify(spec),
} as CreateChatCompletionRequestMessage,
{
role: "user",
content: `${issue.assignees[0].login}'s PR Diff: \n` + JSON.stringify(diff),
} as CreateChatCompletionRequestMessage
);

const gptResponse = await askGPT(`Pr review call for #${issue.number}`, chatHistory);

if (typeof gptResponse === "string") {
return gptResponse;
} else {
if (gptResponse.answer) {
return gptResponse.answer;
} else {
return ErrorDiff(`No answer found for issue #${issue.number}`);
}
}
} else {
return ErrorDiff(`No PR found for issue #${issue.number}`);
}
};

const res = await isPull();
if (res.startsWith("```diff\n")) {
return res;
}
return res + `\n###### Ensure the pull request requirements are in the linked issue's first comment and update it if the scope evolves.`;
};
Loading