diff --git a/client/src/api/chat.ts b/client/src/api/chat.ts index fffe7f152..a675cb732 100644 --- a/client/src/api/chat.ts +++ b/client/src/api/chat.ts @@ -22,7 +22,7 @@ export const getChatHistory = (data: RequestPaging & { appId?: string }) => /** * 删除一条历史记录 */ -export const delChatHistoryById = (id: string) => GET(`/chat/removeHistory?id=${id}`); +export const delChatHistoryById = (chatId: string) => DELETE(`/chat/removeHistory`, { chatId }); /** * get history quotes diff --git a/client/src/api/fetch.ts b/client/src/api/fetch.ts index 0255866cb..e5a774a6e 100644 --- a/client/src/api/fetch.ts +++ b/client/src/api/fetch.ts @@ -78,6 +78,7 @@ export const streamFetch = ({ onMessage(answer); responseText += answer; } else if (item.event === sseResponseEventEnum.appStreamResponse) { + console.log(data); } else if (item.event === sseResponseEventEnum.error) { errMsg = getErrText(data, '流响应错误'); } diff --git a/client/src/api/response/chat.d.ts b/client/src/api/response/chat.d.ts index 303b13df4..a371eb4fa 100644 --- a/client/src/api/response/chat.d.ts +++ b/client/src/api/response/chat.d.ts @@ -20,7 +20,6 @@ export interface InitChatResponse { export interface InitShareChatResponse { userAvatar: string; - maxContext: number; app: { variableModules?: VariableItemType[]; welcomeText?: string; diff --git a/client/src/components/ChatBox/index.tsx b/client/src/components/ChatBox/index.tsx index b39fa71ad..ab74ba60e 100644 --- a/client/src/components/ChatBox/index.tsx +++ b/client/src/components/ChatBox/index.tsx @@ -19,7 +19,6 @@ import { getErrText } from '@/utils/tools'; import { Box, Card, Flex, Input, Textarea, Button, useTheme } from '@chakra-ui/react'; -import { useUserStore } from '@/store/user'; import { feConfigs } from '@/store/static'; import { Types } from 'mongoose'; import { EventNameEnum } from '../Markdown/constant'; @@ -118,6 +117,7 @@ const ChatBox = ( showEmptyIntro = false, chatId, appAvatar, + userAvatar, variableModules, welcomeText, onUpdateVariable, @@ -126,7 +126,8 @@ const ChatBox = ( }: { showEmptyIntro?: boolean; chatId?: string; - appAvatar: string; + appAvatar?: string; + userAvatar?: string; variableModules?: VariableItemType[]; welcomeText?: string; onUpdateVariable?: (e: Record) => void; @@ -142,7 +143,6 @@ const ChatBox = ( const router = useRouter(); const { copyData } = useCopyData(); const { toast } = useToast(); - const { userInfo } = useUserStore(); const { isPc } = useGlobalStore(); const TextareaDom = useRef(null); const controller = useRef(new AbortController()); @@ -585,7 +585,7 @@ const ChatBox = ( )} - + )} {item.obj === 'AI' && ( diff --git a/client/src/pages/api/admin/initChat.ts b/client/src/pages/api/admin/initChat.ts new file mode 100644 index 000000000..9d3e53687 --- /dev/null +++ b/client/src/pages/api/admin/initChat.ts @@ -0,0 +1,61 @@ +// Next.js API route support: https://nextjs.org/docs/api-routes/introduction +import type { NextApiRequest, NextApiResponse } from 'next'; +import { jsonRes } from '@/service/response'; +import { authUser } from '@/service/utils/auth'; +import { connectToDatabase, TrainingData, User, promotionRecord, Chat } from '@/service/mongo'; +import { PRICE_SCALE } from '@/constants/common'; + +export default async function handler(req: NextApiRequest, res: NextApiResponse) { + try { + await authUser({ req, authRoot: true }); + await connectToDatabase(); + + const { limit = 1000 } = req.body as { limit: number }; + let skip = 0; + const total = await Chat.countDocuments({ + chatId: { $exists: false } + }); + let promise = Promise.resolve(); + console.log(total); + + for (let i = 0; i < total; i += limit) { + const skipVal = skip; + skip += limit; + promise = promise + .then(() => init(limit, skipVal)) + .then(() => { + console.log(skipVal); + }); + } + + await promise; + + jsonRes(res, {}); + } catch (error) { + jsonRes(res, { + code: 500, + error + }); + } +} + +async function init(limit: number, skip: number) { + // 遍历 app + const chats = await Chat.find( + { + chatId: { $exists: false } + }, + '_id' + ) + .limit(limit) + .skip(skip); + + await Promise.all( + chats.map((chat) => + Chat.findByIdAndUpdate(chat._id, { + chatId: String(chat._id), + source: 'online' + }) + ) + ); +} diff --git a/client/src/pages/api/admin/initPromotion.ts b/client/src/pages/api/admin/initPromotion.ts deleted file mode 100644 index c9ce5049d..000000000 --- a/client/src/pages/api/admin/initPromotion.ts +++ /dev/null @@ -1,47 +0,0 @@ -// Next.js API route support: https://nextjs.org/docs/api-routes/introduction -import type { NextApiRequest, NextApiResponse } from 'next'; -import { jsonRes } from '@/service/response'; -import { authUser } from '@/service/utils/auth'; -import { connectToDatabase, TrainingData, User, promotionRecord } from '@/service/mongo'; -import { PRICE_SCALE } from '@/constants/common'; - -export default async function handler(req: NextApiRequest, res: NextApiResponse) { - try { - await authUser({ req, authRoot: true }); - await connectToDatabase(); - - // 计算剩余金额 - const countResidue: { userId: string; totalAmount: number }[] = await promotionRecord.aggregate( - [ - { - $group: { - _id: '$userId', // Group by userId - totalAmount: { $sum: '$amount' } // Calculate the sum of amount field - } - }, - { - $project: { - _id: false, // Exclude _id field - userId: '$_id', // Include userId field - totalAmount: true // Include totalAmount field - } - } - ] - ); - - await Promise.all( - countResidue.map((item) => - User.findByIdAndUpdate(item.userId, { - $inc: { balance: item.totalAmount * PRICE_SCALE } - }) - ) - ); - - jsonRes(res, { data: countResidue }); - } catch (error) { - jsonRes(res, { - code: 500, - error - }); - } -} diff --git a/client/src/pages/api/chat/delChatRecordByContentId.ts b/client/src/pages/api/chat/delChatRecordByContentId.ts index 40a4ca329..2b7402f27 100644 --- a/client/src/pages/api/chat/delChatRecordByContentId.ts +++ b/client/src/pages/api/chat/delChatRecordByContentId.ts @@ -16,7 +16,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) // 凭证校验 const { userId } = await authUser({ req, authToken: true }); - const chatRecord = await Chat.findById(chatId); + const chatRecord = await Chat.findOne({ chatId }); if (!chatRecord) { throw new Error('找不到对话'); diff --git a/client/src/pages/api/chat/history/getHistory.ts b/client/src/pages/api/chat/history/getHistory.ts index 90ec90a34..e2af65df3 100644 --- a/client/src/pages/api/chat/history/getHistory.ts +++ b/client/src/pages/api/chat/history/getHistory.ts @@ -17,14 +17,14 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) userId, ...(appId && { appId }) }, - '_id title top customTitle appId updateTime' + 'chatId title top customTitle appId updateTime' ) .sort({ top: -1, updateTime: -1 }) .limit(20); jsonRes(res, { data: data.map((item) => ({ - _id: item._id, + chatId: item.chatId, updateTime: item.updateTime, appId: item.appId, customTitle: item.customTitle, diff --git a/client/src/pages/api/chat/history/getHistoryQuote.ts b/client/src/pages/api/chat/history/getHistoryQuote.ts index 18571a071..6d799c884 100644 --- a/client/src/pages/api/chat/history/getHistoryQuote.ts +++ b/client/src/pages/api/chat/history/getHistoryQuote.ts @@ -3,7 +3,6 @@ import { jsonRes } from '@/service/response'; import { connectToDatabase, Chat } from '@/service/mongo'; import { authUser } from '@/service/utils/auth'; import { Types } from 'mongoose'; -import { rawSearchKey } from '@/constants/chat'; export default async function handler(req: NextApiRequest, res: NextApiResponse) { try { @@ -36,13 +35,13 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) }, { $project: { - [rawSearchKey]: `$content.${rawSearchKey}` + // [rawSearchKey]: `$content.${rawSearchKey}` } } ]); jsonRes(res, { - data: history[0]?.[rawSearchKey] || [] + // data: history[0]?.[rawSearchKey] || [] }); } catch (err) { jsonRes(res, { diff --git a/client/src/pages/api/chat/history/updateChatHistory.ts b/client/src/pages/api/chat/history/updateChatHistory.ts index 7c5595314..f9af33ee9 100644 --- a/client/src/pages/api/chat/history/updateChatHistory.ts +++ b/client/src/pages/api/chat/history/updateChatHistory.ts @@ -20,7 +20,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) await Chat.findOneAndUpdate( { - _id: chatId, + chatId, userId }, { diff --git a/client/src/pages/api/chat/history/updateHistoryQuote.ts b/client/src/pages/api/chat/history/updateHistoryQuote.ts index 65dcc9ae3..973d79c19 100644 --- a/client/src/pages/api/chat/history/updateHistoryQuote.ts +++ b/client/src/pages/api/chat/history/updateHistoryQuote.ts @@ -27,7 +27,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) await Chat.updateOne( { - _id: new Types.ObjectId(chatId), + chatId, userId: new Types.ObjectId(userId), 'content._id': new Types.ObjectId(contentId) }, diff --git a/client/src/pages/api/chat/init.ts b/client/src/pages/api/chat/init.ts index fa9b8e8aa..348c499dd 100644 --- a/client/src/pages/api/chat/init.ts +++ b/client/src/pages/api/chat/init.ts @@ -6,8 +6,7 @@ import { authUser } from '@/service/utils/auth'; import { ChatItemType } from '@/types/chat'; import { authApp } from '@/service/utils/auth'; import mongoose from 'mongoose'; -import type { AppSchema, ChatSchema } from '@/types/mongoSchema'; -import { quoteLenKey, rawSearchKey } from '@/constants/chat'; +import type { ChatSchema } from '@/types/mongoSchema'; import { getSpecialModule } from '@/components/ChatBox'; /* 初始化我的聊天框,需要身份验证 */ @@ -20,72 +19,62 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) chatId: '' | string; }; + if (!appId) { + return jsonRes(res, { + code: 501, + message: "You don't have an app yet" + }); + } + await connectToDatabase(); - // 没有 appId 时,直接获取用户的第一个id - const app = await (async () => { - if (!appId) { - const myModel = await App.findOne({ userId }); - if (!myModel) { - const { _id } = await App.create({ - name: '应用1', - userId - }); - return (await App.findById(_id)) as AppSchema; - } else { - return myModel; - } - } else { - // 校验使用权限 - const authRes = await authApp({ - appId, - userId, - authUser: false, - authOwner: false - }); - return authRes.app; - } - })(); - - appId = appId || app._id; + // 校验使用权限 + const app = ( + await authApp({ + appId, + userId, + authUser: false, + authOwner: false + }) + ).app; // 历史记录 const { chat, history = [] }: { chat?: ChatSchema; history?: ChatItemType[] } = await (async () => { if (chatId) { // auth chatId - const chat = await Chat.findOne({ - _id: chatId, - userId - }); + const [chat, history] = await Promise.all([ + Chat.findOne({ + chatId, + userId + }), + Chat.aggregate([ + { + $match: { + chatId, + userId: new mongoose.Types.ObjectId(userId) + } + }, + { + $project: { + content: { + $slice: ['$content', -50] // 返回 content 数组的最后50个元素 + } + } + }, + { $unwind: '$content' }, + { + $project: { + _id: '$content._id', + obj: '$content.obj', + value: '$content.value' + } + } + ]) + ]); if (!chat) { throw new Error('聊天框不存在'); } - // 获取 chat.content 数据 - const history = await Chat.aggregate([ - { - $match: { - _id: new mongoose.Types.ObjectId(chatId), - userId: new mongoose.Types.ObjectId(userId) - } - }, - { - $project: { - content: { - $slice: ['$content', -50] // 返回 content 数组的最后50个元素 - } - } - }, - { $unwind: '$content' }, - { - $project: { - _id: '$content._id', - obj: '$content.obj', - value: '$content.value', - [quoteLenKey]: { $size: { $ifNull: [`$content.${rawSearchKey}`, []] } } - } - } - ]); return { history, chat }; } return {}; diff --git a/client/src/pages/api/chat/removeHistory.ts b/client/src/pages/api/chat/removeHistory.ts index 08dd31aa0..2b440a91f 100644 --- a/client/src/pages/api/chat/removeHistory.ts +++ b/client/src/pages/api/chat/removeHistory.ts @@ -6,13 +6,13 @@ import { authUser } from '@/service/utils/auth'; /* 获取历史记录 */ export default async function handler(req: NextApiRequest, res: NextApiResponse) { try { - const { id } = req.query; + const { chatId } = req.query; const { userId } = await authUser({ req, authToken: true }); await connectToDatabase(); await Chat.findOneAndRemove({ - _id: id, + chatId, userId }); diff --git a/client/src/pages/api/chat/saveChat.ts b/client/src/pages/api/chat/saveChat.ts deleted file mode 100644 index 35e94957d..000000000 --- a/client/src/pages/api/chat/saveChat.ts +++ /dev/null @@ -1,104 +0,0 @@ -import type { NextApiRequest, NextApiResponse } from 'next'; -import { jsonRes } from '@/service/response'; -import { ChatItemType } from '@/types/chat'; -import { connectToDatabase, Chat, App } from '@/service/mongo'; -import { authApp } from '@/service/utils/auth'; -import { authUser } from '@/service/utils/auth'; -import { Types } from 'mongoose'; - -type Props = { - chatId?: string; - appId: string; - variables?: Record; - prompts: [ChatItemType, ChatItemType]; -}; - -/* 聊天内容存存储 */ -export default async function handler(req: NextApiRequest, res: NextApiResponse) { - try { - const { chatId, appId, prompts } = req.body as Props; - - if (!prompts) { - throw new Error('缺少参数'); - } - - const { userId } = await authUser({ req, authToken: true }); - - const response = await saveChat({ - chatId, - appId, - prompts, - userId - }); - - jsonRes(res, { - data: response - }); - } catch (err) { - jsonRes(res, { - code: 500, - error: err - }); - } -} - -export async function saveChat({ - newChatId, - chatId, - appId, - prompts, - variables, - userId -}: Props & { newChatId?: Types.ObjectId; userId: string }): Promise<{ newChatId: string }> { - await connectToDatabase(); - const { app } = await authApp({ appId, userId, authOwner: false }); - - if (String(app.userId) === userId) { - await App.findByIdAndUpdate(appId, { - updateTime: new Date() - }); - } - - const [response] = await Promise.all([ - ...(chatId - ? [ - Chat.findByIdAndUpdate(chatId, { - $push: { - content: { - $each: prompts - } - }, - variables, - title: prompts[0].value.slice(0, 20), - updateTime: new Date() - }).then(() => ({ - newChatId: '' - })) - ] - : [ - Chat.create({ - _id: newChatId, - userId, - appId, - variables, - content: prompts, - title: prompts[0].value.slice(0, 20) - }).then((res) => ({ - newChatId: String(res._id) - })) - ]), - // update app - ...(String(app.userId) === userId - ? [ - App.findByIdAndUpdate(appId, { - updateTime: new Date() - }) - ] - : []) - ]); - - return { - // @ts-ignore - newChatId: response?.newChatId || '' - }; -} diff --git a/client/src/pages/api/chat/shareChat/create.ts b/client/src/pages/api/chat/shareChat/create.ts index 0f3935038..5a9c17302 100644 --- a/client/src/pages/api/chat/shareChat/create.ts +++ b/client/src/pages/api/chat/shareChat/create.ts @@ -9,7 +9,7 @@ const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 24); /* create a shareChat */ export default async function handler(req: NextApiRequest, res: NextApiResponse) { try { - const { appId, name, maxContext } = req.body as ShareChatEditType & { + const { appId, name } = req.body as ShareChatEditType & { appId: string; }; @@ -27,8 +27,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) shareId, userId, appId, - name, - maxContext + name }); jsonRes(res, { diff --git a/client/src/pages/api/chat/shareChat/init.ts b/client/src/pages/api/chat/shareChat/init.ts index 4043db705..0b43551b6 100644 --- a/client/src/pages/api/chat/shareChat/init.ts +++ b/client/src/pages/api/chat/shareChat/init.ts @@ -3,10 +3,7 @@ import { jsonRes } from '@/service/response'; import { connectToDatabase, ShareChat, User } from '@/service/mongo'; import type { InitShareChatResponse } from '@/api/response/chat'; import { authApp } from '@/service/utils/auth'; -import { hashPassword } from '@/service/utils/tools'; import { HUMAN_ICON } from '@/constants/chat'; -import { FlowModuleTypeEnum } from '@/constants/flow'; -import { SystemInputEnum } from '@/constants/app'; import { getSpecialModule } from '@/components/ChatBox'; /* 初始化我的聊天框,需要身份验证 */ @@ -33,21 +30,18 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) } // 校验使用权限 - const { app } = await authApp({ - appId: shareChat.appId, - userId: String(shareChat.userId), - authOwner: false - }); - - const user = await User.findById(shareChat.userId, 'avatar'); + const [{ app }, user] = await Promise.all([ + authApp({ + appId: shareChat.appId, + userId: String(shareChat.userId), + authOwner: false + }), + User.findById(shareChat.userId, 'avatar') + ]); jsonRes(res, { data: { userAvatar: user?.avatar || HUMAN_ICON, - maxContext: - app.modules - ?.find((item) => item.flowType === FlowModuleTypeEnum.historyNode) - ?.inputs?.find((item) => item.key === 'maxContext')?.value || 0, app: { ...getSpecialModule(app.modules), name: app.name, diff --git a/client/src/pages/api/chat/shareChat/list.ts b/client/src/pages/api/chat/shareChat/list.ts index 80e36c00c..ba44729da 100644 --- a/client/src/pages/api/chat/shareChat/list.ts +++ b/client/src/pages/api/chat/shareChat/list.ts @@ -28,7 +28,6 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) shareId: item.shareId, name: item.name, total: item.total, - maxContext: item.maxContext, lastTime: item.lastTime })) }); diff --git a/client/src/pages/api/openapi/v1/chat/completions.ts b/client/src/pages/api/openapi/v1/chat/completions.ts index b1f5e5136..1b9f78bff 100644 --- a/client/src/pages/api/openapi/v1/chat/completions.ts +++ b/client/src/pages/api/openapi/v1/chat/completions.ts @@ -3,7 +3,7 @@ import { connectToDatabase } from '@/service/mongo'; import { authUser, authApp, authShareChat } from '@/service/utils/auth'; import { sseErrRes, jsonRes } from '@/service/response'; import { withNextCors } from '@/service/utils/tools'; -import { ChatRoleEnum, sseResponseEventEnum } from '@/constants/chat'; +import { ChatRoleEnum, ChatSourceEnum, sseResponseEventEnum } from '@/constants/chat'; import { dispatchHistory, dispatchChatInput, @@ -15,12 +15,11 @@ import { import type { CreateChatCompletionRequest } from 'openai'; import { gptMessage2ChatType } from '@/utils/adapt'; import { getChatHistory } from './getHistory'; -import { saveChat } from '@/pages/api/chat/saveChat'; +import { saveChat } from '@/service/utils/chat/saveChat'; import { sseResponse } from '@/service/utils/tools'; import { type ChatCompletionRequestMessage } from 'openai'; import { TaskResponseKeyEnum } from '@/constants/chat'; import { FlowModuleTypeEnum, initModuleType } from '@/constants/flow'; -import { Types } from 'mongoose'; import { AppModuleItemType, RunningModuleItemType } from '@/types/app'; import { pushTaskBill } from '@/service/events/pushBill'; import { BillSourceEnum } from '@/constants/user'; @@ -101,16 +100,10 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex } // user question const prompt = prompts.pop(); - if (!prompt) { throw new Error('Question is empty'); } - const newChatId = chatId === '' ? new Types.ObjectId() : undefined; - if (stream && newChatId) { - res.setHeader('newChatId', String(newChatId)); - } - /* start process */ const { responseData, answerText } = await dispatchModules({ res, @@ -122,29 +115,39 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex }, stream }); - console.log(responseData, '===', answerText); + // console.log(responseData, '===', answerText); - if (!answerText) { - throw new Error('回复内容为空,可能模块编排出现问题'); - } + // if (!answerText) { + // throw new Error('回复内容为空,可能模块编排出现问题'); + // } // save chat if (typeof chatId === 'string') { await saveChat({ chatId, - newChatId, appId, + userId, variables, - prompts: [ + isOwner, + shareId, + source: (() => { + if (shareId) { + return ChatSourceEnum.share; + } + if (authType === 'apikey') { + return ChatSourceEnum.api; + } + return ChatSourceEnum.online; + })(), + content: [ prompt, { _id: messages[messages.length - 1]._id, obj: ChatRoleEnum.AI, value: answerText, - ...responseData + responseData } - ], - userId + ] }); } diff --git a/client/src/pages/api/openapi/v1/chat/getHistory.ts b/client/src/pages/api/openapi/v1/chat/getHistory.ts index 2531f4b8b..f487aeaf8 100644 --- a/client/src/pages/api/openapi/v1/chat/getHistory.ts +++ b/client/src/pages/api/openapi/v1/chat/getHistory.ts @@ -43,7 +43,7 @@ export async function getChatHistory({ } const history = await Chat.aggregate([ - { $match: { _id: new Types.ObjectId(chatId), userId: new Types.ObjectId(userId) } }, + { $match: { chatId, userId: new Types.ObjectId(userId) } }, { $project: { content: { @@ -54,10 +54,8 @@ export async function getChatHistory({ { $unwind: '$content' }, { $project: { - _id: '$content._id', obj: '$content.obj', - value: '$content.value', - quote: '$content.quote' + value: '$content.value' } } ]); diff --git a/client/src/pages/api/system/getInitData.ts b/client/src/pages/api/system/getInitData.ts index 3d2854a0a..eba6f298c 100644 --- a/client/src/pages/api/system/getInitData.ts +++ b/client/src/pages/api/system/getInitData.ts @@ -42,6 +42,66 @@ export async function getInitConfig() { global.qaModels = res.QAModels; global.vectorModels = res.VectorModels; } catch (error) { + setDefaultData(); return Promise.reject('get init config error'); } } + +export function setDefaultData() { + global.systemEnv = { + vectorMaxProcess: 15, + qaMaxProcess: 15, + pgIvfflatProbe: 20, + sensitiveCheck: false + }; + global.feConfigs = { + show_emptyChat: true, + show_register: true, + show_appStore: true, + show_userDetail: true, + show_git: true, + systemTitle: 'FastAI', + authorText: 'Made by FastAI Team.' + }; + global.chatModels = [ + { + model: 'gpt-3.5-turbo', + name: 'FastAI-4k', + contextMaxToken: 4000, + systemMaxToken: 2400, + maxTemperature: 1.2, + price: 1.5 + }, + { + model: 'gpt-3.5-turbo-16k', + name: 'FastAI-16k', + contextMaxToken: 16000, + systemMaxToken: 8000, + maxTemperature: 1.2, + price: 3 + }, + { + model: 'gpt-4', + name: 'FastAI-Plus', + contextMaxToken: 8000, + systemMaxToken: 4000, + maxTemperature: 1.2, + price: 45 + } + ]; + global.qaModels = [ + { + model: 'gpt-3.5-turbo-16k', + name: 'FastAI-16k', + maxToken: 16000, + price: 3 + } + ]; + global.vectorModels = [ + { + model: 'text-embedding-ada-002', + name: 'Embedding-2', + price: 0.2 + } + ]; +} diff --git a/client/src/pages/app/detail/components/BasicEdit/index.tsx b/client/src/pages/app/detail/components/BasicEdit/index.tsx index 58eaa5a0e..5d3edad49 100644 --- a/client/src/pages/app/detail/components/BasicEdit/index.tsx +++ b/client/src/pages/app/detail/components/BasicEdit/index.tsx @@ -441,7 +441,7 @@ const Settings = ({ appId }: { appId: string }) => { }; const ChatTest = ({ appId }: { appId: string }) => { - const { appDetail } = useUserStore(); + const { appDetail, userInfo } = useUserStore(); const ChatBoxRef = useRef(null); const [modules, setModules] = useState([]); @@ -509,6 +509,7 @@ const ChatTest = ({ appId }: { appId: string }) => { {}} diff --git a/client/src/pages/app/detail/components/Edit/components/ChatTest.tsx b/client/src/pages/app/detail/components/Edit/components/ChatTest.tsx index 8b73c2122..09c83ad96 100644 --- a/client/src/pages/app/detail/components/Edit/components/ChatTest.tsx +++ b/client/src/pages/app/detail/components/Edit/components/ChatTest.tsx @@ -13,6 +13,7 @@ import MyIcon from '@/components/Icon'; import { FlowModuleTypeEnum } from '@/constants/flow'; import { streamFetch } from '@/api/fetch'; import MyTooltip from '@/components/MyTooltip'; +import { useUserStore } from '@/store/user'; import ChatBox, { getSpecialModule, type ComponentRef, @@ -36,6 +37,7 @@ const ChatTest = ( ref: ForwardedRef ) => { const ChatBoxRef = useRef(null); + const { userInfo } = useUserStore(); const isOpen = useMemo(() => modules && modules.length > 0, [modules]); const startChat = useCallback( @@ -47,7 +49,7 @@ const ChatTest = ( const history = messages.slice(-historyMaxLen - 2, -2); // 流请求,获取数据 - const { responseText, rawSearch } = await streamFetch({ + const { responseText } = await streamFetch({ url: '/api/chat/chatTest', data: { history, @@ -61,7 +63,7 @@ const ChatTest = ( abortSignal: controller }); - return { responseText, rawSearch }; + return { responseText }; }, [app._id, app.name, modules] ); @@ -113,6 +115,7 @@ const ChatTest = ( {}} diff --git a/client/src/pages/chat/index.tsx b/client/src/pages/chat/index.tsx index ddccbabc4..359331450 100644 --- a/client/src/pages/chat/index.tsx +++ b/client/src/pages/chat/index.tsx @@ -15,19 +15,24 @@ import { useQuery } from '@tanstack/react-query'; import { streamFetch } from '@/api/fetch'; import { useChatStore } from '@/store/chat'; import { useLoading } from '@/hooks/useLoading'; +import { useToast } from '@/hooks/useToast'; +import { customAlphabet } from 'nanoid'; +const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 12); +import type { ChatHistoryItemType } from '@/types/chat'; import ChatBox, { type ComponentRef, type StartChatFnProps } from '@/components/ChatBox'; -import { ChatHistoryItemType } from '@/types/chat'; import PageContainer from '@/components/PageContainer'; import SideBar from '@/components/SideBar'; import ChatHistorySlider from './components/ChatHistorySlider'; import SliderApps from './components/SliderApps'; import ChatHeader from './components/ChatHeader'; +import { getErrText } from '@/utils/tools'; +import { useUserStore } from '@/store/user'; -const Chat = () => { +const Chat = ({ appId, chatId }: { appId: string; chatId: string }) => { const router = useRouter(); - const { appId = '', chatId = '' } = router.query as { appId: string; chatId: string }; const theme = useTheme(); + const { toast } = useToast(); const ChatBoxRef = useRef(null); const forbidRefresh = useRef(false); @@ -44,6 +49,7 @@ const Chat = () => { chatData, setChatData } = useChatStore(); + const { myApps, userInfo } = useUserStore(); const { isPc } = useGlobalStore(); const { Loading, setIsLoading } = useLoading(); @@ -52,12 +58,14 @@ const Chat = () => { const startChat = useCallback( async ({ messages, controller, generatingMessage, variables }: StartChatFnProps) => { const prompts = messages.slice(-2); - const { responseText, newChatId, rawSearch } = await streamFetch({ + const completionChatId = chatId ? chatId : nanoid(); + + const { responseText } = await streamFetch({ data: { messages: prompts, variables, appId, - chatId + chatId: completionChatId }, onMessage: generatingMessage, abortSignal: controller @@ -66,10 +74,10 @@ const Chat = () => { const newTitle = prompts[0].content?.slice(0, 20) || '新对话'; // update history - if (newChatId && !controller.signal.aborted) { + if (completionChatId !== chatId && !controller.signal.aborted) { forbidRefresh.current = true; const newHistory: ChatHistoryItemType = { - _id: newChatId, + chatId: completionChatId, updateTime: new Date(), title: newTitle, appId, @@ -78,12 +86,12 @@ const Chat = () => { updateHistory(newHistory); router.replace({ query: { - chatId: newChatId, + chatId: completionChatId, appId } }); } else { - const currentChat = history.find((item) => item._id === chatId); + const currentChat = history.find((item) => item.chatId === chatId); currentChat && updateHistory({ ...currentChat, @@ -98,7 +106,7 @@ const Chat = () => { history: ChatBoxRef.current?.getChatHistory() || state.history })); - return { responseText, rawSearch }; + return { responseText }; }, [appId, chatId, history, router, setChatData, updateHistory] ); @@ -153,38 +161,43 @@ const Chat = () => { ChatBoxRef.current?.scrollToBottom('auto'); }, 200); } - - // empty appId request, return first app - if (res.appId !== appId) { - forbidRefresh.current = true; - router.replace({ - query: { - appId: res.appId - } - }); - } } catch (e: any) { // reset all chat tore setLastChatAppId(''); setLastChatId(''); - router.replace('/chat'); + toast({ + title: getErrText(e, '初始化聊天失败'), + status: 'error' + }); + if (e?.code === 501) { + router.replace('/app/list'); + } else { + router.replace('/chat'); + } } setIsLoading(false); return null; }, - [setIsLoading, setChatData, router, setLastChatAppId, setLastChatId] + [setIsLoading, setChatData, router, setLastChatAppId, setLastChatId, toast] ); // 初始化聊天框 useQuery(['init', appId, chatId], () => { // pc: redirect to latest model chat if (!appId && lastChatAppId) { - router.replace({ + return router.replace({ query: { appId: lastChatAppId, chatId: lastChatId } }); - return null; + } + if (!appId && myApps[0]) { + return router.replace({ + query: { + appId: myApps[0]._id, + chatId: lastChatId + } + }); } // store id @@ -196,11 +209,15 @@ const Chat = () => { return null; } - return loadChatInfo({ - appId, - chatId, - loading: appId !== chatData.appId - }); + if (appId) { + return loadChatInfo({ + appId, + chatId, + loading: appId !== chatData.appId + }); + } + + return null; }); useQuery(['loadHistory', appId], () => (appId ? loadHistory({ appId }) : null)); @@ -233,7 +250,7 @@ const Chat = () => { appAvatar={chatData.app.avatar} activeChatId={chatId} history={history.map((item) => ({ - id: item._id, + id: item.chatId, title: item.title, customTitle: item.customTitle, top: item.top @@ -253,7 +270,7 @@ const Chat = () => { onSetHistoryTop={async (e) => { try { await putChatHistory(e); - const historyItem = history.find((item) => item._id === e.chatId); + const historyItem = history.find((item) => item.chatId === e.chatId); if (!historyItem) return; updateHistory({ ...historyItem, @@ -267,7 +284,7 @@ const Chat = () => { chatId: e.chatId, customTitle: e.title }); - const historyItem = history.find((item) => item._id === e.chatId); + const historyItem = history.find((item) => item.chatId === e.chatId); if (!historyItem) return; updateHistory({ ...historyItem, @@ -300,6 +317,7 @@ const Chat = () => { showEmptyIntro chatId={chatId} appAvatar={chatData.app.avatar} + userAvatar={userInfo?.avatar} variableModules={chatData.app.variableModules} welcomeText={chatData.app.welcomeText} onUpdateVariable={(e) => {}} @@ -315,4 +333,13 @@ const Chat = () => { ); }; +export async function getServerSideProps(context: any) { + return { + props: { + appId: context?.query?.appId || '', + chatId: context?.query?.chatId || '' + } + }; +} + export default Chat; diff --git a/client/src/pages/chat/share.tsx b/client/src/pages/chat/share.tsx index 4c5feee04..0404fc0c7 100644 --- a/client/src/pages/chat/share.tsx +++ b/client/src/pages/chat/share.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect, useRef } from 'react'; +import React, { useCallback, useMemo, useRef } from 'react'; import { useRouter } from 'next/router'; import { initShareChatInfo } from '@/api/chat'; import { Box, Flex, useDisclosure, Drawer, DrawerOverlay, DrawerContent } from '@chakra-ui/react'; @@ -10,14 +10,14 @@ import { useShareChatStore, defaultHistory } from '@/store/shareChat'; import SideBar from '@/components/SideBar'; import { gptMessage2ChatType } from '@/utils/adapt'; import { getErrText } from '@/utils/tools'; -import dynamic from 'next/dynamic'; +import { ChatSiteItemType } from '@/types/chat'; +import { customAlphabet } from 'nanoid'; +const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 12); + import ChatBox, { type ComponentRef, type StartChatFnProps } from '@/components/ChatBox'; import PageContainer from '@/components/PageContainer'; import ChatHeader from './components/ChatHeader'; - -const ChatHistorySlider = dynamic(() => import('./components/ChatHistorySlider'), { - ssr: false -}); +import ChatHistorySlider from './components/ChatHistorySlider'; const ShareChat = ({ shareId, chatId }: { shareId: string; chatId: string }) => { const router = useRouter(); @@ -36,44 +36,46 @@ const ShareChat = ({ shareId, chatId }: { shareId: string; chatId: string }) => delOneShareHistoryByChatId, delManyShareChatHistoryByShareId } = useShareChatStore(); + const history = useMemo( + () => shareChatHistory.filter((item) => item.shareId === shareId), + [shareChatHistory, shareId] + ); const startChat = useCallback( async ({ messages, controller, generatingMessage, variables }: StartChatFnProps) => { - const prompts = messages.slice(-shareChatData.maxContext - 2); + const prompts = messages.slice(-2); + const completionChatId = chatId ? chatId : nanoid(); + const { responseText } = await streamFetch({ data: { - history, messages: prompts, variables, - shareId + shareId, + chatId: completionChatId }, onMessage: generatingMessage, abortSignal: controller }); - const result = { - question: messages[messages.length - 2].content || '', - answer: responseText - }; - - prompts[prompts.length - 1].content = responseText; + const result: ChatSiteItemType[] = gptMessage2ChatType(prompts).map((item) => ({ + ...item, + status: 'finish' + })); + result[1].value = responseText; /* save chat */ - const { newChatId } = saveChatResponse({ - chatId, - prompts: gptMessage2ChatType(prompts).map((item) => ({ - ...item, - status: 'finish' - })), + saveChatResponse({ + chatId: completionChatId, + prompts: result, variables, shareId }); - if (newChatId && !controller.signal.aborted) { + if (completionChatId !== chatId && !controller.signal.aborted) { router.replace({ query: { shareId, - chatId: newChatId + chatId: completionChatId } }); } @@ -81,14 +83,17 @@ const ShareChat = ({ shareId, chatId }: { shareId: string; chatId: string }) => window.top?.postMessage( { type: 'shareChatFinish', - data: result + data: { + question: result[0]?.value, + answer: result[1]?.value + } }, '*' ); return { responseText }; }, - [chatId, router, saveChatResponse, shareChatData.maxContext, shareId] + [chatId, router, saveChatResponse, shareId] ); const loadAppInfo = useCallback( @@ -96,7 +101,7 @@ const ShareChat = ({ shareId, chatId }: { shareId: string; chatId: string }) => console.log(shareId, chatId); if (!shareId) return null; - const history = shareChatHistory.find((item) => item._id === chatId) || defaultHistory; + const history = shareChatHistory.find((item) => item.chatId === chatId) || defaultHistory; ChatBoxRef.current?.resetHistory(history.chats); ChatBoxRef.current?.resetVariables(history.variables); @@ -157,11 +162,13 @@ const ShareChat = ({ shareId, chatId }: { shareId: string; chatId: string }) => appName={shareChatData.app.name} appAvatar={shareChatData.app.avatar} activeChatId={chatId} - history={shareChatHistory.map((item) => ({ - id: item._id, + history={history.map((item) => ({ + id: item.chatId, title: item.title }))} onChangeChat={(chatId) => { + console.log(chatId); + router.push({ query: { chatId: chatId || '', @@ -196,6 +203,7 @@ const ShareChat = ({ shareId, chatId }: { shareId: string; chatId: string }) => { diff --git a/client/src/pages/number/index.tsx b/client/src/pages/number/index.tsx index e813ead85..dbde3208b 100644 --- a/client/src/pages/number/index.tsx +++ b/client/src/pages/number/index.tsx @@ -4,13 +4,12 @@ import { useGlobalStore } from '@/store/global'; import { useRouter } from 'next/router'; import dynamic from 'next/dynamic'; import { clearCookie } from '@/utils/user'; - +import { useUserStore } from '@/store/user'; +import { useConfirm } from '@/hooks/useConfirm'; import PageContainer from '@/components/PageContainer'; import SideTabs from '@/components/SideTabs'; - import Tabs from '@/components/Tabs'; import UserInfo from './components/Info'; -import { useUserStore } from '@/store/user'; const BillTable = dynamic(() => import('./components/BillTable'), { ssr: false @@ -39,6 +38,10 @@ const NumberSetting = ({ currentTab }: { currentTab: `${TabEnum}` }) => { { icon: 'loginoutLight', label: '登出', id: TabEnum.loginout, Component: () => <> } ]); + const { openConfirm, ConfirmChild } = useConfirm({ + content: '确认退出登录?' + }); + const router = useRouter(); const theme = useTheme(); const { isPc } = useGlobalStore(); @@ -47,9 +50,11 @@ const NumberSetting = ({ currentTab }: { currentTab: `${TabEnum}` }) => { const setCurrentTab = useCallback( (tab: string) => { if (tab === TabEnum.loginout) { - clearCookie(); - setUserInfo(null); - router.replace('/login'); + openConfirm(() => { + clearCookie(); + setUserInfo(null); + router.replace('/login'); + })(); } else { router.replace({ query: { @@ -58,7 +63,7 @@ const NumberSetting = ({ currentTab }: { currentTab: `${TabEnum}` }) => { }); } }, - [router, setUserInfo] + [openConfirm, router, setUserInfo] ); return ( @@ -105,6 +110,7 @@ const NumberSetting = ({ currentTab }: { currentTab: `${TabEnum}` }) => { {currentTab === TabEnum.inform && } + ); }; diff --git a/client/src/service/models/chat.ts b/client/src/service/models/chat.ts index df5d2fbe2..8ff200533 100644 --- a/client/src/service/models/chat.ts +++ b/client/src/service/models/chat.ts @@ -1,9 +1,13 @@ import { Schema, model, models, Model } from 'mongoose'; import { ChatSchema as ChatType } from '@/types/mongoSchema'; -import { ChatRoleMap } from '@/constants/chat'; +import { ChatRoleMap, TaskResponseKeyEnum } from '@/constants/chat'; import { ChatSourceEnum, ChatSourceMap } from '@/constants/chat'; const ChatSchema = new Schema({ + chatId: { + type: String, + require: true + }, userId: { type: Schema.Types.ObjectId, ref: 'user', @@ -33,14 +37,14 @@ const ChatSchema = new Schema({ type: Object, default: {} }, - // source: { - // type: String, - // enum: Object.keys(ChatSourceMap), - // required: true - // }, - // shareId: { - // type: String - // }, + source: { + type: String, + enum: Object.keys(ChatSourceMap), + required: true + }, + shareId: { + type: String + }, content: { type: [ { @@ -53,14 +57,22 @@ const ChatSchema = new Schema({ type: String, default: '' }, - rawSearch: { + [TaskResponseKeyEnum.responseData]: { type: [ { - id: String, - q: String, - a: String, - kb_id: String, - source: String + moduleName: String, + price: String, + model: String, + tokens: Number, + question: String, + answer: String, + temperature: Number, + maxToken: Number, + finishMessages: Array, + similarity: Number, + limit: Number, + cqList: Array, + cqResult: String } ], default: [] diff --git a/client/src/service/models/shareChat.ts b/client/src/service/models/shareChat.ts index f3de937b0..a9adc3ef0 100644 --- a/client/src/service/models/shareChat.ts +++ b/client/src/service/models/shareChat.ts @@ -24,10 +24,6 @@ const ShareChatSchema = new Schema({ type: Number, default: 0 }, - maxContext: { - type: Number, - default: 20 - }, lastTime: { type: Date } diff --git a/client/src/service/moduleDispatch/chat/oneapi.ts b/client/src/service/moduleDispatch/chat/oneapi.ts index ed0cb2879..6bb9b9ebd 100644 --- a/client/src/service/moduleDispatch/chat/oneapi.ts +++ b/client/src/service/moduleDispatch/chat/oneapi.ts @@ -113,7 +113,7 @@ ${quoteQA.map((item, i) => `${i + 1}. [${item.q}\n${item.a}]`).join('\n')} const adaptMessages = adaptChatItem_openAI({ messages: filterMessages, reserveId: false }); const chatAPI = getOpenAIApi(); - // console.log(adaptMessages); + console.log(adaptMessages); /* count response max token */ const promptsToken = modelToolMap.countTokens({ @@ -128,8 +128,8 @@ ${quoteQA.map((item, i) => `${i + 1}. [${item.q}\n${item.a}]`).join('\n')} temperature: Number(temperature || 0), max_tokens: maxToken, messages: adaptMessages, - frequency_penalty: 0.5, // 越大,重复内容越少 - presence_penalty: -0.5, // 越大,越容易出现新内容 + // frequency_penalty: 0.5, // 越大,重复内容越少 + // presence_penalty: -0.5, // 越大,越容易出现新内容 stream }, { diff --git a/client/src/service/utils/chat/saveChat.ts b/client/src/service/utils/chat/saveChat.ts new file mode 100644 index 000000000..974cfeeb3 --- /dev/null +++ b/client/src/service/utils/chat/saveChat.ts @@ -0,0 +1,65 @@ +import { ChatItemType } from '@/types/chat'; +import { Chat, App } from '@/service/mongo'; +import { ChatSourceEnum } from '@/constants/chat'; + +type Props = { + chatId: string; + appId: string; + userId: string; + variables?: Record; + isOwner: boolean; + source: `${ChatSourceEnum}`; + shareId?: string; + content: [ChatItemType, ChatItemType]; +}; + +export async function saveChat({ + chatId, + appId, + userId, + variables, + isOwner, + source, + shareId, + content +}: Props) { + const chatHistory = await Chat.findOne( + { + chatId, + userId + }, + '_id' + ); + + if (chatHistory) { + await Chat.findOneAndUpdate( + { chatId }, + { + $push: { + content: { + $each: content + } + }, + title: content[0].value.slice(0, 20), + updateTime: new Date() + } + ); + } else { + await Chat.create({ + chatId, + userId, + appId, + variables, + title: content[0].value.slice(0, 20), + source, + shareId, + content: content + }); + } + + if (isOwner && source === ChatSourceEnum.online) { + App.findByIdAndUpdate(appId, { + updateTime: new Date() + }); + } +} diff --git a/client/src/store/chat.ts b/client/src/store/chat.ts index 872a766fc..6a0dbfb46 100644 --- a/client/src/store/chat.ts +++ b/client/src/store/chat.ts @@ -65,12 +65,12 @@ export const useChatStore = create()( }, async delHistory(chatId) { set((state) => { - state.history = state.history.filter((item) => item._id !== chatId); + state.history = state.history.filter((item) => item.chatId !== chatId); }); await delChatHistoryById(chatId); }, updateHistory(history) { - const index = get().history.findIndex((item) => item._id === history._id); + const index = get().history.findIndex((item) => item.chatId === history.chatId); set((state) => { const newHistory = (() => { if (index > -1) { diff --git a/client/src/store/shareChat.ts b/client/src/store/shareChat.ts index dc0caaf33..27f1c5745 100644 --- a/client/src/store/shareChat.ts +++ b/client/src/store/shareChat.ts @@ -4,8 +4,6 @@ import { immer } from 'zustand/middleware/immer'; import type { ChatSiteItemType, ShareChatHistoryItemType, ShareChatType } from '@/types/chat'; import { HUMAN_ICON } from '@/constants/chat'; -import { customAlphabet } from 'nanoid'; -const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 12); type State = { shareChatData: ShareChatType; @@ -16,21 +14,20 @@ type State = { prompts: ChatSiteItemType[]; variables: Record; shareId: string; - }) => { newChatId: string }; + }) => void; delOneShareHistoryByChatId: (chatId: string) => void; delShareChatHistoryItemById: (e: { chatId: string; index: number }) => void; delManyShareChatHistoryByShareId: (shareId?: string) => void; }; export const defaultHistory: ShareChatHistoryItemType = { - _id: `${Date.now()}`, + chatId: `${Date.now()}`, updateTime: new Date(), title: '新对话', shareId: '', chats: [] }; const defaultShareChatData: ShareChatType = { - maxContext: 5, userAvatar: HUMAN_ICON, app: { name: '', @@ -57,32 +54,30 @@ export const useShareChatStore = create()( state.shareChatData = val; // update history state.shareChatHistory = state.shareChatHistory.map((item) => - item._id === val.history._id ? val.history : item + item.chatId === val.history.chatId ? val.history : item ); }); }, shareChatHistory: [], saveChatResponse({ chatId, prompts, variables, shareId }) { - const history = get().shareChatHistory.find((item) => item._id === chatId); - - const newChatId = history ? '' : nanoid(); + const chatHistory = get().shareChatHistory.find((item) => item.chatId === chatId); const historyList = (() => { - if (history) { + if (chatHistory) { return get().shareChatHistory.map((item) => - item._id === chatId + item.chatId === chatId ? { ...item, title: prompts[prompts.length - 2]?.value, updateTime: new Date(), - chats: prompts, + chats: chatHistory.chats.concat(prompts).slice(-50), variables } : item ); } return get().shareChatHistory.concat({ - _id: newChatId, + chatId, shareId, title: prompts[prompts.length - 2]?.value, updateTime: new Date(), @@ -97,21 +92,19 @@ export const useShareChatStore = create()( set((state) => { state.shareChatHistory = historyList.slice(0, 100); }); - - return { - newChatId - }; }, delOneShareHistoryByChatId(chatId: string) { set((state) => { - state.shareChatHistory = state.shareChatHistory.filter((item) => item._id !== chatId); + state.shareChatHistory = state.shareChatHistory.filter( + (item) => item.chatId !== chatId + ); }); }, delShareChatHistoryItemById({ chatId, index }) { set((state) => { // update history store const newHistoryList = state.shareChatHistory.map((item) => - item._id === chatId + item.chatId === chatId ? { ...item, chats: [...item.chats.slice(0, index), ...item.chats.slice(index + 1)] diff --git a/client/src/types/app.d.ts b/client/src/types/app.d.ts index 21880a816..24e2c70eb 100644 --- a/client/src/types/app.d.ts +++ b/client/src/types/app.d.ts @@ -37,7 +37,6 @@ export interface ShareAppItem { export type ShareChatEditType = { name: string; - maxContext: number; }; /* agent */ diff --git a/client/src/types/chat.d.ts b/client/src/types/chat.d.ts index b6011c18e..bc8465369 100644 --- a/client/src/types/chat.d.ts +++ b/client/src/types/chat.d.ts @@ -1,4 +1,4 @@ -import { ChatRoleEnum, rawSearchKey } from '@/constants/chat'; +import { ChatRoleEnum } from '@/constants/chat'; import type { InitChatResponse, InitShareChatResponse } from '@/api/response/chat'; import { TaskResponseKeyEnum } from '@/constants/chat'; import { ClassifyQuestionAgentItemType } from './app'; @@ -9,9 +9,7 @@ export type ChatItemType = { _id?: string; obj: `${ChatRoleEnum}`; value: string; - [rawSearchKey]?: QuoteItemType[]; - quoteLen?: number; - [key: string]: any; + [TaskResponseKeyEnum.responseData]?: ChatHistoryItemResType[]; }; export type ChatSiteItemType = { @@ -19,7 +17,7 @@ export type ChatSiteItemType = { } & ChatItemType; export type HistoryItemType = { - _id: string; + chatId: string; updateTime: Date; customTitle?: string; title: string; diff --git a/client/src/types/index.d.ts b/client/src/types/index.d.ts index 402142e03..289d83057 100644 --- a/client/src/types/index.d.ts +++ b/client/src/types/index.d.ts @@ -18,7 +18,7 @@ export type FeConfigsType = { show_register?: boolean; show_appStore?: boolean; show_userDetail?: boolean; - show_git?: false; + show_git?: boolean; systemTitle?: string; authorText?: string; }; diff --git a/client/src/types/mongoSchema.d.ts b/client/src/types/mongoSchema.d.ts index a0df71627..f35c987ae 100644 --- a/client/src/types/mongoSchema.d.ts +++ b/client/src/types/mongoSchema.d.ts @@ -4,6 +4,7 @@ import type { DataType } from './data'; import { BillSourceEnum, InformTypeEnum } from '@/constants/user'; import { TrainingModeEnum } from '@/constants/plugin'; import type { AppModuleItemType } from './app'; +import { ChatSourceEnum } from '@/constants/chat'; export interface UserModelSchema { _id: string; @@ -78,6 +79,7 @@ export interface TrainingDataSchema { export interface ChatSchema { _id: string; + chatId: string; userId: string; appId: string; updateTime: Date; @@ -85,6 +87,8 @@ export interface ChatSchema { customTitle: string; top: boolean; variables: Record; + source: `${ChatSourceEnum}`; + shareId?: string; content: ChatItemType[]; } @@ -138,7 +142,6 @@ export interface ShareChatSchema { appId: string; name: string; total: number; - maxContext: number; lastTime: Date; }