mirror of
https://github.com/langgenius/dify.git
synced 2026-05-06 10:28:10 +08:00
feat: add AssembleVariablesAlt icon and integrate into sub-graph
components.
This commit is contained in:
@ -7,22 +7,28 @@ import { useShallow } from 'zustand/react/shallow'
|
||||
import { useIsChatMode, useWorkflowVariables } from '@/app/components/workflow/hooks'
|
||||
import Panel from '@/app/components/workflow/panel'
|
||||
import { useStore } from '@/app/components/workflow/store'
|
||||
import { BlockEnum } from '@/app/components/workflow/types'
|
||||
import ConfigPanel from './config-panel'
|
||||
|
||||
type SubGraphChildrenProps = {
|
||||
agentName: string
|
||||
extractorNodeId: string
|
||||
mentionConfig: MentionConfig
|
||||
onMentionConfigChange: (config: MentionConfig) => void
|
||||
}
|
||||
type SubGraphChildrenProps
|
||||
= | {
|
||||
variant: 'agent'
|
||||
title: string
|
||||
extractorNodeId: string
|
||||
mentionConfig: MentionConfig
|
||||
onMentionConfigChange: (config: MentionConfig) => void
|
||||
}
|
||||
| {
|
||||
variant: 'assemble'
|
||||
title: string
|
||||
extractorNodeId: string
|
||||
}
|
||||
|
||||
const SubGraphChildren: FC<SubGraphChildrenProps> = ({
|
||||
agentName,
|
||||
extractorNodeId,
|
||||
mentionConfig,
|
||||
onMentionConfigChange,
|
||||
}) => {
|
||||
const SubGraphChildren: FC<SubGraphChildrenProps> = (props) => {
|
||||
const {
|
||||
variant,
|
||||
title,
|
||||
extractorNodeId,
|
||||
} = props
|
||||
const { getNodeAvailableVars } = useWorkflowVariables()
|
||||
const isChatMode = useIsChatMode()
|
||||
const nodePanelWidth = useStore(s => s.nodePanelWidth)
|
||||
@ -32,7 +38,7 @@ const SubGraphChildren: FC<SubGraphChildrenProps> = ({
|
||||
}))
|
||||
|
||||
const extractorNode = useReactFlowStore(useShallow((s) => {
|
||||
return s.getNodes().find(node => node.data.type === BlockEnum.LLM)
|
||||
return s.getNodes().find(node => node.id === extractorNodeId)
|
||||
}))
|
||||
|
||||
const availableNodes = useMemo(() => {
|
||||
@ -51,8 +57,10 @@ const SubGraphChildren: FC<SubGraphChildrenProps> = ({
|
||||
return vars.filter(item => item.nodeId === extractorNode.id)
|
||||
}, [extractorNode, getNodeAvailableVars, isChatMode])
|
||||
|
||||
const agentProps = variant === 'agent' ? props : null
|
||||
|
||||
const panelRight = useMemo(() => {
|
||||
if (selectedNode)
|
||||
if (!agentProps || selectedNode)
|
||||
return null
|
||||
|
||||
return (
|
||||
@ -62,17 +70,25 @@ const SubGraphChildren: FC<SubGraphChildrenProps> = ({
|
||||
style={{ width: `${nodePanelWidth}px` }}
|
||||
>
|
||||
<ConfigPanel
|
||||
agentName={agentName}
|
||||
agentName={title}
|
||||
extractorNodeId={extractorNodeId}
|
||||
mentionConfig={mentionConfig}
|
||||
mentionConfig={agentProps.mentionConfig}
|
||||
availableNodes={availableNodes}
|
||||
availableVars={availableVars}
|
||||
onMentionConfigChange={onMentionConfigChange}
|
||||
onMentionConfigChange={agentProps.onMentionConfigChange}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}, [agentName, availableNodes, availableVars, extractorNodeId, mentionConfig, nodePanelWidth, onMentionConfigChange, selectedNode])
|
||||
}, [agentProps, availableNodes, availableVars, extractorNodeId, nodePanelWidth, selectedNode, title])
|
||||
|
||||
if (variant === 'assemble') {
|
||||
return (
|
||||
<Panel
|
||||
withHeader={false}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<Panel
|
||||
|
||||
@ -9,35 +9,46 @@ import { useStoreApi } from 'reactflow'
|
||||
import { 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'
|
||||
import { FlowType } from '@/types/common'
|
||||
import { useAvailableNodesMetaData } from '../hooks'
|
||||
import SubGraphChildren from './sub-graph-children'
|
||||
|
||||
type SubGraphMainProps = {
|
||||
type SubGraphMainBaseProps = {
|
||||
nodes: Node[]
|
||||
edges: Edge[]
|
||||
viewport: Viewport
|
||||
agentName: string
|
||||
title: string
|
||||
extractorNodeId: string
|
||||
configsMap?: HooksStoreShape['configsMap']
|
||||
mentionConfig: MentionConfig
|
||||
onMentionConfigChange: (config: MentionConfig) => void
|
||||
selectableNodeTypes?: BlockEnum[]
|
||||
onSave?: (nodes: Node[], edges: Edge[]) => void
|
||||
onSyncWorkflowDraft?: SyncWorkflowDraft
|
||||
}
|
||||
|
||||
const SubGraphMain: FC<SubGraphMainProps> = ({
|
||||
nodes,
|
||||
edges,
|
||||
viewport,
|
||||
agentName,
|
||||
extractorNodeId,
|
||||
configsMap,
|
||||
mentionConfig,
|
||||
onMentionConfigChange,
|
||||
onSave,
|
||||
onSyncWorkflowDraft,
|
||||
}) => {
|
||||
type SubGraphMainProps
|
||||
= | (SubGraphMainBaseProps & {
|
||||
variant: 'agent'
|
||||
mentionConfig: MentionConfig
|
||||
onMentionConfigChange: (config: MentionConfig) => void
|
||||
})
|
||||
| (SubGraphMainBaseProps & {
|
||||
variant: 'assemble'
|
||||
})
|
||||
|
||||
const SubGraphMain: FC<SubGraphMainProps> = (props) => {
|
||||
const {
|
||||
nodes,
|
||||
edges,
|
||||
viewport,
|
||||
variant,
|
||||
title,
|
||||
extractorNodeId,
|
||||
configsMap,
|
||||
selectableNodeTypes,
|
||||
onSave,
|
||||
onSyncWorkflowDraft,
|
||||
} = props
|
||||
const reactFlowStore = useStoreApi()
|
||||
const availableNodesMetaData = useAvailableNodesMetaData()
|
||||
const flowType = configsMap?.flowType ?? FlowType.appFlow
|
||||
@ -76,32 +87,53 @@ const SubGraphMain: FC<SubGraphMainProps> = ({
|
||||
}
|
||||
}, [handleSyncSubGraphDraft, onSyncWorkflowDraft])
|
||||
|
||||
const resolvedSelectableTypes = useMemo(() => {
|
||||
if (selectableNodeTypes && selectableNodeTypes.length > 0)
|
||||
return selectableNodeTypes
|
||||
return variant === 'agent' ? [BlockEnum.LLM] : [BlockEnum.Code]
|
||||
}, [selectableNodeTypes, variant])
|
||||
|
||||
const hooksStore = useMemo(() => ({
|
||||
interactionMode: 'subgraph',
|
||||
subGraphSelectableNodeTypes: resolvedSelectableTypes,
|
||||
availableNodesMetaData,
|
||||
configsMap,
|
||||
fetchInspectVars,
|
||||
...inspectVarsCrud,
|
||||
doSyncWorkflowDraft: handleSyncWorkflowDraft,
|
||||
syncWorkflowDraftWhenPageClose: handleSyncSubGraphDraft,
|
||||
}), [availableNodesMetaData, configsMap, fetchInspectVars, handleSyncSubGraphDraft, handleSyncWorkflowDraft, inspectVarsCrud])
|
||||
}), [availableNodesMetaData, configsMap, fetchInspectVars, handleSyncSubGraphDraft, handleSyncWorkflowDraft, inspectVarsCrud, resolvedSelectableTypes])
|
||||
|
||||
const subGraphChildren = variant === 'agent'
|
||||
? (
|
||||
<SubGraphChildren
|
||||
variant="agent"
|
||||
title={title}
|
||||
extractorNodeId={extractorNodeId}
|
||||
mentionConfig={props.mentionConfig}
|
||||
onMentionConfigChange={props.onMentionConfigChange}
|
||||
/>
|
||||
)
|
||||
: (
|
||||
<SubGraphChildren
|
||||
variant="assemble"
|
||||
title={title}
|
||||
extractorNodeId={extractorNodeId}
|
||||
/>
|
||||
)
|
||||
|
||||
return (
|
||||
<WorkflowWithInnerContext
|
||||
nodes={nodes}
|
||||
edges={edges}
|
||||
viewport={viewport}
|
||||
// eslint-disable-next-line ts/no-explicit-any -- TODO: remove after typing boundary
|
||||
hooksStore={hooksStore as any}
|
||||
allowSelectionWhenReadOnly
|
||||
canvasReadOnly
|
||||
interactionMode="subgraph"
|
||||
>
|
||||
<SubGraphChildren
|
||||
agentName={agentName}
|
||||
extractorNodeId={extractorNodeId}
|
||||
mentionConfig={mentionConfig}
|
||||
onMentionConfigChange={onMentionConfigChange}
|
||||
/>
|
||||
{subGraphChildren}
|
||||
</WorkflowWithInnerContext>
|
||||
)
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@ import { memo, useEffect, useMemo } from 'react'
|
||||
import WorkflowWithDefaultContext from '@/app/components/workflow'
|
||||
import { NODE_WIDTH_X_OFFSET, START_INITIAL_POSITION } from '@/app/components/workflow/constants'
|
||||
import { WorkflowContextProvider } from '@/app/components/workflow/context'
|
||||
import { CUSTOM_SUB_GRAPH_START_NODE } from '@/app/components/workflow/nodes/sub-graph-start/constants'
|
||||
import { useStore } from '@/app/components/workflow/store'
|
||||
import { BlockEnum, EditionType, isPromptMessageContext, PromptRole } from '@/app/components/workflow/types'
|
||||
import SubGraphMain from './components/sub-graph-main'
|
||||
@ -18,7 +19,7 @@ const SUB_GRAPH_ENTRY_POSITION = {
|
||||
x: START_INITIAL_POSITION.x,
|
||||
y: 150,
|
||||
}
|
||||
const SUB_GRAPH_LLM_POSITION = {
|
||||
const SUB_GRAPH_EXTRACTOR_POSITION = {
|
||||
x: SUB_GRAPH_ENTRY_POSITION.x + NODE_WIDTH_X_OFFSET - SUB_GRAPH_EDGE_GAP,
|
||||
y: SUB_GRAPH_ENTRY_POSITION.y,
|
||||
}
|
||||
@ -33,19 +34,19 @@ const SubGraphContent: FC<SubGraphProps> = (props) => {
|
||||
const {
|
||||
toolNodeId,
|
||||
paramKey,
|
||||
agentName,
|
||||
agentNodeId,
|
||||
mentionConfig,
|
||||
onMentionConfigChange,
|
||||
extractorNode,
|
||||
toolParamValue,
|
||||
parentAvailableNodes,
|
||||
parentAvailableVars,
|
||||
configsMap,
|
||||
selectableNodeTypes,
|
||||
onSave,
|
||||
onSyncWorkflowDraft,
|
||||
} = props
|
||||
|
||||
const isAgentVariant = props.variant === 'agent'
|
||||
const sourceTitle = isAgentVariant ? (props.agentName || '') : (props.title || '')
|
||||
const resolvedAgentNodeId = isAgentVariant ? props.agentNodeId : ''
|
||||
|
||||
const setParentAvailableVars = useStore(state => state.setParentAvailableVars)
|
||||
const setParentAvailableNodes = useStore(state => state.setParentAvailableNodes)
|
||||
|
||||
@ -55,28 +56,47 @@ const SubGraphContent: FC<SubGraphProps> = (props) => {
|
||||
}, [parentAvailableNodes, parentAvailableVars, setParentAvailableNodes, setParentAvailableVars])
|
||||
|
||||
const promptText = useMemo(() => {
|
||||
if (!toolParamValue)
|
||||
if (!isAgentVariant || !toolParamValue)
|
||||
return ''
|
||||
// Reason: escape agent id before building a regex pattern.
|
||||
const escapedAgentId = agentNodeId.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
||||
const escapedAgentId = resolvedAgentNodeId.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
||||
const leadingPattern = new RegExp(`^\\{\\{[@#]${escapedAgentId}\\.context[@#]\\}\\}`)
|
||||
return toolParamValue.replace(leadingPattern, '')
|
||||
}, [agentNodeId, toolParamValue])
|
||||
}, [isAgentVariant, resolvedAgentNodeId, toolParamValue])
|
||||
|
||||
const startNode = useMemo(() => {
|
||||
if (!isAgentVariant) {
|
||||
return {
|
||||
id: 'subgraph-source',
|
||||
type: CUSTOM_SUB_GRAPH_START_NODE,
|
||||
position: SUB_GRAPH_ENTRY_POSITION,
|
||||
data: {
|
||||
type: BlockEnum.Start,
|
||||
title: sourceTitle,
|
||||
desc: '',
|
||||
selected: false,
|
||||
iconType: 'assemble',
|
||||
variables: [],
|
||||
},
|
||||
selected: false,
|
||||
selectable: false,
|
||||
draggable: false,
|
||||
connectable: false,
|
||||
focusable: false,
|
||||
deletable: false,
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
id: 'subgraph-source',
|
||||
type: 'custom',
|
||||
type: CUSTOM_SUB_GRAPH_START_NODE,
|
||||
position: SUB_GRAPH_ENTRY_POSITION,
|
||||
data: {
|
||||
type: BlockEnum.Start,
|
||||
title: agentName,
|
||||
title: sourceTitle,
|
||||
desc: '',
|
||||
_connectedSourceHandleIds: ['source'],
|
||||
_connectedTargetHandleIds: [],
|
||||
_subGraphEntry: true,
|
||||
_iconTypeOverride: BlockEnum.Agent,
|
||||
selected: false,
|
||||
iconType: 'agent',
|
||||
variables: [],
|
||||
},
|
||||
selected: false,
|
||||
@ -86,65 +106,83 @@ const SubGraphContent: FC<SubGraphProps> = (props) => {
|
||||
focusable: false,
|
||||
deletable: false,
|
||||
}
|
||||
}, [agentName])
|
||||
}, [isAgentVariant, sourceTitle])
|
||||
|
||||
const extractorDisplayNode = useMemo(() => {
|
||||
if (!extractorNode)
|
||||
return null
|
||||
if (isAgentVariant) {
|
||||
const extractorNode = props.extractorNode
|
||||
if (!extractorNode)
|
||||
return null
|
||||
|
||||
const applyPromptText = (item: PromptItem) => {
|
||||
if (item.edition_type === EditionType.jinja2) {
|
||||
return {
|
||||
...item,
|
||||
text: promptText,
|
||||
jinja2_text: promptText,
|
||||
}
|
||||
}
|
||||
return { ...item, text: promptText }
|
||||
}
|
||||
|
||||
const nextPromptTemplate = (() => {
|
||||
const template = extractorNode.data.prompt_template
|
||||
if (!Array.isArray(template))
|
||||
return applyPromptText(template as PromptItem)
|
||||
|
||||
const userIndex = template.findIndex(
|
||||
item => !isPromptMessageContext(item) && (item as PromptItem).role === PromptRole.user,
|
||||
)
|
||||
if (userIndex >= 0) {
|
||||
return template.map((item, index) => {
|
||||
if (index !== userIndex)
|
||||
return item
|
||||
return applyPromptText(item as PromptItem)
|
||||
}) as PromptTemplateItem[]
|
||||
}
|
||||
|
||||
const useJinja = template.some(
|
||||
item => !isPromptMessageContext(item) && (item as PromptItem).edition_type === EditionType.jinja2,
|
||||
)
|
||||
const defaultUserPrompt: PromptItem = useJinja
|
||||
? {
|
||||
role: PromptRole.user,
|
||||
const applyPromptText = (item: PromptItem) => {
|
||||
if (item.edition_type === EditionType.jinja2) {
|
||||
return {
|
||||
...item,
|
||||
text: promptText,
|
||||
jinja2_text: promptText,
|
||||
edition_type: EditionType.jinja2,
|
||||
}
|
||||
: { role: PromptRole.user, text: promptText }
|
||||
return [...template, defaultUserPrompt] as PromptTemplateItem[]
|
||||
})()
|
||||
}
|
||||
return { ...item, text: promptText }
|
||||
}
|
||||
|
||||
const nextPromptTemplate = (() => {
|
||||
const template = extractorNode.data.prompt_template
|
||||
if (!Array.isArray(template))
|
||||
return applyPromptText(template as PromptItem)
|
||||
|
||||
const userIndex = template.findIndex(
|
||||
item => !isPromptMessageContext(item) && (item as PromptItem).role === PromptRole.user,
|
||||
)
|
||||
if (userIndex >= 0) {
|
||||
return template.map((item, index) => {
|
||||
if (index !== userIndex)
|
||||
return item
|
||||
return applyPromptText(item as PromptItem)
|
||||
}) as PromptTemplateItem[]
|
||||
}
|
||||
|
||||
const useJinja = template.some(
|
||||
item => !isPromptMessageContext(item) && (item as PromptItem).edition_type === EditionType.jinja2,
|
||||
)
|
||||
const defaultUserPrompt: PromptItem = useJinja
|
||||
? {
|
||||
role: PromptRole.user,
|
||||
text: promptText,
|
||||
jinja2_text: promptText,
|
||||
edition_type: EditionType.jinja2,
|
||||
}
|
||||
: { role: PromptRole.user, text: promptText }
|
||||
return [...template, defaultUserPrompt] as PromptTemplateItem[]
|
||||
})()
|
||||
|
||||
return {
|
||||
...extractorNode,
|
||||
hidden: false,
|
||||
selected: false,
|
||||
position: SUB_GRAPH_EXTRACTOR_POSITION,
|
||||
data: {
|
||||
...extractorNode.data,
|
||||
selected: false,
|
||||
prompt_template: nextPromptTemplate,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
const extractorNode = props.extractorNode
|
||||
if (!extractorNode)
|
||||
return null
|
||||
|
||||
return {
|
||||
...extractorNode,
|
||||
hidden: false,
|
||||
selected: false,
|
||||
position: SUB_GRAPH_LLM_POSITION,
|
||||
position: SUB_GRAPH_EXTRACTOR_POSITION,
|
||||
data: {
|
||||
...extractorNode.data,
|
||||
selected: false,
|
||||
prompt_template: nextPromptTemplate,
|
||||
},
|
||||
}
|
||||
}, [extractorNode, promptText])
|
||||
}, [isAgentVariant, promptText, props.extractorNode])
|
||||
|
||||
const nodesSource = useMemo(() => {
|
||||
if (!extractorDisplayNode)
|
||||
@ -168,30 +206,54 @@ const SubGraphContent: FC<SubGraphProps> = (props) => {
|
||||
selectable: false,
|
||||
data: {
|
||||
sourceType: BlockEnum.Start,
|
||||
targetType: BlockEnum.LLM,
|
||||
targetType: isAgentVariant ? BlockEnum.LLM : BlockEnum.Code,
|
||||
_isTemp: true,
|
||||
_isSubGraphTemp: true,
|
||||
},
|
||||
},
|
||||
]
|
||||
}, [extractorDisplayNode, startNode])
|
||||
}, [extractorDisplayNode, isAgentVariant, startNode])
|
||||
|
||||
const { nodes, edges } = useSubGraphNodes(nodesSource, edgesSource)
|
||||
|
||||
if (isAgentVariant) {
|
||||
return (
|
||||
<WorkflowWithDefaultContext
|
||||
nodes={nodes}
|
||||
edges={edges}
|
||||
>
|
||||
<SubGraphMain
|
||||
variant="agent"
|
||||
nodes={nodes}
|
||||
edges={edges}
|
||||
viewport={defaultViewport}
|
||||
title={sourceTitle}
|
||||
extractorNodeId={`${toolNodeId}_ext_${paramKey}`}
|
||||
configsMap={configsMap}
|
||||
mentionConfig={props.mentionConfig}
|
||||
onMentionConfigChange={props.onMentionConfigChange}
|
||||
selectableNodeTypes={selectableNodeTypes}
|
||||
onSave={onSave}
|
||||
onSyncWorkflowDraft={onSyncWorkflowDraft}
|
||||
/>
|
||||
</WorkflowWithDefaultContext>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<WorkflowWithDefaultContext
|
||||
nodes={nodes}
|
||||
edges={edges}
|
||||
>
|
||||
<SubGraphMain
|
||||
variant="assemble"
|
||||
nodes={nodes}
|
||||
edges={edges}
|
||||
viewport={defaultViewport}
|
||||
agentName={agentName}
|
||||
title={sourceTitle}
|
||||
extractorNodeId={`${toolNodeId}_ext_${paramKey}`}
|
||||
configsMap={configsMap}
|
||||
mentionConfig={mentionConfig}
|
||||
onMentionConfigChange={onMentionConfigChange}
|
||||
selectableNodeTypes={selectableNodeTypes}
|
||||
onSave={onSave}
|
||||
onSyncWorkflowDraft={onSyncWorkflowDraft}
|
||||
/>
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
import type { StateCreator } from 'zustand'
|
||||
import type { Shape as HooksStoreShape } from '@/app/components/workflow/hooks-store'
|
||||
import type { MentionConfig } from '@/app/components/workflow/nodes/_base/types'
|
||||
import type { CodeNodeType } from '@/app/components/workflow/nodes/code/types'
|
||||
import type { LLMNodeType } from '@/app/components/workflow/nodes/llm/types'
|
||||
import type { Edge, Node, NodeOutPutVar, ValueSelector } from '@/app/components/workflow/types'
|
||||
import type { BlockEnum, Edge, Node, NodeOutPutVar, ValueSelector } from '@/app/components/workflow/types'
|
||||
|
||||
export type SyncWorkflowDraftCallback = {
|
||||
onSuccess?: () => void
|
||||
@ -15,23 +16,38 @@ export type SyncWorkflowDraft = (
|
||||
callback?: SyncWorkflowDraftCallback,
|
||||
) => Promise<void>
|
||||
|
||||
export type SubGraphProps = {
|
||||
export type SubGraphVariant = 'agent' | 'assemble'
|
||||
|
||||
type BaseSubGraphProps = {
|
||||
toolNodeId: string
|
||||
paramKey: string
|
||||
sourceVariable: ValueSelector
|
||||
agentNodeId: string
|
||||
agentName: string
|
||||
configsMap?: HooksStoreShape['configsMap']
|
||||
mentionConfig: MentionConfig
|
||||
onMentionConfigChange: (config: MentionConfig) => void
|
||||
extractorNode?: Node<LLMNodeType>
|
||||
toolParamValue?: string
|
||||
parentAvailableNodes?: Node[]
|
||||
parentAvailableVars?: NodeOutPutVar[]
|
||||
selectableNodeTypes?: BlockEnum[]
|
||||
onSave?: (nodes: Node[], edges: Edge[]) => void
|
||||
onSyncWorkflowDraft?: SyncWorkflowDraft
|
||||
}
|
||||
|
||||
export type AgentSubGraphProps = BaseSubGraphProps & {
|
||||
variant: 'agent'
|
||||
sourceVariable: ValueSelector
|
||||
agentNodeId: string
|
||||
agentName: string
|
||||
mentionConfig: MentionConfig
|
||||
onMentionConfigChange: (config: MentionConfig) => void
|
||||
extractorNode?: Node<LLMNodeType>
|
||||
}
|
||||
|
||||
export type AssembleSubGraphProps = BaseSubGraphProps & {
|
||||
variant: 'assemble'
|
||||
title: string
|
||||
extractorNode?: Node<CodeNodeType>
|
||||
}
|
||||
|
||||
export type SubGraphProps = AgentSubGraphProps | AssembleSubGraphProps
|
||||
|
||||
export type SubGraphSliceShape = {
|
||||
parentAvailableVars: NodeOutPutVar[]
|
||||
parentAvailableNodes: Node[]
|
||||
|
||||
Reference in New Issue
Block a user