feat: 优化工作流字段化参数配置
- 开始节点固定 user_input 并区分系统入口与自定义参数 - LLM 与知识库节点切换为字段值加上游引用配置 - 单节点调试改为字段预览与上游引用输入模式
This commit is contained in:
@@ -37,6 +37,11 @@
|
||||
import {onDestroy, onMount} from 'svelte';
|
||||
import {isInEditableElement} from '#components/utils/isInEditableElement';
|
||||
import {getAvailableNodes, type NodePaletteItem} from './utils/nodePalette';
|
||||
import {
|
||||
buildSequentialFieldBindingPatches,
|
||||
ensureStartNodeParameters,
|
||||
START_NODE_TYPE,
|
||||
} from '../utils/workflowNodeFields';
|
||||
|
||||
const { onInit }: { onInit: any; [key: string]: any } = $props();
|
||||
const svelteFlow = useSvelteFlow();
|
||||
@@ -142,6 +147,13 @@
|
||||
}
|
||||
} as Node;
|
||||
|
||||
if (newNode.type === START_NODE_TYPE) {
|
||||
newNode.data = {
|
||||
...(newNode.data || {}),
|
||||
parameters: ensureStartNodeParameters((newNode.data?.parameters as Array<any>) || [])
|
||||
};
|
||||
}
|
||||
|
||||
if (sourceNode) {
|
||||
if (connection?.sourceHandle === 'loop_handle') {
|
||||
newNode.parentId = sourceNode.id;
|
||||
@@ -173,6 +185,8 @@
|
||||
});
|
||||
store.addEdge(edge as Edge);
|
||||
}
|
||||
|
||||
applyAutoBindingsForNode(newNode.id);
|
||||
}
|
||||
|
||||
function closeNodePicker() {
|
||||
@@ -367,6 +381,47 @@
|
||||
const { getNodesFromSource } = useGetNodesFromSource();
|
||||
const { getNodeRelativePosition } = useGetNodeRelativePosition();
|
||||
const { ensureParentInNodesBefore } = useEnsureParentInNodesBefore();
|
||||
|
||||
function collectAffectedNodeIds(rootNodeIds: string[], edges: Edge[] = store.getEdges()) {
|
||||
const affectedNodeIds = new Set<string>();
|
||||
const visit = (nodeId: string) => {
|
||||
if (!nodeId || affectedNodeIds.has(nodeId)) {
|
||||
return;
|
||||
}
|
||||
affectedNodeIds.add(nodeId);
|
||||
edges
|
||||
.filter((edge) => edge.source === nodeId && edge.sourceHandle !== 'loop_handle')
|
||||
.forEach((edge) => {
|
||||
if (edge.target) {
|
||||
visit(edge.target);
|
||||
}
|
||||
});
|
||||
};
|
||||
rootNodeIds.forEach(visit);
|
||||
return Array.from(affectedNodeIds);
|
||||
}
|
||||
|
||||
function reconcileBindingsForNodes(
|
||||
nodeIds: string[],
|
||||
options?: {
|
||||
nodes?: Node[];
|
||||
edges?: Edge[];
|
||||
}
|
||||
) {
|
||||
const uniqueNodeIds = Array.from(new Set(nodeIds.filter((nodeId) => asString(nodeId).trim())));
|
||||
if (uniqueNodeIds.length === 0) {
|
||||
return;
|
||||
}
|
||||
queueMicrotask(() => {
|
||||
const nodes = options?.nodes || store.getNodes();
|
||||
const edges = options?.edges || store.getEdges();
|
||||
const patches = buildSequentialFieldBindingPatches(uniqueNodeIds, nodes, edges);
|
||||
patches.forEach(({ nodeId, patch }) => {
|
||||
store.updateNodeData(nodeId, patch);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const onconnectend = (event: any, state: any) => {
|
||||
if (!state.isValid) {
|
||||
if (state.toNode) {
|
||||
@@ -449,7 +504,11 @@
|
||||
const { getEdgesByTarget } = useGetEdgesByTarget();
|
||||
const onDelete = (params: any) => {
|
||||
const deleteEdges = params.edges as Edge[];
|
||||
const affectedRootNodeIds = new Set<string>();
|
||||
deleteEdges.forEach((edge) => {
|
||||
if (edge.target) {
|
||||
affectedRootNodeIds.add(edge.target);
|
||||
}
|
||||
if (edge.id === currentEdge?.id) {
|
||||
currentEdge = null;
|
||||
showEdgePanel = false;
|
||||
@@ -513,6 +572,11 @@
|
||||
}
|
||||
}
|
||||
});
|
||||
if (affectedRootNodeIds.size > 0) {
|
||||
queueMicrotask(() => {
|
||||
reconcileBindingsForNodes(collectAffectedNodeIds(Array.from(affectedRootNodeIds)));
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const { deleteEdge } = useDeleteEdge();
|
||||
@@ -525,9 +589,41 @@
|
||||
|
||||
|
||||
const onconnect = (event: any) => {
|
||||
// console.log('onconnect: ', event);
|
||||
const targetNodeId = asString(event?.target).trim();
|
||||
if (!targetNodeId) {
|
||||
return;
|
||||
}
|
||||
const sourceNodeId = asString(event?.source).trim();
|
||||
const projectedEdges = [...store.getEdges()];
|
||||
const hasSameEdge = projectedEdges.some((edge) =>
|
||||
edge.source === sourceNodeId
|
||||
&& edge.target === targetNodeId
|
||||
&& (edge.sourceHandle || '') === asString(event?.sourceHandle).trim()
|
||||
&& (edge.targetHandle || '') === asString(event?.targetHandle).trim()
|
||||
);
|
||||
|
||||
if (!hasSameEdge && sourceNodeId) {
|
||||
projectedEdges.push({
|
||||
id: asString(event?.id).trim() || `edge_${genShortId()}`,
|
||||
source: sourceNodeId,
|
||||
target: targetNodeId,
|
||||
sourceHandle: asString(event?.sourceHandle).trim() || undefined,
|
||||
targetHandle: asString(event?.targetHandle).trim() || undefined,
|
||||
} as Edge);
|
||||
}
|
||||
|
||||
reconcileBindingsForNodes(
|
||||
collectAffectedNodeIds([targetNodeId], projectedEdges),
|
||||
{
|
||||
edges: projectedEdges
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
function applyAutoBindingsForNode(nodeId: string) {
|
||||
reconcileBindingsForNodes([nodeId]);
|
||||
}
|
||||
|
||||
const { copyHandler, pasteHandler } = useCopyPasteHandler();
|
||||
|
||||
const handleKeyDown = (e: KeyboardEvent) => {
|
||||
|
||||
Reference in New Issue
Block a user