diff --git a/src/bindings/config.ts b/src/bindings/config.ts index 49a3e4fc3..7979111d4 100644 --- a/src/bindings/config.ts +++ b/src/bindings/config.ts @@ -103,8 +103,8 @@ export const loadConfig = async (context: Context): Promise => { registerWalletWithVerification: registerWalletWithVerification, }, ask: { - apiKey: openAIKey, - tokenLimit: openAITokenLimit || 0, + apiKey: process.env.OPENAI_API_KEY || openAIKey, + tokenLimit: openAITokenLimit || 8000, }, accessControl: enableAccessControl, newContributorGreeting: newContributorGreeting, diff --git a/src/configs/ubiquibot-config-default.ts b/src/configs/ubiquibot-config-default.ts index 4a989995f..451d60be3 100644 --- a/src/configs/ubiquibot-config-default.ts +++ b/src/configs/ubiquibot-config-default.ts @@ -50,39 +50,39 @@ export const DefaultConfig: MergedConfig = { commandSettings: [ { name: "start", - enabled: false, + enabled: true, }, { name: "stop", - enabled: false, + enabled: true, }, { name: "wallet", - enabled: false, + enabled: true, }, { name: "payout", - enabled: false, + enabled: true, }, { name: "multiplier", - enabled: false, + enabled: true, }, { name: "query", - enabled: false, + enabled: true, }, { name: "ask", - enabled: false, + enabled: true, }, { name: "allow", - enabled: false, + enabled: true, }, { name: "autopay", - enabled: false, + enabled: true, }, ], incentives: { diff --git a/src/handlers/comment/action.ts b/src/handlers/comment/action.ts index 60ea5bbae..cd435e748 100644 --- a/src/handlers/comment/action.ts +++ b/src/handlers/comment/action.ts @@ -33,6 +33,7 @@ export const handleComment = async (): Promise => { if (userCommand) { const { id, handler, callback, successComment, failureComment } = userCommand; logger.info(`Running a comment handler: ${handler.name}`); + console.log("running a comment handler: ", handler.name); const { payload: _payload } = getBotContext(); const issue = (_payload as Payload).issue; diff --git a/src/handlers/comment/handlers/ask.ts b/src/handlers/comment/handlers/ask.ts index 63777d4ae..54c43e6d3 100644 --- a/src/handlers/comment/handlers/ask.ts +++ b/src/handlers/comment/handlers/ask.ts @@ -16,12 +16,14 @@ export const ask = async (body: string) => { const sender = payload.sender.login; const issue = payload.issue; + console.log("body", body); + if (!body) { return `Please ask a question`; } if (!issue) { - return `This command can only be used on issues`; + return `This command can only be used on issues and pull requests.`; } const chatHistory: CreateChatCompletionRequestMessage[] = []; @@ -35,9 +37,11 @@ export const ask = async (body: string) => { if (matches) { const [, body] = matches; + console.log("body", body); + // standard comments const comments = await getAllIssueComments(issue.number); - // raw so we can grab the tag + // raw so we can grab the tag const commentsRaw = await getAllIssueComments(issue.number, "raw"); if (!comments) { @@ -53,7 +57,7 @@ export const ask = async (body: string) => { // add the rest comments.forEach(async (comment, i) => { - if (comment.user.type == UserType.User || commentsRaw[i].body.includes("")) { + if (comment.user.type == UserType.User || commentsRaw[i].body.includes("")) { streamlined.push({ login: comment.user.login, body: comment.body, @@ -74,13 +78,15 @@ export const ask = async (body: string) => { // let chatgpt deduce what is the most relevant context const gptDecidedContext = await decideContextGPT(chatHistory, streamlined, linkedPRStreamlined, linkedIssueStreamlined); + console.log("gptDecidedContext", gptDecidedContext); + if (linkedIssueStreamlined.length == 0 && linkedPRStreamlined.length == 0) { // No external context to add chatHistory.push( { role: "system", content: sysMsg, - name: "UbiquityAI", + name: "UbiquiBot", } as CreateChatCompletionRequestMessage, { role: "user", @@ -93,7 +99,7 @@ export const ask = async (body: string) => { { role: "system", content: sysMsg, // provide the answer template - name: "UbiquityAI", + name: "UbiquiBot", } as CreateChatCompletionRequestMessage, { role: "system", @@ -108,8 +114,12 @@ export const ask = async (body: string) => { ); } + console.log("chatHistory pre ask"); + const gptResponse = await askGPT(body, chatHistory); + console.log("chatHistory pre ask"); + if (typeof gptResponse === "string") { return gptResponse; } else if (gptResponse.answer) { diff --git a/src/helpers/gpt.ts b/src/helpers/gpt.ts index 046503d79..8bcb7870b 100644 --- a/src/helpers/gpt.ts +++ b/src/helpers/gpt.ts @@ -5,16 +5,16 @@ import OpenAI from "openai"; import { CreateChatCompletionRequestMessage } from "openai/resources/chat"; import { ErrorDiff } from "../utils/helpers"; -export const sysMsg = `You are the UbiquityAI, designed to provide accurate technical answers. \n +export const sysMsg = `You are the UbiquiBot, designed to provide accurate technical answers. \n Whenever appropriate, format your response using GitHub Flavored Markdown. Utilize tables, lists, and code blocks for clear and organized answers. \n Do not make up answers. If you are unsure, say so. \n Original Context exists only to provide you with additional information to the current question, use it to formulate answers. \n Infer the context of the question from the Original Context using your best judgement. \n -All replies MUST end with "\n\n ".\n +All replies MUST end with "\n\n ".\n `; export const gptContextTemplate = ` -You are the UbiquityAI, designed to review and analyze pull requests. +You are the UbiquiBot, designed to review and analyze pull requests. You have been provided with the spec of the issue and all linked issues or pull requests. Using this full context, Reply in pure JSON format, with the following structure omitting irrelvant information pertaining to the specification. You MUST provide the following structure, but you may add additional information if you deem it relevant. @@ -79,7 +79,7 @@ export const decideContextGPT = async ( // standard comments const comments = await getAllIssueComments(issue.number); - // raw so we can grab the tag + // raw so we can grab the tag const commentsRaw = await getAllIssueComments(issue.number, "raw"); if (!comments) { @@ -95,7 +95,7 @@ export const decideContextGPT = async ( // add the rest comments.forEach(async (comment, i) => { - if (comment.user.type == UserType.User || commentsRaw[i].body.includes("")) { + if (comment.user.type == UserType.User || commentsRaw[i].body.includes("")) { streamlined.push({ login: comment.user.login, body: comment.body, @@ -117,18 +117,19 @@ export const decideContextGPT = async ( chatHistory.push( { role: "system", + content: gptContextTemplate, + }, + { + role: "assistant", content: "This issue/Pr context: \n" + JSON.stringify(streamlined), - name: "UbiquityAI", } as CreateChatCompletionRequestMessage, { - role: "system", + role: "assistant", content: "Linked issue(s) context: \n" + JSON.stringify(linkedIssueStreamlined), - name: "UbiquityAI", } as CreateChatCompletionRequestMessage, { - role: "system", + role: "assistant", content: "Linked Pr(s) context: \n" + JSON.stringify(linkedPRStreamlined), - name: "UbiquityAI", } as CreateChatCompletionRequestMessage ); diff --git a/src/helpers/issue.ts b/src/helpers/issue.ts index e014994fe..3ce22b998 100644 --- a/src/helpers/issue.ts +++ b/src/helpers/issue.ts @@ -745,7 +745,7 @@ export const getAllLinkedIssuesAndPullsInBody = async (issueNumber: number) => { const prComments = await getAllIssueComments(linkedPrs[i]); const prCommentsRaw = await getAllIssueComments(linkedPrs[i], "raw"); prComments.forEach(async (comment, i) => { - if (comment.user.type == UserType.User || prCommentsRaw[i].body.includes("")) { + if (comment.user.type == UserType.User || prCommentsRaw[i].body.includes("")) { linkedPRStreamlined.push({ login: comment.user.login, body: comment.body, @@ -767,7 +767,7 @@ export const getAllLinkedIssuesAndPullsInBody = async (issueNumber: number) => { const issueComments = await getAllIssueComments(linkedIssues[i]); const issueCommentsRaw = await getAllIssueComments(linkedIssues[i], "raw"); issueComments.forEach(async (comment, i) => { - if (comment.user.type == UserType.User || issueCommentsRaw[i].body.includes("")) { + if (comment.user.type == UserType.User || issueCommentsRaw[i].body.includes("")) { linkedIssueStreamlined.push({ login: comment.user.login, body: comment.body, diff --git a/src/utils/private.ts b/src/utils/private.ts index 9568f45dd..3c37bea5c 100644 --- a/src/utils/private.ts +++ b/src/utils/private.ts @@ -158,7 +158,7 @@ export const getWideConfig = async (context: Context) => { promotionComment: mergedConfigData.promotionComment, registerWalletWithVerification: mergedConfigData.registerWalletWithVerification, enableAccessControl: mergedConfigData.enableAccessControl, - openAIKey: mergedConfigData.openAIKey, + openAIKey: process.env.OPENAI_API_KEY || mergedConfigData.openAIKey, openAITokenLimit: mergedConfigData.openAITokenLimit, staleBountyTime: mergedConfigData.staleBountyTime, newContributorGreeting: mergedConfigData.newContributorGreeting,