4.8.10 perf (#2378)

* perf: helpline code

* fix: prompt call stream=false response prefix

* fix: app chat log auth

* perf: new chat i18n

* fix: milvus dataset cannot export data

* perf: doc intro
This commit is contained in:
Archer
2024-08-15 13:12:39 +08:00
committed by GitHub
parent fdeb1590d7
commit 86c27e85ef
16 changed files with 499 additions and 479 deletions

View File

@@ -1,11 +1,15 @@
import { authChatCrud } from '@/service/support/permission/auth/chat';
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
import {
ManagePermissionVal,
ReadPermissionVal
} from '@fastgpt/global/support/permission/constant';
import { MongoChatItem } from '@fastgpt/service/core/chat/chatItemSchema';
import { ChatRoleEnum } from '@fastgpt/global/core/chat/constants';
import type { ApiRequestProps, ApiResponseType } from '@fastgpt/service/type/next';
import { NextAPI } from '@/service/middleware/entry';
import { ChatHistoryItemResType } from '@fastgpt/global/core/chat/type';
import { OutLinkChatAuthProps } from '@fastgpt/global/support/permission/chat';
import { authApp } from '@fastgpt/service/support/permission/app/auth';
export type getResDataQuery = OutLinkChatAuthProps & {
chatId?: string;
@@ -25,12 +29,24 @@ async function handler(
if (!appId || !chatId || !dataId) {
return {};
}
await authChatCrud({
req,
authToken: true,
...req.query,
per: ReadPermissionVal
});
// 1. Un login api: share chat, team chat
// 2. Login api: account chat, chat log
try {
await authChatCrud({
req,
authToken: true,
...req.query,
per: ReadPermissionVal
});
} catch (error) {
await authApp({
req,
authToken: true,
appId,
per: ManagePermissionVal
});
}
const chatData = await MongoChatItem.findOne({
appId,

View File

@@ -14,7 +14,7 @@ import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
import { transformPreviewHistories } from '@/global/core/chat/utils';
import { AppTypeEnum } from '@fastgpt/global/core/app/constants';
import { i18nT } from '@fastgpt/web/i18n/utils';
async function handler(
req: NextApiRequest,
res: NextApiResponse
@@ -62,7 +62,7 @@ async function handler(
return {
chatId,
appId,
title: chat?.title || i18nT('chat:new_chat'),
title: chat?.title,
userAvatar: undefined,
variables: chat?.variables || {},
history: app.type === AppTypeEnum.plugin ? histories : transformPreviewHistories(histories),

View File

@@ -18,90 +18,84 @@ import { getAppLatestVersion } from '@fastgpt/service/core/app/controller';
import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
import { AppTypeEnum } from '@fastgpt/global/core/app/constants';
import { transformPreviewHistories } from '@/global/core/chat/utils';
import { i18nT } from '@fastgpt/web/i18n/utils';
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
await connectToDatabase();
import { NextAPI } from '@/service/middleware/entry';
let { chatId, shareId, outLinkUid } = req.query as InitOutLinkChatProps;
async function handler(req: NextApiRequest, res: NextApiResponse) {
let { chatId, shareId, outLinkUid } = req.query as InitOutLinkChatProps;
// auth link permission
const { shareChat, uid, appId } = await authOutLink({ shareId, outLinkUid });
// auth link permission
const { shareChat, uid, appId } = await authOutLink({ shareId, outLinkUid });
// auth app permission
const [tmb, chat, app] = await Promise.all([
MongoTeamMember.findById(shareChat.tmbId, '_id userId').populate('userId', 'avatar').lean(),
MongoChat.findOne({ appId, chatId, shareId }).lean(),
MongoApp.findById(appId).lean()
]);
// auth app permission
const [tmb, chat, app] = await Promise.all([
MongoTeamMember.findById(shareChat.tmbId, '_id userId').populate('userId', 'avatar').lean(),
MongoChat.findOne({ appId, chatId, shareId }).lean(),
MongoApp.findById(appId).lean()
]);
if (!app) {
throw new Error(AppErrEnum.unExist);
}
if (!app) {
throw new Error(AppErrEnum.unExist);
}
// auth chat permission
if (chat && chat.outLinkUid !== uid) {
throw new Error(ChatErrEnum.unAuthChat);
}
// auth chat permission
if (chat && chat.outLinkUid !== uid) {
throw new Error(ChatErrEnum.unAuthChat);
}
const [{ histories }, { nodes }] = await Promise.all([
getChatItems({
appId: app._id,
chatId,
limit: 30,
field: `dataId obj value userGoodFeedback userBadFeedback ${
shareChat.responseDetail || app.type === AppTypeEnum.plugin
? `adminFeedback ${DispatchNodeResponseKeyEnum.nodeResponse}`
: ''
} `
}),
getAppLatestVersion(app._id, app)
]);
const [{ histories }, { nodes }] = await Promise.all([
getChatItems({
appId: app._id,
chatId,
limit: 30,
field: `dataId obj value userGoodFeedback userBadFeedback ${
shareChat.responseDetail || app.type === AppTypeEnum.plugin
? `adminFeedback ${DispatchNodeResponseKeyEnum.nodeResponse}`
: ''
} `
}),
getAppLatestVersion(app._id, app)
]);
// pick share response field
app.type !== AppTypeEnum.plugin &&
histories.forEach((item) => {
if (item.obj === ChatRoleEnum.AI) {
item.responseData = filterPublicNodeResponseData({ flowResponses: item.responseData });
}
});
jsonRes<InitChatResponse>(res, {
data: {
chatId,
appId: app._id,
title: chat?.title || i18nT('chat:new_chat'),
//@ts-ignore
userAvatar: tmb?.userId?.avatar,
variables: chat?.variables || {},
history: app.type === AppTypeEnum.plugin ? histories : transformPreviewHistories(histories),
app: {
chatConfig: getAppChatConfig({
chatConfig: app.chatConfig,
systemConfigNode: getGuideModule(nodes),
storeVariables: chat?.variableList,
storeWelcomeText: chat?.welcomeText,
isPublicFetch: false
}),
chatModels: getChatModelNameListByModules(nodes),
name: app.name,
avatar: app.avatar,
intro: app.intro,
type: app.type,
pluginInputs:
app?.modules?.find((node) => node.flowNodeType === FlowNodeTypeEnum.pluginInput)
?.inputs ?? []
}
// pick share response field
app.type !== AppTypeEnum.plugin &&
histories.forEach((item) => {
if (item.obj === ChatRoleEnum.AI) {
item.responseData = filterPublicNodeResponseData({ flowResponses: item.responseData });
}
});
} catch (err) {
jsonRes(res, {
code: 500,
error: err
});
}
jsonRes<InitChatResponse>(res, {
data: {
chatId,
appId: app._id,
title: chat?.title,
//@ts-ignore
userAvatar: tmb?.userId?.avatar,
variables: chat?.variables || {},
history: app.type === AppTypeEnum.plugin ? histories : transformPreviewHistories(histories),
app: {
chatConfig: getAppChatConfig({
chatConfig: app.chatConfig,
systemConfigNode: getGuideModule(nodes),
storeVariables: chat?.variableList,
storeWelcomeText: chat?.welcomeText,
isPublicFetch: false
}),
chatModels: getChatModelNameListByModules(nodes),
name: app.name,
avatar: app.avatar,
intro: app.intro,
type: app.type,
pluginInputs:
app?.modules?.find((node) => node.flowNodeType === FlowNodeTypeEnum.pluginInput)
?.inputs ?? []
}
}
});
}
export default NextAPI(handler);
export const config = {
api: {
responseLimit: '10mb'

View File

@@ -18,92 +18,85 @@ import { getAppLatestVersion } from '@fastgpt/service/core/app/controller';
import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
import { AppTypeEnum } from '@fastgpt/global/core/app/constants';
import { transformPreviewHistories } from '@/global/core/chat/utils';
import { i18nT } from '@fastgpt/web/i18n/utils';
import { NextAPI } from '@/service/middleware/entry';
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
await connectToDatabase();
async function handler(req: NextApiRequest, res: NextApiResponse) {
let { teamId, appId, chatId, teamToken } = req.query as InitTeamChatProps;
let { teamId, appId, chatId, teamToken } = req.query as InitTeamChatProps;
if (!teamId || !appId || !teamToken) {
throw new Error('teamId, appId, teamToken are required');
}
if (!teamId || !appId || !teamToken) {
throw new Error('teamId, appId, teamToken are required');
}
const { uid } = await authTeamSpaceToken({
teamId,
teamToken
});
const { uid } = await authTeamSpaceToken({
teamId,
teamToken
});
const [team, chat, app] = await Promise.all([
MongoTeam.findById(teamId, 'name avatar').lean(),
MongoChat.findOne({ teamId, appId, chatId }).lean(),
MongoApp.findById(appId).lean()
]);
const [team, chat, app] = await Promise.all([
MongoTeam.findById(teamId, 'name avatar').lean(),
MongoChat.findOne({ teamId, appId, chatId }).lean(),
MongoApp.findById(appId).lean()
]);
if (!app) {
throw new Error(AppErrEnum.unExist);
}
if (!app) {
throw new Error(AppErrEnum.unExist);
}
// auth chat permission
if (chat && chat.outLinkUid !== uid) {
throw new Error(ChatErrEnum.unAuthChat);
}
// auth chat permission
if (chat && chat.outLinkUid !== uid) {
throw new Error(ChatErrEnum.unAuthChat);
}
// get app and history
const [{ histories }, { nodes }] = await Promise.all([
getChatItems({
appId,
chatId,
limit: 30,
field: `dataId obj value userGoodFeedback userBadFeedback adminFeedback ${DispatchNodeResponseKeyEnum.nodeResponse}`
}),
getAppLatestVersion(app._id, app)
]);
// get app and history
const [{ histories }, { nodes }] = await Promise.all([
getChatItems({
appId,
chatId,
limit: 30,
field: `dataId obj value userGoodFeedback userBadFeedback adminFeedback ${DispatchNodeResponseKeyEnum.nodeResponse}`
}),
getAppLatestVersion(app._id, app)
]);
// pick share response field
app.type !== AppTypeEnum.plugin &&
histories.forEach((item) => {
if (item.obj === ChatRoleEnum.AI) {
item.responseData = filterPublicNodeResponseData({ flowResponses: item.responseData });
}
});
jsonRes<InitChatResponse>(res, {
data: {
chatId,
appId,
title: chat?.title || i18nT('chat:new_chat'),
userAvatar: team?.avatar,
variables: chat?.variables || {},
history: app.type === AppTypeEnum.plugin ? histories : transformPreviewHistories(histories),
app: {
chatConfig: getAppChatConfig({
chatConfig: app.chatConfig,
systemConfigNode: getGuideModule(nodes),
storeVariables: chat?.variableList,
storeWelcomeText: chat?.welcomeText,
isPublicFetch: false
}),
chatModels: getChatModelNameListByModules(nodes),
name: app.name,
avatar: app.avatar,
intro: app.intro,
type: app.type,
pluginInputs:
app?.modules?.find((node) => node.flowNodeType === FlowNodeTypeEnum.pluginInput)
?.inputs ?? []
}
// pick share response field
app.type !== AppTypeEnum.plugin &&
histories.forEach((item) => {
if (item.obj === ChatRoleEnum.AI) {
item.responseData = filterPublicNodeResponseData({ flowResponses: item.responseData });
}
});
} catch (err) {
jsonRes(res, {
code: 500,
error: err
});
}
jsonRes<InitChatResponse>(res, {
data: {
chatId,
appId,
title: chat?.title,
userAvatar: team?.avatar,
variables: chat?.variables || {},
history: app.type === AppTypeEnum.plugin ? histories : transformPreviewHistories(histories),
app: {
chatConfig: getAppChatConfig({
chatConfig: app.chatConfig,
systemConfigNode: getGuideModule(nodes),
storeVariables: chat?.variableList,
storeWelcomeText: chat?.welcomeText,
isPublicFetch: false
}),
chatModels: getChatModelNameListByModules(nodes),
name: app.name,
avatar: app.avatar,
intro: app.intro,
type: app.type,
pluginInputs:
app?.modules?.find((node) => node.flowNodeType === FlowNodeTypeEnum.pluginInput)
?.inputs ?? []
}
}
});
}
export default NextAPI(handler);
export const config = {
api: {
responseLimit: '10mb'

View File

@@ -18,7 +18,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
datasetId: string;
};
if (!datasetId || !global.pgClient) {
if (!datasetId) {
return Promise.reject(CommonErrEnum.missingParams);
}