feat: 支持上下文联想
This commit is contained in:
parent
52bfd15ad8
commit
4b16560958
|
@ -1,19 +1,54 @@
|
||||||
import dotenv from 'dotenv'
|
import dotenv from 'dotenv'
|
||||||
import { ChatGPTAPI } from 'chatgpt'
|
import { ChatGPTAPI } from 'chatgpt'
|
||||||
|
|
||||||
|
interface ChatContext {
|
||||||
|
conversationId?: string
|
||||||
|
parentMessageId?: string
|
||||||
|
}
|
||||||
|
|
||||||
dotenv.config()
|
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<ChatContext>()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* More Info: https://github.com/transitive-bullshit/chatgpt-api
|
* 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) {
|
async function chatReply(message: string) {
|
||||||
if (!message)
|
if (!message)
|
||||||
return
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
export { chatReply }
|
async function clearChatContext() {
|
||||||
|
// Clear the chat context
|
||||||
|
chatContext.clear()
|
||||||
|
return Promise.resolve({ message: 'Chat context cleared' })
|
||||||
|
}
|
||||||
|
|
||||||
|
export { chatReply, clearChatContext }
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import express from 'express'
|
import express from 'express'
|
||||||
import { chatReply } from './chatgpt'
|
import { chatReply, clearChatContext } from './chatgpt'
|
||||||
|
|
||||||
const app = express()
|
const app = express()
|
||||||
|
|
||||||
|
@ -19,3 +19,8 @@ app.post('/chat', async (req, res) => {
|
||||||
const response = await chatReply(message)
|
const response = await chatReply(message)
|
||||||
res.send(response)
|
res.send(response)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
app.post('/clear', async (req, res) => {
|
||||||
|
const response = await clearChatContext()
|
||||||
|
res.send(response)
|
||||||
|
})
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
import { nextTick, onMounted, ref } from 'vue'
|
import { nextTick, onMounted, ref } from 'vue'
|
||||||
import { NButton, NInput, NPopover, useMessage } from 'naive-ui'
|
import { NButton, NInput, NPopover, useMessage } from 'naive-ui'
|
||||||
import { Message } from './components'
|
import { Message } from './components'
|
||||||
import { fetchChatAPI } from './request'
|
import { clearChatContext, fetchChatAPI } from './request'
|
||||||
import { Icon } from '@/components'
|
import { Icon } from '@/components'
|
||||||
|
|
||||||
interface ListProps {
|
interface ListProps {
|
||||||
|
@ -27,9 +27,16 @@ function initChat() {
|
||||||
addMessage('Hi, I am ChatGPT, a chatbot based on GPT-3.', false)
|
addMessage('Hi, I am ChatGPT, a chatbot based on GPT-3.', false)
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleClear() {
|
async function handleClear() {
|
||||||
list.value = []
|
try {
|
||||||
setTimeout(initChat, 100)
|
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) {
|
function handleEnter(event: KeyboardEvent) {
|
||||||
|
@ -81,7 +88,7 @@ function addMessage(message: string, reversal = false) {
|
||||||
<Icon icon="ri:delete-bin-6-line" />
|
<Icon icon="ri:delete-bin-6-line" />
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
<span>Clear</span>
|
<span>Clear Context</span>
|
||||||
</NPopover>
|
</NPopover>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
async function fetchChatAPI(message: string) {
|
const BASE_URL = import.meta.env.VITE_GLOB_API_URL
|
||||||
const url = `${import.meta.env.VITE_GLOB_API_URL}/chat`
|
|
||||||
|
|
||||||
|
async function fetchChatAPI(message: string) {
|
||||||
if (!message || message.trim() === '')
|
if (!message || message.trim() === '')
|
||||||
return
|
return
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { status, data } = await axios.post(url, { message })
|
const { status, data } = await axios.post(`${BASE_URL}/chat`, { message })
|
||||||
|
|
||||||
if (status === 200) {
|
if (status === 200) {
|
||||||
if (data.text)
|
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 }
|
||||||
|
|
Loading…
Reference in New Issue