mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-23 13:03:50 +00:00
feat: node version (#1484)
* feat: node version tip * fix * i18n * init version * fix ts * fix ts * fix ts
This commit is contained in:
@@ -131,6 +131,7 @@ export const appWorkflow2Form = ({ nodes }: { nodes: StoreNodeItemType[] }) => {
|
|||||||
intro: node.intro || '',
|
intro: node.intro || '',
|
||||||
flowNodeType: node.flowNodeType,
|
flowNodeType: node.flowNodeType,
|
||||||
showStatus: node.showStatus,
|
showStatus: node.showStatus,
|
||||||
|
version: '481',
|
||||||
inputs: node.inputs,
|
inputs: node.inputs,
|
||||||
outputs: node.outputs,
|
outputs: node.outputs,
|
||||||
templateType: FlowNodeTemplateTypeEnum.other
|
templateType: FlowNodeTemplateTypeEnum.other
|
||||||
|
@@ -282,6 +282,7 @@ export const httpApiSchema2Plugins = async ({
|
|||||||
x: 616.4226348688949,
|
x: 616.4226348688949,
|
||||||
y: -165.05298493910115
|
y: -165.05298493910115
|
||||||
},
|
},
|
||||||
|
version: PluginInputModule.version,
|
||||||
inputs: pluginInputs,
|
inputs: pluginInputs,
|
||||||
outputs: pluginOutputs
|
outputs: pluginOutputs
|
||||||
},
|
},
|
||||||
@@ -296,6 +297,7 @@ export const httpApiSchema2Plugins = async ({
|
|||||||
x: 1607.7142331269126,
|
x: 1607.7142331269126,
|
||||||
y: -151.8669210746189
|
y: -151.8669210746189
|
||||||
},
|
},
|
||||||
|
version: PluginOutputModule.version,
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
key: pluginOutputKey,
|
key: pluginOutputKey,
|
||||||
@@ -334,6 +336,7 @@ export const httpApiSchema2Plugins = async ({
|
|||||||
x: 1042.549746602742,
|
x: 1042.549746602742,
|
||||||
y: -447.77496332641647
|
y: -447.77496332641647
|
||||||
},
|
},
|
||||||
|
version: HttpModule468.version,
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
key: NodeInputKeyEnum.addInputParam,
|
key: NodeInputKeyEnum.addInputParam,
|
||||||
|
@@ -31,6 +31,7 @@ export const AiChatModule: FlowNodeTemplateType = {
|
|||||||
intro: 'AI 大模型对话',
|
intro: 'AI 大模型对话',
|
||||||
showStatus: true,
|
showStatus: true,
|
||||||
isTool: true,
|
isTool: true,
|
||||||
|
version: '481',
|
||||||
inputs: [
|
inputs: [
|
||||||
Input_Template_SettingAiModel,
|
Input_Template_SettingAiModel,
|
||||||
// --- settings modal
|
// --- settings modal
|
||||||
|
@@ -17,6 +17,7 @@ export const AssignedAnswerModule: FlowNodeTemplateType = {
|
|||||||
name: '指定回复',
|
name: '指定回复',
|
||||||
intro:
|
intro:
|
||||||
'该模块可以直接回复一段指定的内容。常用于引导、提示。非字符串内容传入时,会转成字符串进行输出。',
|
'该模块可以直接回复一段指定的内容。常用于引导、提示。非字符串内容传入时,会转成字符串进行输出。',
|
||||||
|
version: '481',
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
key: NodeInputKeyEnum.answerText,
|
key: NodeInputKeyEnum.answerText,
|
||||||
|
@@ -29,6 +29,7 @@ export const ClassifyQuestionModule: FlowNodeTemplateType = {
|
|||||||
name: '问题分类',
|
name: '问题分类',
|
||||||
intro: `根据用户的历史记录和当前问题判断该次提问的类型。可以添加多组问题类型,下面是一个模板例子:\n类型1: 打招呼\n类型2: 关于商品“使用”问题\n类型3: 关于商品“购买”问题\n类型4: 其他问题`,
|
intro: `根据用户的历史记录和当前问题判断该次提问的类型。可以添加多组问题类型,下面是一个模板例子:\n类型1: 打招呼\n类型2: 关于商品“使用”问题\n类型3: 关于商品“购买”问题\n类型4: 其他问题`,
|
||||||
showStatus: true,
|
showStatus: true,
|
||||||
|
version: '481',
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
...Input_Template_SelectAIModel,
|
...Input_Template_SelectAIModel,
|
||||||
|
@@ -25,6 +25,7 @@ export const ContextExtractModule: FlowNodeTemplateType = {
|
|||||||
intro: '可从文本中提取指定的数据,例如:sql语句、搜索关键词、代码等',
|
intro: '可从文本中提取指定的数据,例如:sql语句、搜索关键词、代码等',
|
||||||
showStatus: true,
|
showStatus: true,
|
||||||
isTool: true,
|
isTool: true,
|
||||||
|
version: '481',
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
...Input_Template_SelectAIModel,
|
...Input_Template_SelectAIModel,
|
||||||
|
@@ -42,6 +42,7 @@ export const DatasetConcatModule: FlowNodeTemplateType = {
|
|||||||
name: '知识库搜索引用合并',
|
name: '知识库搜索引用合并',
|
||||||
intro: '可以将多个知识库搜索结果进行合并输出。使用 RRF 的合并方式进行最终排序输出。',
|
intro: '可以将多个知识库搜索结果进行合并输出。使用 RRF 的合并方式进行最终排序输出。',
|
||||||
showStatus: false,
|
showStatus: false,
|
||||||
|
version: '481',
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
key: NodeInputKeyEnum.datasetMaxTokens,
|
key: NodeInputKeyEnum.datasetMaxTokens,
|
||||||
|
@@ -28,6 +28,7 @@ export const DatasetSearchModule: FlowNodeTemplateType = {
|
|||||||
intro: Dataset_SEARCH_DESC,
|
intro: Dataset_SEARCH_DESC,
|
||||||
showStatus: true,
|
showStatus: true,
|
||||||
isTool: true,
|
isTool: true,
|
||||||
|
version: '481',
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
key: NodeInputKeyEnum.datasetSelectList,
|
key: NodeInputKeyEnum.datasetSelectList,
|
||||||
|
@@ -12,6 +12,7 @@ export const EmptyNode: FlowNodeTemplateType = {
|
|||||||
avatar: '',
|
avatar: '',
|
||||||
name: '',
|
name: '',
|
||||||
intro: '',
|
intro: '',
|
||||||
|
version: '481',
|
||||||
inputs: [],
|
inputs: [],
|
||||||
outputs: []
|
outputs: []
|
||||||
};
|
};
|
||||||
|
@@ -20,6 +20,7 @@ export const getGlobalVariableNode = ({
|
|||||||
avatar: '/imgs/workflow/variable.png',
|
avatar: '/imgs/workflow/variable.png',
|
||||||
name: '全局变量',
|
name: '全局变量',
|
||||||
intro: '',
|
intro: '',
|
||||||
|
version: '481',
|
||||||
inputs: [],
|
inputs: [],
|
||||||
outputs: variables.map((item) => ({
|
outputs: variables.map((item) => ({
|
||||||
id: item.key,
|
id: item.key,
|
||||||
|
@@ -25,6 +25,7 @@ export const HttpModule468: FlowNodeTemplateType = {
|
|||||||
intro: '可以发出一个 HTTP 请求,实现更为复杂的操作(联网搜索、数据库查询等)',
|
intro: '可以发出一个 HTTP 请求,实现更为复杂的操作(联网搜索、数据库查询等)',
|
||||||
showStatus: true,
|
showStatus: true,
|
||||||
isTool: true,
|
isTool: true,
|
||||||
|
version: '481',
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
...Input_Template_DynamicInput,
|
...Input_Template_DynamicInput,
|
||||||
|
@@ -22,6 +22,7 @@ export const IfElseNode: FlowNodeTemplateType = {
|
|||||||
name: '判断器',
|
name: '判断器',
|
||||||
intro: '根据一定的条件,执行不同的分支。',
|
intro: '根据一定的条件,执行不同的分支。',
|
||||||
showStatus: true,
|
showStatus: true,
|
||||||
|
version: '481',
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
key: NodeInputKeyEnum.ifElseList,
|
key: NodeInputKeyEnum.ifElseList,
|
||||||
|
@@ -25,6 +25,7 @@ export const LafModule: FlowNodeTemplateType = {
|
|||||||
intro: '可以调用Laf账号下的云函数。',
|
intro: '可以调用Laf账号下的云函数。',
|
||||||
showStatus: true,
|
showStatus: true,
|
||||||
isTool: true,
|
isTool: true,
|
||||||
|
version: '481',
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
...Input_Template_DynamicInput,
|
...Input_Template_DynamicInput,
|
||||||
|
@@ -15,6 +15,7 @@ export const PluginInputModule: FlowNodeTemplateType = {
|
|||||||
name: '自定义插件输入',
|
name: '自定义插件输入',
|
||||||
intro: '自定义配置外部输入,使用插件时,仅暴露自定义配置的输入',
|
intro: '自定义配置外部输入,使用插件时,仅暴露自定义配置的输入',
|
||||||
showStatus: false,
|
showStatus: false,
|
||||||
|
version: '481',
|
||||||
inputs: [],
|
inputs: [],
|
||||||
outputs: []
|
outputs: []
|
||||||
};
|
};
|
||||||
|
@@ -15,6 +15,7 @@ export const PluginOutputModule: FlowNodeTemplateType = {
|
|||||||
name: '自定义插件输出',
|
name: '自定义插件输出',
|
||||||
intro: '自定义配置外部输出,使用插件时,仅暴露自定义配置的输出',
|
intro: '自定义配置外部输出,使用插件时,仅暴露自定义配置的输出',
|
||||||
showStatus: false,
|
showStatus: false,
|
||||||
|
version: '481',
|
||||||
inputs: [],
|
inputs: [],
|
||||||
outputs: []
|
outputs: []
|
||||||
};
|
};
|
||||||
|
@@ -29,6 +29,7 @@ export const AiQueryExtension: FlowNodeTemplateType = {
|
|||||||
intro:
|
intro:
|
||||||
'使用问题优化功能,可以提高知识库连续对话时搜索的精度。使用该功能后,会先利用 AI 根据上下文构建一个或多个新的检索词,这些检索词更利于进行知识库搜索。该模块已内置在知识库搜索模块中,如果您仅进行一次知识库搜索,可直接使用知识库内置的补全功能。',
|
'使用问题优化功能,可以提高知识库连续对话时搜索的精度。使用该功能后,会先利用 AI 根据上下文构建一个或多个新的检索词,这些检索词更利于进行知识库搜索。该模块已内置在知识库搜索模块中,如果您仅进行一次知识库搜索,可直接使用知识库内置的补全功能。',
|
||||||
showStatus: true,
|
showStatus: true,
|
||||||
|
version: '481',
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
...Input_Template_SelectAIModel,
|
...Input_Template_SelectAIModel,
|
||||||
|
@@ -23,6 +23,7 @@ export const RunAppModule: FlowNodeTemplateType = {
|
|||||||
name: '应用调用',
|
name: '应用调用',
|
||||||
intro: '可以选择一个其他应用进行调用',
|
intro: '可以选择一个其他应用进行调用',
|
||||||
showStatus: true,
|
showStatus: true,
|
||||||
|
version: '481',
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
key: NodeInputKeyEnum.runAppSelectApp,
|
key: NodeInputKeyEnum.runAppSelectApp,
|
||||||
|
@@ -13,6 +13,7 @@ export const RunPluginModule: FlowNodeTemplateType = {
|
|||||||
name: '',
|
name: '',
|
||||||
showStatus: false,
|
showStatus: false,
|
||||||
isTool: true,
|
isTool: true,
|
||||||
|
version: '481',
|
||||||
inputs: [], // [{key:'pluginId'},...]
|
inputs: [], // [{key:'pluginId'},...]
|
||||||
outputs: []
|
outputs: []
|
||||||
};
|
};
|
||||||
|
@@ -13,6 +13,7 @@ export const StopToolNode: FlowNodeTemplateType = {
|
|||||||
name: '工具调用终止',
|
name: '工具调用终止',
|
||||||
intro:
|
intro:
|
||||||
'该模块需配置工具调用使用。当该模块被执行时,本次工具调用将会强制结束,并且不再调用AI针对工具调用结果回答问题。',
|
'该模块需配置工具调用使用。当该模块被执行时,本次工具调用将会强制结束,并且不再调用AI针对工具调用结果回答问题。',
|
||||||
|
version: '481',
|
||||||
inputs: [],
|
inputs: [],
|
||||||
outputs: []
|
outputs: []
|
||||||
};
|
};
|
||||||
|
@@ -18,6 +18,7 @@ export const SystemConfigNode: FlowNodeTemplateType = {
|
|||||||
intro: '可以配置应用的系统参数。',
|
intro: '可以配置应用的系统参数。',
|
||||||
unique: true,
|
unique: true,
|
||||||
forbidDelete: true,
|
forbidDelete: true,
|
||||||
|
version: '481',
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
key: NodeInputKeyEnum.welcomeText,
|
key: NodeInputKeyEnum.welcomeText,
|
||||||
|
@@ -30,6 +30,7 @@ export const ToolModule: FlowNodeTemplateType = {
|
|||||||
name: '工具调用(实验)',
|
name: '工具调用(实验)',
|
||||||
intro: '通过AI模型自动选择一个或多个功能块进行调用,也可以对插件进行调用。',
|
intro: '通过AI模型自动选择一个或多个功能块进行调用,也可以对插件进行调用。',
|
||||||
showStatus: true,
|
showStatus: true,
|
||||||
|
version: '481',
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
...Input_Template_SettingAiModel,
|
...Input_Template_SettingAiModel,
|
||||||
|
@@ -18,6 +18,7 @@ export const VariableUpdateNode: FlowNodeTemplateType = {
|
|||||||
intro: '可以更新指定节点的输出值或更新全局变量',
|
intro: '可以更新指定节点的输出值或更新全局变量',
|
||||||
showStatus: true,
|
showStatus: true,
|
||||||
isTool: false,
|
isTool: false,
|
||||||
|
version: '481',
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
key: NodeInputKeyEnum.updateList,
|
key: NodeInputKeyEnum.updateList,
|
||||||
|
@@ -19,6 +19,7 @@ export const WorkflowStart: FlowNodeTemplateType = {
|
|||||||
intro: '',
|
intro: '',
|
||||||
forbidDelete: true,
|
forbidDelete: true,
|
||||||
unique: true,
|
unique: true,
|
||||||
|
version: '481',
|
||||||
inputs: [{ ...Input_Template_UserChatInput, toolDescription: '用户问题' }],
|
inputs: [{ ...Input_Template_UserChatInput, toolDescription: '用户问题' }],
|
||||||
outputs: [
|
outputs: [
|
||||||
{
|
{
|
||||||
|
@@ -28,6 +28,7 @@ export type FlowNodeCommonType = {
|
|||||||
name: string;
|
name: string;
|
||||||
intro?: string; // template list intro
|
intro?: string; // template list intro
|
||||||
showStatus?: boolean; // chatting response step status
|
showStatus?: boolean; // chatting response step status
|
||||||
|
version: string;
|
||||||
|
|
||||||
// data
|
// data
|
||||||
inputs: FlowNodeInputItemType[];
|
inputs: FlowNodeInputItemType[];
|
||||||
|
@@ -72,6 +72,7 @@ export async function getPluginPreviewNode({ id }: { id: string }): Promise<Flow
|
|||||||
intro: plugin.intro,
|
intro: plugin.intro,
|
||||||
showStatus: plugin.showStatus,
|
showStatus: plugin.showStatus,
|
||||||
isTool: plugin.isTool,
|
isTool: plugin.isTool,
|
||||||
|
version: '481',
|
||||||
sourceHandle: getHandleConfig(true, true, true, true),
|
sourceHandle: getHandleConfig(true, true, true, true),
|
||||||
targetHandle: getHandleConfig(true, true, true, true),
|
targetHandle: getHandleConfig(true, true, true, true),
|
||||||
...pluginData2FlowNodeIO(plugin.nodes)
|
...pluginData2FlowNodeIO(plugin.nodes)
|
||||||
|
@@ -521,6 +521,19 @@ export const theme = extendTheme({
|
|||||||
800: '#05603A',
|
800: '#05603A',
|
||||||
900: '#054F31'
|
900: '#054F31'
|
||||||
},
|
},
|
||||||
|
yellow: {
|
||||||
|
25: '#FFFDFA',
|
||||||
|
50: '#FFFAEB',
|
||||||
|
100: '#FEF0C7',
|
||||||
|
200: '#FEDF89',
|
||||||
|
300: '#F5C149',
|
||||||
|
400: '#FDB022',
|
||||||
|
500: '#F79009',
|
||||||
|
600: '#DC6803',
|
||||||
|
700: '#B54708',
|
||||||
|
800: '#93370D',
|
||||||
|
900: '#7A2E0E'
|
||||||
|
},
|
||||||
borderColor: {
|
borderColor: {
|
||||||
low: '#E8EBF0',
|
low: '#E8EBF0',
|
||||||
base: '#DFE2EA',
|
base: '#DFE2EA',
|
||||||
|
@@ -31,6 +31,12 @@
|
|||||||
"To Chat": "Go to Chat",
|
"To Chat": "Go to Chat",
|
||||||
"To Settings": "View Details",
|
"To Settings": "View Details",
|
||||||
"Variable Key Repeat Tip": "Variable key is duplicate",
|
"Variable Key Repeat Tip": "Variable key is duplicate",
|
||||||
|
"app": {
|
||||||
|
"modules": {
|
||||||
|
"click to update": "click to update",
|
||||||
|
"has new version": "has new version"
|
||||||
|
}
|
||||||
|
},
|
||||||
"module": {
|
"module": {
|
||||||
"Combine Modules": "Combine Modules",
|
"Combine Modules": "Combine Modules",
|
||||||
"Custom Title Tip": "This title will be displayed during the conversation",
|
"Custom Title Tip": "This title will be displayed during the conversation",
|
||||||
|
@@ -30,6 +30,12 @@
|
|||||||
"To Chat": "前去对话",
|
"To Chat": "前去对话",
|
||||||
"To Settings": "查看详情",
|
"To Settings": "查看详情",
|
||||||
"Variable Key Repeat Tip": "变量 key 重复",
|
"Variable Key Repeat Tip": "变量 key 重复",
|
||||||
|
"app": {
|
||||||
|
"modules": {
|
||||||
|
"click to update": "点击更新",
|
||||||
|
"has new version": "有新版本"
|
||||||
|
}
|
||||||
|
},
|
||||||
"module": {
|
"module": {
|
||||||
"Combine Modules": "组合模块",
|
"Combine Modules": "组合模块",
|
||||||
"Custom Title Tip": "该标题名字会展示在对话过程中",
|
"Custom Title Tip": "该标题名字会展示在对话过程中",
|
||||||
|
@@ -18,11 +18,14 @@ import { ResponseBox } from '@/components/ChatBox/WholeResponseModal';
|
|||||||
import EmptyTip from '@fastgpt/web/components/common/EmptyTip';
|
import EmptyTip from '@fastgpt/web/components/common/EmptyTip';
|
||||||
import { getPreviewPluginModule } from '@/web/core/plugin/api';
|
import { getPreviewPluginModule } from '@/web/core/plugin/api';
|
||||||
import { getErrText } from '@fastgpt/global/common/error/utils';
|
import { getErrText } from '@fastgpt/global/common/error/utils';
|
||||||
import { storeNode2FlowNode } from '@/web/core/workflow/utils';
|
import { storeNode2FlowNode, updateFlowNodeVersion } from '@/web/core/workflow/utils';
|
||||||
import { getNanoid } from '@fastgpt/global/common/string/tools';
|
import { getNanoid } from '@fastgpt/global/common/string/tools';
|
||||||
import { useContextSelector } from 'use-context-selector';
|
import { useContextSelector } from 'use-context-selector';
|
||||||
import { WorkflowContext } from '../../../context';
|
import { WorkflowContext } from '../../../context';
|
||||||
import { useI18n } from '@/web/context/I18n';
|
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';
|
||||||
|
|
||||||
type Props = FlowNodeItemType & {
|
type Props = FlowNodeItemType & {
|
||||||
children?: React.ReactNode | React.ReactNode[] | string;
|
children?: React.ReactNode | React.ReactNode[] | string;
|
||||||
@@ -65,6 +68,7 @@ const NodeCard = (props: Props) => {
|
|||||||
const setHoverNodeId = useContextSelector(WorkflowContext, (v) => v.setHoverNodeId);
|
const setHoverNodeId = useContextSelector(WorkflowContext, (v) => v.setHoverNodeId);
|
||||||
const onUpdateNodeError = useContextSelector(WorkflowContext, (v) => v.onUpdateNodeError);
|
const onUpdateNodeError = useContextSelector(WorkflowContext, (v) => v.onUpdateNodeError);
|
||||||
const onChangeNode = useContextSelector(WorkflowContext, (v) => v.onChangeNode);
|
const onChangeNode = useContextSelector(WorkflowContext, (v) => v.onChangeNode);
|
||||||
|
const onResetNode = useContextSelector(WorkflowContext, (v) => v.onResetNode);
|
||||||
|
|
||||||
// custom title edit
|
// custom title edit
|
||||||
const { onOpenModal: onOpenCustomTitleModal, EditModal: EditTitleModal } = useEditTitle({
|
const { onOpenModal: onOpenCustomTitleModal, EditModal: EditTitleModal } = useEditTitle({
|
||||||
@@ -77,12 +81,21 @@ const NodeCard = (props: Props) => {
|
|||||||
[isTool, nodeList]
|
[isTool, nodeList]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const node = nodeList.find((node) => node.nodeId === nodeId);
|
||||||
|
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]);
|
||||||
|
|
||||||
/* Node header */
|
/* Node header */
|
||||||
const Header = useMemo(() => {
|
const Header = useMemo(() => {
|
||||||
return (
|
return (
|
||||||
<Box position={'relative'}>
|
<Box position={'relative'}>
|
||||||
{/* debug */}
|
{/* debug */}
|
||||||
<Box className="custom-drag-handle" px={4} py={3}>
|
<Box px={4} py={3}>
|
||||||
{/* tool target handle */}
|
{/* tool target handle */}
|
||||||
{showToolHandle && <ToolTargetHandle nodeId={nodeId} />}
|
{showToolHandle && <ToolTargetHandle nodeId={nodeId} />}
|
||||||
|
|
||||||
@@ -123,6 +136,33 @@ const NodeCard = (props: Props) => {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
<Box flex={1} />
|
||||||
|
{hasNewVersion && (
|
||||||
|
<MyTooltip label={appT('app.modules.click to update')}>
|
||||||
|
<Button
|
||||||
|
bg={'yellow.50'}
|
||||||
|
color={'yellow.600'}
|
||||||
|
variant={'ghost'}
|
||||||
|
h={8}
|
||||||
|
px={2}
|
||||||
|
rounded={'6px'}
|
||||||
|
fontSize={'xs'}
|
||||||
|
fontWeight={'medium'}
|
||||||
|
cursor={'pointer'}
|
||||||
|
_hover={{ bg: 'yellow.100' }}
|
||||||
|
onClick={() => {
|
||||||
|
if (!node || !template) return;
|
||||||
|
onResetNode({
|
||||||
|
id: nodeId,
|
||||||
|
node: updateFlowNodeVersion(node, template)
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box>{appT('app.modules.has new version')}</Box>
|
||||||
|
<QuestionOutlineIcon ml={1} />
|
||||||
|
</Button>
|
||||||
|
</MyTooltip>
|
||||||
|
)}
|
||||||
</Flex>
|
</Flex>
|
||||||
<MenuRender
|
<MenuRender
|
||||||
nodeId={nodeId}
|
nodeId={nodeId}
|
||||||
@@ -141,13 +181,17 @@ const NodeCard = (props: Props) => {
|
|||||||
t,
|
t,
|
||||||
name,
|
name,
|
||||||
menuForbid,
|
menuForbid,
|
||||||
|
hasNewVersion,
|
||||||
pluginId,
|
pluginId,
|
||||||
flowNodeType,
|
flowNodeType,
|
||||||
intro,
|
intro,
|
||||||
onOpenCustomTitleModal,
|
onOpenCustomTitleModal,
|
||||||
onChangeNode,
|
onChangeNode,
|
||||||
toast,
|
toast,
|
||||||
appT
|
appT,
|
||||||
|
node,
|
||||||
|
template,
|
||||||
|
onResetNode
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -236,7 +280,8 @@ const MenuRender = React.memo(function MenuRender({
|
|||||||
inputs: node.data.inputs,
|
inputs: node.data.inputs,
|
||||||
outputs: node.data.outputs,
|
outputs: node.data.outputs,
|
||||||
showStatus: node.data.showStatus,
|
showStatus: node.data.showStatus,
|
||||||
pluginId: node.data.pluginId
|
pluginId: node.data.pluginId,
|
||||||
|
version: node.data.version
|
||||||
};
|
};
|
||||||
return state.concat(
|
return state.concat(
|
||||||
storeNode2FlowNode({
|
storeNode2FlowNode({
|
||||||
@@ -250,7 +295,8 @@ const MenuRender = React.memo(function MenuRender({
|
|||||||
showStatus: template.showStatus,
|
showStatus: template.showStatus,
|
||||||
pluginId: template.pluginId,
|
pluginId: template.pluginId,
|
||||||
inputs: template.inputs,
|
inputs: template.inputs,
|
||||||
outputs: template.outputs
|
outputs: template.outputs,
|
||||||
|
version: template.version
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@@ -265,7 +311,7 @@ const MenuRender = React.memo(function MenuRender({
|
|||||||
},
|
},
|
||||||
[setEdges, setNodes]
|
[setEdges, setNodes]
|
||||||
);
|
);
|
||||||
const onclickSyncVersion = useCallback(async () => {
|
const onClickSyncVersion = useCallback(async () => {
|
||||||
if (!pluginId) return;
|
if (!pluginId) return;
|
||||||
try {
|
try {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
@@ -310,7 +356,7 @@ const MenuRender = React.memo(function MenuRender({
|
|||||||
icon: 'common/refreshLight',
|
icon: 'common/refreshLight',
|
||||||
label: t('plugin.Synchronous version'),
|
label: t('plugin.Synchronous version'),
|
||||||
variant: 'whiteBase',
|
variant: 'whiteBase',
|
||||||
onClick: onOpenConfirmSync(onclickSyncVersion)
|
onClick: onOpenConfirmSync(onClickSyncVersion)
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
: []),
|
: []),
|
||||||
@@ -362,21 +408,21 @@ const MenuRender = React.memo(function MenuRender({
|
|||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}, [
|
}, [
|
||||||
ConfirmDeleteModal,
|
|
||||||
ConfirmSyncModal,
|
|
||||||
DebugInputModal,
|
|
||||||
flowNodeType,
|
|
||||||
menuForbid?.copy,
|
|
||||||
menuForbid?.debug,
|
menuForbid?.debug,
|
||||||
|
menuForbid?.copy,
|
||||||
menuForbid?.delete,
|
menuForbid?.delete,
|
||||||
|
t,
|
||||||
|
flowNodeType,
|
||||||
|
onOpenConfirmSync,
|
||||||
|
onClickSyncVersion,
|
||||||
|
onOpenConfirmDeleteNode,
|
||||||
|
ConfirmSyncModal,
|
||||||
|
ConfirmDeleteModal,
|
||||||
|
DebugInputModal,
|
||||||
|
openDebugNode,
|
||||||
nodeId,
|
nodeId,
|
||||||
onCopyNode,
|
onCopyNode,
|
||||||
onDelNode,
|
onDelNode
|
||||||
onOpenConfirmDeleteNode,
|
|
||||||
onOpenConfirmSync,
|
|
||||||
onclickSyncVersion,
|
|
||||||
openDebugNode,
|
|
||||||
t
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return Render;
|
return Render;
|
||||||
|
@@ -19,6 +19,7 @@ export const flowNode2StoreNodes = ({
|
|||||||
flowNodeType: item.data.flowNodeType,
|
flowNodeType: item.data.flowNodeType,
|
||||||
showStatus: item.data.showStatus,
|
showStatus: item.data.showStatus,
|
||||||
position: item.position,
|
position: item.position,
|
||||||
|
version: item.data.version,
|
||||||
inputs: item.data.inputs,
|
inputs: item.data.inputs,
|
||||||
outputs: item.data.outputs,
|
outputs: item.data.outputs,
|
||||||
pluginId: item.data.pluginId
|
pluginId: item.data.pluginId
|
||||||
|
@@ -22,6 +22,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
|
|||||||
intro: plugin.intro,
|
intro: plugin.intro,
|
||||||
showStatus: true,
|
showStatus: true,
|
||||||
isTool: plugin.isTool,
|
isTool: plugin.isTool,
|
||||||
|
version: '481',
|
||||||
inputs: [],
|
inputs: [],
|
||||||
outputs: []
|
outputs: []
|
||||||
})) || [];
|
})) || [];
|
||||||
|
@@ -47,6 +47,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
|
|||||||
name: plugin.name,
|
name: plugin.name,
|
||||||
intro: plugin.intro,
|
intro: plugin.intro,
|
||||||
showStatus: false,
|
showStatus: false,
|
||||||
|
version: '481',
|
||||||
inputs: [],
|
inputs: [],
|
||||||
outputs: []
|
outputs: []
|
||||||
}));
|
}));
|
||||||
|
@@ -39,6 +39,7 @@ export const defaultForm: EditFormType = {
|
|||||||
x: 616.4226348688949,
|
x: 616.4226348688949,
|
||||||
y: -165.05298493910115
|
y: -165.05298493910115
|
||||||
},
|
},
|
||||||
|
version: '481',
|
||||||
inputs: [],
|
inputs: [],
|
||||||
outputs: []
|
outputs: []
|
||||||
},
|
},
|
||||||
@@ -52,6 +53,7 @@ export const defaultForm: EditFormType = {
|
|||||||
x: 1607.7142331269126,
|
x: 1607.7142331269126,
|
||||||
y: -151.8669210746189
|
y: -151.8669210746189
|
||||||
},
|
},
|
||||||
|
version: '481',
|
||||||
inputs: [],
|
inputs: [],
|
||||||
outputs: []
|
outputs: []
|
||||||
}
|
}
|
||||||
|
@@ -26,6 +26,7 @@ export const appTemplates: (AppItemType & {
|
|||||||
x: 531.2422736065552,
|
x: 531.2422736065552,
|
||||||
y: -486.7611729549753
|
y: -486.7611729549753
|
||||||
},
|
},
|
||||||
|
version: '481',
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
key: 'welcomeText',
|
key: 'welcomeText',
|
||||||
@@ -88,6 +89,7 @@ export const appTemplates: (AppItemType & {
|
|||||||
x: 558.4082376415505,
|
x: 558.4082376415505,
|
||||||
y: 123.72387429194112
|
y: 123.72387429194112
|
||||||
},
|
},
|
||||||
|
version: '481',
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
key: 'userChatInput',
|
key: 'userChatInput',
|
||||||
@@ -119,6 +121,7 @@ export const appTemplates: (AppItemType & {
|
|||||||
x: 1097.7317280958762,
|
x: 1097.7317280958762,
|
||||||
y: -244.16014496351386
|
y: -244.16014496351386
|
||||||
},
|
},
|
||||||
|
version: '481',
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
key: 'model',
|
key: 'model',
|
||||||
@@ -253,6 +256,7 @@ export const appTemplates: (AppItemType & {
|
|||||||
x: 496.57560693988853,
|
x: 496.57560693988853,
|
||||||
y: -490.7611729549753
|
y: -490.7611729549753
|
||||||
},
|
},
|
||||||
|
version: '481',
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
key: 'welcomeText',
|
key: 'welcomeText',
|
||||||
@@ -332,6 +336,7 @@ export const appTemplates: (AppItemType & {
|
|||||||
x: 558.4082376415505,
|
x: 558.4082376415505,
|
||||||
y: 123.72387429194112
|
y: 123.72387429194112
|
||||||
},
|
},
|
||||||
|
version: '481',
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
key: 'userChatInput',
|
key: 'userChatInput',
|
||||||
@@ -363,6 +368,7 @@ export const appTemplates: (AppItemType & {
|
|||||||
x: 1097.7317280958762,
|
x: 1097.7317280958762,
|
||||||
y: -244.16014496351386
|
y: -244.16014496351386
|
||||||
},
|
},
|
||||||
|
version: '481',
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
key: 'model',
|
key: 'model',
|
||||||
@@ -497,6 +503,7 @@ export const appTemplates: (AppItemType & {
|
|||||||
x: 531.2422736065552,
|
x: 531.2422736065552,
|
||||||
y: -486.7611729549753
|
y: -486.7611729549753
|
||||||
},
|
},
|
||||||
|
version: '481',
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
key: 'welcomeText',
|
key: 'welcomeText',
|
||||||
@@ -559,6 +566,7 @@ export const appTemplates: (AppItemType & {
|
|||||||
x: 558.4082376415505,
|
x: 558.4082376415505,
|
||||||
y: 123.72387429194112
|
y: 123.72387429194112
|
||||||
},
|
},
|
||||||
|
version: '481',
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
key: 'userChatInput',
|
key: 'userChatInput',
|
||||||
@@ -590,6 +598,7 @@ export const appTemplates: (AppItemType & {
|
|||||||
x: 1638.509551404687,
|
x: 1638.509551404687,
|
||||||
y: -341.0428450861567
|
y: -341.0428450861567
|
||||||
},
|
},
|
||||||
|
version: '481',
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
key: 'model',
|
key: 'model',
|
||||||
@@ -709,6 +718,7 @@ export const appTemplates: (AppItemType & {
|
|||||||
x: 918.5901682164496,
|
x: 918.5901682164496,
|
||||||
y: -227.11542247619582
|
y: -227.11542247619582
|
||||||
},
|
},
|
||||||
|
version: '481',
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
key: 'datasets',
|
key: 'datasets',
|
||||||
@@ -821,6 +831,7 @@ export const appTemplates: (AppItemType & {
|
|||||||
x: 531.2422736065552,
|
x: 531.2422736065552,
|
||||||
y: -486.7611729549753
|
y: -486.7611729549753
|
||||||
},
|
},
|
||||||
|
version: '481',
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
key: 'welcomeText',
|
key: 'welcomeText',
|
||||||
@@ -883,6 +894,7 @@ export const appTemplates: (AppItemType & {
|
|||||||
x: 558.4082376415505,
|
x: 558.4082376415505,
|
||||||
y: 123.72387429194112
|
y: 123.72387429194112
|
||||||
},
|
},
|
||||||
|
version: '481',
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
key: 'userChatInput',
|
key: 'userChatInput',
|
||||||
@@ -914,6 +926,7 @@ export const appTemplates: (AppItemType & {
|
|||||||
x: 2701.1267277679685,
|
x: 2701.1267277679685,
|
||||||
y: -767.8956312653042
|
y: -767.8956312653042
|
||||||
},
|
},
|
||||||
|
version: '481',
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
key: 'model',
|
key: 'model',
|
||||||
@@ -1034,6 +1047,7 @@ export const appTemplates: (AppItemType & {
|
|||||||
x: 1020.9667229609946,
|
x: 1020.9667229609946,
|
||||||
y: -385.0060974413916
|
y: -385.0060974413916
|
||||||
},
|
},
|
||||||
|
version: '481',
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
key: 'model',
|
key: 'model',
|
||||||
@@ -1114,6 +1128,7 @@ export const appTemplates: (AppItemType & {
|
|||||||
x: 1874.9167551056487,
|
x: 1874.9167551056487,
|
||||||
y: 434.98431875888207
|
y: 434.98431875888207
|
||||||
},
|
},
|
||||||
|
version: '481',
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
key: 'text',
|
key: 'text',
|
||||||
@@ -1139,6 +1154,7 @@ export const appTemplates: (AppItemType & {
|
|||||||
x: 1851.010152279949,
|
x: 1851.010152279949,
|
||||||
y: -613.3555232387284
|
y: -613.3555232387284
|
||||||
},
|
},
|
||||||
|
version: '481',
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
key: 'datasets',
|
key: 'datasets',
|
||||||
|
@@ -27,6 +27,7 @@ export function form2AppWorkflow(data: AppSimpleEditFormType): WorkflowType {
|
|||||||
x: 531.2422736065552,
|
x: 531.2422736065552,
|
||||||
y: -486.7611729549753
|
y: -486.7611729549753
|
||||||
},
|
},
|
||||||
|
version: '481',
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
key: NodeInputKeyEnum.welcomeText,
|
key: NodeInputKeyEnum.welcomeText,
|
||||||
@@ -79,6 +80,7 @@ export function form2AppWorkflow(data: AppSimpleEditFormType): WorkflowType {
|
|||||||
x: 558.4082376415505,
|
x: 558.4082376415505,
|
||||||
y: 123.72387429194112
|
y: 123.72387429194112
|
||||||
},
|
},
|
||||||
|
version: '481',
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
key: 'userChatInput',
|
key: 'userChatInput',
|
||||||
@@ -115,6 +117,7 @@ export function form2AppWorkflow(data: AppSimpleEditFormType): WorkflowType {
|
|||||||
x: 1106.3238387960757,
|
x: 1106.3238387960757,
|
||||||
y: -350.6030674683474
|
y: -350.6030674683474
|
||||||
},
|
},
|
||||||
|
version: '481',
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
key: 'model',
|
key: 'model',
|
||||||
@@ -247,6 +250,7 @@ export function form2AppWorkflow(data: AppSimpleEditFormType): WorkflowType {
|
|||||||
x: 1638.509551404687,
|
x: 1638.509551404687,
|
||||||
y: -341.0428450861567
|
y: -341.0428450861567
|
||||||
},
|
},
|
||||||
|
version: '481', // [FlowNodeTypeEnum.chatNode]
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
key: 'model',
|
key: 'model',
|
||||||
@@ -366,6 +370,7 @@ export function form2AppWorkflow(data: AppSimpleEditFormType): WorkflowType {
|
|||||||
x: 918.5901682164496,
|
x: 918.5901682164496,
|
||||||
y: -227.11542247619582
|
y: -227.11542247619582
|
||||||
},
|
},
|
||||||
|
version: '481',
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
key: 'datasets',
|
key: 'datasets',
|
||||||
@@ -484,6 +489,7 @@ export function form2AppWorkflow(data: AppSimpleEditFormType): WorkflowType {
|
|||||||
x: 500,
|
x: 500,
|
||||||
y: 545
|
y: 545
|
||||||
},
|
},
|
||||||
|
version: '481',
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
key: 'datasets',
|
key: 'datasets',
|
||||||
@@ -597,6 +603,7 @@ export function form2AppWorkflow(data: AppSimpleEditFormType): WorkflowType {
|
|||||||
x: 500 + 500 * (i + 1),
|
x: 500 + 500 * (i + 1),
|
||||||
y: 545
|
y: 545
|
||||||
},
|
},
|
||||||
|
version: tool.version,
|
||||||
inputs: tool.inputs,
|
inputs: tool.inputs,
|
||||||
outputs: tool.outputs
|
outputs: tool.outputs
|
||||||
}
|
}
|
||||||
@@ -625,6 +632,7 @@ export function form2AppWorkflow(data: AppSimpleEditFormType): WorkflowType {
|
|||||||
x: 1062.1738942532802,
|
x: 1062.1738942532802,
|
||||||
y: -223.65033022650476
|
y: -223.65033022650476
|
||||||
},
|
},
|
||||||
|
version: '481',
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
key: 'model',
|
key: 'model',
|
||||||
|
@@ -39,6 +39,7 @@ export const getGlobalVariableNode = (nodes: FlowNodeItemType[], t: TFunction) =
|
|||||||
intro: '',
|
intro: '',
|
||||||
unique: true,
|
unique: true,
|
||||||
forbidDelete: true,
|
forbidDelete: true,
|
||||||
|
version: '481',
|
||||||
inputs: [],
|
inputs: [],
|
||||||
outputs: []
|
outputs: []
|
||||||
};
|
};
|
||||||
@@ -418,6 +419,7 @@ export const v1Workflow2V2 = (
|
|||||||
pluginId,
|
pluginId,
|
||||||
pluginType: node.pluginType,
|
pluginType: node.pluginType,
|
||||||
parentId: node.parentId,
|
parentId: node.parentId,
|
||||||
|
version: 'v2.0',
|
||||||
|
|
||||||
inputs,
|
inputs,
|
||||||
outputs
|
outputs
|
||||||
|
@@ -24,7 +24,11 @@ import {
|
|||||||
} from '@fastgpt/global/core/workflow/utils';
|
} from '@fastgpt/global/core/workflow/utils';
|
||||||
import { getSystemVariables } from '../app/utils';
|
import { getSystemVariables } from '../app/utils';
|
||||||
import { TFunction } from 'next-i18next';
|
import { TFunction } from 'next-i18next';
|
||||||
import { ReferenceValueProps } from '@fastgpt/global/core/workflow/type/io';
|
import {
|
||||||
|
FlowNodeInputItemType,
|
||||||
|
FlowNodeOutputItemType,
|
||||||
|
ReferenceValueProps
|
||||||
|
} from '@fastgpt/global/core/workflow/type/io';
|
||||||
import { IfElseListItemType } from '@fastgpt/global/core/workflow/template/system/ifElse/type';
|
import { IfElseListItemType } from '@fastgpt/global/core/workflow/template/system/ifElse/type';
|
||||||
import { VariableConditionEnum } from '@fastgpt/global/core/workflow/template/system/ifElse/constant';
|
import { VariableConditionEnum } from '@fastgpt/global/core/workflow/template/system/ifElse/constant';
|
||||||
|
|
||||||
@@ -87,7 +91,8 @@ export const storeNode2FlowNode = ({
|
|||||||
...templateOutput,
|
...templateOutput,
|
||||||
value: storeOutput.value
|
value: storeOutput.value
|
||||||
};
|
};
|
||||||
})
|
}),
|
||||||
|
version: storeNode.version || '481'
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -298,3 +303,34 @@ export const getWorkflowGlobalVariables = (
|
|||||||
|
|
||||||
return [...globalVariables, ...systemVariables];
|
return [...globalVariables, ...systemVariables];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type CombinedItemType = Partial<FlowNodeInputItemType> & Partial<FlowNodeOutputItemType>;
|
||||||
|
|
||||||
|
export const updateFlowNodeVersion = (
|
||||||
|
node: FlowNodeItemType,
|
||||||
|
template: FlowNodeTemplateType
|
||||||
|
): FlowNodeItemType => {
|
||||||
|
function updateArrayBasedOnTemplate<T extends FlowNodeInputItemType | FlowNodeOutputItemType>(
|
||||||
|
nodeArray: T[],
|
||||||
|
templateArray: T[]
|
||||||
|
): T[] {
|
||||||
|
return templateArray.map((templateItem) => {
|
||||||
|
const nodeItem = nodeArray.find((item) => item.key === templateItem.key);
|
||||||
|
if (nodeItem) {
|
||||||
|
return { ...templateItem, ...nodeItem } as T;
|
||||||
|
}
|
||||||
|
return { ...templateItem };
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const updatedNode: FlowNodeItemType = { ...node, ...template, name: node.name };
|
||||||
|
|
||||||
|
if (node.inputs && template.inputs) {
|
||||||
|
updatedNode.inputs = updateArrayBasedOnTemplate(node.inputs, template.inputs);
|
||||||
|
}
|
||||||
|
if (node.outputs && template.outputs) {
|
||||||
|
updatedNode.outputs = updateArrayBasedOnTemplate(node.outputs, template.outputs);
|
||||||
|
}
|
||||||
|
|
||||||
|
return updatedNode;
|
||||||
|
};
|
||||||
|
Reference in New Issue
Block a user