@@ -10,8 +10,8 @@ import {
1010} from "@/utils/componentSpec" ;
1111import { DEFAULT_NODE_DIMENSIONS } from "@/utils/constants" ;
1212import {
13- inputNameToInputId ,
14- outputNameToOutputId ,
13+ inputIdToInputName ,
14+ outputIdToOutputName ,
1515} from "@/utils/nodes/nodeIdUtils" ;
1616
1717import addTask from "./addTask" ;
@@ -44,8 +44,58 @@ export function addAndConnectNode({
4444
4545 const oldGraphSpec = componentSpec . implementation . graph ;
4646
47- const fromHandleId = fromHandle ?. id ;
48- const fromHandleType = fromHandleId ?. startsWith ( "input" ) ? "input" : "output" ;
47+ if ( ! fromHandle ?. id ) {
48+ return componentSpec ;
49+ }
50+
51+ const isTaskHandle = nodeManager . isManaged ( fromHandle . id ) ;
52+ let fromHandleType : "input" | "output" ;
53+ let fromHandleName : string | undefined ;
54+ let fromTaskId : string | undefined ;
55+
56+ if ( isTaskHandle ) {
57+ // Handle is managed by NodeManager (task handle)
58+ const fromHandleInfo = nodeManager . getHandleInfo ( fromHandle . id ) ;
59+ const fromNodeType = nodeManager . getNodeType ( fromHandle . id ) ;
60+
61+ if ( ! fromHandleInfo || ! fromNodeType ) {
62+ return componentSpec ;
63+ }
64+
65+ fromHandleType = fromNodeType === "taskInput" ? "input" : "output" ;
66+ fromHandleName = fromHandleInfo . handleName ;
67+ fromTaskId = fromHandleInfo . taskId ;
68+ } else {
69+ // Simple IO node handle - get info from the source node, not the handle
70+ const fromNodeId = fromHandle . nodeId ;
71+ const fromNodeType = nodeManager . getNodeType ( fromNodeId ) ;
72+
73+ if ( ! fromNodeType ) {
74+ return componentSpec ;
75+ }
76+
77+ if ( fromNodeType === "input" ) {
78+ fromHandleType = "output" ;
79+ const inputId = nodeManager . getTaskId ( fromNodeId ) ;
80+ if ( inputId ) {
81+ fromHandleName = inputIdToInputName ( inputId ) ;
82+ fromTaskId = inputId ;
83+ }
84+ } else if ( fromNodeType === "output" ) {
85+ fromHandleType = "input" ;
86+ const outputId = nodeManager . getTaskId ( fromNodeId ) ;
87+ if ( outputId ) {
88+ fromHandleName = outputIdToOutputName ( outputId ) ;
89+ fromTaskId = outputId ;
90+ }
91+ } else {
92+ return componentSpec ;
93+ }
94+ }
95+
96+ if ( ! fromTaskId || ! fromHandleName ) {
97+ return componentSpec ;
98+ }
4999
50100 const adjustedPosition =
51101 fromHandleType === "input"
@@ -77,22 +127,17 @@ export function addAndConnectNode({
77127 const newNodeId = nodeManager . getNodeId ( newTaskId , "task" ) ;
78128
79129 // 3. Determine the connection data type and find the first matching handle on the new node
80- if ( ! fromHandle ) {
81- return newComponentSpec ;
130+ let fromComponentSpec : ComponentSpec | undefined ;
131+
132+ if ( isTaskHandle ) {
133+ // Get spec from task
134+ const fromTaskSpec = graphSpec . tasks [ fromTaskId ] ;
135+ fromComponentSpec = fromTaskSpec ?. componentRef . spec ;
136+ } else {
137+ // For IO nodes, get spec from component spec
138+ fromComponentSpec = componentSpec ;
82139 }
83140
84- const fromTaskId = nodeManager . getTaskId ( fromHandle . nodeId ) ;
85- if ( ! fromTaskId ) {
86- return newComponentSpec ;
87- }
88-
89- const fromTaskSpec = graphSpec . tasks [ fromTaskId ] ;
90- const fromComponentSpec = fromTaskSpec ?. componentRef . spec ;
91-
92- const fromNodeId = fromHandle . nodeId ;
93-
94- const fromHandleName = fromHandleId ?. replace ( `${ fromHandleType } _` , "" ) ;
95-
96141 let connectionType : TypeSpecType | undefined ;
97142 if ( fromHandleType === "input" ) {
98143 connectionType = fromComponentSpec ?. inputs ?. find (
@@ -106,7 +151,6 @@ export function addAndConnectNode({
106151
107152 // Find the first matching handle on the new node
108153 const toHandleType = fromHandleType === "input" ? "output" : "input" ;
109-
110154 let targetHandleId : string | undefined ;
111155
112156 if ( toHandleType === "input" ) {
@@ -117,8 +161,11 @@ export function addAndConnectNode({
117161 return newComponentSpec ;
118162 }
119163
120- const inputId = inputNameToInputId ( handleName ) ;
121- targetHandleId = nodeManager . getNodeId ( inputId , "taskInput" ) ;
164+ targetHandleId = nodeManager . getTaskHandleNodeId (
165+ newTaskId ,
166+ handleName ,
167+ "taskInput" ,
168+ ) ;
122169 } else if ( toHandleType === "output" ) {
123170 const handleName = componentRef . spec ?. outputs ?. find (
124171 ( io ) => io . type === connectionType ,
@@ -127,14 +174,21 @@ export function addAndConnectNode({
127174 return newComponentSpec ;
128175 }
129176
130- const outputId = outputNameToOutputId ( handleName ) ;
131- targetHandleId = nodeManager . getNodeId ( outputId , "taskOutput" ) ;
177+ targetHandleId = nodeManager . getTaskHandleNodeId (
178+ newTaskId ,
179+ handleName ,
180+ "taskOutput" ,
181+ ) ;
132182 }
133183
134184 // 4. Build a Connection object and use handleConnection to add the edge
135- if ( fromNodeId && fromHandleId && targetHandleId ) {
185+ if ( targetHandleId ) {
186+ const fromNodeId = fromHandle . nodeId ;
187+ const fromHandleId = fromHandle . id ;
188+
136189 const isReversedConnection =
137190 fromHandleType === "input" && toHandleType === "output" ;
191+
138192 const connection : Connection = isReversedConnection
139193 ? // Drawing from an input handle to a new output handle
140194 {
0 commit comments