mirror of
https://github.com/langgenius/dify.git
synced 2026-03-29 01:49:57 +08:00
feat: Merge parent workflow nodes into subgraph variable scope.And some
performance improve.
This commit is contained in:
@ -6,7 +6,7 @@ import type { NestedNodeConfig } from '@/app/components/workflow/nodes/_base/typ
|
||||
import type { Edge, Node } from '@/app/components/workflow/types'
|
||||
import { useCallback, useMemo } from 'react'
|
||||
import { useStoreApi } from 'reactflow'
|
||||
import { WorkflowWithInnerContext } from '@/app/components/workflow'
|
||||
import { InteractionMode, WorkflowWithInnerContext } from '@/app/components/workflow'
|
||||
import { useSetWorkflowVarsWithValue } from '@/app/components/workflow/hooks/use-fetch-workflow-inspect-vars'
|
||||
import { useInspectVarsCrudCommon } from '@/app/components/workflow/hooks/use-inspect-vars-crud-common'
|
||||
import { BlockEnum } from '@/app/components/workflow/types'
|
||||
@ -96,7 +96,7 @@ const SubGraphMain: FC<SubGraphMainProps> = (props) => {
|
||||
}, [selectableNodeTypes, variant])
|
||||
|
||||
const hooksStore = useMemo(() => ({
|
||||
interactionMode: 'subgraph',
|
||||
interactionMode: InteractionMode.Subgraph,
|
||||
subGraphSelectableNodeTypes: resolvedSelectableTypes,
|
||||
availableNodesMetaData,
|
||||
configsMap,
|
||||
@ -135,7 +135,7 @@ const SubGraphMain: FC<SubGraphMainProps> = (props) => {
|
||||
hooksStore={hooksStore as any}
|
||||
allowSelectionWhenReadOnly
|
||||
canvasReadOnly
|
||||
interactionMode="subgraph"
|
||||
interactionMode={InteractionMode.Subgraph}
|
||||
>
|
||||
{subGraphChildren}
|
||||
</WorkflowWithInnerContext>
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
import type { Node, NodeOutPutVar, ValueSelector, Var } from '@/app/components/workflow/types'
|
||||
import { useCallback } from 'react'
|
||||
import { useShallow } from 'zustand/react/shallow'
|
||||
import {
|
||||
useIsChatMode,
|
||||
useWorkflow,
|
||||
useWorkflowVariables,
|
||||
} from '@/app/components/workflow/hooks'
|
||||
import { useStore } from '@/app/components/workflow/store'
|
||||
import { BlockEnum } from '@/app/components/workflow/types'
|
||||
|
||||
type Params = {
|
||||
@ -15,6 +17,20 @@ type Params = {
|
||||
passedInAvailableNodes?: Node[]
|
||||
}
|
||||
|
||||
const mergeAvailableNodes = (baseNodes: Node[], extraNodes: Node[]) => {
|
||||
if (!extraNodes.length)
|
||||
return baseNodes
|
||||
const merged = new Map<string, Node>()
|
||||
baseNodes.forEach((node) => {
|
||||
merged.set(node.id, node)
|
||||
})
|
||||
extraNodes.forEach((node) => {
|
||||
if (!merged.has(node.id))
|
||||
merged.set(node.id, node)
|
||||
})
|
||||
return Array.from(merged.values())
|
||||
}
|
||||
|
||||
const getNodeInfo = (nodeId: string, nodes: Node[]) => {
|
||||
const allNodes = nodes
|
||||
const node = allNodes.find(n => n.id === nodeId)
|
||||
@ -44,12 +60,14 @@ const useNodesAvailableVarList = (nodes: Node[], {
|
||||
const { getTreeLeafNodes, getBeforeNodesInSameBranchIncludeParent } = useWorkflow()
|
||||
const { getNodeAvailableVars } = useWorkflowVariables()
|
||||
const isChatMode = useIsChatMode()
|
||||
const parentAvailableNodes = useStore(useShallow(s => s.parentAvailableNodes)) || []
|
||||
|
||||
const nodeAvailabilityMap: { [key: string ]: { availableVars: NodeOutPutVar[], availableNodes: Node[] } } = {}
|
||||
|
||||
nodes.forEach((node) => {
|
||||
const nodeId = node.id
|
||||
const availableNodes = passedInAvailableNodes || (onlyLeafNodeVar ? getTreeLeafNodes(nodeId) : getBeforeNodesInSameBranchIncludeParent(nodeId))
|
||||
const baseAvailableNodes = passedInAvailableNodes || (onlyLeafNodeVar ? getTreeLeafNodes(nodeId) : getBeforeNodesInSameBranchIncludeParent(nodeId))
|
||||
const availableNodes = mergeAvailableNodes(baseAvailableNodes, parentAvailableNodes)
|
||||
if (node.data.type === BlockEnum.Loop)
|
||||
availableNodes.push(node)
|
||||
|
||||
@ -79,6 +97,7 @@ export const useGetNodesAvailableVarList = () => {
|
||||
const { getTreeLeafNodes, getBeforeNodesInSameBranchIncludeParent } = useWorkflow()
|
||||
const { getNodeAvailableVars } = useWorkflowVariables()
|
||||
const isChatMode = useIsChatMode()
|
||||
const parentAvailableNodes = useStore(useShallow(s => s.parentAvailableNodes)) || []
|
||||
const getNodesAvailableVarList = useCallback((nodes: Node[], {
|
||||
onlyLeafNodeVar,
|
||||
filterVar,
|
||||
@ -93,7 +112,8 @@ export const useGetNodesAvailableVarList = () => {
|
||||
|
||||
nodes.forEach((node) => {
|
||||
const nodeId = node.id
|
||||
const availableNodes = passedInAvailableNodes || (onlyLeafNodeVar ? getTreeLeafNodes(nodeId) : getBeforeNodesInSameBranchIncludeParent(nodeId))
|
||||
const baseAvailableNodes = passedInAvailableNodes || (onlyLeafNodeVar ? getTreeLeafNodes(nodeId) : getBeforeNodesInSameBranchIncludeParent(nodeId))
|
||||
const availableNodes = mergeAvailableNodes(baseAvailableNodes, parentAvailableNodes)
|
||||
if (node.data.type === BlockEnum.Loop)
|
||||
availableNodes.push(node)
|
||||
|
||||
@ -117,7 +137,7 @@ export const useGetNodesAvailableVarList = () => {
|
||||
nodeAvailabilityMap[nodeId] = result
|
||||
})
|
||||
return nodeAvailabilityMap
|
||||
}, [getTreeLeafNodes, getBeforeNodesInSameBranchIncludeParent, getNodeAvailableVars, isChatMode])
|
||||
}, [getTreeLeafNodes, getBeforeNodesInSameBranchIncludeParent, getNodeAvailableVars, isChatMode, parentAvailableNodes])
|
||||
return {
|
||||
getNodesAvailableVarList,
|
||||
}
|
||||
|
||||
@ -134,6 +134,11 @@ const edgeTypes = {
|
||||
[CUSTOM_EDGE]: CustomEdge,
|
||||
}
|
||||
|
||||
export enum InteractionMode {
|
||||
Default = 'default',
|
||||
Subgraph = 'subgraph',
|
||||
}
|
||||
|
||||
export type WorkflowProps = {
|
||||
nodes: Node[]
|
||||
edges: Edge[]
|
||||
@ -142,7 +147,7 @@ export type WorkflowProps = {
|
||||
onWorkflowDataUpdate?: (v: any) => void
|
||||
allowSelectionWhenReadOnly?: boolean
|
||||
canvasReadOnly?: boolean
|
||||
interactionMode?: 'default' | 'subgraph'
|
||||
interactionMode?: InteractionMode
|
||||
}
|
||||
export const Workflow: FC<WorkflowProps> = memo(({
|
||||
nodes: originalNodes,
|
||||
@ -223,7 +228,7 @@ export const Workflow: FC<WorkflowProps> = memo(({
|
||||
const store = useStoreApi()
|
||||
eventEmitter?.useSubscription((v: any) => {
|
||||
if (v.type === WORKFLOW_DATA_UPDATE) {
|
||||
if (interactionMode === 'subgraph')
|
||||
if (interactionMode === InteractionMode.Subgraph)
|
||||
return
|
||||
setNodes(v.payload.nodes)
|
||||
store.getState().setNodes(v.payload.nodes)
|
||||
|
||||
@ -270,8 +270,9 @@ const VarReferencePicker: FC<Props> = ({
|
||||
}, [onChange, varKindType])
|
||||
|
||||
const handleVariableJump = useCallback((nodeId: string) => {
|
||||
const currentNodeIndex = availableNodes.findIndex(node => node.id === nodeId)
|
||||
const currentNode = availableNodes[currentNodeIndex]
|
||||
const currentNode = nodes.find(node => node.id === nodeId)
|
||||
if (!currentNode)
|
||||
return
|
||||
|
||||
const workflowContainer = document.getElementById('workflow-container')
|
||||
const {
|
||||
@ -289,7 +290,7 @@ const VarReferencePicker: FC<Props> = ({
|
||||
y: (clientHeight - currentNode.height! * zoom) / 2 - position.y * zoom,
|
||||
zoom: transform[2],
|
||||
})
|
||||
}, [availableNodes, reactflow, store])
|
||||
}, [nodes, reactflow, store])
|
||||
|
||||
const type = getCurrentVariableType({
|
||||
parentNode: (isInIteration ? iterationNode : loopNode) as any,
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
import type { Node, NodeOutPutVar, ValueSelector, Var } from '@/app/components/workflow/types'
|
||||
import { useMemo } from 'react'
|
||||
import { useShallow } from 'zustand/react/shallow'
|
||||
import {
|
||||
useIsChatMode,
|
||||
useWorkflow,
|
||||
@ -31,7 +33,23 @@ const useAvailableVarList = (nodeId: string, {
|
||||
const { getTreeLeafNodes, getNodeById, getBeforeNodesInSameBranchIncludeParent } = useWorkflow()
|
||||
const { getNodeAvailableVars } = useWorkflowVariables()
|
||||
const isChatMode = useIsChatMode()
|
||||
const availableNodes = passedInAvailableNodes || (onlyLeafNodeVar ? getTreeLeafNodes(nodeId) : getBeforeNodesInSameBranchIncludeParent(nodeId))
|
||||
const baseAvailableNodes = useMemo(() => {
|
||||
return passedInAvailableNodes || (onlyLeafNodeVar ? getTreeLeafNodes(nodeId) : getBeforeNodesInSameBranchIncludeParent(nodeId))
|
||||
}, [passedInAvailableNodes, onlyLeafNodeVar, nodeId, getTreeLeafNodes, getBeforeNodesInSameBranchIncludeParent])
|
||||
const parentAvailableNodes = useWorkflowStore(useShallow(s => s.parentAvailableNodes)) || []
|
||||
const availableNodes = useMemo(() => {
|
||||
if (!parentAvailableNodes.length)
|
||||
return baseAvailableNodes
|
||||
const merged = new Map<string, Node>()
|
||||
baseAvailableNodes.forEach((node) => {
|
||||
merged.set(node.id, node)
|
||||
})
|
||||
parentAvailableNodes.forEach((node) => {
|
||||
if (!merged.has(node.id))
|
||||
merged.set(node.id, node)
|
||||
})
|
||||
return Array.from(merged.values())
|
||||
}, [baseAvailableNodes, parentAvailableNodes])
|
||||
const {
|
||||
parentNode: iterationNode,
|
||||
} = useNodeInfo(nodeId)
|
||||
@ -71,10 +89,12 @@ const useAvailableVarList = (nodeId: string, {
|
||||
hideEnv,
|
||||
hideChatVar,
|
||||
}), ...dataSourceRagVars]
|
||||
const availableNodesWithParent = [
|
||||
...availableNodes,
|
||||
...(isDataSourceNode ? [currNode] : []),
|
||||
]
|
||||
const availableNodesWithParent = useMemo(() => {
|
||||
return [
|
||||
...availableNodes,
|
||||
...(isDataSourceNode ? [currNode] : []),
|
||||
]
|
||||
}, [availableNodes, currNode, isDataSourceNode])
|
||||
const llmNodeIds = new Set(
|
||||
availableNodesWithParent
|
||||
.filter(node => node?.data.type === BlockEnum.LLM)
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import type { CommonNodeType, InputVar, TriggerNodeType, ValueSelector, Var, Variable } from '@/app/components/workflow/types'
|
||||
import type { CommonNodeType, InputVar, Node, TriggerNodeType, ValueSelector, Var, Variable } from '@/app/components/workflow/types'
|
||||
import type { FlowType } from '@/types/common'
|
||||
import type { NodeRunResult, NodeTracing } from '@/types/workflow'
|
||||
import { unionBy } from 'es-toolkit/compat'
|
||||
@ -10,6 +10,7 @@ import { useTranslation } from 'react-i18next'
|
||||
import {
|
||||
useStoreApi,
|
||||
} from 'reactflow'
|
||||
import { useShallow } from 'zustand/react/shallow'
|
||||
import { trackEvent } from '@/app/components/base/amplitude'
|
||||
import { getInputVars as doGetInputVars } from '@/app/components/base/prompt-editor/constants'
|
||||
import Toast from '@/app/components/base/toast'
|
||||
@ -150,9 +151,24 @@ const useOneStepRun = <T>({
|
||||
const isIteration = data.type === BlockEnum.Iteration
|
||||
const isLoop = data.type === BlockEnum.Loop
|
||||
const isStartNode = data.type === BlockEnum.Start
|
||||
const parentAvailableNodes = useStore(useShallow(s => s.parentAvailableNodes)) || []
|
||||
|
||||
const availableNodes = getBeforeNodesInSameBranch(id)
|
||||
const availableNodesIncludeParent = getBeforeNodesInSameBranchIncludeParent(id)
|
||||
const mergeAvailableNodes = (baseNodes: Node[]) => {
|
||||
if (!parentAvailableNodes.length)
|
||||
return baseNodes
|
||||
const merged = new Map<string, Node>()
|
||||
baseNodes.forEach((node) => {
|
||||
merged.set(node.id, node)
|
||||
})
|
||||
parentAvailableNodes.forEach((node) => {
|
||||
if (!merged.has(node.id))
|
||||
merged.set(node.id, node)
|
||||
})
|
||||
return Array.from(merged.values())
|
||||
}
|
||||
|
||||
const availableNodes = mergeAvailableNodes(getBeforeNodesInSameBranch(id))
|
||||
const availableNodesIncludeParent = mergeAvailableNodes(getBeforeNodesInSameBranchIncludeParent(id))
|
||||
const workflowStore = useWorkflowStore()
|
||||
const { schemaTypeDefinitions } = useMatchSchemaType()
|
||||
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
import type { RefObject } from 'react'
|
||||
import type { IterationNodeType } from './types'
|
||||
import type { InputVar, ValueSelector, Variable } from '@/app/components/workflow/types'
|
||||
import type { InputVar, Node, ValueSelector, Variable } from '@/app/components/workflow/types'
|
||||
import type { NodeTracing } from '@/types/workflow'
|
||||
import { useCallback, useMemo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useShallow } from 'zustand/react/shallow'
|
||||
import formatTracing from '@/app/components/workflow/run/utils/format-log'
|
||||
import { useStore } from '@/app/components/workflow/store'
|
||||
import { InputVarType, VarType } from '@/app/components/workflow/types'
|
||||
import { VALUE_SELECTOR_DELIMITER as DELIMITER } from '@/config'
|
||||
import { useIsNodeInIteration, useWorkflow } from '../../hooks'
|
||||
@ -34,8 +36,22 @@ const useSingleRunFormParams = ({
|
||||
const { isNodeInIteration } = useIsNodeInIteration(id)
|
||||
|
||||
const { getIterationNodeChildren, getBeforeNodesInSameBranch } = useWorkflow()
|
||||
const parentAvailableNodes = useStore(useShallow(s => s.parentAvailableNodes)) || []
|
||||
const iterationChildrenNodes = getIterationNodeChildren(id)
|
||||
const beforeNodes = getBeforeNodesInSameBranch(id)
|
||||
const beforeNodes = (() => {
|
||||
const baseBeforeNodes = getBeforeNodesInSameBranch(id)
|
||||
if (!parentAvailableNodes.length)
|
||||
return baseBeforeNodes
|
||||
const merged = new Map<string, Node>()
|
||||
baseBeforeNodes.forEach((node) => {
|
||||
merged.set(node.id, node)
|
||||
})
|
||||
parentAvailableNodes.forEach((node) => {
|
||||
if (!merged.has(node.id))
|
||||
merged.set(node.id, node)
|
||||
})
|
||||
return Array.from(merged.values())
|
||||
})()
|
||||
const canChooseVarNodes = [...beforeNodes, ...iterationChildrenNodes]
|
||||
|
||||
const iteratorInputKey = `${id}.input_selector`
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
'use client'
|
||||
import type { FC } from 'react'
|
||||
import type { ModelConfig, Node, NodeOutPutVar, PromptItem, PromptMessageContext, PromptTemplateItem, ValueSelector, Var, Variable } from '../../../types'
|
||||
import type { ModelConfig, NodeOutPutVar, PromptItem, PromptMessageContext, PromptTemplateItem, ValueSelector, Var, Variable } from '../../../types'
|
||||
import { produce } from 'immer'
|
||||
import * as React from 'react'
|
||||
import { useCallback, useMemo, useRef, useState } from 'react'
|
||||
@ -18,7 +18,7 @@ import AddButton from '@/app/components/workflow/nodes/_base/components/add-butt
|
||||
import Editor from '@/app/components/workflow/nodes/_base/components/prompt/editor'
|
||||
import VarReferenceVars from '@/app/components/workflow/nodes/_base/components/variable/var-reference-vars'
|
||||
import { cn } from '@/utils/classnames'
|
||||
import { useStore, useWorkflowStore } from '../../../store'
|
||||
import { useWorkflowStore } from '../../../store'
|
||||
import { BlockEnum, EditionType, isPromptMessageContext, PromptRole, VarType } from '../../../types'
|
||||
import useAvailableVarList from '../../_base/hooks/use-available-var-list'
|
||||
import ConfigContextItem from './config-context-item'
|
||||
@ -88,39 +88,9 @@ const ConfigPrompt: FC<Props> = ({
|
||||
onlyLeafNodeVar: false,
|
||||
filterVar,
|
||||
})
|
||||
const parentAvailableVars = useStore(state => state.parentAvailableVars) || []
|
||||
const parentAvailableNodes = useStore(state => state.parentAvailableNodes) || []
|
||||
|
||||
const mergedAvailableVars = useMemo(() => {
|
||||
if (!parentAvailableVars.length)
|
||||
return availableVars
|
||||
const merged = new Map<string, NodeOutPutVar>()
|
||||
availableVars.forEach((item) => {
|
||||
merged.set(item.nodeId, item)
|
||||
})
|
||||
parentAvailableVars.forEach((item) => {
|
||||
if (!merged.has(item.nodeId))
|
||||
merged.set(item.nodeId, item)
|
||||
})
|
||||
return Array.from(merged.values())
|
||||
}, [availableVars, parentAvailableVars])
|
||||
|
||||
const mergedAvailableNodesWithParent = useMemo(() => {
|
||||
if (!parentAvailableNodes.length)
|
||||
return availableNodesWithParent
|
||||
const merged = new Map<string, Node>()
|
||||
availableNodesWithParent.forEach((node) => {
|
||||
merged.set(node.id, node)
|
||||
})
|
||||
parentAvailableNodes.forEach((node) => {
|
||||
if (!merged.has(node.id))
|
||||
merged.set(node.id, node)
|
||||
})
|
||||
return Array.from(merged.values())
|
||||
}, [availableNodesWithParent, parentAvailableNodes])
|
||||
|
||||
const contextVarOptions = useMemo<NodeOutPutVar[]>(() => {
|
||||
return mergedAvailableNodesWithParent
|
||||
return availableNodesWithParent
|
||||
.filter(node => node.data.type === BlockEnum.Agent || node.data.type === BlockEnum.LLM)
|
||||
.map(node => ({
|
||||
nodeId: node.id,
|
||||
@ -133,7 +103,7 @@ const ConfigPrompt: FC<Props> = ({
|
||||
},
|
||||
],
|
||||
}))
|
||||
}, [mergedAvailableNodesWithParent])
|
||||
}, [availableNodesWithParent])
|
||||
|
||||
const handleChatModePromptChange = useCallback((index: number) => {
|
||||
return (prompt: string) => {
|
||||
@ -315,7 +285,7 @@ const ConfigPrompt: FC<Props> = ({
|
||||
readOnly={readOnly}
|
||||
payload={item}
|
||||
contextVars={contextVarOptions}
|
||||
availableNodes={mergedAvailableNodesWithParent}
|
||||
availableNodes={availableNodesWithParent}
|
||||
onChange={handleContextChange(index)}
|
||||
onRemove={handleRemove(index)}
|
||||
/>
|
||||
@ -354,8 +324,8 @@ const ConfigPrompt: FC<Props> = ({
|
||||
onRemove={handleRemove(index)}
|
||||
isShowContext={isShowContext}
|
||||
hasSetBlockStatus={hasSetBlockStatus}
|
||||
availableVars={mergedAvailableVars}
|
||||
availableNodes={mergedAvailableNodesWithParent}
|
||||
availableVars={availableVars}
|
||||
availableNodes={availableNodesWithParent}
|
||||
varList={varList}
|
||||
handleAddVariable={handleAddVariable}
|
||||
modelConfig={modelConfig}
|
||||
@ -425,8 +395,8 @@ const ConfigPrompt: FC<Props> = ({
|
||||
isChatApp={isChatApp}
|
||||
isShowContext={isShowContext}
|
||||
hasSetBlockStatus={hasSetBlockStatus}
|
||||
nodesOutputVars={mergedAvailableVars}
|
||||
availableNodes={mergedAvailableNodesWithParent}
|
||||
nodesOutputVars={availableVars}
|
||||
availableNodes={availableNodesWithParent}
|
||||
isSupportPromptGenerator
|
||||
isSupportJinja
|
||||
editionType={(payload as PromptItem).edition_type}
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
import type { InputVar, ValueSelector, Variable } from '../../types'
|
||||
import type { InputVar, Node, ValueSelector, Variable } from '../../types'
|
||||
import type { CaseItem, Condition, LoopNodeType } from './types'
|
||||
import type { NodeTracing } from '@/types/workflow'
|
||||
import { useCallback, useMemo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useShallow } from 'zustand/react/shallow'
|
||||
import formatTracing from '@/app/components/workflow/run/utils/format-log'
|
||||
import { useStore } from '@/app/components/workflow/store'
|
||||
import { ValueType } from '@/app/components/workflow/types'
|
||||
import { VALUE_SELECTOR_DELIMITER as DELIMITER } from '@/config'
|
||||
import { useIsNodeInLoop, useWorkflow } from '../../hooks'
|
||||
@ -35,8 +37,22 @@ const useSingleRunFormParams = ({
|
||||
const { isNodeInLoop } = useIsNodeInLoop(id)
|
||||
|
||||
const { getLoopNodeChildren, getBeforeNodesInSameBranch } = useWorkflow()
|
||||
const parentAvailableNodes = useStore(useShallow(s => s.parentAvailableNodes)) || []
|
||||
const loopChildrenNodes = getLoopNodeChildren(id)
|
||||
const beforeNodes = getBeforeNodesInSameBranch(id)
|
||||
const beforeNodes = (() => {
|
||||
const baseBeforeNodes = getBeforeNodesInSameBranch(id)
|
||||
if (!parentAvailableNodes.length)
|
||||
return baseBeforeNodes
|
||||
const merged = new Map<string, Node>()
|
||||
baseBeforeNodes.forEach((node) => {
|
||||
merged.set(node.id, node)
|
||||
})
|
||||
parentAvailableNodes.forEach((node) => {
|
||||
if (!merged.has(node.id))
|
||||
merged.set(node.id, node)
|
||||
})
|
||||
return Array.from(merged.values())
|
||||
})()
|
||||
const canChooseVarNodes = [...beforeNodes, ...loopChildrenNodes]
|
||||
|
||||
const { usedOutVars, allVarObject } = (() => {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import type { PointerEvent, RefObject } from 'react'
|
||||
import type { ContextGenerateResponse } from '@/service/debug'
|
||||
import { RiArrowDownSLine, RiCheckLine, RiCloseLine } from '@remixicon/react'
|
||||
import { RiArrowDownSLine, RiCheckLine, RiCloseLine, RiPlayLargeLine } from '@remixicon/react'
|
||||
import { useCallback, useMemo, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import ActionButton from '@/app/components/base/action-button'
|
||||
@ -178,6 +178,7 @@ const RightPanel = ({
|
||||
onClick={onRun}
|
||||
disabled={!canRun || isGenerating}
|
||||
>
|
||||
<RiPlayLargeLine className="mr-1 h-4 w-4" />
|
||||
{t('nodes.tool.contextGenerate.run', { ns: 'workflow' })}
|
||||
</Button>
|
||||
)}
|
||||
|
||||
@ -18,7 +18,7 @@ import { useIsChatMode, useNodesSyncDraft, useWorkflow, useWorkflowVariables } f
|
||||
import { useHooksStore } from '@/app/components/workflow/hooks-store'
|
||||
import { VarKindType } from '@/app/components/workflow/nodes/_base/types'
|
||||
import { useStore as useWorkflowStore } from '@/app/components/workflow/store'
|
||||
import { BlockEnum, EditionType, isPromptMessageContext, PromptRole, VarType } from '@/app/components/workflow/types'
|
||||
import { EditionType, isPromptMessageContext, PromptRole, VarType } from '@/app/components/workflow/types'
|
||||
import SubGraphCanvas from './sub-graph-canvas'
|
||||
|
||||
const SubGraphModal: FC<SubGraphModalProps> = (props) => {
|
||||
@ -64,17 +64,11 @@ const SubGraphModal: FC<SubGraphModalProps> = (props) => {
|
||||
return getBeforeNodesInSameBranch(toolNodeId, workflowNodes, workflowEdges)
|
||||
}, [getBeforeNodesInSameBranch, isOpen, toolNodeId, workflowEdges, workflowNodes])
|
||||
|
||||
const parentContextNodes = useMemo(() => {
|
||||
if (!parentBeforeNodes.length || !isAgentVariant)
|
||||
return []
|
||||
return parentBeforeNodes.filter(node => node.data.type === BlockEnum.Agent || node.data.type === BlockEnum.LLM)
|
||||
}, [isAgentVariant, parentBeforeNodes])
|
||||
|
||||
const parentAvailableNodes = useMemo(() => {
|
||||
if (!isOpen)
|
||||
return []
|
||||
return isAgentVariant ? parentContextNodes : parentBeforeNodes
|
||||
}, [isAgentVariant, isOpen, parentBeforeNodes, parentContextNodes])
|
||||
return parentBeforeNodes
|
||||
}, [isOpen, parentBeforeNodes])
|
||||
|
||||
const parentAvailableVars = useMemo(() => {
|
||||
if (!parentAvailableNodes.length)
|
||||
|
||||
Reference in New Issue
Block a user