diff --git a/service-web/client/src/components/flow/FlowEditor.tsx b/service-web/client/src/components/flow/FlowEditor.tsx index c10c53e..3192049 100644 --- a/service-web/client/src/components/flow/FlowEditor.tsx +++ b/service-web/client/src/components/flow/FlowEditor.tsx @@ -1,7 +1,7 @@ import {PlusCircleFilled, RollbackOutlined, SaveFilled} from '@ant-design/icons' import {Background, BackgroundVariant, Controls, type Edge, MiniMap, type Node, ReactFlow} from '@xyflow/react' import {Button, Dropdown, message, Popconfirm, Space} from 'antd' -import {arrToMap, find, isEqual, randomId} from 'licia' +import {arrToMap, randomId} from 'licia' import {useEffect} from 'react' import {useNavigate} from 'react-router' import styled from 'styled-components' @@ -52,33 +52,45 @@ const FlowableDiv = styled.div` } ` -const nodeDefine = [ - { +type NodeDefine = { + key: string, + name: string, + description: string, + component: any, +} + +const nodeDefine: Record = { + 'output-node': { key: 'output-node', name: '输出', + description: '定义输出变量', component: OutputNode, }, - { + 'llm-node': { key: 'llm-node', name: '大模型', + description: '使用大模型对话', component: LlmNode, }, - { + 'knowledge-node': { key: 'knowledge-node', name: '知识库', + description: '', component: KnowledgeNode, }, - { + 'code-node': { key: 'code-node', name: '代码执行', + description: '执行自定义的处理代码', component: CodeNode, }, - { + 'switch-node': { key: 'switch-node', - name: '条件分支', + name: '分支节点', + description: '根据不同的情况前往不同的分支', component: SwitchNode, }, -] +} export type GraphData = { nodes: Node[], edges: Edge[], data: any } @@ -92,7 +104,7 @@ function FlowEditor(props: FlowEditorProps) { const navigate = useNavigate() const [messageApi, contextHolder] = message.useMessage() - const {data, setData} = useDataStore() + const {data, setData, setDataById} = useDataStore() const { nodes, addNode, @@ -127,15 +139,29 @@ function FlowEditor(props: FlowEditorProps) { ({key: def.key, label: def.name})), + items: Object.keys(nodeDefine).map(key => ({key: key, label: nodeDefine[key]!.name})), onClick: ({key}) => { try { if (commonInfo.debug) { console.info('Add', key, JSON.stringify({nodes, edges, data})) } checkAddNode(key, nodes, edges) + + let nodeId = randomId(10, 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM') + let define = nodeDefine[key] + + setDataById( + nodeId, + { + node: { + name: define.name, + description: define.description, + }, + }, + ) + addNode({ - id: randomId(10), + id: nodeId, type: key, position: {x: 100, y: 100}, data: {}, @@ -196,10 +222,7 @@ function FlowEditor(props: FlowEditorProps) { } }} // @ts-ignore - nodeTypes={arrToMap( - nodeDefine.map(def => def.key), - key => find(nodeDefine, def => isEqual(key, def.key))!.component) - } + nodeTypes={arrToMap(Object.keys(nodeDefine), key => nodeDefine[key]!.component)} > diff --git a/service-web/client/src/components/flow/node/AmisNode.tsx b/service-web/client/src/components/flow/node/AmisNode.tsx index d6d004c..409050f 100644 --- a/service-web/client/src/components/flow/node/AmisNode.tsx +++ b/service-web/client/src/components/flow/node/AmisNode.tsx @@ -42,7 +42,7 @@ export function inputsFormColumns( data: any, ): Schema[] { let inputSchemaVariables: InputFormOptions[] = Object.keys(inputSchema).map(key => ({ - label: inputSchema[key]?.label ?? '', + label: `${key} (${inputSchema[key]?.label ?? ''})`, value: key, })) @@ -50,10 +50,14 @@ export function inputsFormColumns( let incomerVariables: InputFormOptionsGroup[] = [] for (const incomerId of incomerIds) { let nodeData = data[incomerId] ?? {} + let group = incomerId + if (has(nodeData, 'node') && has(nodeData.node, 'name')) { + group = `${nodeData.node.name} ${incomerId}` + } if (has(nodeData, 'outputs')) { let outputs = nodeData?.outputs ?? [] incomerVariables.push({ - group: incomerId, + group: group, variables: Object.keys(outputs).map(key => ({ value: `${incomerId}.${key}`, label: key, @@ -151,8 +155,6 @@ export function outputsFormColumns(editable: boolean = false, required: boolean type AmisNodeProps = { nodeProps: NodeProps - defaultNodeName: String - defaultNodeDescription?: String extraNodeDescription?: JSX.Element handler: JSX.Element columnSchema?: () => Schema[] @@ -187,8 +189,6 @@ export const NormalNodeHandler = () => { const AmisNode: (props: AmisNodeProps) => JSX.Element = ({ nodeProps, - defaultNodeName, - defaultNodeDescription, extraNodeDescription, handler, columnSchema, @@ -198,8 +198,8 @@ const AmisNode: (props: AmisNodeProps) => JSX.Element = ({ const {id} = nodeProps // @ts-ignore const nodeData = getDataById(id) - const nodeName = isEmpty(nodeData?.node?.name) ? defaultNodeName : nodeData.node.name - const nodeDescription = isEmpty(nodeData?.node?.description) ? defaultNodeDescription : nodeData.node?.description + const nodeName = nodeData?.node?.name ?? '' + const nodeDescription = nodeData?.node?.description ?? '' const [editDrawerOpen, setEditDrawerOpen] = useState(false) const [editDrawerForm, setEditDrawerForm] = useState(<>) diff --git a/service-web/client/src/components/flow/node/CodeNode.tsx b/service-web/client/src/components/flow/node/CodeNode.tsx index 3b8cd23..3c74b82 100644 --- a/service-web/client/src/components/flow/node/CodeNode.tsx +++ b/service-web/client/src/components/flow/node/CodeNode.tsx @@ -66,8 +66,6 @@ const CodeNode = (props: NodeProps) => { return ( } /> diff --git a/service-web/client/src/components/flow/node/KnowledgeNode.tsx b/service-web/client/src/components/flow/node/KnowledgeNode.tsx index 7afef4b..6f41e96 100644 --- a/service-web/client/src/components/flow/node/KnowledgeNode.tsx +++ b/service-web/client/src/components/flow/node/KnowledgeNode.tsx @@ -80,8 +80,6 @@ const KnowledgeNode = (props: NodeProps) => { return ( } /> diff --git a/service-web/client/src/components/flow/node/LlmNode.tsx b/service-web/client/src/components/flow/node/LlmNode.tsx index 6a21b1a..e0677e7 100644 --- a/service-web/client/src/components/flow/node/LlmNode.tsx +++ b/service-web/client/src/components/flow/node/LlmNode.tsx @@ -58,8 +58,6 @@ const LlmNode = (props: NodeProps) => { return ( diff --git a/service-web/client/src/components/flow/node/OutputNode.tsx b/service-web/client/src/components/flow/node/OutputNode.tsx index f58d9f0..39cecb3 100644 --- a/service-web/client/src/components/flow/node/OutputNode.tsx +++ b/service-web/client/src/components/flow/node/OutputNode.tsx @@ -1,15 +1,22 @@ import type {NodeProps} from '@xyflow/react' import React, {useCallback} from 'react' -import AmisNode, {EndNodeHandler, outputsFormColumns} from './AmisNode.tsx' +import {useContextStore} from '../store/ContextStore.ts' +import {useDataStore} from '../store/DataStore.ts' +import {useFlowStore} from '../store/FlowStore.ts' +import AmisNode, {EndNodeHandler, inputsFormColumns} from './AmisNode.tsx' const OutputNode = (props: NodeProps) => { - const columnsSchema = useCallback(() => outputsFormColumns(true), [props.id]) + const {getNodes, getEdges} = useFlowStore() + const {getData} = useDataStore() + const {getInputSchema} = useContextStore() + const columnsSchema = useCallback( + () => inputsFormColumns(props.id, getInputSchema(), getNodes(), getEdges(), getData()), + [props.id], + ) return ( } /> diff --git a/service-web/client/src/components/flow/node/SwitchNode.tsx b/service-web/client/src/components/flow/node/SwitchNode.tsx index 80aa404..5f3426c 100644 --- a/service-web/client/src/components/flow/node/SwitchNode.tsx +++ b/service-web/client/src/components/flow/node/SwitchNode.tsx @@ -19,8 +19,6 @@ const SwitchNode = (props: NodeProps) => { return ( {cases.map(item => (