diff --git a/web/app/components/workflow/block-selector/blocks.tsx b/web/app/components/workflow/block-selector/blocks.tsx index 829ff64377..764fb46f02 100644 --- a/web/app/components/workflow/block-selector/blocks.tsx +++ b/web/app/components/workflow/block-selector/blocks.tsx @@ -19,10 +19,12 @@ import Tooltip from '@/app/components/base/tooltip' type BlocksProps = { searchText: string onSelect: (type: BlockEnum, tool?: ToolDefaultValue) => void + availableBlocksTypes?: BlockEnum[] } const Blocks = ({ searchText, onSelect, + availableBlocksTypes = [], }: BlocksProps) => { const { t } = useTranslation() const isChatMode = useIsChatMode() @@ -35,7 +37,7 @@ const Blocks = ({ if (block.type === BlockEnum.Answer && !isChatMode) return false - return block.title.toLowerCase().includes(searchText.toLowerCase()) + return block.title.toLowerCase().includes(searchText.toLowerCase()) && availableBlocksTypes.includes(block.type) }) return { @@ -43,7 +45,7 @@ const Blocks = ({ [classification]: list, } }, {} as Record) - }, [blocks, isChatMode, searchText]) + }, [blocks, isChatMode, searchText, availableBlocksTypes]) const isEmpty = Object.values(groups).every(list => !list.length) const renderGroup = useCallback((classification: string) => { diff --git a/web/app/components/workflow/block-selector/index.tsx b/web/app/components/workflow/block-selector/index.tsx index 46ab16dd32..6b948a86fa 100644 --- a/web/app/components/workflow/block-selector/index.tsx +++ b/web/app/components/workflow/block-selector/index.tsx @@ -12,6 +12,7 @@ import type { OffsetOptions, Placement, } from '@floating-ui/react' +import type { BlockEnum, OnSelectBlock } from '../types' import Tabs from './tabs' import { PortalToFollowElem, @@ -22,7 +23,6 @@ import { Plus02, SearchLg, } from '@/app/components/base/icons/src/vender/line/general' -import type { OnSelectBlock } from '@/app/components/workflow/types' import { XCircle } from '@/app/components/base/icons/src/vender/solid/general' type NodeSelectorProps = { @@ -36,6 +36,7 @@ type NodeSelectorProps = { triggerClassName?: (open: boolean) => string popupClassName?: string asChild?: boolean + availableBlocksTypes?: BlockEnum[] } const NodeSelector: FC = ({ open: openFromProps, @@ -48,6 +49,7 @@ const NodeSelector: FC = ({ triggerStyle, popupClassName, asChild, + availableBlocksTypes, }) => { const { t } = useTranslation() const [searchText, setSearchText] = useState('') @@ -125,6 +127,7 @@ const NodeSelector: FC = ({ diff --git a/web/app/components/workflow/block-selector/tabs.tsx b/web/app/components/workflow/block-selector/tabs.tsx index 5e6a31c072..e717461c1c 100644 --- a/web/app/components/workflow/block-selector/tabs.tsx +++ b/web/app/components/workflow/block-selector/tabs.tsx @@ -13,10 +13,12 @@ import Blocks from './blocks' export type TabsProps = { searchText: string onSelect: (type: BlockEnum, tool?: ToolDefaultValue) => void + availableBlocksTypes?: BlockEnum[] } const Tabs: FC = ({ searchText, onSelect, + availableBlocksTypes, }) => { const tabs = useTabs() const [activeTab, setActiveTab] = useState(tabs[0].key) @@ -46,6 +48,7 @@ const Tabs: FC = ({ ) } diff --git a/web/app/components/workflow/constants.ts b/web/app/components/workflow/constants.ts index 323f800c26..494d429a82 100644 --- a/web/app/components/workflow/constants.ts +++ b/web/app/components/workflow/constants.ts @@ -13,59 +13,128 @@ import ToolDefault from './nodes/tool/default' import VariableAssignerDefault from './nodes/variable-assigner/default' import EndNodeDefault from './nodes/end/default' -export const NODES_EXTRA_DATA = { +type NodesExtraData = { + author: string + about: string + availablePrevNodes: BlockEnum[] + availableNextNodes: BlockEnum[] + getAvailablePrevNodes: (isChatMode: boolean) => BlockEnum[] + getAvailableNextNodes: (isChatMode: boolean) => BlockEnum[] + checkValid: any +} +export const NODES_EXTRA_DATA: Record = { [BlockEnum.Start]: { author: 'Dify', about: '', + availablePrevNodes: [], + availableNextNodes: [], + getAvailablePrevNodes: StartNodeDefault.getAvailablePrevNodes, + getAvailableNextNodes: StartNodeDefault.getAvailableNextNodes, + checkValid: StartNodeDefault.checkValid, }, [BlockEnum.End]: { author: 'Dify', about: '', + availablePrevNodes: [], + availableNextNodes: [], + getAvailablePrevNodes: EndNodeDefault.getAvailablePrevNodes, + getAvailableNextNodes: EndNodeDefault.getAvailableNextNodes, + checkValid: EndNodeDefault.checkValid, }, [BlockEnum.Answer]: { author: 'Dify', about: '', + availablePrevNodes: [], + availableNextNodes: [], + getAvailablePrevNodes: AnswerDefault.getAvailablePrevNodes, + getAvailableNextNodes: AnswerDefault.getAvailableNextNodes, + checkValid: AnswerDefault.checkValid, }, [BlockEnum.LLM]: { author: 'Dify', about: '', + availablePrevNodes: [], + availableNextNodes: [], + getAvailablePrevNodes: LLMDefault.getAvailablePrevNodes, + getAvailableNextNodes: LLMDefault.getAvailableNextNodes, + checkValid: LLMDefault.checkValid, }, [BlockEnum.KnowledgeRetrieval]: { author: 'Dify', about: '', + availablePrevNodes: [], + availableNextNodes: [], + getAvailablePrevNodes: KnowledgeRetrievalDefault.getAvailablePrevNodes, + getAvailableNextNodes: KnowledgeRetrievalDefault.getAvailableNextNodes, + checkValid: KnowledgeRetrievalDefault.checkValid, }, [BlockEnum.IfElse]: { author: 'Dify', about: '', + availablePrevNodes: [], + availableNextNodes: [], + getAvailablePrevNodes: IfElseDefault.getAvailablePrevNodes, + getAvailableNextNodes: IfElseDefault.getAvailableNextNodes, + checkValid: IfElseDefault.checkValid, }, [BlockEnum.Code]: { author: 'Dify', about: '', + availablePrevNodes: [], + availableNextNodes: [], + getAvailablePrevNodes: CodeDefault.getAvailablePrevNodes, + getAvailableNextNodes: CodeDefault.getAvailableNextNodes, + checkValid: CodeDefault.checkValid, }, [BlockEnum.TemplateTransform]: { author: 'Dify', about: '', + availablePrevNodes: [], + availableNextNodes: [], + getAvailablePrevNodes: TemplateTransformDefault.getAvailablePrevNodes, + getAvailableNextNodes: TemplateTransformDefault.getAvailableNextNodes, + checkValid: TemplateTransformDefault.checkValid, }, [BlockEnum.QuestionClassifier]: { author: 'Dify', about: '', + availablePrevNodes: [], + availableNextNodes: [], + getAvailablePrevNodes: QuestionClassifierDefault.getAvailablePrevNodes, + getAvailableNextNodes: QuestionClassifierDefault.getAvailableNextNodes, + checkValid: QuestionClassifierDefault.checkValid, }, [BlockEnum.HttpRequest]: { author: 'Dify', about: '', + availablePrevNodes: [], + availableNextNodes: [], + getAvailablePrevNodes: HttpRequestDefault.getAvailablePrevNodes, + getAvailableNextNodes: HttpRequestDefault.getAvailableNextNodes, + checkValid: HttpRequestDefault.checkValid, }, [BlockEnum.VariableAssigner]: { author: 'Dify', about: '', + availablePrevNodes: [], + availableNextNodes: [], + getAvailablePrevNodes: VariableAssignerDefault.getAvailablePrevNodes, + getAvailableNextNodes: VariableAssignerDefault.getAvailableNextNodes, + checkValid: VariableAssignerDefault.checkValid, }, [BlockEnum.Tool]: { author: 'Dify', about: '', + availablePrevNodes: [], + availableNextNodes: [], + getAvailablePrevNodes: ToolDefault.getAvailablePrevNodes, + getAvailableNextNodes: ToolDefault.getAvailableNextNodes, + checkValid: ToolDefault.checkValid, }, } -export const ALL_CHAT_AVAILABLE_BLOCKS = Object.keys(NODES_EXTRA_DATA).filter(key => key !== BlockEnum.End) as BlockEnum[] -export const ALL_COMPLETION_AVAILABLE_BLOCKS = Object.keys(NODES_EXTRA_DATA).filter(key => key !== BlockEnum.Answer) as BlockEnum[] +export const ALL_CHAT_AVAILABLE_BLOCKS = Object.keys(NODES_EXTRA_DATA).filter(key => key !== BlockEnum.End && key !== BlockEnum.Start) as BlockEnum[] +export const ALL_COMPLETION_AVAILABLE_BLOCKS = Object.keys(NODES_EXTRA_DATA).filter(key => key !== BlockEnum.Answer && key !== BlockEnum.Start) as BlockEnum[] export const NODES_INITIAL_DATA = { [BlockEnum.Start]: { diff --git a/web/app/components/workflow/hooks/use-nodes-data.ts b/web/app/components/workflow/hooks/use-nodes-data.ts index 8a1ab815cb..9eaa40ce3c 100644 --- a/web/app/components/workflow/hooks/use-nodes-data.ts +++ b/web/app/components/workflow/hooks/use-nodes-data.ts @@ -7,6 +7,7 @@ import { NODES_INITIAL_DATA, } from '../constants' import { useStore } from '../store' +import { useIsChatMode } from './use-workflow' export const useNodesInitialData = () => { const { t } = useTranslation() @@ -28,10 +29,13 @@ export const useNodesInitialData = () => { export const useNodesExtraData = () => { const { t } = useTranslation() + const isChatMode = useIsChatMode() return useMemo(() => produce(NODES_EXTRA_DATA, (draft) => { Object.keys(draft).forEach((key) => { draft[key as BlockEnum].about = t(`workflow.blocksAbout.${key}`) + draft[key as BlockEnum].availablePrevNodes = draft[key as BlockEnum].getAvailablePrevNodes(isChatMode) + draft[key as BlockEnum].availableNextNodes = draft[key as BlockEnum].getAvailableNextNodes(isChatMode) }) - }), [t]) + }), [t, isChatMode]) } diff --git a/web/app/components/workflow/hooks/use-workflow.ts b/web/app/components/workflow/hooks/use-workflow.ts index 4da89fdf5d..ee2a5bb303 100644 --- a/web/app/components/workflow/hooks/use-workflow.ts +++ b/web/app/components/workflow/hooks/use-workflow.ts @@ -96,13 +96,7 @@ export const useWorkflow = () => { list.push(...incomers) return list.filter((item) => { - if (item.data.type === BlockEnum.IfElse) - return false - - if (item.data.type === BlockEnum.QuestionClassifier) - return false - - return true + return SUPPORT_OUTPUT_VARS_NODE.includes(item.data.type) }) }, [store]) @@ -175,21 +169,16 @@ export const useWorkflow = () => { return list }, [store]) - const getIncomersNodes = useCallback((currentNode: Node) => { - const { - getNodes, - edges, - } = store.getState() - - return getIncomers(currentNode, getNodes(), edges) - }, [store]) + const isValidConnection = useCallback(() => { + return true + }, []) return { handleLayout, getTreeLeafNodes, getBeforeNodesInSameBranch, getAfterNodesInSameBranch, - getIncomersNodes, + isValidConnection, } } diff --git a/web/app/components/workflow/index.tsx b/web/app/components/workflow/index.tsx index 35a26338c6..54b572b169 100644 --- a/web/app/components/workflow/index.tsx +++ b/web/app/components/workflow/index.tsx @@ -10,6 +10,7 @@ import ReactFlow, { Background, ReactFlowProvider, useOnViewportChange, + useStoreApi, } from 'reactflow' import type { Viewport } from 'reactflow' import 'reactflow/dist/style.css' @@ -21,6 +22,7 @@ import { useEdgesInteractions, useNodesInteractions, useNodesSyncDraft, + useWorkflow, useWorkflowInit, } from './hooks' import Header from './header' @@ -60,6 +62,7 @@ const Workflow: FC = memo(({ const showFeaturesPanel = useStore(state => state.showFeaturesPanel) const runningStatus = useStore(s => s.runningStatus) const { handleSyncWorkflowDraft } = useNodesSyncDraft() + const store = useStoreApi() useEffect(() => { setAutoFreeze(false) @@ -84,6 +87,7 @@ const Workflow: FC = memo(({ handleEdgeDelete, handleEdgesChange, } = useEdgesInteractions() + const { isValidConnection } = useWorkflow() useOnViewportChange({ onEnd: () => handleSyncWorkflowDraft(), @@ -130,6 +134,7 @@ const Workflow: FC = memo(({ zoomOnPinch={!runningStatus} zoomOnScroll={!runningStatus} zoomOnDoubleClick={!runningStatus} + isValidConnection={isValidConnection} > { const { t } = useTranslation() const { handleNodeAdd } = useNodesInteractions() + const nodesExtraData = useNodesExtraData() + const availableNextNodes = nodesExtraData[nodeType].availableNextNodes const handleSelect = useCallback((type, toolDefaultValue) => { handleNodeAdd( @@ -65,6 +75,7 @@ const Add = ({ offset={0} trigger={renderTrigger} popupClassName='!w-[328px]' + availableBlocksTypes={availableNextNodes} /> ) } diff --git a/web/app/components/workflow/nodes/_base/components/next-step/index.tsx b/web/app/components/workflow/nodes/_base/components/next-step/index.tsx index f34b5d8e60..f0cb6802af 100644 --- a/web/app/components/workflow/nodes/_base/components/next-step/index.tsx +++ b/web/app/components/workflow/nodes/_base/components/next-step/index.tsx @@ -51,6 +51,7 @@ const NextStep = ({ !nodeWithBranches && !outgoers.length && ( ) @@ -81,6 +82,7 @@ const NextStep = ({ diff --git a/web/app/components/workflow/nodes/_base/components/next-step/item.tsx b/web/app/components/workflow/nodes/_base/components/next-step/item.tsx index 7a112a1403..3c62026898 100644 --- a/web/app/components/workflow/nodes/_base/components/next-step/item.tsx +++ b/web/app/components/workflow/nodes/_base/components/next-step/item.tsx @@ -3,13 +3,17 @@ import { useCallback, } from 'react' import { useTranslation } from 'react-i18next' +import { union } from 'lodash-es' import type { CommonNodeType, OnSelectBlock, } from '@/app/components/workflow/types' import BlockIcon from '@/app/components/workflow/block-icon' import BlockSelector from '@/app/components/workflow/block-selector' -import { useNodesInteractions } from '@/app/components/workflow/hooks' +import { + useNodesExtraData, + useNodesInteractions, +} from '@/app/components/workflow/hooks' import Button from '@/app/components/base/button' type ItemProps = { @@ -26,6 +30,9 @@ const Item = ({ }: ItemProps) => { const { t } = useTranslation() const { handleNodeChange } = useNodesInteractions() + const nodesExtraData = useNodesExtraData() + const availablePrevNodes = nodesExtraData[data.type].availablePrevNodes + const availableNextNodes = nodesExtraData[data.type].availableNextNodes const handleSelect = useCallback((type, toolDefaultValue) => { handleNodeChange(nodeId, type, sourceHandle, toolDefaultValue) }, [nodeId, sourceHandle, handleNodeChange]) @@ -68,6 +75,7 @@ const Item = ({ }} trigger={renderTrigger} popupClassName='!w-[328px]' + availableBlocksTypes={union(availablePrevNodes, availableNextNodes)} /> ) diff --git a/web/app/components/workflow/nodes/_base/components/node-handle.tsx b/web/app/components/workflow/nodes/_base/components/node-handle.tsx index 7b87e7e0ef..84f99c56bc 100644 --- a/web/app/components/workflow/nodes/_base/components/node-handle.tsx +++ b/web/app/components/workflow/nodes/_base/components/node-handle.tsx @@ -13,7 +13,10 @@ import { BlockEnum } from '../../../types' import type { Node } from '../../../types' import BlockSelector from '../../../block-selector' import type { ToolDefaultValue } from '../../../block-selector/types' -import { useNodesInteractions } from '../../../hooks' +import { + useNodesExtraData, + useNodesInteractions, +} from '../../../hooks' import { useStore } from '../../../store' type NodeHandleProps = { @@ -31,7 +34,10 @@ export const NodeTargetHandle = memo(({ }: NodeHandleProps) => { const [open, setOpen] = useState(false) const { handleNodeAdd } = useNodesInteractions() + const nodesExtraData = useNodesExtraData() const connected = data._connectedTargetHandleIds?.includes(handleId) + const availablePrevNodes = nodesExtraData[data.type].availablePrevNodes + const isConnectable = !!availablePrevNodes.length const handleOpenChange = useCallback((v: boolean) => { setOpen(v) @@ -67,11 +73,11 @@ export const NodeTargetHandle = memo(({ ${data.type === BlockEnum.Start && 'opacity-0'} ${handleClassName} `} - isConnectable={data.type !== BlockEnum.Start} + isConnectable={isConnectable} onClick={handleHandleClick} > { - !connected && data.type !== BlockEnum.Start && ( + !connected && isConnectable && ( ) } @@ -103,6 +110,9 @@ export const NodeSourceHandle = memo(({ const notInitialWorkflow = useStore(s => s.notInitialWorkflow) const [open, setOpen] = useState(false) const { handleNodeAdd } = useNodesInteractions() + const nodesExtraData = useNodesExtraData() + const availableNextNodes = nodesExtraData[data.type].availableNextNodes + const isConnectable = !!availableNextNodes.length const connected = data._connectedSourceHandleIds?.includes(handleId) const handleOpenChange = useCallback((v: boolean) => { setOpen(v) @@ -142,10 +152,11 @@ export const NodeSourceHandle = memo(({ ${!connected && 'after:opacity-0'} ${handleClassName} `} + isConnectable={isConnectable} onClick={handleHandleClick} > { - !connected && ( + !connected && isConnectable && ( ) } diff --git a/web/app/components/workflow/nodes/_base/components/panel-operator/change-block.tsx b/web/app/components/workflow/nodes/_base/components/panel-operator/change-block.tsx index c5071f057c..21d1b4d776 100644 --- a/web/app/components/workflow/nodes/_base/components/panel-operator/change-block.tsx +++ b/web/app/components/workflow/nodes/_base/components/panel-operator/change-block.tsx @@ -3,20 +3,32 @@ import { useCallback, } from 'react' import { useTranslation } from 'react-i18next' +import { union } from 'lodash-es' import BlockSelector from '@/app/components/workflow/block-selector' -import { useNodesInteractions } from '@/app/components/workflow/hooks' -import type { OnSelectBlock } from '@/app/components/workflow/types' +import { + useNodesExtraData, + useNodesInteractions, +} from '@/app/components/workflow/hooks' +import type { + BlockEnum, + OnSelectBlock, +} from '@/app/components/workflow/types' type ChangeBlockProps = { nodeId: string + nodeType: BlockEnum sourceHandle: string } const ChangeBlock = ({ nodeId, + nodeType, sourceHandle, }: ChangeBlockProps) => { const { t } = useTranslation() const { handleNodeChange } = useNodesInteractions() + const nodesExtraData = useNodesExtraData() + const availablePrevNodes = nodesExtraData[nodeType].availablePrevNodes + const availableNextNodes = nodesExtraData[nodeType].availableNextNodes const handleSelect = useCallback((type, toolDefaultValue) => { handleNodeChange(nodeId, type, sourceHandle, toolDefaultValue) @@ -39,6 +51,7 @@ const ChangeBlock = ({ }} onSelect={handleSelect} trigger={renderTrigger} + availableBlocksTypes={union(availablePrevNodes, availableNextNodes)} /> ) } diff --git a/web/app/components/workflow/nodes/_base/components/panel-operator/index.tsx b/web/app/components/workflow/nodes/_base/components/panel-operator/index.tsx index 4e4a4a414e..c00a986e91 100644 --- a/web/app/components/workflow/nodes/_base/components/panel-operator/index.tsx +++ b/web/app/components/workflow/nodes/_base/components/panel-operator/index.tsx @@ -129,6 +129,7 @@ const PanelOperator = ({ data.type !== BlockEnum.Start && ( ) diff --git a/web/app/components/workflow/nodes/_base/panel.tsx b/web/app/components/workflow/nodes/_base/panel.tsx index 059b8bfee8..c29125daf4 100644 --- a/web/app/components/workflow/nodes/_base/panel.tsx +++ b/web/app/components/workflow/nodes/_base/panel.tsx @@ -20,6 +20,7 @@ import { import BlockIcon from '@/app/components/workflow/block-icon' import { useNodeDataUpdate, + useNodesExtraData, useNodesInteractions, } from '@/app/components/workflow/hooks' import { canRunBySingle } from '@/app/components/workflow/utils' @@ -27,7 +28,6 @@ import { GitBranch01 } from '@/app/components/base/icons/src/vender/line/develop import { Play } from '@/app/components/base/icons/src/vender/line/mediaAndDevices' import TooltipPlus from '@/app/components/base/tooltip-plus' import type { Node } from '@/app/components/workflow/types' -import { BlockEnum } from '@/app/components/workflow/types' type BasePanelProps = { children: ReactElement @@ -40,6 +40,9 @@ const BasePanel: FC = ({ }) => { const { t } = useTranslation() const { handleNodeSelect } = useNodesInteractions() + const nodesExtraData = useNodesExtraData() + const availableNextNodes = nodesExtraData[data.type].availableNextNodes + const { handleNodeDataUpdate, handleNodeDataUpdateWithSyncDraft, @@ -102,7 +105,7 @@ const BasePanel: FC = ({ {cloneElement(children, { id, data })} { - data.type !== BlockEnum.End && ( + !!availableNextNodes.length && (
diff --git a/web/app/components/workflow/nodes/if-else/default.ts b/web/app/components/workflow/nodes/if-else/default.ts index 3fbfa03d90..f81bcc2a47 100644 --- a/web/app/components/workflow/nodes/if-else/default.ts +++ b/web/app/components/workflow/nodes/if-else/default.ts @@ -1,4 +1,4 @@ -import type { NodeDefault } from '../../types' +import { BlockEnum, type NodeDefault } from '../../types' import { type IfElseNodeType, LogicalOperator } from './types' import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/constants' @@ -23,7 +23,7 @@ const nodeDefault: NodeDefault = { }, getAvailableNextNodes(isChatMode: boolean) { const nodes = isChatMode ? ALL_CHAT_AVAILABLE_BLOCKS : ALL_COMPLETION_AVAILABLE_BLOCKS - return nodes + return nodes.filter(type => type !== BlockEnum.VariableAssigner) }, checkValid(payload: IfElseNodeType) { let isValid = true diff --git a/web/app/components/workflow/nodes/question-classifier/default.ts b/web/app/components/workflow/nodes/question-classifier/default.ts index 21ad9e00f7..13edc69577 100644 --- a/web/app/components/workflow/nodes/question-classifier/default.ts +++ b/web/app/components/workflow/nodes/question-classifier/default.ts @@ -1,4 +1,5 @@ import type { NodeDefault } from '../../types' +import { BlockEnum } from '../../types' import type { QuestionClassifierNodeType } from './types' import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/constants' @@ -21,7 +22,7 @@ const nodeDefault: NodeDefault = { }, getAvailableNextNodes(isChatMode: boolean) { const nodes = isChatMode ? ALL_CHAT_AVAILABLE_BLOCKS : ALL_COMPLETION_AVAILABLE_BLOCKS - return nodes + return nodes.filter(type => type !== BlockEnum.VariableAssigner) }, checkValid(payload: QuestionClassifierNodeType) { let isValid = true diff --git a/web/app/components/workflow/nodes/variable-assigner/default.ts b/web/app/components/workflow/nodes/variable-assigner/default.ts index 9f45c6861b..b2bdd77e5f 100644 --- a/web/app/components/workflow/nodes/variable-assigner/default.ts +++ b/web/app/components/workflow/nodes/variable-assigner/default.ts @@ -1,4 +1,5 @@ import { type NodeDefault, VarType } from '../../types' +import { BlockEnum } from '../../types' import type { VariableAssignerNodeType } from './types' import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/constants' @@ -9,7 +10,7 @@ const nodeDefault: NodeDefault = { }, getAvailablePrevNodes(isChatMode: boolean) { const nodes = isChatMode ? ALL_CHAT_AVAILABLE_BLOCKS : ALL_COMPLETION_AVAILABLE_BLOCKS - return nodes + return nodes.filter(type => type !== BlockEnum.IfElse && type !== BlockEnum.QuestionClassifier) }, getAvailableNextNodes(isChatMode: boolean) { const nodes = isChatMode ? ALL_CHAT_AVAILABLE_BLOCKS : ALL_COMPLETION_AVAILABLE_BLOCKS