diff --git a/service/chatgpt.ts b/service/chatgpt.ts index 874d6d75ae..e2cc28c06e 100644 --- a/service/chatgpt.ts +++ b/service/chatgpt.ts @@ -1,19 +1,54 @@ import dotenv from 'dotenv' import { ChatGPTAPI } from 'chatgpt' +interface ChatContext { + conversationId?: string + parentMessageId?: string +} + dotenv.config() -const apiKey = '' +const apiKey = process.env.OPENAI_API_KEY + +if (apiKey === undefined) + throw new Error('OPENAI_API_KEY is not defined') + +const chatContext = new Set() /** * More Info: https://github.com/transitive-bullshit/chatgpt-api */ -const api = new ChatGPTAPI({ apiKey: process.env.OPENAI_API_KEY || apiKey }) +const api = new ChatGPTAPI({ apiKey }) async function chatReply(message: string) { if (!message) return - return await api.sendMessage(message) + + // Get the last context from the chat context + // If there is a last context, add it to the options + let options = {} + const lastContext = Array.from(chatContext).pop() + if (lastContext) { + const { conversationId, parentMessageId } = lastContext + options = { conversationId, parentMessageId } + } + + // Send the message to the API + const response = await api.sendMessage(message, { ...options }) + + const { conversationId, id } = response + + // Add the new context to the chat context + if (conversationId && id) + chatContext.add({ conversationId, parentMessageId: id }) + + return response +} + +async function clearChatContext() { + // Clear the chat context + chatContext.clear() + return Promise.resolve({ message: 'Chat context cleared' }) } -export { chatReply } +export { chatReply, clearChatContext } diff --git a/service/index.ts b/service/index.ts index ce7df19860..d6317b5076 100644 --- a/service/index.ts +++ b/service/index.ts @@ -1,5 +1,5 @@ import express from 'express' -import { chatReply } from './chatgpt' +import { chatReply, clearChatContext } from './chatgpt' const app = express() @@ -19,3 +19,8 @@ app.post('/chat', async (req, res) => { const response = await chatReply(message) res.send(response) }) + +app.post('/clear', async (req, res) => { + const response = await clearChatContext() + res.send(response) +}) diff --git a/src/views/Chat/index.vue b/src/views/Chat/index.vue index e2cd6ec69e..75dd1dc766 100644 --- a/src/views/Chat/index.vue +++ b/src/views/Chat/index.vue @@ -2,7 +2,7 @@ import { nextTick, onMounted, ref } from 'vue' import { NButton, NInput, NPopover, useMessage } from 'naive-ui' import { Message } from './components' -import { fetchChatAPI } from './request' +import { clearChatContext, fetchChatAPI } from './request' import { Icon } from '@/components' interface ListProps { @@ -27,9 +27,16 @@ function initChat() { addMessage('Hi, I am ChatGPT, a chatbot based on GPT-3.', false) } -function handleClear() { - list.value = [] - setTimeout(initChat, 100) +async function handleClear() { + try { + const { message } = await clearChatContext() + ms.success(message) + list.value = [] + setTimeout(initChat, 100) + } + catch (error) { + ms.error('Clear failed, please try again later.') + } } function handleEnter(event: KeyboardEvent) { @@ -81,7 +88,7 @@ function addMessage(message: string, reversal = false) { - Clear + Clear Context diff --git a/src/views/Chat/request.ts b/src/views/Chat/request.ts index b05cb3629b..cc32f56629 100644 --- a/src/views/Chat/request.ts +++ b/src/views/Chat/request.ts @@ -1,13 +1,13 @@ import axios from 'axios' -async function fetchChatAPI(message: string) { - const url = `${import.meta.env.VITE_GLOB_API_URL}/chat` +const BASE_URL = import.meta.env.VITE_GLOB_API_URL +async function fetchChatAPI(message: string) { if (!message || message.trim() === '') return try { - const { status, data } = await axios.post(url, { message }) + const { status, data } = await axios.post(`${BASE_URL}/chat`, { message }) if (status === 200) { if (data.text) @@ -24,4 +24,18 @@ async function fetchChatAPI(message: string) { } } -export { fetchChatAPI } +async function clearChatContext() { + try { + const { status, data } = await axios.post(`${BASE_URL}/clear`) + + if (status === 200) + return Promise.resolve(data) + + return Promise.reject(new Error('Request failed')) + } + catch (error) { + return Promise.reject(error) + } +} + +export { fetchChatAPI, clearChatContext }