feat: workflow new nodes (#4683)
Co-authored-by: Joel <iamjoel007@gmail.com> Co-authored-by: Patryk Garstecki <patryk20120@yahoo.pl> Co-authored-by: Sebastian.W <thiner@gmail.com> Co-authored-by: 呆萌闷油瓶 <253605712@qq.com> Co-authored-by: takatost <takatost@users.noreply.github.com> Co-authored-by: rechardwang <wh_goodjob@163.com> Co-authored-by: Nite Knite <nkCoding@gmail.com> Co-authored-by: Chenhe Gu <guchenhe@gmail.com> Co-authored-by: Joshua <138381132+joshua20231026@users.noreply.github.com> Co-authored-by: Weaxs <459312872@qq.com> Co-authored-by: Ikko Eltociear Ashimine <eltociear@gmail.com> Co-authored-by: leejoo0 <81673835+leejoo0@users.noreply.github.com> Co-authored-by: JzoNg <jzongcode@gmail.com> Co-authored-by: sino <sino2322@gmail.com> Co-authored-by: Vikey Chen <vikeytk@gmail.com> Co-authored-by: wanghl <Wang-HL@users.noreply.github.com> Co-authored-by: Haolin Wang-汪皓临 <haolin.wang@atlaslovestravel.com> Co-authored-by: Zixuan Cheng <61724187+Theysua@users.noreply.github.com> Co-authored-by: crazywoola <100913391+crazywoola@users.noreply.github.com> Co-authored-by: Bowen Liang <bowenliang@apache.org> Co-authored-by: Bowen Liang <liangbowen@gf.com.cn> Co-authored-by: fanghongtai <42790567+fanghongtai@users.noreply.github.com> Co-authored-by: wxfanghongtai <wxfanghongtai@gf.com.cn> Co-authored-by: Matri <qjp@bithuman.io> Co-authored-by: Benjamin <benjaminx@gmail.com>
This commit is contained in:
@@ -3,7 +3,7 @@ import {
|
||||
getConnectedEdges,
|
||||
getOutgoers,
|
||||
} from 'reactflow'
|
||||
import dagre from 'dagre'
|
||||
import dagre from '@dagrejs/dagre'
|
||||
import { v4 as uuid4 } from 'uuid'
|
||||
import {
|
||||
cloneDeep,
|
||||
@@ -17,6 +17,7 @@ import type {
|
||||
} from './types'
|
||||
import { BlockEnum } from './types'
|
||||
import {
|
||||
ITERATION_NODE_Z_INDEX,
|
||||
NODE_WIDTH_X_OFFSET,
|
||||
START_INITIAL_POSITION,
|
||||
} from './constants'
|
||||
@@ -93,6 +94,16 @@ export const initialNodes = (originNodes: Node[], originEdges: Edge[]) => {
|
||||
})
|
||||
}
|
||||
|
||||
const iterationNodeMap = nodes.reduce((acc, node) => {
|
||||
if (node.parentId) {
|
||||
if (acc[node.parentId])
|
||||
acc[node.parentId].push(node.id)
|
||||
else
|
||||
acc[node.parentId] = [node.id]
|
||||
}
|
||||
return acc
|
||||
}, {} as Record<string, string[]>)
|
||||
|
||||
return nodes.map((node) => {
|
||||
node.type = 'custom'
|
||||
|
||||
@@ -119,6 +130,9 @@ export const initialNodes = (originNodes: Node[], originEdges: Edge[]) => {
|
||||
})
|
||||
}
|
||||
|
||||
if (node.data.type === BlockEnum.Iteration)
|
||||
node.data._children = iterationNodeMap[node.id] || []
|
||||
|
||||
return node
|
||||
})
|
||||
}
|
||||
@@ -172,19 +186,25 @@ export const initialEdges = (originEdges: Edge[], originNodes: Node[]) => {
|
||||
})
|
||||
}
|
||||
|
||||
const dagreGraph = new dagre.graphlib.Graph()
|
||||
dagreGraph.setDefaultEdgeLabel(() => ({}))
|
||||
export const getLayoutByDagre = (originNodes: Node[], originEdges: Edge[]) => {
|
||||
const nodes = cloneDeep(originNodes)
|
||||
const edges = cloneDeep(originEdges)
|
||||
const dagreGraph = new dagre.graphlib.Graph()
|
||||
dagreGraph.setDefaultEdgeLabel(() => ({}))
|
||||
const nodes = cloneDeep(originNodes).filter(node => !node.parentId)
|
||||
const edges = cloneDeep(originEdges).filter(edge => !edge.data?.isInIteration)
|
||||
dagreGraph.setGraph({
|
||||
rankdir: 'LR',
|
||||
align: 'UL',
|
||||
nodesep: 40,
|
||||
ranksep: 60,
|
||||
ranker: 'tight-tree',
|
||||
marginx: 30,
|
||||
marginy: 200,
|
||||
})
|
||||
nodes.forEach((node) => {
|
||||
dagreGraph.setNode(node.id, { width: node.width, height: node.height })
|
||||
dagreGraph.setNode(node.id, {
|
||||
width: node.width!,
|
||||
height: node.height!,
|
||||
})
|
||||
})
|
||||
|
||||
edges.forEach((edge) => {
|
||||
@@ -204,6 +224,8 @@ export const canRunBySingle = (nodeType: BlockEnum) => {
|
||||
|| nodeType === BlockEnum.QuestionClassifier
|
||||
|| nodeType === BlockEnum.HttpRequest
|
||||
|| nodeType === BlockEnum.Tool
|
||||
|| nodeType === BlockEnum.ParameterExtractor
|
||||
|| nodeType === BlockEnum.Iteration
|
||||
}
|
||||
|
||||
type ConnectedSourceOrTargetNodesChange = {
|
||||
@@ -254,7 +276,7 @@ export const getNodesConnectedSourceOrTargetHandleIdsMap = (changes: ConnectedSo
|
||||
return nodesConnectedSourceOrTargetHandleIdsMap
|
||||
}
|
||||
|
||||
export const generateNewNode = ({ data, position, id }: Pick<Node, 'data' | 'position'> & { id?: string }) => {
|
||||
export const generateNewNode = ({ data, position, id, zIndex, ...rest }: Omit<Node, 'id'> & { id?: string }) => {
|
||||
return {
|
||||
id: id || `${Date.now()}`,
|
||||
type: 'custom',
|
||||
@@ -262,6 +284,8 @@ export const generateNewNode = ({ data, position, id }: Pick<Node, 'data' | 'pos
|
||||
position,
|
||||
targetPosition: Position.Left,
|
||||
sourcePosition: Position.Right,
|
||||
zIndex: data.type === BlockEnum.Iteration ? ITERATION_NODE_Z_INDEX : zIndex,
|
||||
...rest,
|
||||
} as Node
|
||||
}
|
||||
|
||||
@@ -287,11 +311,15 @@ export const getValidTreeNodes = (nodes: Node[], edges: Edge[]) => {
|
||||
if (outgoers.length) {
|
||||
outgoers.forEach((outgoer) => {
|
||||
list.push(outgoer)
|
||||
if (outgoer.data.type === BlockEnum.Iteration)
|
||||
list.push(...nodes.filter(node => node.parentId === outgoer.id))
|
||||
traverse(outgoer, depth + 1)
|
||||
})
|
||||
}
|
||||
else {
|
||||
list.push(root)
|
||||
if (root.data.type === BlockEnum.Iteration)
|
||||
list.push(...nodes.filter(node => node.parentId === root.id))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -307,11 +335,12 @@ export const getToolCheckParams = (
|
||||
toolData: ToolNodeType,
|
||||
buildInTools: ToolWithProvider[],
|
||||
customTools: ToolWithProvider[],
|
||||
workflowTools: ToolWithProvider[],
|
||||
language: string,
|
||||
) => {
|
||||
const { provider_id, provider_type, tool_name } = toolData
|
||||
const isBuiltIn = provider_type === CollectionType.builtIn
|
||||
const currentTools = isBuiltIn ? buildInTools : customTools
|
||||
const currentTools = provider_type === CollectionType.builtIn ? buildInTools : provider_type === CollectionType.custom ? customTools : workflowTools
|
||||
const currCollection = currentTools.find(item => item.id === provider_id)
|
||||
const currTool = currCollection?.tools.find(tool => tool.name === tool_name)
|
||||
const formSchemas = currTool ? toolParametersToFormSchemas(currTool.parameters) : []
|
||||
|
Reference in New Issue
Block a user