From 26152d7e5f65b4fc2474a28a5b0ed5b5a90a36fc Mon Sep 17 00:00:00 2001 From: Danny Avila <110412045+danny-avila@users.noreply.github.com> Date: Wed, 17 May 2023 21:58:56 -0400 Subject: [PATCH] feat(api): add support for user-provided OpenAI API key (#311) - Add support for user-provided OpenAI API key by setting OPENAI_KEY to "user_provided" in .env.example - Pass oaiApiKey to titleConvo function in titleConvo.js - Pass oaiApiKey to askClient function in askOpenAI.js - Modify openAI object in endpoints.js to include userProvide property based on whether OPENAI_KEY is set to "user_provided" or not. --- api/.env.example | 3 ++- api/app/titleConvo.js | 4 ++-- api/server/routes/ask/askOpenAI.js | 5 +++-- api/server/routes/endpoints.js | 8 +++++--- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/api/.env.example b/api/.env.example index f8549f81fa..81d8582df9 100644 --- a/api/.env.example +++ b/api/.env.example @@ -24,7 +24,8 @@ MONGO_URI=mongodb://127.0.0.1:27017/chatgpt-clone ########################## # Access key from OpenAI platform. -# Leave it blank to disable this feature. +# Leave it blank to disable this feature. +# Set to "user_provided" to allow the user to provide their API key from the UI. OPENAI_KEY= # Identify the available models, separated by commas *without spaces*. diff --git a/api/app/titleConvo.js b/api/app/titleConvo.js index 15092498e2..b15688f63a 100644 --- a/api/app/titleConvo.js +++ b/api/app/titleConvo.js @@ -17,7 +17,7 @@ const proxyEnvToAxiosProxy = (proxyString) => { return proxyConfig; }; -const titleConvo = async ({ endpoint, text, response }) => { +const titleConvo = async ({ endpoint, text, response, oaiApiKey }) => { let title = 'New Chat'; const ChatGPTClient = (await import('@waylaidwanderer/chatgpt-api')).default; @@ -50,7 +50,7 @@ const titleConvo = async ({ endpoint, text, response }) => { frequency_penalty: 0 }; - let apiKey = process.env.OPENAI_KEY; + let apiKey = oaiApiKey || process.env.OPENAI_KEY; if (azure) { apiKey = process.env.AZURE_OPENAI_API_KEY; diff --git a/api/server/routes/ask/askOpenAI.js b/api/server/routes/ask/askOpenAI.js index c8595b8dbf..38e700db10 100644 --- a/api/server/routes/ask/askOpenAI.js +++ b/api/server/routes/ask/askOpenAI.js @@ -169,12 +169,13 @@ const ask = async ({ }; const abortKey = conversationId; abortControllers.set(abortKey, { abortController, ...endpointOption }); + const oaiApiKey = req.body?.token ?? null; let response = await askClient({ text, parentMessageId: userParentMessageId, conversationId, - oaiApiKey: req.body?.token ?? null, + oaiApiKey, ...endpointOption, onProgress: progressCallback.call(null, { res, @@ -250,7 +251,7 @@ const ask = async ({ res.end(); if (userParentMessageId == '00000000-0000-0000-0000-000000000000') { - const title = await titleConvo({ endpoint: endpointOption?.endpoint, text, response: responseMessage }); + const title = await titleConvo({ endpoint: endpointOption?.endpoint, text, response: responseMessage, oaiApiKey }); await saveConvo(req.user.id, { conversationId: conversationId, title diff --git a/api/server/routes/endpoints.js b/api/server/routes/endpoints.js index 7edc7a4beb..175ae08cc5 100644 --- a/api/server/routes/endpoints.js +++ b/api/server/routes/endpoints.js @@ -38,9 +38,11 @@ router.get('/', async function (req, res) { const google = key || palmUser ? { userProvide: palmUser, availableModels: ['chat-bison', 'text-bison'] } : false; const azureOpenAI = !!process.env.AZURE_OPENAI_KEY; + const apiKey = process.env.OPENAI_KEY || process.env.AZURE_OPENAI_API_KEY; + console.log('API KEY', apiKey); const openAI = - process.env.OPENAI_KEY || process.env.AZURE_OPENAI_API_KEY - ? { availableModels: getOpenAIModels(), userProvide: true } + apiKey + ? { availableModels: getOpenAIModels(), userProvide: apiKey === 'user_provided' } : false; const bingAI = process.env.BINGAI_TOKEN ? { userProvide: process.env.BINGAI_TOKEN == 'user_provided' } @@ -55,4 +57,4 @@ router.get('/', async function (req, res) { res.send(JSON.stringify({ azureOpenAI, openAI, google, bingAI, chatGPTBrowser })); }); -module.exports = { router, getOpenAIModels, getChatGPTBrowserModels }; +module.exports = { router, getOpenAIModels, getChatGPTBrowserModels }; \ No newline at end of file