feat: 添加角色设定预留API 设定页(#768)

* add systemMessage

* perf: 优化代码和类型

* perf: 补全翻译和为以后做准备

---------

Co-authored-by: ChenZhaoYu <790348264@qq.com>
This commit is contained in:
quzard
2023-03-22 17:47:07 +08:00
committed by GitHub
parent e02ab1fbad
commit 6ecc61ac5d
14 changed files with 160 additions and 22 deletions

View File

@@ -9,6 +9,9 @@ import axios from 'axios'
import { sendResponse } from '../utils'
import { isNotEmptyString } from '../utils/is'
import type { ApiModel, ChatContext, ChatGPTUnofficialProxyAPIOptions, ModelConfig } from '../types'
import type { RequestOptions } from './types'
dotenv.config()
const ErrorCodeMessage: Record<string, string> = {
401: '[OpenAI] 提供错误的API密钥 | Incorrect API key provided',
@@ -19,13 +22,11 @@ const ErrorCodeMessage: Record<string, string> = {
500: '[OpenAI] 服务器繁忙,请稍后再试 | Internal Server Error',
}
dotenv.config()
const timeoutMs: number = !isNaN(+process.env.TIMEOUT_MS) ? +process.env.TIMEOUT_MS : 30 * 1000
let apiModel: ApiModel
if (!process.env.OPENAI_API_KEY && !process.env.OPENAI_ACCESS_TOKEN)
if (!isNotEmptyString(process.env.OPENAI_API_KEY) && !isNotEmptyString(process.env.OPENAI_ACCESS_TOKEN))
throw new Error('Missing OPENAI_API_KEY or OPENAI_ACCESS_TOKEN environment variable')
let api: ChatGPTAPI | ChatGPTUnofficialProxyAPI
@@ -33,7 +34,7 @@ let api: ChatGPTAPI | ChatGPTUnofficialProxyAPI
(async () => {
// More Info: https://github.com/transitive-bullshit/chatgpt-api
if (process.env.OPENAI_API_KEY) {
if (isNotEmptyString(process.env.OPENAI_API_KEY)) {
const OPENAI_API_MODEL = process.env.OPENAI_API_MODEL
const model = isNotEmptyString(OPENAI_API_MODEL) ? OPENAI_API_MODEL : 'gpt-3.5-turbo'
@@ -67,17 +68,19 @@ let api: ChatGPTAPI | ChatGPTUnofficialProxyAPI
}
})()
async function chatReplyProcess(
message: string,
lastContext?: { conversationId?: string; parentMessageId?: string },
process?: (chat: ChatMessage) => void,
) {
async function chatReplyProcess(options: RequestOptions) {
const { message, lastContext, process, systemMessage } = options
try {
let options: SendMessageOptions = { timeoutMs }
if (lastContext) {
if (apiModel === 'ChatGPTAPI') {
if (isNotEmptyString(systemMessage))
options.systemMessage = systemMessage
}
if (lastContext != null) {
if (apiModel === 'ChatGPTAPI')
options = { parentMessageId: lastContext.parentMessageId }
options.parentMessageId = lastContext.parentMessageId
else
options = { ...lastContext }
}

View File

@@ -0,0 +1,8 @@
import type { ChatMessage } from 'chatgpt'
export interface RequestOptions {
message: string
lastContext?: { conversationId?: string; parentMessageId?: string }
process?: (chat: ChatMessage) => void
systemMessage?: string
}

View File

@@ -1,5 +1,6 @@
import express from 'express'
import type { ChatContext, ChatMessage } from './chatgpt'
import type { RequestProps } from './types'
import type { ChatMessage } from './chatgpt'
import { chatConfig, chatReplyProcess, currentModel } from './chatgpt'
import { auth } from './middleware/auth'
import { limiter } from './middleware/limiter'
@@ -22,11 +23,16 @@ router.post('/chat-process', [auth, limiter], async (req, res) => {
res.setHeader('Content-type', 'application/octet-stream')
try {
const { prompt, options = {} } = req.body as { prompt: string; options?: ChatContext }
const { prompt, options = {}, systemMessage } = req.body as RequestProps
let firstChunk = true
await chatReplyProcess(prompt, options, (chat: ChatMessage) => {
res.write(firstChunk ? JSON.stringify(chat) : `\n${JSON.stringify(chat)}`)
firstChunk = false
await chatReplyProcess({
message: prompt,
lastContext: options,
process: (chat: ChatMessage) => {
res.write(firstChunk ? JSON.stringify(chat) : `\n${JSON.stringify(chat)}`)
firstChunk = false
},
systemMessage,
})
}
catch (error) {

View File

@@ -1,5 +1,11 @@
import type { FetchFn } from 'chatgpt'
export interface RequestProps {
prompt: string
options?: ChatContext
systemMessage: string
}
export interface ChatContext {
conversationId?: string
parentMessageId?: string