mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-30 02:12:38 +00:00
Perf input guide (#1557)
* perf: input guide code * perf: input guide ui * Chat input guide api * Update app chat config store * perf: app chat config field * perf: app context * perf: params * fix: ts * perf: filter private config * perf: filter private config * perf: import workflow * perf: limit max tip amount
This commit is contained in:
@@ -6,7 +6,7 @@ import { MongoApp } from '@fastgpt/service/core/app/schema';
|
||||
import { authUserNotVisitor } from '@fastgpt/service/support/permission/auth/user';
|
||||
import { checkTeamAppLimit } from '@fastgpt/service/support/permission/teamLimit';
|
||||
import { mongoSessionRun } from '@fastgpt/service/common/mongo/sessionRun';
|
||||
import { MongoAppVersion } from '@fastgpt/service/core/app/versionSchema';
|
||||
import { MongoAppVersion } from '@fastgpt/service/core/app/version/schema';
|
||||
import { NextAPI } from '@/service/middleware/entry';
|
||||
|
||||
async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
|
||||
|
@@ -5,9 +5,9 @@ import { MongoOutLink } from '@fastgpt/service/support/outLink/schema';
|
||||
import { authApp } from '@fastgpt/service/support/permission/auth/app';
|
||||
import { MongoChatItem } from '@fastgpt/service/core/chat/chatItemSchema';
|
||||
import { mongoSessionRun } from '@fastgpt/service/common/mongo/sessionRun';
|
||||
import { MongoAppVersion } from '@fastgpt/service/core/app/versionSchema';
|
||||
import { MongoAppQGuide } from '@fastgpt/service/core/app/qGuideSchema';
|
||||
import { MongoAppVersion } from '@fastgpt/service/core/app/version/schema';
|
||||
import { NextAPI } from '@/service/middleware/entry';
|
||||
import { MongoChatInputGuide } from '@fastgpt/service/core/chat/inputGuide/schema';
|
||||
|
||||
async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
|
||||
const { appId } = req.query as { appId: string };
|
||||
@@ -47,7 +47,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
|
||||
},
|
||||
{ session }
|
||||
);
|
||||
await MongoAppQGuide.deleteMany(
|
||||
await MongoChatInputGuide.deleteMany(
|
||||
{
|
||||
appId
|
||||
},
|
||||
|
@@ -1,6 +1,4 @@
|
||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
import { jsonRes } from '@fastgpt/service/common/response';
|
||||
import { connectToDatabase } from '@/service/mongo';
|
||||
import { authApp } from '@fastgpt/service/support/permission/auth/app';
|
||||
import { NextAPI } from '@/service/middleware/entry';
|
||||
|
||||
|
@@ -1,20 +1,20 @@
|
||||
import { authUserNotVisitor } from '@fastgpt/service/support/permission/auth/user';
|
||||
import { NextApiRequest, NextApiResponse } from 'next';
|
||||
import { MongoAppQGuide } from '@fastgpt/service/core/app/qGuideSchema';
|
||||
import { MongoChatInputGuide } from '@fastgpt/service/core/chat/inputGuide/schema';
|
||||
import axios from 'axios';
|
||||
import { NextAPI } from '@/service/middleware/entry';
|
||||
|
||||
async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
|
||||
const { textList = [], appId, customURL } = req.body;
|
||||
const { textList = [], appId, customUrl } = req.body;
|
||||
|
||||
if (!customURL) {
|
||||
if (!customUrl) {
|
||||
const { teamId } = await authUserNotVisitor({ req, authToken: true });
|
||||
|
||||
const currentQGuide = await MongoAppQGuide.find({ appId, teamId });
|
||||
const currentQGuide = await MongoChatInputGuide.find({ appId, teamId });
|
||||
const currentTexts = currentQGuide.map((item) => item.text);
|
||||
const textsToDelete = currentTexts.filter((text) => !textList.includes(text));
|
||||
|
||||
await MongoAppQGuide.deleteMany({ text: { $in: textsToDelete }, appId, teamId });
|
||||
await MongoChatInputGuide.deleteMany({ text: { $in: textsToDelete }, appId, teamId });
|
||||
|
||||
const newTexts = textList.filter((text: string) => !currentTexts.includes(text));
|
||||
|
||||
@@ -24,10 +24,10 @@ async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
|
||||
teamId: teamId
|
||||
}));
|
||||
|
||||
await MongoAppQGuide.insertMany(newDocuments);
|
||||
await MongoChatInputGuide.insertMany(newDocuments);
|
||||
} else {
|
||||
try {
|
||||
const response = await axios.post(customURL, {
|
||||
const response = await axios.post(customUrl, {
|
||||
textList,
|
||||
appId
|
||||
});
|
||||
|
@@ -1,48 +0,0 @@
|
||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
import { MongoAppQGuide } from '@fastgpt/service/core/app/qGuideSchema';
|
||||
import axios from 'axios';
|
||||
import { PaginationProps } from '@fastgpt/web/common/fetch/type';
|
||||
import { NextAPI } from '@/service/middleware/entry';
|
||||
|
||||
type Props = PaginationProps<{
|
||||
appId: string;
|
||||
customURL: string;
|
||||
searchKey: string;
|
||||
}>;
|
||||
|
||||
async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
|
||||
const { appId, customURL, current, pageSize, searchKey } = req.query as unknown as Props;
|
||||
|
||||
if (!customURL) {
|
||||
const [result, total] = await Promise.all([
|
||||
MongoAppQGuide.find({
|
||||
appId,
|
||||
...(searchKey && { text: { $regex: new RegExp(searchKey, 'i') } })
|
||||
})
|
||||
.sort({
|
||||
time: -1
|
||||
})
|
||||
.skip((current - 1) * pageSize)
|
||||
.limit(pageSize),
|
||||
MongoAppQGuide.countDocuments({ appId })
|
||||
]);
|
||||
|
||||
return {
|
||||
list: result.map((item) => item.text) || [],
|
||||
total
|
||||
};
|
||||
} else {
|
||||
try {
|
||||
const response = await axios.get(customURL as string, {
|
||||
params: {
|
||||
appid: appId
|
||||
}
|
||||
});
|
||||
res.status(200).json(response.data);
|
||||
} catch (error) {
|
||||
res.status(500).json({ error });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default NextAPI(handler);
|
@@ -7,7 +7,7 @@ import { NextAPI } from '@/service/middleware/entry';
|
||||
|
||||
/* 获取我的模型 */
|
||||
async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
|
||||
const { name, avatar, type, intro, nodes, edges, permission, teamTags } =
|
||||
const { name, avatar, type, intro, nodes, edges, chatConfig, permission, teamTags } =
|
||||
req.body as AppUpdateParams;
|
||||
const { appId } = req.query as { appId: string };
|
||||
|
||||
@@ -39,7 +39,8 @@ async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
|
||||
}),
|
||||
...(edges && {
|
||||
edges
|
||||
})
|
||||
}),
|
||||
...(chatConfig && { chatConfig })
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
import { NextAPI } from '@/service/middleware/entry';
|
||||
import { MongoAppVersion } from '@fastgpt/service/core/app/versionSchema';
|
||||
import { MongoAppVersion } from '@fastgpt/service/core/app/version/schema';
|
||||
import { PaginationProps, PaginationResponse } from '@fastgpt/web/common/fetch/type';
|
||||
import { AppVersionSchemaType } from '@fastgpt/global/core/app/version';
|
||||
|
||||
|
@@ -1,11 +1,10 @@
|
||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
import { NextAPI } from '@/service/middleware/entry';
|
||||
import { authApp } from '@fastgpt/service/support/permission/auth/app';
|
||||
import { MongoAppVersion } from '@fastgpt/service/core/app/versionSchema';
|
||||
import { MongoAppVersion } from '@fastgpt/service/core/app/version/schema';
|
||||
import { mongoSessionRun } from '@fastgpt/service/common/mongo/sessionRun';
|
||||
import { MongoApp } from '@fastgpt/service/core/app/schema';
|
||||
import { beforeUpdateAppFormat } from '@fastgpt/service/core/app/controller';
|
||||
import { getGuideModule, splitGuideModule } from '@fastgpt/global/core/workflow/utils';
|
||||
import { getNextTimeByCronStringAndTimezone } from '@fastgpt/global/common/string/time';
|
||||
import { PostPublishAppProps } from '@/global/core/app/api';
|
||||
|
||||
@@ -13,14 +12,12 @@ type Response = {};
|
||||
|
||||
async function handler(req: NextApiRequest, res: NextApiResponse<any>): Promise<{}> {
|
||||
const { appId } = req.query as { appId: string };
|
||||
const { nodes = [], edges = [], type } = req.body as PostPublishAppProps;
|
||||
const { nodes = [], edges = [], chatConfig, type } = req.body as PostPublishAppProps;
|
||||
|
||||
await authApp({ appId, req, per: 'w', authToken: true });
|
||||
|
||||
const { nodes: formatNodes } = beforeUpdateAppFormat({ nodes });
|
||||
|
||||
const { scheduledTriggerConfig } = splitGuideModule(getGuideModule(formatNodes || []));
|
||||
|
||||
await mongoSessionRun(async (session) => {
|
||||
// create version histories
|
||||
await MongoAppVersion.create(
|
||||
@@ -28,7 +25,8 @@ async function handler(req: NextApiRequest, res: NextApiResponse<any>): Promise<
|
||||
{
|
||||
appId,
|
||||
nodes: formatNodes,
|
||||
edges
|
||||
edges,
|
||||
chatConfig
|
||||
}
|
||||
],
|
||||
{ session }
|
||||
@@ -38,12 +36,13 @@ async function handler(req: NextApiRequest, res: NextApiResponse<any>): Promise<
|
||||
await MongoApp.findByIdAndUpdate(appId, {
|
||||
modules: formatNodes,
|
||||
edges,
|
||||
chatConfig,
|
||||
updateTime: new Date(),
|
||||
version: 'v2',
|
||||
type,
|
||||
scheduledTriggerConfig,
|
||||
scheduledTriggerNextTime: scheduledTriggerConfig
|
||||
? getNextTimeByCronStringAndTimezone(scheduledTriggerConfig)
|
||||
scheduledTriggerConfig: chatConfig?.scheduledTriggerConfig,
|
||||
scheduledTriggerNextTime: chatConfig?.scheduledTriggerConfig
|
||||
? getNextTimeByCronStringAndTimezone(chatConfig.scheduledTriggerConfig)
|
||||
: null
|
||||
});
|
||||
});
|
||||
|
@@ -1,11 +1,10 @@
|
||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
import { NextAPI } from '@/service/middleware/entry';
|
||||
import { authApp } from '@fastgpt/service/support/permission/auth/app';
|
||||
import { MongoAppVersion } from '@fastgpt/service/core/app/versionSchema';
|
||||
import { MongoAppVersion } from '@fastgpt/service/core/app/version/schema';
|
||||
import { mongoSessionRun } from '@fastgpt/service/common/mongo/sessionRun';
|
||||
import { MongoApp } from '@fastgpt/service/core/app/schema';
|
||||
import { beforeUpdateAppFormat } from '@fastgpt/service/core/app/controller';
|
||||
import { getGuideModule, splitGuideModule } from '@fastgpt/global/core/workflow/utils';
|
||||
import { getNextTimeByCronStringAndTimezone } from '@fastgpt/global/common/string/time';
|
||||
import { PostRevertAppProps } from '@/global/core/app/api';
|
||||
|
||||
@@ -28,7 +27,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse<any>): Promise<
|
||||
|
||||
const { nodes: formatEditNodes } = beforeUpdateAppFormat({ nodes: editNodes });
|
||||
|
||||
const { scheduledTriggerConfig } = splitGuideModule(getGuideModule(version.nodes));
|
||||
const scheduledTriggerConfig = version.chatConfig.scheduledTriggerConfig;
|
||||
|
||||
await mongoSessionRun(async (session) => {
|
||||
// 为编辑中的数据创建一个版本
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
import { jsonRes } from '@fastgpt/service/common/response';
|
||||
import { authApp } from '@fastgpt/service/support/permission/auth/app';
|
||||
import { getGuideModule, replaceAppChatConfig } from '@fastgpt/global/core/workflow/utils';
|
||||
import { getGuideModule, getAppChatConfig } from '@fastgpt/global/core/workflow/utils';
|
||||
import { getChatModelNameListByModules } from '@/service/core/app/workflow';
|
||||
import type { InitChatProps, InitChatResponse } from '@/global/core/chat/api.d';
|
||||
import { MongoChat } from '@fastgpt/service/core/chat/chatSchema';
|
||||
@@ -61,10 +61,12 @@ async function handler(
|
||||
variables: chat?.variables || {},
|
||||
history,
|
||||
app: {
|
||||
userGuideModule: replaceAppChatConfig({
|
||||
node: getGuideModule(nodes),
|
||||
variableList: chat?.variableList,
|
||||
welcomeText: chat?.welcomeText
|
||||
chatConfig: getAppChatConfig({
|
||||
chatConfig: app.chatConfig,
|
||||
systemConfigNode: getGuideModule(nodes),
|
||||
storeVariables: chat?.variableList,
|
||||
storeWelcomeText: chat?.welcomeText,
|
||||
isPublicFetch: false
|
||||
}),
|
||||
chatModels: getChatModelNameListByModules(nodes),
|
||||
name: app.name,
|
||||
|
@@ -0,0 +1,30 @@
|
||||
import type { ApiRequestProps, ApiResponseType } from '@fastgpt/service/type/next';
|
||||
import { NextAPI } from '@/service/middleware/entry';
|
||||
import { MongoChatInputGuide } from '@fastgpt/service/core/chat/inputGuide/schema';
|
||||
import { authCert } from '@fastgpt/service/support/permission/auth/common';
|
||||
|
||||
export type countChatInputGuideTotalQuery = { appId: string };
|
||||
|
||||
export type countChatInputGuideTotalBody = {};
|
||||
|
||||
export type countChatInputGuideTotalResponse = { total: number };
|
||||
|
||||
async function handler(
|
||||
req: ApiRequestProps<countChatInputGuideTotalBody, countChatInputGuideTotalQuery>,
|
||||
res: ApiResponseType<any>
|
||||
): Promise<countChatInputGuideTotalResponse> {
|
||||
await authCert({ req, authToken: true });
|
||||
|
||||
const appId = req.query.appId;
|
||||
if (!appId) {
|
||||
return {
|
||||
total: 0
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
total: await MongoChatInputGuide.countDocuments({ appId })
|
||||
};
|
||||
}
|
||||
|
||||
export default NextAPI(handler);
|
45
projects/app/src/pages/api/core/chat/inputGuide/create.ts
Normal file
45
projects/app/src/pages/api/core/chat/inputGuide/create.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import type { ApiRequestProps, ApiResponseType } from '@fastgpt/service/type/next';
|
||||
import { NextAPI } from '@/service/middleware/entry';
|
||||
import { authApp } from '@fastgpt/service/support/permission/auth/app';
|
||||
import { MongoChatInputGuide } from '@fastgpt/service/core/chat/inputGuide/schema';
|
||||
|
||||
export type createChatInputGuideQuery = {};
|
||||
|
||||
export type createInputGuideBody = {
|
||||
appId: string;
|
||||
textList: string[];
|
||||
};
|
||||
|
||||
export type createInputGuideResponse = {
|
||||
insertLength: number;
|
||||
};
|
||||
|
||||
async function handler(
|
||||
req: ApiRequestProps<createInputGuideBody, createChatInputGuideQuery>,
|
||||
res: ApiResponseType<any>
|
||||
): Promise<createInputGuideResponse> {
|
||||
const { appId, textList } = req.body;
|
||||
await authApp({ req, appId, authToken: true, per: 'r' });
|
||||
|
||||
try {
|
||||
const result = await MongoChatInputGuide.insertMany(
|
||||
textList.map((text) => ({
|
||||
appId,
|
||||
text
|
||||
})),
|
||||
{
|
||||
ordered: false
|
||||
}
|
||||
);
|
||||
return {
|
||||
insertLength: result.length
|
||||
};
|
||||
} catch (error: any) {
|
||||
const errLength = error.writeErrors?.length ?? textList.length;
|
||||
return {
|
||||
insertLength: textList.length - errLength
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export default NextAPI(handler);
|
27
projects/app/src/pages/api/core/chat/inputGuide/delete.ts
Normal file
27
projects/app/src/pages/api/core/chat/inputGuide/delete.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import type { ApiRequestProps, ApiResponseType } from '@fastgpt/service/type/next';
|
||||
import { NextAPI } from '@/service/middleware/entry';
|
||||
import { authApp } from '@fastgpt/service/support/permission/auth/app';
|
||||
import { MongoChatInputGuide } from '@fastgpt/service/core/chat/inputGuide/schema';
|
||||
|
||||
export type deleteChatInputGuideQuery = {};
|
||||
|
||||
export type deleteInputGuideBody = { appId: string; dataIdList: string[] };
|
||||
|
||||
export type deleteInputGuideResponse = {};
|
||||
|
||||
async function handler(
|
||||
req: ApiRequestProps<deleteInputGuideBody, deleteChatInputGuideQuery>,
|
||||
res: ApiResponseType<any>
|
||||
): Promise<deleteInputGuideResponse> {
|
||||
const { appId, dataIdList } = req.body;
|
||||
await authApp({ req, appId, authToken: true, per: 'r' });
|
||||
console.log(dataIdList);
|
||||
await MongoChatInputGuide.deleteMany({
|
||||
_id: { $in: dataIdList },
|
||||
appId
|
||||
});
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
export default NextAPI(handler);
|
42
projects/app/src/pages/api/core/chat/inputGuide/list.ts
Normal file
42
projects/app/src/pages/api/core/chat/inputGuide/list.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import type { NextApiResponse } from 'next';
|
||||
import { MongoChatInputGuide } from '@fastgpt/service/core/chat/inputGuide/schema';
|
||||
import { PaginationProps, PaginationResponse } from '@fastgpt/web/common/fetch/type';
|
||||
import { NextAPI } from '@/service/middleware/entry';
|
||||
import { ApiRequestProps } from '@fastgpt/service/type/next';
|
||||
import { ChatInputGuideSchemaType } from '@fastgpt/global/core/chat/inputGuide/type';
|
||||
import { authApp } from '@fastgpt/service/support/permission/auth/app';
|
||||
|
||||
export type ChatInputGuideProps = PaginationProps<{
|
||||
appId: string;
|
||||
searchKey: string;
|
||||
}>;
|
||||
export type ChatInputGuideResponse = PaginationResponse<ChatInputGuideSchemaType>;
|
||||
|
||||
async function handler(
|
||||
req: ApiRequestProps<{}, ChatInputGuideProps>,
|
||||
res: NextApiResponse<any>
|
||||
): Promise<ChatInputGuideResponse> {
|
||||
const { appId, pageSize, current, searchKey } = req.query;
|
||||
|
||||
await authApp({ req, appId, authToken: true, per: 'r' });
|
||||
|
||||
const params = {
|
||||
appId,
|
||||
...(searchKey && { text: { $regex: new RegExp(searchKey, 'i') } })
|
||||
};
|
||||
|
||||
const [result, total] = await Promise.all([
|
||||
MongoChatInputGuide.find(params)
|
||||
.sort({ _id: -1 })
|
||||
.skip(pageSize * (current - 1))
|
||||
.limit(pageSize),
|
||||
MongoChatInputGuide.countDocuments(params)
|
||||
]);
|
||||
|
||||
return {
|
||||
list: result,
|
||||
total
|
||||
};
|
||||
}
|
||||
|
||||
export default NextAPI(handler);
|
34
projects/app/src/pages/api/core/chat/inputGuide/query.ts
Normal file
34
projects/app/src/pages/api/core/chat/inputGuide/query.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import type { NextApiResponse } from 'next';
|
||||
import { MongoChatInputGuide } from '@fastgpt/service/core/chat/inputGuide/schema';
|
||||
import { NextAPI } from '@/service/middleware/entry';
|
||||
import { ApiRequestProps } from '@fastgpt/service/type/next';
|
||||
import { authApp } from '@fastgpt/service/support/permission/auth/app';
|
||||
|
||||
export type QueryChatInputGuideProps = {
|
||||
appId: string;
|
||||
searchKey: string;
|
||||
};
|
||||
export type QueryChatInputGuideResponse = string[];
|
||||
|
||||
async function handler(
|
||||
req: ApiRequestProps<{}, QueryChatInputGuideProps>,
|
||||
res: NextApiResponse<any>
|
||||
): Promise<QueryChatInputGuideResponse> {
|
||||
const { appId, searchKey } = req.query;
|
||||
|
||||
await authApp({ req, appId, authToken: true, authApiKey: true, per: 'r' });
|
||||
|
||||
const params = {
|
||||
appId,
|
||||
...(searchKey && { text: { $regex: new RegExp(searchKey, 'i') } })
|
||||
};
|
||||
|
||||
const result = await MongoChatInputGuide.find(params).sort({ _id: -1 }).limit(6);
|
||||
|
||||
return result
|
||||
.map((item) => item.text)
|
||||
.filter(Boolean)
|
||||
.filter((item) => item !== searchKey);
|
||||
}
|
||||
|
||||
export default NextAPI(handler);
|
36
projects/app/src/pages/api/core/chat/inputGuide/update.ts
Normal file
36
projects/app/src/pages/api/core/chat/inputGuide/update.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import type { ApiRequestProps, ApiResponseType } from '@fastgpt/service/type/next';
|
||||
import { NextAPI } from '@/service/middleware/entry';
|
||||
import { authApp } from '@fastgpt/service/support/permission/auth/app';
|
||||
import { MongoChatInputGuide } from '@fastgpt/service/core/chat/inputGuide/schema';
|
||||
|
||||
export type updateChatInputGuideQuery = {};
|
||||
|
||||
export type updateInputGuideBody = {
|
||||
appId: string;
|
||||
dataId: string;
|
||||
text: string;
|
||||
};
|
||||
|
||||
export type updateInputGuideResponse = {};
|
||||
|
||||
async function handler(
|
||||
req: ApiRequestProps<updateInputGuideBody, updateChatInputGuideQuery>,
|
||||
res: ApiResponseType<any>
|
||||
): Promise<updateInputGuideResponse> {
|
||||
const { appId, dataId, text } = req.body;
|
||||
await authApp({ req, appId, authToken: true, per: 'r' });
|
||||
|
||||
await MongoChatInputGuide.findOneAndUpdate(
|
||||
{
|
||||
_id: dataId,
|
||||
appId
|
||||
},
|
||||
{
|
||||
text
|
||||
}
|
||||
);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
export default NextAPI(handler);
|
@@ -2,7 +2,7 @@ import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
import { jsonRes } from '@fastgpt/service/common/response';
|
||||
import { connectToDatabase } from '@/service/mongo';
|
||||
import type { InitChatResponse, InitOutLinkChatProps } from '@/global/core/chat/api.d';
|
||||
import { getGuideModule, replaceAppChatConfig } from '@fastgpt/global/core/workflow/utils';
|
||||
import { getGuideModule, getAppChatConfig } from '@fastgpt/global/core/workflow/utils';
|
||||
import { getChatModelNameListByModules } from '@/service/core/app/workflow';
|
||||
import { DispatchNodeResponseKeyEnum } from '@fastgpt/global/core/workflow/runtime/constants';
|
||||
import { getChatItems } from '@fastgpt/service/core/chat/controller';
|
||||
@@ -72,10 +72,12 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
variables: chat?.variables || {},
|
||||
history,
|
||||
app: {
|
||||
userGuideModule: replaceAppChatConfig({
|
||||
node: getGuideModule(nodes),
|
||||
variableList: chat?.variableList,
|
||||
welcomeText: chat?.welcomeText
|
||||
chatConfig: getAppChatConfig({
|
||||
chatConfig: app.chatConfig,
|
||||
systemConfigNode: getGuideModule(nodes),
|
||||
storeVariables: chat?.variableList,
|
||||
storeWelcomeText: chat?.welcomeText,
|
||||
isPublicFetch: false
|
||||
}),
|
||||
chatModels: getChatModelNameListByModules(nodes),
|
||||
name: app.name,
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
import { jsonRes } from '@fastgpt/service/common/response';
|
||||
import { connectToDatabase } from '@/service/mongo';
|
||||
import { getGuideModule, replaceAppChatConfig } from '@fastgpt/global/core/workflow/utils';
|
||||
import { getGuideModule, getAppChatConfig } from '@fastgpt/global/core/workflow/utils';
|
||||
import { getChatModelNameListByModules } from '@/service/core/app/workflow';
|
||||
import { DispatchNodeResponseKeyEnum } from '@fastgpt/global/core/workflow/runtime/constants';
|
||||
import type { InitChatResponse, InitTeamChatProps } from '@/global/core/chat/api.d';
|
||||
@@ -73,10 +73,12 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
variables: chat?.variables || {},
|
||||
history,
|
||||
app: {
|
||||
userGuideModule: replaceAppChatConfig({
|
||||
node: getGuideModule(nodes),
|
||||
variableList: chat?.variableList,
|
||||
welcomeText: chat?.welcomeText
|
||||
chatConfig: getAppChatConfig({
|
||||
chatConfig: app.chatConfig,
|
||||
systemConfigNode: getGuideModule(nodes),
|
||||
storeVariables: chat?.variableList,
|
||||
storeWelcomeText: chat?.welcomeText,
|
||||
isPublicFetch: false
|
||||
}),
|
||||
chatModels: getChatModelNameListByModules(nodes),
|
||||
name: app.name,
|
||||
|
@@ -1,82 +0,0 @@
|
||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
import { jsonRes } from '@fastgpt/service/common/response';
|
||||
import { connectToDatabase } from '@/service/mongo';
|
||||
import { authApp } from '@fastgpt/service/support/permission/auth/app';
|
||||
import { getGuideModule } from '@fastgpt/global/core/workflow/utils';
|
||||
import { getChatModelNameListByModules } from '@/service/core/app/workflow';
|
||||
import { NodeOutputKeyEnum } from '@fastgpt/global/core/workflow/constants';
|
||||
import type { InitChatProps, InitChatResponse } from '@/global/core/chat/api.d';
|
||||
import { MongoChat } from '@fastgpt/service/core/chat/chatSchema';
|
||||
import { getChatItems } from '@fastgpt/service/core/chat/controller';
|
||||
import { ChatErrEnum } from '@fastgpt/global/common/error/code/chat';
|
||||
import { DispatchNodeResponseKeyEnum } from '@fastgpt/global/core/workflow/runtime/constants';
|
||||
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
try {
|
||||
await connectToDatabase();
|
||||
|
||||
let { appId, chatId, loadCustomFeedbacks } = req.query as InitChatProps;
|
||||
|
||||
if (!appId) {
|
||||
return jsonRes(res, {
|
||||
code: 501,
|
||||
message: "You don't have an app yet"
|
||||
});
|
||||
}
|
||||
|
||||
// auth app permission
|
||||
const [{ app, tmbId }, chat] = await Promise.all([
|
||||
authApp({
|
||||
req,
|
||||
authToken: true,
|
||||
appId,
|
||||
per: 'r'
|
||||
}),
|
||||
chatId ? MongoChat.findOne({ appId, chatId }) : undefined
|
||||
]);
|
||||
|
||||
// // auth chat permission
|
||||
// if (chat && !app.canWrite && String(tmbId) !== String(chat?.tmbId)) {
|
||||
// throw new Error(ChatErrEnum.unAuthChat);
|
||||
// }
|
||||
|
||||
// get app and history
|
||||
const { history } = await getChatItems({
|
||||
appId,
|
||||
chatId,
|
||||
limit: 30,
|
||||
field: `dataId obj value adminFeedback userBadFeedback userGoodFeedback ${
|
||||
DispatchNodeResponseKeyEnum.nodeResponse
|
||||
} ${loadCustomFeedbacks ? 'customFeedbacks' : ''}`
|
||||
});
|
||||
|
||||
jsonRes<InitChatResponse>(res, {
|
||||
data: {
|
||||
chatId,
|
||||
appId,
|
||||
title: chat?.title || '新对话',
|
||||
userAvatar: undefined,
|
||||
variables: chat?.variables || {},
|
||||
history,
|
||||
app: {
|
||||
userGuideModule: getGuideModule(app.modules),
|
||||
chatModels: getChatModelNameListByModules(app.modules),
|
||||
name: app.name,
|
||||
avatar: app.avatar,
|
||||
intro: app.intro
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (err) {
|
||||
jsonRes(res, {
|
||||
code: 500,
|
||||
error: err
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const config = {
|
||||
api: {
|
||||
responseLimit: '10mb'
|
||||
}
|
||||
};
|
@@ -26,7 +26,7 @@ async function handler(
|
||||
});
|
||||
|
||||
const [rebuildingCount, trainingCount] = await Promise.all([
|
||||
MongoDatasetData.countDocuments({ teamId, datasetId, rebuilding: true }),
|
||||
MongoDatasetData.countDocuments({ rebuilding: true, teamId, datasetId }),
|
||||
MongoDatasetTraining.countDocuments({ teamId, datasetId })
|
||||
]);
|
||||
|
||||
|
@@ -7,7 +7,6 @@ import { getAIApi } from '@fastgpt/service/core/ai/config';
|
||||
import { pushWhisperUsage } from '@/service/support/wallet/usage/push';
|
||||
import { authChatCert } from '@/service/support/permission/auth/chat';
|
||||
import { MongoApp } from '@fastgpt/service/core/app/schema';
|
||||
import { getGuideModule, splitGuideModule } from '@fastgpt/global/core/workflow/utils';
|
||||
import { OutLinkChatAuthProps } from '@fastgpt/global/support/permission/chat';
|
||||
import { NextAPI } from '@/service/middleware/entry';
|
||||
|
||||
@@ -47,14 +46,13 @@ async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
|
||||
// auth role
|
||||
const { teamId, tmbId } = await authChatCert({ req, authToken: true });
|
||||
// auth app
|
||||
const app = await MongoApp.findById(appId, 'modules').lean();
|
||||
if (!app) {
|
||||
throw new Error('app not found');
|
||||
}
|
||||
const { whisperConfig } = splitGuideModule(getGuideModule(app?.modules));
|
||||
if (!whisperConfig?.open) {
|
||||
throw new Error('Whisper is not open in the app');
|
||||
}
|
||||
// const app = await MongoApp.findById(appId, 'modules').lean();
|
||||
// if (!app) {
|
||||
// throw new Error('app not found');
|
||||
// }
|
||||
// if (!whisperConfig?.open) {
|
||||
// throw new Error('Whisper is not open in the app');
|
||||
// }
|
||||
|
||||
const ai = getAIApi();
|
||||
|
||||
|
@@ -170,7 +170,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
|
||||
// 1. get and concat history; 2. get app workflow
|
||||
const limit = getMaxHistoryLimitFromNodes(app.modules);
|
||||
const [{ history }, { nodes, edges }] = await Promise.all([
|
||||
const [{ history }, { nodes, edges, chatConfig }] = await Promise.all([
|
||||
getChatItems({
|
||||
appId: app._id,
|
||||
chatId,
|
||||
@@ -249,6 +249,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
teamId,
|
||||
tmbId: tmbId,
|
||||
nodes,
|
||||
appChatConfig: chatConfig,
|
||||
variables: newVariables,
|
||||
isUpdateUseTime: isOwnerUse && source === ChatSourceEnum.online, // owner update use time
|
||||
shareId,
|
||||
|
@@ -1,7 +1,6 @@
|
||||
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { Box, Flex, IconButton, useTheme, useDisclosure, Button } from '@chakra-ui/react';
|
||||
import { StoreNodeItemType } from '@fastgpt/global/core/workflow/type/index.d';
|
||||
import { AppSchema } from '@fastgpt/global/core/app/type.d';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useCopyData } from '@/web/common/hooks/useCopyData';
|
||||
import { AppTypeEnum } from '@fastgpt/global/core/app/constants';
|
||||
@@ -9,8 +8,7 @@ import dynamic from 'next/dynamic';
|
||||
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import ChatTest, { type ChatTestComponentRef } from '@/components/core/workflow/Flow/ChatTest';
|
||||
import { flowNode2StoreNodes } from '@/components/core/workflow/utils';
|
||||
import { useAppStore } from '@/web/core/app/store/useAppStore';
|
||||
import { uiWorkflow2StoreWorkflow } from '@/components/core/workflow/utils';
|
||||
import { useToast } from '@fastgpt/web/hooks/useToast';
|
||||
import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
|
||||
import { getErrText } from '@fastgpt/global/common/error/utils';
|
||||
@@ -27,19 +25,16 @@ import { useContextSelector } from 'use-context-selector';
|
||||
import { WorkflowContext, getWorkflowStore } from '@/components/core/workflow/context';
|
||||
import { useInterval, useUpdateEffect } from 'ahooks';
|
||||
import { useI18n } from '@/web/context/I18n';
|
||||
import { getGuideModule, splitGuideModule } from '@fastgpt/global/core/workflow/utils';
|
||||
import { importQuestionGuides } from '@/web/core/app/api';
|
||||
import { getAppQGuideCustomURL, getNodesWithNoQGuide } from '@/web/core/app/utils';
|
||||
import { AppContext } from '@/web/core/app/context/appContext';
|
||||
|
||||
const ImportSettings = dynamic(() => import('@/components/core/workflow/Flow/ImportSettings'));
|
||||
const PublishHistories = dynamic(
|
||||
() => import('@/components/core/workflow/components/PublishHistoriesSlider')
|
||||
);
|
||||
|
||||
type Props = { app: AppSchema; onClose: () => void };
|
||||
type Props = { onClose: () => void };
|
||||
|
||||
const RenderHeaderContainer = React.memo(function RenderHeaderContainer({
|
||||
app,
|
||||
ChatTestRef,
|
||||
setWorkflowTestData,
|
||||
onClose
|
||||
@@ -55,7 +50,9 @@ const RenderHeaderContainer = React.memo(function RenderHeaderContainer({
|
||||
>
|
||||
>;
|
||||
}) {
|
||||
const isV2Workflow = app?.version === 'v2';
|
||||
const { appDetail } = useContextSelector(AppContext, (v) => v);
|
||||
|
||||
const isV2Workflow = appDetail?.version === 'v2';
|
||||
|
||||
const theme = useTheme();
|
||||
const { toast } = useToast();
|
||||
@@ -66,7 +63,7 @@ const RenderHeaderContainer = React.memo(function RenderHeaderContainer({
|
||||
const { openConfirm: openConfigPublish, ConfirmModal } = useConfirm({
|
||||
content: t('core.app.Publish Confirm')
|
||||
});
|
||||
const { publishApp, updateAppDetail } = useAppStore();
|
||||
const { publishApp, updateAppDetail } = useContextSelector(AppContext, (v) => v);
|
||||
const edges = useContextSelector(WorkflowContext, (v) => v.edges);
|
||||
|
||||
const [isSaving, setIsSaving] = useState(false);
|
||||
@@ -90,7 +87,7 @@ const RenderHeaderContainer = React.memo(function RenderHeaderContainer({
|
||||
const checkResults = checkWorkflowNodeAndConnection({ nodes, edges });
|
||||
|
||||
if (!checkResults) {
|
||||
const storeNodes = flowNode2StoreNodes({ nodes, edges });
|
||||
const storeNodes = uiWorkflow2StoreWorkflow({ nodes, edges });
|
||||
|
||||
return storeNodes;
|
||||
} else {
|
||||
@@ -112,12 +109,13 @@ const RenderHeaderContainer = React.memo(function RenderHeaderContainer({
|
||||
if (nodes.length === 0) return null;
|
||||
setIsSaving(true);
|
||||
|
||||
const storeWorkflow = flowNode2StoreNodes({ nodes, edges });
|
||||
const storeWorkflow = uiWorkflow2StoreWorkflow({ nodes, edges });
|
||||
|
||||
try {
|
||||
await updateAppDetail(app._id, {
|
||||
await updateAppDetail({
|
||||
...storeWorkflow,
|
||||
type: AppTypeEnum.advanced,
|
||||
chatConfig: appDetail.chatConfig,
|
||||
//@ts-ignore
|
||||
version: 'v2'
|
||||
});
|
||||
@@ -134,7 +132,7 @@ const RenderHeaderContainer = React.memo(function RenderHeaderContainer({
|
||||
|
||||
return null;
|
||||
},
|
||||
[isV2Workflow, isShowVersionHistories, edges, updateAppDetail, app._id, t]
|
||||
[isV2Workflow, isShowVersionHistories, edges, updateAppDetail, appDetail.chatConfig, t]
|
||||
);
|
||||
|
||||
const onclickPublish = useCallback(async () => {
|
||||
@@ -142,19 +140,10 @@ const RenderHeaderContainer = React.memo(function RenderHeaderContainer({
|
||||
const data = await flowData2StoreDataAndCheck();
|
||||
if (data) {
|
||||
try {
|
||||
const { questionGuideText } = splitGuideModule(getGuideModule(data.nodes));
|
||||
await importQuestionGuides({
|
||||
appId: app._id,
|
||||
textList: questionGuideText.textList,
|
||||
customURL: getAppQGuideCustomURL(app)
|
||||
});
|
||||
|
||||
const newNodes = getNodesWithNoQGuide(data.nodes, questionGuideText);
|
||||
|
||||
await publishApp(app._id, {
|
||||
await publishApp({
|
||||
...data,
|
||||
nodes: newNodes,
|
||||
type: AppTypeEnum.advanced,
|
||||
chatConfig: appDetail.chatConfig,
|
||||
//@ts-ignore
|
||||
version: 'v2'
|
||||
});
|
||||
@@ -172,7 +161,7 @@ const RenderHeaderContainer = React.memo(function RenderHeaderContainer({
|
||||
}
|
||||
|
||||
setIsSaving(false);
|
||||
}, [flowData2StoreDataAndCheck, publishApp, app._id, toast, t, ChatTestRef]);
|
||||
}, [flowData2StoreDataAndCheck, publishApp, appDetail.chatConfig, toast, t, ChatTestRef]);
|
||||
|
||||
const saveAndBack = useCallback(async () => {
|
||||
try {
|
||||
@@ -188,7 +177,8 @@ const RenderHeaderContainer = React.memo(function RenderHeaderContainer({
|
||||
JSON.stringify(
|
||||
{
|
||||
nodes: filterSensitiveNodesData(data.nodes),
|
||||
edges: data.edges
|
||||
edges: data.edges,
|
||||
chatConfig: appDetail.chatConfig
|
||||
},
|
||||
null,
|
||||
2
|
||||
@@ -196,7 +186,7 @@ const RenderHeaderContainer = React.memo(function RenderHeaderContainer({
|
||||
appT('Export Config Successful')
|
||||
);
|
||||
}
|
||||
}, [appT, copyData, flowData2StoreDataAndCheck]);
|
||||
}, [appDetail.chatConfig, appT, copyData, flowData2StoreDataAndCheck]);
|
||||
|
||||
// effect
|
||||
useBeforeunload({
|
||||
@@ -205,7 +195,7 @@ const RenderHeaderContainer = React.memo(function RenderHeaderContainer({
|
||||
});
|
||||
|
||||
useInterval(() => {
|
||||
if (!app._id) return;
|
||||
if (!appDetail._id) return;
|
||||
onclickSave(!!workflowDebugData);
|
||||
}, 20000);
|
||||
|
||||
@@ -235,7 +225,7 @@ const RenderHeaderContainer = React.memo(function RenderHeaderContainer({
|
||||
/>
|
||||
<Box ml={[2, 4]}>
|
||||
<Box fontSize={['md', 'lg']} fontWeight={'bold'}>
|
||||
{app.name}
|
||||
{appDetail.name}
|
||||
</Box>
|
||||
{!isShowVersionHistories && isV2Workflow && (
|
||||
<MyTooltip label={t('core.app.Onclick to save')}>
|
||||
@@ -327,7 +317,7 @@ const RenderHeaderContainer = React.memo(function RenderHeaderContainer({
|
||||
theme.borders.base,
|
||||
isSaving,
|
||||
saveAndBack,
|
||||
app.name,
|
||||
appDetail.name,
|
||||
isShowVersionHistories,
|
||||
isV2Workflow,
|
||||
t,
|
||||
@@ -354,7 +344,6 @@ const RenderHeaderContainer = React.memo(function RenderHeaderContainer({
|
||||
});
|
||||
|
||||
const Header = (props: Props) => {
|
||||
const { app } = props;
|
||||
const ChatTestRef = useRef<ChatTestComponentRef>(null);
|
||||
|
||||
const [workflowTestData, setWorkflowTestData] = useState<{
|
||||
@@ -374,13 +363,7 @@ const Header = (props: Props) => {
|
||||
ChatTestRef={ChatTestRef}
|
||||
setWorkflowTestData={setWorkflowTestData}
|
||||
/>
|
||||
<ChatTest
|
||||
ref={ChatTestRef}
|
||||
isOpen={isOpenTest}
|
||||
{...workflowTestData}
|
||||
app={app}
|
||||
onClose={onCloseTest}
|
||||
/>
|
||||
<ChatTest ref={ChatTestRef} isOpen={isOpenTest} {...workflowTestData} onClose={onCloseTest} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@@ -7,11 +7,15 @@ import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
|
||||
import { v1Workflow2V2 } from '@/web/core/workflow/adapt';
|
||||
import WorkflowContextProvider, { WorkflowContext } from '@/components/core/workflow/context';
|
||||
import { useContextSelector } from 'use-context-selector';
|
||||
import { AppContext } from '@/web/core/app/context/appContext';
|
||||
import { useMount } from 'ahooks';
|
||||
|
||||
type Props = { app: AppSchema; onClose: () => void };
|
||||
type Props = { onClose: () => void };
|
||||
|
||||
const Render = ({ app, onClose }: Props) => {
|
||||
const isV2Workflow = app?.version === 'v2';
|
||||
const Render = ({ onClose }: Props) => {
|
||||
const appDetail = useContextSelector(AppContext, (e) => e.appDetail);
|
||||
|
||||
const isV2Workflow = appDetail?.version === 'v2';
|
||||
const { openConfirm, ConfirmModal } = useConfirm({
|
||||
showCancel: false,
|
||||
content:
|
||||
@@ -21,26 +25,23 @@ const Render = ({ app, onClose }: Props) => {
|
||||
const initData = useContextSelector(WorkflowContext, (v) => v.initData);
|
||||
|
||||
const workflowStringData = JSON.stringify({
|
||||
nodes: app.modules || [],
|
||||
edges: app.edges || []
|
||||
nodes: appDetail.modules || [],
|
||||
edges: appDetail.edges || []
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (!isV2Workflow) return;
|
||||
initData(JSON.parse(workflowStringData));
|
||||
}, [isV2Workflow, initData, app._id, workflowStringData]);
|
||||
|
||||
useEffect(() => {
|
||||
useMount(() => {
|
||||
if (!isV2Workflow) {
|
||||
openConfirm(() => {
|
||||
initData(JSON.parse(JSON.stringify(v1Workflow2V2((app.modules || []) as any))));
|
||||
initData(JSON.parse(JSON.stringify(v1Workflow2V2((appDetail.modules || []) as any))));
|
||||
})();
|
||||
} else {
|
||||
initData(JSON.parse(workflowStringData));
|
||||
}
|
||||
}, [app.modules, initData, isV2Workflow, openConfirm]);
|
||||
});
|
||||
|
||||
const memoRender = useMemo(() => {
|
||||
return <Flow Header={<Header app={app} onClose={onClose} />} />;
|
||||
}, [app, onClose]);
|
||||
return <Flow Header={<Header onClose={onClose} />} />;
|
||||
}, [onClose]);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -51,12 +52,13 @@ const Render = ({ app, onClose }: Props) => {
|
||||
};
|
||||
|
||||
export default React.memo(function FlowEdit(props: Props) {
|
||||
const filterAppIds = useMemo(() => [props.app._id], [props.app._id]);
|
||||
const appDetail = useContextSelector(AppContext, (e) => e.appDetail);
|
||||
const filterAppIds = useMemo(() => [appDetail._id], [appDetail._id]);
|
||||
|
||||
return (
|
||||
<WorkflowContextProvider
|
||||
value={{
|
||||
appId: props.app._id,
|
||||
appId: appDetail._id,
|
||||
mode: 'app',
|
||||
filterAppIds,
|
||||
basicNodeTemplates: appSystemModuleTemplates
|
||||
|
@@ -19,10 +19,11 @@ import { getErrText } from '@fastgpt/global/common/error/utils';
|
||||
import { useRequest } from '@fastgpt/web/hooks/useRequest';
|
||||
import Avatar from '@/components/Avatar';
|
||||
import MyModal from '@fastgpt/web/components/common/MyModal';
|
||||
import { useAppStore } from '@/web/core/app/store/useAppStore';
|
||||
import PermissionRadio from '@/components/support/permission/Radio';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { MongoImageTypeEnum } from '@fastgpt/global/common/file/image/constants';
|
||||
import { AppContext } from '@/web/core/app/context/appContext';
|
||||
import { useContextSelector } from 'use-context-selector';
|
||||
|
||||
const InfoModal = ({
|
||||
defaultApp,
|
||||
@@ -35,7 +36,7 @@ const InfoModal = ({
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const { toast } = useToast();
|
||||
const { updateAppDetail } = useAppStore();
|
||||
const { updateAppDetail } = useContextSelector(AppContext, (v) => v);
|
||||
|
||||
const { File, onOpen: onOpenSelectFile } = useSelectFile({
|
||||
fileType: '.jpg,.png',
|
||||
@@ -55,7 +56,7 @@ const InfoModal = ({
|
||||
// submit config
|
||||
const { mutate: saveSubmitSuccess, isLoading: btnLoading } = useRequest({
|
||||
mutationFn: async (data: AppSchema) => {
|
||||
await updateAppDetail(data._id, {
|
||||
await updateAppDetail({
|
||||
name: data.name,
|
||||
avatar: data.avatar,
|
||||
intro: data.intro,
|
||||
|
@@ -335,7 +335,7 @@ const DetailLogsModal = ({
|
||||
feedbackType={'admin'}
|
||||
showMarkIcon
|
||||
showVoiceIcon={false}
|
||||
userGuideModule={chat?.app?.userGuideModule}
|
||||
chatConfig={chat?.app?.chatConfig}
|
||||
appId={appId}
|
||||
chatId={chatId}
|
||||
/>
|
||||
|
@@ -8,7 +8,6 @@ import { useToast } from '@fastgpt/web/hooks/useToast';
|
||||
import { AppSchema } from '@fastgpt/global/core/app/type.d';
|
||||
import { delModelById } from '@/web/core/app/api';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useAppStore } from '@/web/core/app/store/useAppStore';
|
||||
import PermissionIconText from '@/components/support/permission/IconText';
|
||||
import dynamic from 'next/dynamic';
|
||||
import Avatar from '@/components/Avatar';
|
||||
@@ -16,6 +15,8 @@ import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import TagsEditModal from './TagsEditModal';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import { useI18n } from '@/web/context/I18n';
|
||||
import { AppContext } from '@/web/core/app/context/appContext';
|
||||
import { useContextSelector } from 'use-context-selector';
|
||||
const InfoModal = dynamic(() => import('../InfoModal'));
|
||||
|
||||
const AppCard = ({ appId }: { appId: string }) => {
|
||||
@@ -24,7 +25,7 @@ const AppCard = ({ appId }: { appId: string }) => {
|
||||
const { appT } = useI18n();
|
||||
|
||||
const { toast } = useToast();
|
||||
const { appDetail } = useAppStore();
|
||||
const { appDetail } = useContextSelector(AppContext, (v) => v);
|
||||
const { feConfigs } = useSystemStore();
|
||||
const [settingAppInfo, setSettingAppInfo] = useState<AppSchema>();
|
||||
const [TeamTagsSet, setTeamTagsSet] = useState<AppSchema>();
|
||||
|
@@ -16,12 +16,13 @@ import {
|
||||
initWorkflowEdgeStatus,
|
||||
storeNodes2RuntimeNodes
|
||||
} from '@fastgpt/global/core/workflow/runtime/utils';
|
||||
import { useCreation, useMemoizedFn, useSafeState } from 'ahooks';
|
||||
import { useMemoizedFn, useSafeState } from 'ahooks';
|
||||
import { UseFormReturn } from 'react-hook-form';
|
||||
import { AppSimpleEditFormType } from '@fastgpt/global/core/app/type';
|
||||
import { useAppStore } from '@/web/core/app/store/useAppStore';
|
||||
import { form2AppWorkflow } from '@/web/core/app/utils';
|
||||
import { useI18n } from '@/web/context/I18n';
|
||||
import { useContextSelector } from 'use-context-selector';
|
||||
import { AppContext } from '@/web/core/app/context/appContext';
|
||||
|
||||
const ChatTest = ({
|
||||
editForm,
|
||||
@@ -35,18 +36,15 @@ const ChatTest = ({
|
||||
|
||||
const { userInfo } = useUserStore();
|
||||
const ChatBoxRef = useRef<ComponentRef>(null);
|
||||
const { appDetail } = useAppStore();
|
||||
const { appDetail } = useContextSelector(AppContext, (v) => v);
|
||||
|
||||
const { watch } = editForm;
|
||||
const chatConfig = watch('chatConfig');
|
||||
|
||||
const [workflowData, setWorkflowData] = useSafeState({
|
||||
nodes: appDetail.modules || [],
|
||||
edges: appDetail.edges || []
|
||||
});
|
||||
const userGuideModule = useCreation(
|
||||
() => getGuideModule(workflowData.nodes),
|
||||
[workflowData.nodes]
|
||||
);
|
||||
|
||||
const startChat = useMemoizedFn(
|
||||
async ({ chatList, controller, generatingMessage, variables }: StartChatFnProps) => {
|
||||
@@ -131,7 +129,7 @@ const ChatTest = ({
|
||||
appAvatar={appDetail.avatar}
|
||||
userAvatar={userInfo?.avatar}
|
||||
showMarkIcon
|
||||
userGuideModule={userGuideModule}
|
||||
chatConfig={chatConfig}
|
||||
showFileSelector={checkChatSupportSelectFileByModules(workflowData.nodes)}
|
||||
onStartChat={startChat}
|
||||
onDelMessage={() => {}}
|
||||
|
@@ -11,12 +11,7 @@ import { useRouter } from 'next/router';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { AppTypeEnum } from '@fastgpt/global/core/app/constants';
|
||||
import { useDatasetStore } from '@/web/core/dataset/store/dataset';
|
||||
import { useAppStore } from '@/web/core/app/store/useAppStore';
|
||||
import {
|
||||
form2AppWorkflow,
|
||||
getAppQGuideCustomURL,
|
||||
getNodesWithNoQGuide
|
||||
} from '@/web/core/app/utils';
|
||||
import { form2AppWorkflow } from '@/web/core/app/utils';
|
||||
|
||||
import dynamic from 'next/dynamic';
|
||||
import MyTooltip from '@/components/MyTooltip';
|
||||
@@ -34,15 +29,27 @@ import { TTSTypeEnum } from '@/web/core/app/constants';
|
||||
import { getSystemVariables } from '@/web/core/app/utils';
|
||||
import { useUpdate } from 'ahooks';
|
||||
import { useI18n } from '@/web/context/I18n';
|
||||
import { importQuestionGuides } from '@/web/core/app/api';
|
||||
import { useContextSelector } from 'use-context-selector';
|
||||
import { AppContext } from '@/web/core/app/context/appContext';
|
||||
|
||||
const DatasetSelectModal = dynamic(() => import('@/components/core/app/DatasetSelectModal'));
|
||||
const DatasetParamsModal = dynamic(() => import('@/components/core/app/DatasetParamsModal'));
|
||||
const ToolSelectModal = dynamic(() => import('./ToolSelectModal'));
|
||||
const TTSSelect = dynamic(() => import('@/components/core/app/TTSSelect'));
|
||||
const QGSwitch = dynamic(() => import('@/components/core/app/QGSwitch'));
|
||||
const WhisperConfig = dynamic(() => import('@/components/core/app/WhisperConfig'));
|
||||
const QGuidesConfigModal = dynamic(() => import('@/components/core/app/QGuidesConfig'));
|
||||
const DatasetSelectModal = dynamic(() => import('@/components/core/app/DatasetSelectModal'), {
|
||||
ssr: false
|
||||
});
|
||||
const DatasetParamsModal = dynamic(() => import('@/components/core/app/DatasetParamsModal'), {
|
||||
ssr: false
|
||||
});
|
||||
const ToolSelectModal = dynamic(() => import('./ToolSelectModal'), { ssr: false });
|
||||
const TTSSelect = dynamic(() => import('@/components/core/app/TTSSelect'), { ssr: false });
|
||||
const QGSwitch = dynamic(() => import('@/components/core/app/QGSwitch'), { ssr: false });
|
||||
const WhisperConfig = dynamic(() => import('@/components/core/app/WhisperConfig'), { ssr: false });
|
||||
const InputGuideConfig = dynamic(
|
||||
() => import('@/components/core/chat/appConfig/InputGuideConfig'),
|
||||
{ ssr: false }
|
||||
);
|
||||
const ScheduledTriggerConfig = dynamic(
|
||||
() => import('@/components/core/app/ScheduledTriggerConfig'),
|
||||
{ ssr: false }
|
||||
);
|
||||
|
||||
const BoxStyles: BoxProps = {
|
||||
px: 5,
|
||||
@@ -70,7 +77,7 @@ const EditForm = ({
|
||||
const { t } = useTranslation();
|
||||
const { appT } = useI18n();
|
||||
|
||||
const { appDetail, publishApp } = useAppStore();
|
||||
const { appDetail, publishApp } = useContextSelector(AppContext, (v) => v);
|
||||
|
||||
const { allDatasets } = useDatasetStore();
|
||||
const { llmModelList } = useSystemStore();
|
||||
@@ -107,18 +114,19 @@ const EditForm = ({
|
||||
const aiSystemPrompt = watch('aiSettings.systemPrompt');
|
||||
const selectLLMModel = watch('aiSettings.model');
|
||||
const datasetSearchSetting = watch('dataset');
|
||||
const variables = watch('userGuide.variables');
|
||||
const variables = watch('chatConfig.variables');
|
||||
|
||||
const formatVariables: any = useMemo(
|
||||
() => formatEditorVariablePickerIcon([...getSystemVariables(t), ...variables]),
|
||||
() => formatEditorVariablePickerIcon([...getSystemVariables(t), ...(variables || [])]),
|
||||
[t, variables]
|
||||
);
|
||||
const searchMode = watch('dataset.searchMode');
|
||||
const tts = getValues('userGuide.tts');
|
||||
const whisperConfig = getValues('userGuide.whisper');
|
||||
const postQuestionGuide = getValues('userGuide.questionGuide');
|
||||
const tts = getValues('chatConfig.ttsConfig');
|
||||
const whisperConfig = getValues('chatConfig.whisperConfig');
|
||||
const postQuestionGuide = getValues('chatConfig.questionGuide');
|
||||
const selectedTools = watch('selectedTools');
|
||||
const QGuidesConfig = watch('userGuide.questionGuideText');
|
||||
const inputGuideConfig = watch('chatConfig.chatInputGuide');
|
||||
const scheduledTriggerConfig = watch('chatConfig.scheduledTriggerConfig');
|
||||
const searchMode = watch('dataset.searchMode');
|
||||
|
||||
const selectDatasets = useMemo(
|
||||
() => allDatasets.filter((item) => datasets.find((dataset) => dataset.datasetId === item._id)),
|
||||
@@ -132,20 +140,11 @@ const EditForm = ({
|
||||
/* on save app */
|
||||
const { mutate: onSubmitPublish, isLoading: isSaving } = useRequest({
|
||||
mutationFn: async (data: AppSimpleEditFormType) => {
|
||||
const questionGuideText = data.userGuide.questionGuideText;
|
||||
await importQuestionGuides({
|
||||
appId: appDetail._id,
|
||||
textList: questionGuideText.textList,
|
||||
customURL: getAppQGuideCustomURL(appDetail)
|
||||
});
|
||||
|
||||
const { nodes, edges } = form2AppWorkflow(data);
|
||||
|
||||
const newNodes = getNodesWithNoQGuide(nodes, questionGuideText);
|
||||
|
||||
await publishApp(appDetail._id, {
|
||||
nodes: newNodes,
|
||||
await publishApp({
|
||||
nodes,
|
||||
edges,
|
||||
chatConfig: data.chatConfig,
|
||||
type: AppTypeEnum.simple
|
||||
});
|
||||
},
|
||||
@@ -403,7 +402,7 @@ const EditForm = ({
|
||||
<VariableEdit
|
||||
variables={variables}
|
||||
onChange={(e) => {
|
||||
setValue('userGuide.variables', e);
|
||||
setValue('chatConfig.variables', e);
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
@@ -422,9 +421,9 @@ const EditForm = ({
|
||||
bg={'myWhite.400'}
|
||||
rows={5}
|
||||
placeholder={t(welcomeTextTip)}
|
||||
defaultValue={getValues('userGuide.welcomeText')}
|
||||
defaultValue={getValues('chatConfig.welcomeText')}
|
||||
onBlur={(e) => {
|
||||
setValue('userGuide.welcomeText', e.target.value || '');
|
||||
setValue('chatConfig.welcomeText', e.target.value || '');
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
@@ -434,7 +433,7 @@ const EditForm = ({
|
||||
<TTSSelect
|
||||
value={tts}
|
||||
onChange={(e) => {
|
||||
setValue('userGuide.tts', e);
|
||||
setValue('chatConfig.ttsConfig', e);
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
@@ -442,10 +441,10 @@ const EditForm = ({
|
||||
{/* whisper */}
|
||||
<Box {...BoxStyles}>
|
||||
<WhisperConfig
|
||||
isOpenAudio={tts.type !== TTSTypeEnum.none}
|
||||
isOpenAudio={tts?.type !== TTSTypeEnum.none}
|
||||
value={whisperConfig}
|
||||
onChange={(e) => {
|
||||
setValue('userGuide.whisper', e);
|
||||
setValue('chatConfig.whisperConfig', e);
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
@@ -456,17 +455,28 @@ const EditForm = ({
|
||||
isChecked={postQuestionGuide}
|
||||
size={'lg'}
|
||||
onChange={(e) => {
|
||||
setValue('userGuide.questionGuide', e.target.checked);
|
||||
setValue('chatConfig.questionGuide', e.target.checked);
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
{/* question tips */}
|
||||
<Box {...BoxStyles} borderBottom={'none'}>
|
||||
<QGuidesConfigModal
|
||||
value={QGuidesConfig}
|
||||
<Box {...BoxStyles}>
|
||||
<InputGuideConfig
|
||||
appId={appDetail._id}
|
||||
value={inputGuideConfig}
|
||||
onChange={(e) => {
|
||||
setValue('userGuide.questionGuideText', e);
|
||||
setValue('chatConfig.chatInputGuide', e);
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
{/* timer trigger */}
|
||||
<Box {...BoxStyles} borderBottom={'none'}>
|
||||
<ScheduledTriggerConfig
|
||||
value={scheduledTriggerConfig}
|
||||
onChange={(e) => {
|
||||
setValue('chatConfig.scheduledTriggerConfig', e);
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
|
@@ -19,22 +19,22 @@ import {
|
||||
TagLabel
|
||||
} from '@chakra-ui/react';
|
||||
import { useToast } from '@fastgpt/web/hooks/useToast';
|
||||
import { useAppStore } from '@/web/core/app/store/useAppStore';
|
||||
import { useRequest } from '@fastgpt/web/hooks/useRequest';
|
||||
import { getTeamsTags } from '@/web/support/user/team/api';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { useContextSelector } from 'use-context-selector';
|
||||
import { AppContext } from '@/web/core/app/context/appContext';
|
||||
|
||||
const TagsEditModal = ({ onClose }: { onClose: () => void }) => {
|
||||
const { t } = useTranslation();
|
||||
const { appDetail } = useAppStore();
|
||||
const { toast } = useToast();
|
||||
const { updateAppDetail } = useAppStore();
|
||||
const { appDetail, updateAppDetail } = useContextSelector(AppContext, (v) => v);
|
||||
const [selectedTags, setSelectedTags] = useState<string[]>(appDetail?.teamTags || []);
|
||||
|
||||
// submit config
|
||||
const { mutate: saveSubmitSuccess, isLoading: btnLoading } = useRequest({
|
||||
mutationFn: async () => {
|
||||
await updateAppDetail(appDetail._id, {
|
||||
await updateAppDetail({
|
||||
teamTags: selectedTags
|
||||
});
|
||||
},
|
||||
|
@@ -4,36 +4,42 @@ import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import { useSticky } from '@/web/common/hooks/useSticky';
|
||||
import { useMount } from 'ahooks';
|
||||
import { useDatasetStore } from '@/web/core/dataset/store/dataset';
|
||||
import { useAppStore } from '@/web/core/app/store/useAppStore';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { appWorkflow2Form } from '@fastgpt/global/core/app/utils';
|
||||
import { appWorkflow2Form, getDefaultAppForm } from '@fastgpt/global/core/app/utils';
|
||||
|
||||
import ChatTest from './ChatTest';
|
||||
import AppCard from './AppCard';
|
||||
import EditForm from './EditForm';
|
||||
import { AppSimpleEditFormType } from '@fastgpt/global/core/app/type';
|
||||
import { v1Workflow2V2 } from '@/web/core/workflow/adapt';
|
||||
import { AppContext } from '@/web/core/app/context/appContext';
|
||||
import { useContextSelector } from 'use-context-selector';
|
||||
|
||||
const SimpleEdit = ({ appId }: { appId: string }) => {
|
||||
const { isPc } = useSystemStore();
|
||||
const { parentRef, divRef, isSticky } = useSticky();
|
||||
const { loadAllDatasets } = useDatasetStore();
|
||||
const { appDetail } = useAppStore();
|
||||
const { appDetail } = useContextSelector(AppContext, (v) => v);
|
||||
|
||||
const editForm = useForm<AppSimpleEditFormType>({
|
||||
defaultValues: appWorkflow2Form({
|
||||
nodes: appDetail.modules
|
||||
})
|
||||
defaultValues: getDefaultAppForm()
|
||||
});
|
||||
|
||||
// show selected dataset
|
||||
useMount(() => {
|
||||
loadAllDatasets();
|
||||
editForm.reset(
|
||||
appWorkflow2Form({
|
||||
nodes: appDetail.modules,
|
||||
chatConfig: appDetail.chatConfig
|
||||
})
|
||||
);
|
||||
|
||||
if (appDetail.version !== 'v2') {
|
||||
editForm.reset(
|
||||
appWorkflow2Form({
|
||||
nodes: v1Workflow2V2((appDetail.modules || []) as any)?.nodes
|
||||
nodes: v1Workflow2V2((appDetail.modules || []) as any)?.nodes,
|
||||
chatConfig: appDetail.chatConfig
|
||||
})
|
||||
);
|
||||
}
|
||||
|
@@ -1,9 +1,7 @@
|
||||
import React, { useEffect, useMemo, useCallback } from 'react';
|
||||
import React, { useMemo, useCallback } from 'react';
|
||||
import { useRouter } from 'next/router';
|
||||
import { Box, Flex, IconButton, useTheme } from '@chakra-ui/react';
|
||||
import dynamic from 'next/dynamic';
|
||||
import { useToast } from '@fastgpt/web/hooks/useToast';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
|
||||
import Tabs from '@/components/Tabs';
|
||||
@@ -14,11 +12,11 @@ import PageContainer from '@/components/PageContainer';
|
||||
import Loading from '@fastgpt/web/components/common/MyLoading';
|
||||
import SimpleEdit from './components/SimpleEdit';
|
||||
import { serviceSideProps } from '@/web/common/utils/i18n';
|
||||
import { useAppStore } from '@/web/core/app/store/useAppStore';
|
||||
import Head from 'next/head';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useI18n } from '@/web/context/I18n';
|
||||
import { getAppQGuideCustomURL } from '@/web/core/app/utils';
|
||||
import { AppContext, AppContextProvider } from '@/web/core/app/context/appContext';
|
||||
import { useContextSelector } from 'use-context-selector';
|
||||
|
||||
const FlowEdit = dynamic(() => import('./components/FlowEdit'), {
|
||||
loading: () => <Loading />
|
||||
@@ -34,19 +32,16 @@ enum TabEnum {
|
||||
'startChat' = 'startChat'
|
||||
}
|
||||
|
||||
const AppDetail = ({ currentTab }: { currentTab: `${TabEnum}` }) => {
|
||||
const AppDetail = ({ appId, currentTab }: { appId: string; currentTab: TabEnum }) => {
|
||||
const { t } = useTranslation();
|
||||
const { appT } = useI18n();
|
||||
|
||||
const router = useRouter();
|
||||
const theme = useTheme();
|
||||
const { feConfigs } = useSystemStore();
|
||||
const { toast } = useToast();
|
||||
const { appId } = router.query as { appId: string };
|
||||
const { appDetail, loadAppDetail } = useAppStore();
|
||||
const { appDetail, loadingApp } = useContextSelector(AppContext, (e) => e);
|
||||
|
||||
const setCurrentTab = useCallback(
|
||||
(tab: `${TabEnum}`) => {
|
||||
(tab: TabEnum) => {
|
||||
router.push({
|
||||
query: {
|
||||
...router.query,
|
||||
@@ -86,26 +81,13 @@ const AppDetail = ({ currentTab }: { currentTab: `${TabEnum}` }) => {
|
||||
|
||||
const onCloseFlowEdit = useCallback(() => setCurrentTab(TabEnum.simpleEdit), [setCurrentTab]);
|
||||
|
||||
const { isSuccess, isLoading } = useQuery([appId], () => loadAppDetail(appId, true), {
|
||||
onError(err: any) {
|
||||
toast({
|
||||
title: err?.message || t('core.app.error.Get app failed'),
|
||||
status: 'error'
|
||||
});
|
||||
router.replace('/app/list');
|
||||
},
|
||||
onSettled() {
|
||||
router.prefetch(`/chat?appId=${appId}`);
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>{appDetail.name}</title>
|
||||
</Head>
|
||||
<PageContainer isLoading={isLoading}>
|
||||
{isSuccess && (
|
||||
<PageContainer isLoading={loadingApp}>
|
||||
{!loadingApp && (
|
||||
<Flex flexDirection={['column', 'row']} h={'100%'}>
|
||||
{/* pc tab */}
|
||||
<Box
|
||||
@@ -180,9 +162,7 @@ const AppDetail = ({ currentTab }: { currentTab: `${TabEnum}` }) => {
|
||||
</Box>
|
||||
<Box flex={'1 0 0'} h={[0, '100%']} overflow={['overlay', '']}>
|
||||
{currentTab === TabEnum.simpleEdit && <SimpleEdit appId={appId} />}
|
||||
{currentTab === TabEnum.adEdit && appDetail && (
|
||||
<FlowEdit app={appDetail} onClose={onCloseFlowEdit} />
|
||||
)}
|
||||
{currentTab === TabEnum.adEdit && appDetail && <FlowEdit onClose={onCloseFlowEdit} />}
|
||||
{currentTab === TabEnum.logs && <Logs appId={appId} />}
|
||||
{currentTab === TabEnum.publish && <Publish appId={appId} />}
|
||||
</Box>
|
||||
@@ -193,15 +173,25 @@ const AppDetail = ({ currentTab }: { currentTab: `${TabEnum}` }) => {
|
||||
);
|
||||
};
|
||||
|
||||
const Provider = ({ appId, currentTab }: { appId: string; currentTab: TabEnum }) => {
|
||||
return (
|
||||
<AppContextProvider appId={appId}>
|
||||
<AppDetail appId={appId} currentTab={currentTab} />
|
||||
</AppContextProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export async function getServerSideProps(context: any) {
|
||||
const currentTab = context?.query?.currentTab || TabEnum.simpleEdit;
|
||||
const appId = context?.query?.appId || '';
|
||||
|
||||
return {
|
||||
props: {
|
||||
currentTab,
|
||||
...(await serviceSideProps(context, ['app', 'file', 'publish', 'workflow']))
|
||||
appId,
|
||||
...(await serviceSideProps(context, ['app', 'chat', 'file', 'publish', 'workflow']))
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default AppDetail;
|
||||
export default Provider;
|
||||
|
@@ -45,7 +45,7 @@ const MyApps = () => {
|
||||
title: '删除成功',
|
||||
status: 'success'
|
||||
});
|
||||
loadMyApps(true);
|
||||
loadMyApps();
|
||||
} catch (err: any) {
|
||||
toast({
|
||||
title: err?.message || t('common.Delete Failed'),
|
||||
@@ -57,7 +57,7 @@ const MyApps = () => {
|
||||
);
|
||||
|
||||
/* 加载模型 */
|
||||
const { isFetching } = useQuery(['loadApps'], () => loadMyApps(true), {
|
||||
const { isFetching } = useQuery(['loadApps'], () => loadMyApps(), {
|
||||
refetchOnMount: true
|
||||
});
|
||||
|
||||
@@ -182,7 +182,7 @@ const MyApps = () => {
|
||||
)}
|
||||
<ConfirmModal />
|
||||
{isOpenCreateModal && (
|
||||
<CreateModal onClose={onCloseCreateModal} onSuccess={() => loadMyApps(true)} />
|
||||
<CreateModal onClose={onCloseCreateModal} onSuccess={() => loadMyApps()} />
|
||||
)}
|
||||
</PageContainer>
|
||||
);
|
||||
|
@@ -33,15 +33,10 @@ import { getErrText } from '@fastgpt/global/common/error/utils';
|
||||
import { useUserStore } from '@/web/support/user/useUserStore';
|
||||
import { serviceSideProps } from '@/web/common/utils/i18n';
|
||||
import { useAppStore } from '@/web/core/app/store/useAppStore';
|
||||
import {
|
||||
checkChatSupportSelectFileByChatModels,
|
||||
getAppQuestionGuidesByUserGuideModule
|
||||
} from '@/web/core/chat/utils';
|
||||
import { checkChatSupportSelectFileByChatModels } from '@/web/core/chat/utils';
|
||||
import { getChatTitleFromChatMessage } from '@fastgpt/global/core/chat/utils';
|
||||
import { ChatStatusEnum } from '@fastgpt/global/core/chat/constants';
|
||||
import { GPTMessages2Chats } from '@fastgpt/global/core/chat/adapt';
|
||||
import { StoreNodeItemType } from '@fastgpt/global/core/workflow/type';
|
||||
import { getAppQGuideCustomURL } from '@/web/core/app/utils';
|
||||
|
||||
const Chat = ({ appId, chatId }: { appId: string; chatId: string }) => {
|
||||
const router = useRouter();
|
||||
@@ -133,7 +128,7 @@ const Chat = ({ appId, chatId }: { appId: string; chatId: string }) => {
|
||||
[appId, chatId, histories, pushHistory, router, setChatData, updateHistory]
|
||||
);
|
||||
|
||||
useQuery(['loadModels'], () => loadMyApps(false));
|
||||
useQuery(['loadModels'], () => loadMyApps());
|
||||
|
||||
// get chat app info
|
||||
const loadChatInfo = useCallback(
|
||||
@@ -354,7 +349,7 @@ const Chat = ({ appId, chatId }: { appId: string; chatId: string }) => {
|
||||
showEmptyIntro
|
||||
appAvatar={chatData.app.avatar}
|
||||
userAvatar={userInfo?.avatar}
|
||||
userGuideModule={chatData.app?.userGuideModule}
|
||||
chatConfig={chatData.app?.chatConfig}
|
||||
showFileSelector={checkChatSupportSelectFileByChatModels(chatData.app.chatModels)}
|
||||
feedbackType={'user'}
|
||||
onStartChat={startChat}
|
||||
|
@@ -20,10 +20,7 @@ import PageContainer from '@/components/PageContainer';
|
||||
import ChatHeader from './components/ChatHeader';
|
||||
import ChatHistorySlider from './components/ChatHistorySlider';
|
||||
import { serviceSideProps } from '@/web/common/utils/i18n';
|
||||
import {
|
||||
checkChatSupportSelectFileByChatModels,
|
||||
getAppQuestionGuidesByUserGuideModule
|
||||
} from '@/web/core/chat/utils';
|
||||
import { checkChatSupportSelectFileByChatModels } from '@/web/core/chat/utils';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { getInitOutLinkChatInfo } from '@/web/core/chat/api';
|
||||
import { getChatTitleFromChatMessage } from '@fastgpt/global/core/chat/utils';
|
||||
@@ -34,9 +31,6 @@ import { MongoOutLink } from '@fastgpt/service/support/outLink/schema';
|
||||
import { OutLinkWithAppType } from '@fastgpt/global/support/outLink/type';
|
||||
import { addLog } from '@fastgpt/service/common/system/log';
|
||||
import { connectToDatabase } from '@/service/mongo';
|
||||
import { StoreNodeItemType } from '@fastgpt/global/core/workflow/type';
|
||||
import { useAppStore } from '@/web/core/app/store/useAppStore';
|
||||
import { getAppQGuideCustomURL } from '@/web/core/app/utils';
|
||||
|
||||
const OutLink = ({
|
||||
appName,
|
||||
@@ -393,7 +387,7 @@ const OutLink = ({
|
||||
ref={ChatBoxRef}
|
||||
appAvatar={chatData.app.avatar}
|
||||
userAvatar={chatData.userAvatar}
|
||||
userGuideModule={chatData.app?.userGuideModule}
|
||||
chatConfig={chatData.app?.chatConfig}
|
||||
showFileSelector={checkChatSupportSelectFileByChatModels(chatData.app.chatModels)}
|
||||
feedbackType={'user'}
|
||||
onUpdateVariable={(e) => {}}
|
||||
|
@@ -39,7 +39,6 @@ import MyBox from '@fastgpt/web/components/common/MyBox';
|
||||
import SliderApps from './components/SliderApps';
|
||||
import { GPTMessages2Chats } from '@fastgpt/global/core/chat/adapt';
|
||||
import { StoreNodeItemType } from '@fastgpt/global/core/workflow/type';
|
||||
import { useAppStore } from '@/web/core/app/store/useAppStore';
|
||||
import { getAppQGuideCustomURL } from '@/web/core/app/utils';
|
||||
|
||||
const OutLink = () => {
|
||||
@@ -364,7 +363,7 @@ const OutLink = () => {
|
||||
ref={ChatBoxRef}
|
||||
appAvatar={chatData.app.avatar}
|
||||
userAvatar={chatData.userAvatar}
|
||||
userGuideModule={chatData.app?.userGuideModule}
|
||||
chatConfig={chatData.app?.chatConfig}
|
||||
showFileSelector={checkChatSupportSelectFileByChatModels(chatData.app.chatModels)}
|
||||
feedbackType={'user'}
|
||||
onUpdateVariable={(e) => {}}
|
||||
|
@@ -7,7 +7,7 @@ import { useCopyData } from '@/web/common/hooks/useCopyData';
|
||||
import dynamic from 'next/dynamic';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import MyTooltip from '@/components/MyTooltip';
|
||||
import { flowNode2StoreNodes } from '@/components/core/workflow/utils';
|
||||
import { uiWorkflow2StoreWorkflow } from '@/components/core/workflow/utils';
|
||||
import { putUpdatePlugin } from '@/web/core/plugin/api';
|
||||
import { useToast } from '@fastgpt/web/hooks/useToast';
|
||||
import MyMenu from '@fastgpt/web/components/common/MyMenu';
|
||||
@@ -39,7 +39,7 @@ const Header = ({ plugin, onClose }: Props) => {
|
||||
|
||||
const checkResults = checkWorkflowNodeAndConnection({ nodes, edges });
|
||||
if (!checkResults) {
|
||||
const storeNodes = flowNode2StoreNodes({ nodes, edges });
|
||||
const storeNodes = uiWorkflow2StoreWorkflow({ nodes, edges });
|
||||
|
||||
return storeNodes;
|
||||
} else {
|
||||
@@ -68,7 +68,7 @@ const Header = ({ plugin, onClose }: Props) => {
|
||||
}
|
||||
});
|
||||
|
||||
const onCopy = useCallback(async () => {
|
||||
const onExportWorkflow = useCallback(async () => {
|
||||
const data = await flowData2StoreDataAndCheck();
|
||||
if (data) {
|
||||
copyData(
|
||||
@@ -125,7 +125,7 @@ const Header = ({ plugin, onClose }: Props) => {
|
||||
{
|
||||
label: appT('Export Configs'),
|
||||
icon: 'export',
|
||||
onClick: onCopy
|
||||
onClick: onExportWorkflow
|
||||
}
|
||||
]}
|
||||
/>
|
||||
@@ -147,7 +147,7 @@ const Header = ({ plugin, onClose }: Props) => {
|
||||
isOpenImport,
|
||||
onClose,
|
||||
onCloseImport,
|
||||
onCopy,
|
||||
onExportWorkflow,
|
||||
onOpenImport,
|
||||
onclickSave,
|
||||
plugin.name,
|
||||
|
@@ -15,6 +15,7 @@ import { v1Workflow2V2 } from '@/web/core/workflow/adapt';
|
||||
import { useBeforeunload } from '@fastgpt/web/hooks/useBeforeunload';
|
||||
import WorkflowContextProvider, { WorkflowContext } from '@/components/core/workflow/context';
|
||||
import { useContextSelector } from 'use-context-selector';
|
||||
import { AppContextProvider } from '@/web/core/app/context/appContext';
|
||||
|
||||
type Props = { pluginId: string };
|
||||
|
||||
@@ -77,13 +78,15 @@ const Render = ({ pluginId }: Props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default function FlowEdit(props: any) {
|
||||
function Provider(props: Props) {
|
||||
return (
|
||||
<WorkflowContextProvider
|
||||
value={{ mode: 'plugin', basicNodeTemplates: pluginSystemModuleTemplates }}
|
||||
>
|
||||
<Render {...props} />
|
||||
</WorkflowContextProvider>
|
||||
<AppContextProvider appId={''}>
|
||||
<WorkflowContextProvider
|
||||
value={{ mode: 'plugin', basicNodeTemplates: pluginSystemModuleTemplates }}
|
||||
>
|
||||
<Render {...props} />
|
||||
</WorkflowContextProvider>
|
||||
</AppContextProvider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -95,3 +98,5 @@ export async function getServerSideProps(context: any) {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default Provider;
|
||||
|
Reference in New Issue
Block a user