@ -333,12 +333,22 @@ export function WorkflowCanvas() {
const nodeData = node . data as { inputSchema? : Array < { name : string ; type : string } > } ;
const nodeData = node . data as { inputSchema? : Array < { name : string ; type : string } > } ;
if ( nodeData . inputSchema && nodeData . inputSchema . length > 0 ) {
if ( nodeData . inputSchema && nodeData . inputSchema . length > 0 ) {
if ( needInput ) {
if ( needInput ) {
// Find first input handle matching the type
// Find input handles matching the type
const matchingInputs = nodeData . inputSchema . filter ( i = > i . type === handleType ) ;
const matchingInputs = nodeData . inputSchema . filter ( i = > i . type === handleType ) ;
if ( matchingInputs . length > 0 ) {
const numHandles = matchingInputs . length ;
// Return normalized handle ID, not schema name
if ( numHandles > 0 ) {
// Always use indexed IDs (image-0, text-0) for schema inputs for consistency
// Find the first unoccupied indexed handle by checking existing edges
return ` ${ handleType } -0 ` ;
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
// Output handle - check for video or image type
@ -425,7 +435,7 @@ export function WorkflowCanvas() {
sourceHandleId : fromHandleId ,
sourceHandleId : fromHandleId ,
} ) ;
} ) ;
} ,
} ,
[ screenToFlowPosition , nodes , handleConnect ]
[ screenToFlowPosition , nodes , edges , handleConnect ]
) ;
) ;
// Handle the splitGrid action - uses automated grid detection
// Handle the splitGrid action - uses automated grid detection