diff --git a/src/components/WorkflowCanvas.tsx b/src/components/WorkflowCanvas.tsx index 425c798f..4d3c9205 100644 --- a/src/components/WorkflowCanvas.tsx +++ b/src/components/WorkflowCanvas.tsx @@ -333,12 +333,22 @@ export function WorkflowCanvas() { const nodeData = node.data as { inputSchema?: Array<{ name: string; type: string }> }; if (nodeData.inputSchema && nodeData.inputSchema.length > 0) { if (needInput) { - // Find first input handle matching the type + // Find input handles matching the type const matchingInputs = nodeData.inputSchema.filter(i => i.type === handleType); - if (matchingInputs.length > 0) { - // Return normalized handle ID, not schema name - // Always use indexed IDs (image-0, text-0) for schema inputs for consistency - return `${handleType}-0`; + const numHandles = matchingInputs.length; + if (numHandles > 0) { + // Find the first unoccupied indexed handle by checking existing edges + for (let i = 0; i < numHandles; i++) { + const candidateHandle = `${handleType}-${i}`; + const isOccupied = edges.some( + (edge) => edge.target === node.id && edge.targetHandle === candidateHandle + ); + if (!isOccupied) { + return candidateHandle; + } + } + // All handles are occupied + return null; } } // Output handle - check for video or image type @@ -425,7 +435,7 @@ export function WorkflowCanvas() { sourceHandleId: fromHandleId, }); }, - [screenToFlowPosition, nodes, handleConnect] + [screenToFlowPosition, nodes, edges, handleConnect] ); // Handle the splitGrid action - uses automated grid detection