Skip to content

Commit

Permalink
perf:change plugin version update position (#1493)
Browse files Browse the repository at this point in the history
* perf:change plugin version update position

* use nodeversion
  • Loading branch information
newfish-cmyk authored May 15, 2024
1 parent 8386f70 commit d5073f9
Show file tree
Hide file tree
Showing 10 changed files with 98 additions and 66 deletions.
2 changes: 2 additions & 0 deletions packages/global/core/plugin/type.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export type PluginItemSchema = {
customHeaders?: string;
};
version?: 'v1' | 'v2';
nodeVersion?: string;
};

/* plugin template */
Expand All @@ -32,6 +33,7 @@ export type PluginTemplateType = PluginRuntimeType & {
source: `${PluginSourceEnum}`;
templateType: FlowNodeTemplateType['templateType'];
intro: string;
nodeVersion: string;
};

export type PluginRuntimeType = {
Expand Down
1 change: 1 addition & 0 deletions packages/global/core/workflow/type/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export type FlowNodeTemplateType = FlowNodeCommonType & {
// action
forbidDelete?: boolean; // forbid delete
unique?: boolean;
nodeVersion?: string;
};
export type FlowNodeItemType = FlowNodeTemplateType & {
nodeId: string;
Expand Down
4 changes: 3 additions & 1 deletion packages/service/core/plugin/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ const getPluginTemplateById = async (id: string): Promise<PluginTemplateType> =>
nodes: item.modules,
edges: item.edges,
templateType: FlowNodeTemplateTypeEnum.personalPlugin,
isTool: true
isTool: true,
nodeVersion: item?.nodeVersion || ''
};
}
return Promise.reject('plugin not found');
Expand All @@ -72,6 +73,7 @@ export async function getPluginPreviewNode({ id }: { id: string }): Promise<Flow
intro: plugin.intro,
showStatus: plugin.showStatus,
isTool: plugin.isTool,
nodeVersion: plugin.nodeVersion,
version: '481',
sourceHandle: getHandleConfig(true, true, true, true),
targetHandle: getHandleConfig(true, true, true, true),
Expand Down
4 changes: 4 additions & 0 deletions packages/service/core/plugin/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ const PluginSchema = new Schema({
version: {
type: String,
enum: ['v1', 'v2']
},
nodeVersion: {
type: String,
default: ''
}
});

Expand Down
2 changes: 1 addition & 1 deletion packages/service/core/workflow/dispatch/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export const valueTypeFormat = (value: any, type?: WorkflowIOValueTypeEnum) => {
return JSON.stringify(value);
}
if (type === 'number') return Number(value);
if (type === 'boolean') return Boolean(value);
if (type === 'boolean') return value === 'true' ? true : false;
try {
if (type === WorkflowIOValueTypeEnum.datasetQuote && !Array.isArray(value)) {
return JSON.parse(value);
Expand Down
1 change: 1 addition & 0 deletions projects/app/i18n/en/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
},
"module": {
"Combine Modules": "Combine Modules",
"Confirm Sync": "Using the latest template will overwrite the existing one and may result in the loss of some previous configuration information. Please confirm.",
"Custom Title Tip": "This title will be displayed during the conversation",
"My Modules": "My Modules",
"No Modules": "No modules yet~",
Expand Down
1 change: 1 addition & 0 deletions projects/app/i18n/zh/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
},
"module": {
"Combine Modules": "组合模块",
"Confirm Sync": "将会使用最新模板进行覆盖,可能会丢失一些旧的配置信息,请确认",
"Custom Title Tip": "该标题名字会展示在对话过程中",
"My Modules": "",
"No Modules": "还没有模块~",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import React, { useCallback, useMemo } from 'react';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { Box, Button, Card, Flex } from '@chakra-ui/react';
import MyIcon from '@fastgpt/web/components/common/Icon';
import Avatar from '@/components/Avatar';
import type { FlowNodeItemType } from '@fastgpt/global/core/workflow/type/index.d';
import type {
FlowNodeItemType,
FlowNodeTemplateType
} from '@fastgpt/global/core/workflow/type/index.d';
import { useTranslation } from 'next-i18next';
import { useEditTitle } from '@/web/common/hooks/useEditTitle';
import { useToast } from '@fastgpt/web/hooks/useToast';
import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
import { useSystemStore } from '@/web/common/system/useSystemStore';
import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
import { LOGO_ICON } from '@fastgpt/global/common/system/constants';
import { ToolTargetHandle } from './Handle/ToolHandle';
Expand All @@ -17,7 +19,6 @@ import { useDebug } from '../../hooks/useDebug';
import { ResponseBox } from '@/components/ChatBox/WholeResponseModal';
import EmptyTip from '@fastgpt/web/components/common/EmptyTip';
import { getPreviewPluginModule } from '@/web/core/plugin/api';
import { getErrText } from '@fastgpt/global/common/error/utils';
import { storeNode2FlowNode, updateFlowNodeVersion } from '@/web/core/workflow/utils';
import { getNanoid } from '@fastgpt/global/common/string/tools';
import { useContextSelector } from 'use-context-selector';
Expand All @@ -26,6 +27,8 @@ import { useI18n } from '@/web/context/I18n';
import { moduleTemplatesFlat } from '@fastgpt/global/core/workflow/template/constants';
import { QuestionOutlineIcon } from '@chakra-ui/icons';
import MyTooltip from '@/components/MyTooltip';
import { isEqual } from 'lodash';
import { useSystemStore } from '@/web/common/system/useSystemStore';

type Props = FlowNodeItemType & {
children?: React.ReactNode | React.ReactNode[] | string;
Expand Down Expand Up @@ -69,6 +72,9 @@ const NodeCard = (props: Props) => {
const onChangeNode = useContextSelector(WorkflowContext, (v) => v.onChangeNode);
const onResetNode = useContextSelector(WorkflowContext, (v) => v.onResetNode);

const [hasNewVersion, setHasNewVersion] = useState(false);
const { setLoading } = useSystemStore();

// custom title edit
const { onOpenModal: onOpenCustomTitleModal, EditModal: EditTitleModal } = useEditTitle({
title: t('common.Custom Title'),
Expand All @@ -81,13 +87,50 @@ const NodeCard = (props: Props) => {
);

const node = nodeList.find((node) => node.nodeId === nodeId);
const { openConfirm: onOpenConfirmSync, ConfirmModal: ConfirmSyncModal } = useConfirm({
content: appT('module.Confirm Sync')
});

useEffect(() => {
const fetchPluginModule = async () => {
if (node?.flowNodeType === FlowNodeTypeEnum.pluginModule) {
if (!node?.pluginId) return;
const template = await getPreviewPluginModule(node.pluginId);
setHasNewVersion(!!template.nodeVersion && node.nodeVersion !== template.nodeVersion);
} else {
const template = moduleTemplatesFlat.find(
(item) => item.flowNodeType === node?.flowNodeType
);
setHasNewVersion(node?.version !== template?.version);
}
};

fetchPluginModule();
}, [node]);

const template = moduleTemplatesFlat.find((item) => item.flowNodeType === node?.flowNodeType);
const hasNewVersion = useMemo(() => {
return (
template?.flowNodeType !== FlowNodeTypeEnum.pluginModule &&
node?.version !== template?.version
);
}, [node?.version, template?.flowNodeType, template?.version]);

const onClickSyncVersion = useCallback(async () => {
try {
setLoading(true);
if (!node || !template) return;
if (node?.flowNodeType === 'pluginModule') {
if (!node.pluginId) return;
onResetNode({
id: nodeId,
node: await getPreviewPluginModule(node.pluginId)
});
} else {
onResetNode({
id: nodeId,
node: updateFlowNodeVersion(node, template)
});
}
} catch (error) {
console.error('Error fetching plugin module:', error);
}
setLoading(false);
}, [node, nodeId, onResetNode, setLoading, template]);

/* Node header */
const Header = useMemo(() => {
Expand Down Expand Up @@ -149,13 +192,7 @@ const NodeCard = (props: Props) => {
fontWeight={'medium'}
cursor={'pointer'}
_hover={{ bg: 'yellow.100' }}
onClick={() => {
if (!node || !template) return;
onResetNode({
id: nodeId,
node: updateFlowNodeVersion(node, template)
});
}}
onClick={onOpenConfirmSync(onClickSyncVersion)}
>
<Box>{appT('app.modules.has new version')}</Box>
<QuestionOutlineIcon ml={1} />
Expand All @@ -171,6 +208,7 @@ const NodeCard = (props: Props) => {
/>
<NodeIntro nodeId={nodeId} intro={intro} />
</Box>
<ConfirmSyncModal />
</Box>
);
}, [
Expand All @@ -181,16 +219,16 @@ const NodeCard = (props: Props) => {
name,
menuForbid,
hasNewVersion,
appT,
onOpenConfirmSync,
onClickSyncVersion,
pluginId,
flowNodeType,
intro,
ConfirmSyncModal,
onOpenCustomTitleModal,
onChangeNode,
toast,
appT,
node,
template,
onResetNode
toast
]);

return (
Expand Down Expand Up @@ -249,21 +287,14 @@ const MenuRender = React.memo(function MenuRender({
menuForbid?: Props['menuForbid'];
}) {
const { t } = useTranslation();
const { toast } = useToast();
const { setLoading } = useSystemStore();
const { openDebugNode, DebugInputModal } = useDebug();

const { openConfirm: onOpenConfirmSync, ConfirmModal: ConfirmSyncModal } = useConfirm({
content: t('module.Confirm Sync Plugin')
});

const { openConfirm: onOpenConfirmDeleteNode, ConfirmModal: ConfirmDeleteModal } = useConfirm({
content: t('core.module.Confirm Delete Node'),
type: 'delete'
});

const setNodes = useContextSelector(WorkflowContext, (v) => v.setNodes);
const onResetNode = useContextSelector(WorkflowContext, (v) => v.onResetNode);
const setEdges = useContextSelector(WorkflowContext, (v) => v.setEdges);

const onCopyNode = useCallback(
Expand Down Expand Up @@ -310,22 +341,6 @@ const MenuRender = React.memo(function MenuRender({
},
[setEdges, setNodes]
);
const onClickSyncVersion = useCallback(async () => {
if (!pluginId) return;
try {
setLoading(true);
onResetNode({
id: nodeId,
node: await getPreviewPluginModule(pluginId)
});
} catch (e) {
return toast({
status: 'error',
title: getErrText(e, t('plugin.Get Plugin Module Detail Failed'))
});
}
setLoading(false);
}, [nodeId, onResetNode, pluginId, setLoading, t, toast]);

const Render = useMemo(() => {
const menuList = [
Expand All @@ -349,17 +364,6 @@ const MenuRender = React.memo(function MenuRender({
onClick: () => onCopyNode(nodeId)
}
]),
...(flowNodeType === FlowNodeTypeEnum.pluginModule
? [
{
icon: 'common/refreshLight',
label: t('plugin.Synchronous version'),
variant: 'whiteBase',
onClick: onOpenConfirmSync(onClickSyncVersion)
}
]
: []),

...(menuForbid?.delete
? []
: [
Expand Down Expand Up @@ -401,7 +405,6 @@ const MenuRender = React.memo(function MenuRender({
</Box>
))}
</Box>
<ConfirmSyncModal />
<ConfirmDeleteModal />
<DebugInputModal />
</>
Expand All @@ -411,11 +414,7 @@ const MenuRender = React.memo(function MenuRender({
menuForbid?.copy,
menuForbid?.delete,
t,
flowNodeType,
onOpenConfirmSync,
onClickSyncVersion,
onOpenConfirmDeleteNode,
ConfirmSyncModal,
ConfirmDeleteModal,
DebugInputModal,
openDebugNode,
Expand Down
3 changes: 2 additions & 1 deletion projects/app/src/components/core/workflow/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ export const flowNode2StoreNodes = ({
version: item.data.version,
inputs: item.data.inputs,
outputs: item.data.outputs,
pluginId: item.data.pluginId
pluginId: item.data.pluginId,
nodeVersion: item.data.nodeVersion
}));

// get all handle
Expand Down
25 changes: 23 additions & 2 deletions projects/app/src/pages/api/core/plugin/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { MongoPlugin } from '@fastgpt/service/core/plugin/schema';
import { mongoSessionRun } from '@fastgpt/service/common/mongo/sessionRun';
import { ClientSession } from '@fastgpt/service/common/mongo';
import { httpApiSchema2Plugins } from '@fastgpt/global/core/plugin/httpPlugin/utils';
import { isEqual } from 'lodash';
import { nanoid } from 'nanoid';

export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
try {
Expand All @@ -22,7 +24,9 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
per: 'owner'
});

const updateData = {
const originPlugin = await MongoPlugin.findById(id);

let updateData = {
name: props.name,
intro: props.intro,
avatar: props.avatar,
Expand All @@ -32,9 +36,26 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
modules: modules
}),
...(edges?.length && { edges }),
metadata: props.metadata
metadata: props.metadata,
nodeVersion: originPlugin?.nodeVersion
};

const isNodeVersionEqual =
isEqual(
originPlugin?.modules.map((module) => {
return { ...module, position: undefined };
}),
updateData.modules?.map((module) => {
return { ...module, position: undefined };
})
) && isEqual(originPlugin?.edges, updateData.edges);

if (!isNodeVersionEqual) {
updateData = {
...updateData,
nodeVersion: nanoid(6)
};
}
if (props.metadata?.apiSchemaStr) {
await mongoSessionRun(async (session) => {
// update children
Expand Down

0 comments on commit d5073f9

Please sign in to comment.