From dd522eb404a4f03b6f9c2161c8555485f1e55b0d Mon Sep 17 00:00:00 2001 From: ChenZhaoYu <790348264@qq.com> Date: Mon, 13 Feb 2023 15:08:55 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=BB=9F=E4=B8=80=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=AB=AF=E8=BF=94=E5=9B=9E=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- service/src/chatgpt.ts | 64 +++++++++++++++++++++++++++----------- service/src/index.ts | 25 ++++++++++++--- service/src/utils/index.ts | 22 +++++++++++++ 3 files changed, 88 insertions(+), 23 deletions(-) create mode 100644 service/src/utils/index.ts diff --git a/service/src/chatgpt.ts b/service/src/chatgpt.ts index 823324a..43ff8d0 100644 --- a/service/src/chatgpt.ts +++ b/service/src/chatgpt.ts @@ -1,7 +1,9 @@ import * as dotenv from 'dotenv' +import type { SendMessageOptions } from 'chatgpt' import { ChatGPTAPI } from 'chatgpt' +import { sendResponse } from './utils' -interface ChatContext { +export interface ChatContext { conversationId?: string parentMessageId?: string } @@ -22,33 +24,57 @@ const api = new ChatGPTAPI({ apiKey }) async function chatReply(message: string) { if (!message) - return - - // 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 } + return sendResponse({ type: 'fail', message: 'Message is empty' }) + + try { + // Get the last context from the chat context + let options: SendMessageOptions = {} + + const lastContext = Array.from(chatContext).pop() + + if (lastContext) + options = { ...lastContext } + + 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 sendResponse({ type: 'success', data: response }) } + catch (error: any) { + return sendResponse({ type: 'fail', message: error.message }) + } +} + +async function chatReplayOne(message: string, options?: ChatContext) { + if (!message) + return sendResponse({ type: 'fail', message: 'Message is empty' }) - // Send the message to the API - const response = await api.sendMessage(message, { ...options }) + try { + let messageOptions: SendMessageOptions = {} - const { conversationId, id } = response + if (options) { + const { conversationId, parentMessageId } = options + messageOptions = { conversationId, parentMessageId } - // Add the new context to the chat context - if (conversationId && id) - chatContext.add({ conversationId, parentMessageId: id }) + const response = await api.sendMessage(message, { ...messageOptions }) - return response + return sendResponse({ type: 'success', data: response }) + } + } + catch (error: any) { + return sendResponse({ type: 'fail', message: error.message }) + } } async function clearChatContext() { // Clear the chat context chatContext.clear() - return Promise.resolve({ message: 'Chat context cleared' }) + return sendResponse({ type: 'success', message: 'Chat context cleared' }) } -export { chatReply, clearChatContext } +export { chatReply, chatReplayOne, clearChatContext } diff --git a/service/src/index.ts b/service/src/index.ts index d6317b5..91ba3e5 100644 --- a/service/src/index.ts +++ b/service/src/index.ts @@ -1,5 +1,6 @@ import express from 'express' -import { chatReply, clearChatContext } from './chatgpt' +import type { ChatContext } from './chatgpt' +import { chatReplayOne, chatReply, clearChatContext } from './chatgpt' const app = express() @@ -15,9 +16,25 @@ app.all('*', (req, res, next) => { app.listen(3002, () => globalThis.console.log('Server is running on port 3002')) app.post('/chat', async (req, res) => { - const { message } = req.body - const response = await chatReply(message) - res.send(response) + try { + const { prompt } = req.body as { prompt: string } + const response = await chatReply(prompt) + res.send(response) + } + catch (error) { + res.send(error) + } +}) + +app.post('./chatOne', async (req, res) => { + try { + const { prompt, options = {} } = req.body as { prompt: string; options?: ChatContext } + const response = await chatReplayOne(prompt, options) + res.send(response) + } + catch (error) { + res.send(error) + } }) app.post('/clear', async (req, res) => { diff --git a/service/src/utils/index.ts b/service/src/utils/index.ts new file mode 100644 index 0000000..392f9d9 --- /dev/null +++ b/service/src/utils/index.ts @@ -0,0 +1,22 @@ +interface SendResponseOptions { + type: 'success' | 'fail' + message?: string + data?: any +} + +export function sendResponse(options: SendResponseOptions) { + if (options.type === 'success') { + return Promise.resolve({ + message: options.message ?? 'Success', + data: options.data ?? null, + status: options.type, + }) + } + + // eslint-disable-next-line prefer-promise-reject-errors + return Promise.reject({ + message: options.message ?? 'Failed', + data: options.data ?? null, + status: options.type, + }) +}