mirror of
https://github.com/labring/FastGPT.git
synced 2025-12-26 04:32:50 +00:00
* perf: system toolset & mcp (#5200) * feat: support system toolset * fix: type * fix: system tool config * chore: mcptool config migrate * refactor: mcp toolset * fix: fe type error * fix: type error * fix: show version * chore: support extract tool's secretInputConfig out of inputs * chore: compatible with old version mcp * chore: adjust * deps: update dependency @fastgpt-skd/plugin * fix: version * fix: some bug (#5316) * chore: compatible with old version mcp * fix: version * fix: compatible bug * fix: mcp object params * fix: type error * chore: update test cases * chore: remove log * fix: toolset node name * optimize app logs sort (#5310) * log keys config modal * multiple select * api * fontsize * code * chatid * fix build * fix * fix component * change name * log keys config * fix * delete unused * fix * perf: log code * perf: send auth code modal enter press * fix log (#5328) * perf: mcp toolset comment * perf: log ui * remove log (#5347) * doc * fix: action * remove log * fix: Table Optimization (#5319) * feat: table test: 1 * feat: table test: 2 * feat: table test: 3 * feat: table test: 4 * feat: table test : 5 把maxSize改回chunkSize * feat: table test : 6 都删了,只看maxSize * feat: table test : 7 恢复初始,接下来删除标签功能 * feat: table test : 8 删除标签功能 * feat: table test : 9 删除标签功能成功 * feat: table test : 10 继续调试,修改trainingStates * feat: table test : 11 修改第一步 * feat: table test : 12 修改第二步 * feat: table test : 13 修改了HtmlTable2Md * feat: table test : 14 修改表头分块规则 * feat: table test : 15 前面表格分的太细了 * feat: table test : 16 改着改着表头又不加了 * feat: table test : 17 用CUSTOM_SPLIT_SIGN不行,重新改 * feat: table test : 18 表头仍然还会多加,但现在分块搞的合理了终于 * feat: table test : 19 还是需要搞好表头问题,先保存一下调试情况 * feat: table test : 20 调试结束,看一下replace有没有问题,没问题就pr * feat: table test : 21 先把注释删了 * feat: table test : 21 注释replace都改了,下面切main分支看看情况 * feat: table test : 22 修改旧文件 * feat: table test : 23 修改测试文件 * feat: table test : 24 xlsx表格处理 * feat: table test : 25 刚才没保存先com了 * feat: table test : 26 fix * feat: table test : 27 先com一版调试 * feat: table test : 28 试试放format2csv里 * feat: table test : 29 xlsx解决 * feat: table test : 30 tablesplit解决 * feat: table test : 31 * feat: table test : 32 * perf: table split * perf: mcp old version compatibility (#5342) * fix: system-tool secret inputs * fix: rewrite runtime node i18n for system tool * perf: mcp old version compatibility * fix: splitPluginId * fix: old mcp toolId * fix: filter secret key * feat: support system toolset activation * chore: remove log * perf: mcp update * perf: rewrite toolset * fix:delete variable id (#5335) * perf: variable update * fix: multiple select ui * perf: model config move to plugin * fix: var conflit * perf: variable checker * Avoid empty number * update doc time * fix: test * fix: mcp object * update count app * update count app --------- Co-authored-by: Finley Ge <32237950+FinleyGe@users.noreply.github.com> Co-authored-by: heheer <heheer@sealos.io> Co-authored-by: heheer <zhiyu44@qq.com> Co-authored-by: colnii <1286949794@qq.com> Co-authored-by: dreamer6680 <1468683855@qq.com>
625 lines
18 KiB
TypeScript
625 lines
18 KiB
TypeScript
import type {
|
|
NodeToolConfigType,
|
|
FlowNodeTemplateType
|
|
} from '@fastgpt/global/core/workflow/type/node.d';
|
|
import {
|
|
FlowNodeOutputTypeEnum,
|
|
FlowNodeInputTypeEnum,
|
|
FlowNodeTypeEnum
|
|
} from '@fastgpt/global/core/workflow/node/constant';
|
|
import {
|
|
appData2FlowNodeIO,
|
|
pluginData2FlowNodeIO,
|
|
toolData2FlowNodeIO,
|
|
toolSetData2FlowNodeIO
|
|
} from '@fastgpt/global/core/workflow/utils';
|
|
import { MongoApp } from '../schema';
|
|
import type { localeType } from '@fastgpt/global/common/i18n/type';
|
|
import { parseI18nString } from '@fastgpt/global/common/i18n/utils';
|
|
import type { WorkflowTemplateBasicType } from '@fastgpt/global/core/workflow/type';
|
|
import { type SystemPluginTemplateItemType } from '@fastgpt/global/core/app/plugin/type';
|
|
import {
|
|
checkIsLatestVersion,
|
|
getAppLatestVersion,
|
|
getAppVersionById
|
|
} from '../version/controller';
|
|
import { type PluginRuntimeType } from '@fastgpt/global/core/app/plugin/type';
|
|
import { MongoSystemPlugin } from './systemPluginSchema';
|
|
import { PluginErrEnum } from '@fastgpt/global/common/error/code/plugin';
|
|
import { PluginSourceEnum } from '@fastgpt/global/core/app/plugin/constants';
|
|
import {
|
|
FlowNodeTemplateTypeEnum,
|
|
NodeInputKeyEnum
|
|
} from '@fastgpt/global/core/workflow/constants';
|
|
import { getNanoid } from '@fastgpt/global/common/string/tools';
|
|
import { APIGetSystemToolList } from '../tool/api';
|
|
import { Types } from '../../../common/mongo';
|
|
import type { SystemPluginConfigSchemaType } from './type';
|
|
import type {
|
|
FlowNodeInputItemType,
|
|
FlowNodeOutputItemType
|
|
} from '@fastgpt/global/core/workflow/type/io';
|
|
import { isProduction } from '@fastgpt/global/common/system/constants';
|
|
import { Output_Template_Error_Message } from '@fastgpt/global/core/workflow/template/output';
|
|
import type { RuntimeNodeItemType } from '@fastgpt/global/core/workflow/runtime/type';
|
|
import { splitCombinePluginId } from '@fastgpt/global/core/app/plugin/utils';
|
|
import { getMCPToolRuntimeNode } from '@fastgpt/global/core/app/mcpTools/utils';
|
|
import { AppTypeEnum } from '@fastgpt/global/core/app/constants';
|
|
import { getMCPChildren } from '../mcp';
|
|
|
|
type ChildAppType = SystemPluginTemplateItemType & {
|
|
teamId?: string;
|
|
tmbId?: string;
|
|
workflow?: WorkflowTemplateBasicType;
|
|
versionLabel?: string; // Auto computed
|
|
isLatestVersion?: boolean; // Auto computed
|
|
};
|
|
|
|
export const getSystemPluginByIdAndVersionId = async (
|
|
pluginId: string,
|
|
versionId?: string
|
|
): Promise<ChildAppType> => {
|
|
const plugin = await getSystemToolById(pluginId);
|
|
|
|
// Admin selected system tool
|
|
if (plugin.associatedPluginId) {
|
|
// The verification plugin is set as a system plugin
|
|
const systemPlugin = await MongoSystemPlugin.findOne(
|
|
{ pluginId: plugin.id, 'customConfig.associatedPluginId': plugin.associatedPluginId },
|
|
'associatedPluginId'
|
|
).lean();
|
|
if (!systemPlugin) return Promise.reject(PluginErrEnum.unExist);
|
|
|
|
const app = await MongoApp.findById(plugin.associatedPluginId).lean();
|
|
if (!app) return Promise.reject(PluginErrEnum.unExist);
|
|
|
|
const version = versionId
|
|
? await getAppVersionById({
|
|
appId: plugin.associatedPluginId,
|
|
versionId,
|
|
app
|
|
})
|
|
: await getAppLatestVersion(plugin.associatedPluginId, app);
|
|
if (!version.versionId) return Promise.reject('App version not found');
|
|
const isLatest = version.versionId
|
|
? await checkIsLatestVersion({
|
|
appId: plugin.associatedPluginId,
|
|
versionId: version.versionId
|
|
})
|
|
: true;
|
|
|
|
return {
|
|
...plugin,
|
|
workflow: {
|
|
nodes: version.nodes,
|
|
edges: version.edges,
|
|
chatConfig: version.chatConfig
|
|
},
|
|
version: versionId ? version?.versionId : '',
|
|
versionLabel: version?.versionName,
|
|
isLatestVersion: isLatest,
|
|
teamId: String(app.teamId),
|
|
tmbId: String(app.tmbId)
|
|
};
|
|
}
|
|
|
|
// System toolset
|
|
if (plugin.isFolder) {
|
|
return {
|
|
...plugin,
|
|
inputs: [],
|
|
outputs: [],
|
|
inputList: plugin.inputList,
|
|
version: '',
|
|
isLatestVersion: true
|
|
};
|
|
}
|
|
|
|
// System tool
|
|
const versionList = (plugin.versionList as SystemPluginTemplateItemType['versionList']) || [];
|
|
|
|
if (versionList.length === 0) {
|
|
return Promise.reject('Can not find plugin version list');
|
|
}
|
|
|
|
const version = versionId
|
|
? versionList.find((item) => item.value === versionId) ?? versionList[0]
|
|
: versionList[0];
|
|
const lastVersion = versionList[0];
|
|
|
|
// concat parent (if exists) input config
|
|
const parent = plugin.parentId ? await getSystemToolById(plugin.parentId) : undefined;
|
|
if (parent && parent.inputList) {
|
|
plugin?.inputs?.push({
|
|
key: 'system_input_config',
|
|
label: '',
|
|
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
|
inputList: parent.inputList
|
|
});
|
|
}
|
|
|
|
return {
|
|
...plugin,
|
|
inputs: version.inputs,
|
|
outputs: version.outputs,
|
|
version: versionId ? version?.value : '',
|
|
versionLabel: versionId ? version?.value : '',
|
|
isLatestVersion: !version || !lastVersion || version.value === lastVersion?.value
|
|
};
|
|
};
|
|
|
|
/*
|
|
Format plugin to workflow preview node data
|
|
Persion workflow/plugin: objectId
|
|
Persion mcptoolset: objectId
|
|
Persion mcp tool: mcp-parentId/name
|
|
System tool/toolset: system-toolId
|
|
*/
|
|
export async function getChildAppPreviewNode({
|
|
appId,
|
|
versionId,
|
|
lang = 'en'
|
|
}: {
|
|
appId: string;
|
|
versionId?: string;
|
|
lang?: localeType;
|
|
}): Promise<FlowNodeTemplateType> {
|
|
const { source, pluginId } = splitCombinePluginId(appId);
|
|
|
|
const app: ChildAppType = await (async () => {
|
|
// 1. App
|
|
// 2. MCP ToolSets
|
|
if (source === PluginSourceEnum.personal) {
|
|
const item = await MongoApp.findById(pluginId).lean();
|
|
if (!item) return Promise.reject(PluginErrEnum.unExist);
|
|
|
|
const version = await getAppVersionById({ appId: pluginId, versionId, app: item });
|
|
|
|
const isLatest =
|
|
version.versionId && Types.ObjectId.isValid(version.versionId)
|
|
? await checkIsLatestVersion({
|
|
appId: pluginId,
|
|
versionId: version.versionId
|
|
})
|
|
: true;
|
|
|
|
if (item.type === AppTypeEnum.toolSet) {
|
|
const children = await getMCPChildren(item);
|
|
version.nodes[0].toolConfig = {
|
|
mcpToolSet: {
|
|
toolId: pluginId,
|
|
toolList: children,
|
|
url: ''
|
|
}
|
|
};
|
|
}
|
|
|
|
return {
|
|
id: String(item._id),
|
|
teamId: String(item.teamId),
|
|
name: item.name,
|
|
avatar: item.avatar,
|
|
intro: item.intro,
|
|
showStatus: true,
|
|
workflow: {
|
|
nodes: version.nodes,
|
|
edges: version.edges,
|
|
chatConfig: version.chatConfig
|
|
},
|
|
templateType: FlowNodeTemplateTypeEnum.teamApp,
|
|
|
|
version: versionId ? version?.versionId : '',
|
|
versionLabel: version?.versionName,
|
|
isLatestVersion: isLatest,
|
|
|
|
originCost: 0,
|
|
currentCost: 0,
|
|
hasTokenFee: false,
|
|
pluginOrder: 0
|
|
};
|
|
}
|
|
// mcp tool
|
|
else if (source === PluginSourceEnum.mcp) {
|
|
const [parentId, toolName] = pluginId.split('/');
|
|
// 1. get parentApp
|
|
const item = await MongoApp.findById(parentId).lean();
|
|
if (!item) return Promise.reject(PluginErrEnum.unExist);
|
|
|
|
const version = await getAppVersionById({ appId: parentId, versionId, app: item });
|
|
const toolConfig = version.nodes[0].toolConfig?.mcpToolSet;
|
|
const tool = toolConfig?.toolList.find((item) => item.name === toolName);
|
|
if (!tool || !toolConfig) return Promise.reject(PluginErrEnum.unExist);
|
|
|
|
return {
|
|
avatar: item.avatar,
|
|
id: appId,
|
|
name: tool.name,
|
|
templateType: FlowNodeTemplateTypeEnum.tools,
|
|
workflow: {
|
|
nodes: [
|
|
getMCPToolRuntimeNode({
|
|
tool: {
|
|
description: tool.description,
|
|
inputSchema: tool.inputSchema,
|
|
name: tool.name
|
|
},
|
|
avatar: item.avatar,
|
|
parentId: item._id
|
|
})
|
|
],
|
|
edges: []
|
|
},
|
|
version: '',
|
|
isLatestVersion: true
|
|
};
|
|
}
|
|
// 1. System Tools
|
|
// 2. System Plugins configured in Pro (has associatedPluginId)
|
|
else {
|
|
return getSystemPluginByIdAndVersionId(pluginId, versionId);
|
|
}
|
|
})();
|
|
|
|
const { flowNodeType, nodeIOConfig } = await (async (): Promise<{
|
|
flowNodeType: FlowNodeTypeEnum;
|
|
nodeIOConfig: {
|
|
inputs: FlowNodeInputItemType[];
|
|
outputs: FlowNodeOutputItemType[];
|
|
toolConfig?: NodeToolConfigType;
|
|
showSourceHandle?: boolean;
|
|
showTargetHandle?: boolean;
|
|
};
|
|
}> => {
|
|
if (source === PluginSourceEnum.systemTool) {
|
|
// system Tool or Toolsets
|
|
const children = app.isFolder
|
|
? (await getSystemTools()).filter((item) => item.parentId === pluginId)
|
|
: [];
|
|
|
|
return {
|
|
flowNodeType: app.isFolder ? FlowNodeTypeEnum.toolSet : FlowNodeTypeEnum.tool,
|
|
nodeIOConfig: {
|
|
inputs: [
|
|
...(app.inputList
|
|
? [
|
|
{
|
|
key: NodeInputKeyEnum.systemInputConfig,
|
|
label: '',
|
|
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
|
inputList: app.inputList
|
|
}
|
|
]
|
|
: []),
|
|
...(app.inputs ?? [])
|
|
],
|
|
outputs: app.outputs ?? [],
|
|
toolConfig: {
|
|
...(app.isFolder
|
|
? {
|
|
systemToolSet: {
|
|
toolId: app.id,
|
|
toolList: children.map((item) => ({
|
|
toolId: item.id,
|
|
name: parseI18nString(item.name, lang),
|
|
description: parseI18nString(item.intro, lang)
|
|
}))
|
|
}
|
|
}
|
|
: { systemTool: { toolId: app.id } })
|
|
},
|
|
showSourceHandle: app.isFolder ? false : true,
|
|
showTargetHandle: app.isFolder ? false : true
|
|
}
|
|
};
|
|
}
|
|
|
|
// Plugin workflow
|
|
if (!!app.workflow.nodes.find((node) => node.flowNodeType === FlowNodeTypeEnum.pluginInput)) {
|
|
// plugin app
|
|
return {
|
|
flowNodeType: FlowNodeTypeEnum.pluginModule,
|
|
nodeIOConfig: pluginData2FlowNodeIO({ nodes: app.workflow.nodes })
|
|
};
|
|
}
|
|
|
|
// Mcp
|
|
if (
|
|
!!app.workflow.nodes.find((node) => node.flowNodeType === FlowNodeTypeEnum.toolSet) &&
|
|
app.workflow.nodes.length === 1
|
|
) {
|
|
// mcp tools
|
|
return {
|
|
flowNodeType: FlowNodeTypeEnum.toolSet,
|
|
nodeIOConfig: toolSetData2FlowNodeIO({ nodes: app.workflow.nodes })
|
|
};
|
|
}
|
|
|
|
if (
|
|
!!app.workflow.nodes.find((node) => node.flowNodeType === FlowNodeTypeEnum.tool) &&
|
|
app.workflow.nodes.length === 1
|
|
) {
|
|
return {
|
|
flowNodeType: FlowNodeTypeEnum.tool,
|
|
nodeIOConfig: toolData2FlowNodeIO({ nodes: app.workflow.nodes })
|
|
};
|
|
}
|
|
|
|
// Chat workflow
|
|
return {
|
|
flowNodeType: FlowNodeTypeEnum.appModule,
|
|
nodeIOConfig: appData2FlowNodeIO({ chatConfig: app.workflow.chatConfig })
|
|
};
|
|
})();
|
|
|
|
return {
|
|
id: getNanoid(),
|
|
pluginId: app.id,
|
|
templateType: app.templateType,
|
|
flowNodeType,
|
|
avatar: app.avatar,
|
|
name: parseI18nString(app.name, lang),
|
|
intro: parseI18nString(app.intro, lang),
|
|
courseUrl: app.courseUrl,
|
|
userGuide: app.userGuide,
|
|
showStatus: true,
|
|
isTool: true,
|
|
catchError: false,
|
|
|
|
version: app.version,
|
|
versionLabel: app.versionLabel,
|
|
isLatestVersion: app.isLatestVersion,
|
|
showSourceHandle: true,
|
|
showTargetHandle: true,
|
|
|
|
currentCost: app.currentCost,
|
|
hasTokenFee: app.hasTokenFee,
|
|
hasSystemSecret: app.hasSystemSecret,
|
|
|
|
...nodeIOConfig,
|
|
outputs: nodeIOConfig.outputs.some((item) => item.type === FlowNodeOutputTypeEnum.error)
|
|
? nodeIOConfig.outputs
|
|
: [...nodeIOConfig.outputs, Output_Template_Error_Message]
|
|
};
|
|
}
|
|
|
|
/**
|
|
Get runtime plugin data
|
|
System plugin: plugin id
|
|
Personal plugin: Version id
|
|
*/
|
|
export async function getChildAppRuntimeById({
|
|
id,
|
|
versionId,
|
|
lang = 'en'
|
|
}: {
|
|
id: string;
|
|
versionId?: string;
|
|
lang?: localeType;
|
|
}): Promise<PluginRuntimeType> {
|
|
const app = await (async () => {
|
|
const { source, pluginId } = splitCombinePluginId(id);
|
|
|
|
if (source === PluginSourceEnum.personal) {
|
|
const item = await MongoApp.findById(pluginId).lean();
|
|
if (!item) return Promise.reject(PluginErrEnum.unExist);
|
|
|
|
const version = await getAppVersionById({
|
|
appId: pluginId,
|
|
versionId,
|
|
app: item
|
|
});
|
|
|
|
return {
|
|
id: String(item._id),
|
|
teamId: String(item.teamId),
|
|
tmbId: String(item.tmbId),
|
|
name: item.name,
|
|
avatar: item.avatar,
|
|
intro: item.intro,
|
|
showStatus: true,
|
|
workflow: {
|
|
nodes: version.nodes,
|
|
edges: version.edges,
|
|
chatConfig: version.chatConfig
|
|
},
|
|
templateType: FlowNodeTemplateTypeEnum.teamApp,
|
|
|
|
originCost: 0,
|
|
currentCost: 0,
|
|
hasTokenFee: false,
|
|
pluginOrder: 0
|
|
};
|
|
} else {
|
|
return getSystemPluginByIdAndVersionId(pluginId, versionId);
|
|
}
|
|
})();
|
|
|
|
return {
|
|
id: app.id,
|
|
teamId: app.teamId,
|
|
tmbId: app.tmbId,
|
|
name: parseI18nString(app.name, lang),
|
|
avatar: app.avatar || '',
|
|
showStatus: true,
|
|
currentCost: app.currentCost,
|
|
nodes: app.workflow.nodes,
|
|
edges: app.workflow.edges,
|
|
hasTokenFee: app.hasTokenFee
|
|
};
|
|
}
|
|
|
|
export async function getSystemPluginRuntimeNodeById({
|
|
pluginId,
|
|
name,
|
|
intro
|
|
}: {
|
|
pluginId: string;
|
|
name: string;
|
|
intro: string;
|
|
}): Promise<RuntimeNodeItemType> {
|
|
const { source } = splitCombinePluginId(pluginId);
|
|
if (source === PluginSourceEnum.systemTool) {
|
|
const tool = await getSystemPluginByIdAndVersionId(pluginId);
|
|
return {
|
|
...tool,
|
|
name,
|
|
intro,
|
|
inputs: tool.inputs ?? [],
|
|
outputs: tool.outputs ?? [],
|
|
flowNodeType: FlowNodeTypeEnum.tool,
|
|
nodeId: getNanoid(),
|
|
toolConfig: {
|
|
systemTool: {
|
|
toolId: pluginId
|
|
}
|
|
}
|
|
};
|
|
}
|
|
return Promise.reject(PluginErrEnum.unExist);
|
|
}
|
|
|
|
const dbPluginFormat = (item: SystemPluginConfigSchemaType): SystemPluginTemplateItemType => {
|
|
const { name, avatar, intro, version, weight, templateType, associatedPluginId, userGuide } =
|
|
item.customConfig!;
|
|
|
|
return {
|
|
id: item.pluginId,
|
|
isActive: item.isActive,
|
|
isFolder: false,
|
|
parentId: null,
|
|
author: item.customConfig?.author || '',
|
|
version,
|
|
name,
|
|
avatar,
|
|
intro,
|
|
weight,
|
|
templateType,
|
|
originCost: item.originCost,
|
|
currentCost: item.currentCost,
|
|
hasTokenFee: item.hasTokenFee,
|
|
pluginOrder: item.pluginOrder,
|
|
associatedPluginId,
|
|
userGuide,
|
|
workflow: {
|
|
nodes: [],
|
|
edges: []
|
|
}
|
|
};
|
|
};
|
|
|
|
/* FastsGPT-Pluign api: */
|
|
function getCachedSystemPlugins() {
|
|
if (!global.systemPlugins_cache) {
|
|
global.systemPlugins_cache = {
|
|
expires: 0,
|
|
data: [] as SystemPluginTemplateItemType[]
|
|
};
|
|
}
|
|
return global.systemPlugins_cache;
|
|
}
|
|
|
|
const cleanSystemPluginCache = () => {
|
|
global.systemPlugins_cache = undefined;
|
|
};
|
|
|
|
export const refetchSystemPlugins = () => {
|
|
const changeStream = MongoSystemPlugin.watch();
|
|
|
|
changeStream.on('change', () => {
|
|
try {
|
|
cleanSystemPluginCache();
|
|
} catch (error) {}
|
|
});
|
|
};
|
|
|
|
export const getSystemTools = async (): Promise<SystemPluginTemplateItemType[]> => {
|
|
if (getCachedSystemPlugins().expires > Date.now() && isProduction) {
|
|
return getCachedSystemPlugins().data;
|
|
} else {
|
|
const tools = await APIGetSystemToolList();
|
|
|
|
// 从数据库里加载插件配置进行替换
|
|
const systemPluginsArray = await MongoSystemPlugin.find({}).lean();
|
|
const systemPlugins = new Map(systemPluginsArray.map((plugin) => [plugin.pluginId, plugin]));
|
|
|
|
tools.forEach((tool) => {
|
|
// 如果有插件的配置信息,则需要进行替换
|
|
const dbPluginConfig = systemPlugins.get(tool.id);
|
|
|
|
if (dbPluginConfig) {
|
|
const children = tools.filter((item) => item.parentId === tool.id);
|
|
const list = [tool, ...children];
|
|
list.forEach((item) => {
|
|
item.isActive = dbPluginConfig.isActive ?? item.isActive ?? true;
|
|
item.originCost = dbPluginConfig.originCost ?? 0;
|
|
item.currentCost = dbPluginConfig.currentCost ?? 0;
|
|
item.hasTokenFee = dbPluginConfig.hasTokenFee ?? false;
|
|
item.pluginOrder = dbPluginConfig.pluginOrder ?? 0;
|
|
});
|
|
}
|
|
});
|
|
|
|
const formatTools = tools.map<SystemPluginTemplateItemType>((item) => {
|
|
const dbPluginConfig = systemPlugins.get(item.id);
|
|
|
|
const versionList = (item.versionList as SystemPluginTemplateItemType['versionList']) || [];
|
|
const inputs = versionList[0]?.inputs ?? [];
|
|
const outputs = versionList[0]?.outputs ?? [];
|
|
|
|
return {
|
|
...item,
|
|
isFolder: tools.some((tool) => tool.parentId === item.id),
|
|
showStatus: true,
|
|
workflow: {
|
|
nodes: [],
|
|
edges: []
|
|
},
|
|
versionList,
|
|
inputs,
|
|
outputs,
|
|
inputList: item?.secretInputConfig,
|
|
hasSystemSecret: !!dbPluginConfig?.inputListVal
|
|
};
|
|
});
|
|
|
|
const dbPlugins = systemPluginsArray
|
|
.filter((item) => item.customConfig)
|
|
.map((item) => dbPluginFormat(item));
|
|
|
|
const plugins = [...formatTools, ...dbPlugins];
|
|
plugins.sort((a, b) => (a.pluginOrder ?? 0) - (b.pluginOrder ?? 0));
|
|
|
|
global.systemPlugins_cache = {
|
|
expires: Date.now() + 30 * 60 * 1000, // 30 minutes
|
|
data: plugins
|
|
};
|
|
|
|
return plugins;
|
|
}
|
|
};
|
|
|
|
export const getSystemToolById = async (id: string): Promise<SystemPluginTemplateItemType> => {
|
|
const { source, pluginId } = splitCombinePluginId(id);
|
|
if (source === PluginSourceEnum.systemTool) {
|
|
const tools = await getSystemTools();
|
|
const tool = tools.find((item) => item.id === pluginId);
|
|
if (tool) {
|
|
return tool;
|
|
}
|
|
return Promise.reject(PluginErrEnum.unExist);
|
|
}
|
|
|
|
const dbPlugin = await MongoSystemPlugin.findOne({ pluginId }).lean();
|
|
if (!dbPlugin) return Promise.reject(PluginErrEnum.unExist);
|
|
return dbPluginFormat(dbPlugin);
|
|
};
|
|
|
|
declare global {
|
|
var systemPlugins_cache:
|
|
| {
|
|
expires: number;
|
|
data: SystemPluginTemplateItemType[];
|
|
}
|
|
| undefined;
|
|
}
|