griptape-nodes 0.58.0__py3-none-any.whl → 0.59.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. griptape_nodes/bootstrap/utils/python_subprocess_executor.py +2 -2
  2. griptape_nodes/bootstrap/workflow_executors/local_session_workflow_executor.py +0 -5
  3. griptape_nodes/bootstrap/workflow_executors/local_workflow_executor.py +9 -5
  4. griptape_nodes/bootstrap/workflow_executors/subprocess_workflow_executor.py +0 -1
  5. griptape_nodes/bootstrap/workflow_executors/workflow_executor.py +1 -3
  6. griptape_nodes/bootstrap/workflow_publishers/local_workflow_publisher.py +1 -1
  7. griptape_nodes/cli/commands/init.py +53 -7
  8. griptape_nodes/cli/shared.py +1 -0
  9. griptape_nodes/common/node_executor.py +216 -40
  10. griptape_nodes/exe_types/core_types.py +46 -0
  11. griptape_nodes/exe_types/node_types.py +272 -0
  12. griptape_nodes/machines/control_flow.py +222 -16
  13. griptape_nodes/machines/dag_builder.py +212 -1
  14. griptape_nodes/machines/parallel_resolution.py +237 -4
  15. griptape_nodes/node_library/workflow_registry.py +1 -1
  16. griptape_nodes/retained_mode/events/execution_events.py +5 -4
  17. griptape_nodes/retained_mode/events/flow_events.py +17 -67
  18. griptape_nodes/retained_mode/events/parameter_events.py +122 -1
  19. griptape_nodes/retained_mode/managers/event_manager.py +17 -13
  20. griptape_nodes/retained_mode/managers/flow_manager.py +316 -573
  21. griptape_nodes/retained_mode/managers/library_manager.py +32 -20
  22. griptape_nodes/retained_mode/managers/model_manager.py +19 -8
  23. griptape_nodes/retained_mode/managers/node_manager.py +463 -3
  24. griptape_nodes/retained_mode/managers/object_manager.py +2 -2
  25. griptape_nodes/retained_mode/managers/workflow_manager.py +37 -46
  26. griptape_nodes/retained_mode/retained_mode.py +297 -3
  27. {griptape_nodes-0.58.0.dist-info → griptape_nodes-0.59.0.dist-info}/METADATA +3 -2
  28. {griptape_nodes-0.58.0.dist-info → griptape_nodes-0.59.0.dist-info}/RECORD +30 -30
  29. {griptape_nodes-0.58.0.dist-info → griptape_nodes-0.59.0.dist-info}/WHEEL +1 -1
  30. {griptape_nodes-0.58.0.dist-info → griptape_nodes-0.59.0.dist-info}/entry_points.txt +0 -0
@@ -20,6 +20,7 @@ from griptape_nodes.exe_types.node_types import (
20
20
  EndLoopNode,
21
21
  ErrorProxyNode,
22
22
  NodeDependencies,
23
+ NodeGroupProxyNode,
23
24
  NodeResolutionState,
24
25
  StartLoopNode,
25
26
  )
@@ -33,8 +34,10 @@ from griptape_nodes.retained_mode.events.base_events import (
33
34
  )
34
35
  from griptape_nodes.retained_mode.events.connection_events import (
35
36
  CreateConnectionRequest,
37
+ CreateConnectionResultSuccess,
36
38
  DeleteConnectionRequest,
37
39
  DeleteConnectionResultFailure,
40
+ DeleteConnectionResultSuccess,
38
41
  IncomingConnection,
39
42
  ListConnectionsForNodeRequest,
40
43
  ListConnectionsForNodeResultFailure,
@@ -118,6 +121,9 @@ from griptape_nodes.retained_mode.events.parameter_events import (
118
121
  GetCompatibleParametersRequest,
119
122
  GetCompatibleParametersResultFailure,
120
123
  GetCompatibleParametersResultSuccess,
124
+ GetConnectionsForParameterRequest,
125
+ GetConnectionsForParameterResultFailure,
126
+ GetConnectionsForParameterResultSuccess,
121
127
  GetNodeElementDetailsRequest,
122
128
  GetNodeElementDetailsResultFailure,
123
129
  GetNodeElementDetailsResultSuccess,
@@ -127,6 +133,9 @@ from griptape_nodes.retained_mode.events.parameter_events import (
127
133
  GetParameterValueRequest,
128
134
  GetParameterValueResultFailure,
129
135
  GetParameterValueResultSuccess,
136
+ MigrateParameterRequest,
137
+ MigrateParameterResultFailure,
138
+ MigrateParameterResultSuccess,
130
139
  ParameterAndMode,
131
140
  RemoveParameterFromNodeRequest,
132
141
  RemoveParameterFromNodeResultFailure,
@@ -145,6 +154,7 @@ from griptape_nodes.retained_mode.events.validation_events import (
145
154
  )
146
155
  from griptape_nodes.retained_mode.griptape_nodes import GriptapeNodes
147
156
  from griptape_nodes.retained_mode.managers.event_manager import EventManager
157
+ from griptape_nodes.retained_mode.retained_mode import RetainedMode
148
158
 
149
159
  logger = logging.getLogger("griptape_nodes")
150
160
 
@@ -180,6 +190,9 @@ class NodeManager:
180
190
  event_manager.assign_manager_to_request_type(
181
191
  ListConnectionsForNodeRequest, self.on_list_connections_for_node_request
182
192
  )
193
+ event_manager.assign_manager_to_request_type(
194
+ GetConnectionsForParameterRequest, self.on_get_connections_for_parameter_request
195
+ )
183
196
  event_manager.assign_manager_to_request_type(
184
197
  ListParametersOnNodeRequest, self.on_list_parameters_on_node_request
185
198
  )
@@ -194,6 +207,7 @@ class NodeManager:
194
207
  event_manager.assign_manager_to_request_type(GetParameterValueRequest, self.on_get_parameter_value_request)
195
208
  event_manager.assign_manager_to_request_type(SetParameterValueRequest, self.on_set_parameter_value_request)
196
209
  event_manager.assign_manager_to_request_type(RenameParameterRequest, self.on_rename_parameter_request)
210
+ event_manager.assign_manager_to_request_type(MigrateParameterRequest, self.on_migrate_parameter_request)
197
211
  event_manager.assign_manager_to_request_type(ResolveNodeRequest, self.on_resolve_from_node_request)
198
212
  event_manager.assign_manager_to_request_type(GetAllNodeInfoRequest, self.on_get_all_node_info_request)
199
213
  event_manager.assign_manager_to_request_type(
@@ -460,7 +474,7 @@ class NodeManager:
460
474
  # get the current node executing / resolving
461
475
  # if it's in connected nodes, cancel flow.
462
476
  # otherwise, leave it.
463
- control_node_names, resolving_node_names = GriptapeNodes.FlowManager().flow_state(parent_flow)
477
+ control_node_names, resolving_node_names, _ = GriptapeNodes.FlowManager().flow_state(parent_flow)
464
478
  connected_nodes = parent_flow.get_all_connected_nodes(node)
465
479
  cancelled = False
466
480
  if control_node_names is not None:
@@ -776,6 +790,84 @@ class NodeManager:
776
790
  )
777
791
  return result
778
792
 
793
+ def on_get_connections_for_parameter_request(
794
+ self, request: GetConnectionsForParameterRequest
795
+ ) -> GetConnectionsForParameterResultFailure | GetConnectionsForParameterResultSuccess:
796
+ parameter_name = request.parameter_name
797
+ node_name = request.node_name
798
+ node = None
799
+
800
+ if node_name is None:
801
+ # Get from the current context.
802
+ if not GriptapeNodes.ContextManager().has_current_node():
803
+ details = "Attempted to get connections for a parameter from the Current Context. Failed because the Current Context is empty."
804
+ return GetConnectionsForParameterResultFailure(result_details=details)
805
+
806
+ node = GriptapeNodes.ContextManager().get_current_node()
807
+ node_name = node.name
808
+
809
+ # Does this node exist?
810
+ if node is None:
811
+ obj_mgr = GriptapeNodes.ObjectManager()
812
+ node = obj_mgr.attempt_get_object_by_name_as_type(node_name, BaseNode)
813
+ if node is None:
814
+ details = f"Attempted to get connections for parameter '{parameter_name}' on node '{node_name}', but no such node was found."
815
+ return GetConnectionsForParameterResultFailure(result_details=details)
816
+
817
+ # Does this parameter exist on the node?
818
+ parameter = node.get_parameter_by_name(parameter_name)
819
+ if parameter is None:
820
+ details = f"Attempted to get connections for parameter '{parameter_name}' on node '{node_name}', but no such parameter was found."
821
+ return GetConnectionsForParameterResultFailure(result_details=details)
822
+
823
+ parent_flow_name = self._name_to_parent_flow_name[node_name]
824
+ try:
825
+ GriptapeNodes.FlowManager().get_flow_by_name(parent_flow_name)
826
+ except KeyError as err:
827
+ details = (
828
+ f"Attempted to get connections for parameter '{parameter_name}' on node '{node_name}'. Error: {err}"
829
+ )
830
+ return GetConnectionsForParameterResultFailure(result_details=details)
831
+
832
+ # Get connections for this specific parameter
833
+ connection_mgr = GriptapeNodes.FlowManager().get_connections()
834
+
835
+ # Get outgoing connections for this parameter
836
+ outgoing_connections_list = []
837
+ if node_name in connection_mgr.outgoing_index and parameter_name in connection_mgr.outgoing_index[node_name]:
838
+ outgoing_connections_list = [
839
+ OutgoingConnection(
840
+ source_parameter_name=connection.source_parameter.name,
841
+ target_node_name=connection.target_node.name,
842
+ target_parameter_name=connection.target_parameter.name,
843
+ )
844
+ for connection_id in connection_mgr.outgoing_index[node_name][parameter_name]
845
+ for connection in [connection_mgr.connections[connection_id]]
846
+ ]
847
+
848
+ # Get incoming connections for this parameter
849
+ incoming_connections_list = []
850
+ if node_name in connection_mgr.incoming_index and parameter_name in connection_mgr.incoming_index[node_name]:
851
+ incoming_connections_list = [
852
+ IncomingConnection(
853
+ source_node_name=connection.source_node.name,
854
+ source_parameter_name=connection.source_parameter.name,
855
+ target_parameter_name=connection.target_parameter.name,
856
+ )
857
+ for connection_id in connection_mgr.incoming_index[node_name][parameter_name]
858
+ for connection in [connection_mgr.connections[connection_id]]
859
+ ]
860
+
861
+ details = f"Successfully retrieved connections for parameter '{parameter_name}' on node '{node_name}'."
862
+ result = GetConnectionsForParameterResultSuccess(
863
+ parameter_name=parameter_name,
864
+ node_name=node_name,
865
+ incoming_connections=incoming_connections_list,
866
+ outgoing_connections=outgoing_connections_list,
867
+ result_details=details,
868
+ )
869
+ return result
870
+
779
871
  def on_list_parameters_on_node_request(self, request: ListParametersOnNodeRequest) -> ResultPayload:
780
872
  node_name = request.node_name
781
873
  node = None
@@ -1493,6 +1585,33 @@ class NodeManager:
1493
1585
  # Reject runtime parameter value changes on ErrorProxy
1494
1586
  details = f"Cannot set parameter '{param_name}' on placeholder node '{node_name}'. This placeholder preserves your workflow structure but doesn't allow parameter changes, as they could cause issues when the original node is restored."
1495
1587
  return SetParameterValueResultFailure(result_details=details)
1588
+ elif isinstance(node, NodeGroupProxyNode):
1589
+ # For NodeGroupProxyNode, set the value on both the proxy AND the original node
1590
+ node.set_parameter_value(param_name, request.value)
1591
+
1592
+ # Forward the value to the original node if this proxy parameter maps to one
1593
+ result = None
1594
+ if param_name in node._proxy_param_to_node_param:
1595
+ original_node, original_param_name = node._proxy_param_to_node_param[param_name]
1596
+ result = GriptapeNodes.handle_request(
1597
+ SetParameterValueRequest(
1598
+ parameter_name=original_param_name,
1599
+ node_name=original_node.name,
1600
+ value=request.value,
1601
+ data_type=request.data_type,
1602
+ incoming_connection_source_node_name=request.incoming_connection_source_node_name,
1603
+ incoming_connection_source_parameter_name=request.incoming_connection_source_parameter_name,
1604
+ )
1605
+ )
1606
+ logger.debug(
1607
+ "Forwarded parameter value from proxy '%s.%s' to original '%s.%s'",
1608
+ node.name,
1609
+ param_name,
1610
+ original_node.name,
1611
+ original_param_name,
1612
+ )
1613
+ details = f"Attempted to set parameter value for '{node_name}.{param_name}'. Successfully set value on the NodeGroupProxyNode '{node_name}', but failed to set value on the original node'."
1614
+ return result if result else SetParameterValueResultFailure(result_details=details)
1496
1615
 
1497
1616
  # Does the Parameter actually exist on the Node?
1498
1617
  parameter = node.get_parameter_by_name(param_name)
@@ -1589,8 +1708,14 @@ class NodeManager:
1589
1708
  # (not manual property setting) so it bypasses the INPUT+PROPERTY connection blocking logic
1590
1709
  conn_output_nodes = parent_flow.get_connected_output_parameters(node, parameter)
1591
1710
  for target_node, target_parameter in conn_output_nodes:
1592
- # Skip propagation for Control Parameters as they should not receive values
1593
- if ParameterType.attempt_get_builtin(parameter.output_type) != ParameterTypeBuiltin.CONTROL_TYPE:
1711
+ # Skip propagation for:
1712
+ # 1. Control Parameters as they should not receive values
1713
+ # 2. Locked nodes
1714
+ is_control_parameter = (
1715
+ ParameterType.attempt_get_builtin(parameter.output_type) == ParameterTypeBuiltin.CONTROL_TYPE
1716
+ )
1717
+ is_dest_node_locked = target_node.lock
1718
+ if (not is_control_parameter) and (not is_dest_node_locked):
1594
1719
  GriptapeNodes.handle_request(
1595
1720
  SetParameterValueRequest(
1596
1721
  parameter_name=target_parameter.name,
@@ -2941,3 +3066,338 @@ class NodeManager:
2941
3066
  return GetFlowForNodeResultFailure(
2942
3067
  result_details=f"Node '{request.node_name}' not found or not assigned to any flow.",
2943
3068
  )
3069
+
3070
+ def on_migrate_parameter_request(
3071
+ self, request: MigrateParameterRequest
3072
+ ) -> MigrateParameterResultFailure | MigrateParameterResultSuccess:
3073
+ """Handle parameter migration requests."""
3074
+ # Validate nodes exist - get_node_by_name can raise ValueError
3075
+ try:
3076
+ source_node = self.get_node_by_name(request.source_node_name)
3077
+ target_node = self.get_node_by_name(request.target_node_name)
3078
+ logger.debug(
3079
+ "Successfully validated nodes exist for parameter migration: %s -> %s",
3080
+ source_node.name,
3081
+ target_node.name,
3082
+ )
3083
+ except ValueError as e:
3084
+ return MigrateParameterResultFailure(result_details=f"Node validation failed: {e}")
3085
+
3086
+ # Get connections for the source parameter
3087
+ connections_result = self.on_get_connections_for_parameter_request(
3088
+ GetConnectionsForParameterRequest(
3089
+ parameter_name=request.source_parameter_name, node_name=request.source_node_name
3090
+ )
3091
+ )
3092
+
3093
+ if not isinstance(connections_result, GetConnectionsForParameterResultSuccess):
3094
+ return MigrateParameterResultFailure(
3095
+ result_details=f"Failed to get connections for parameter '{request.source_parameter_name}' on node '{request.source_node_name}'."
3096
+ )
3097
+
3098
+ # Break original connections if requested (do this FIRST before creating new connections)
3099
+ if request.break_connections:
3100
+ self._break_parameter_connections(
3101
+ connections_result, request.source_node_name, request.source_parameter_name
3102
+ )
3103
+
3104
+ # Handle incoming connections
3105
+ if connections_result.has_incoming_connections():
3106
+ result = self._migrate_incoming_connections(request, connections_result)
3107
+ if isinstance(result, MigrateParameterResultFailure):
3108
+ return result
3109
+
3110
+ # Handle outgoing connections
3111
+ if connections_result.has_outgoing_connections():
3112
+ result = self._migrate_outgoing_connections(request, connections_result)
3113
+ if isinstance(result, MigrateParameterResultFailure):
3114
+ return result
3115
+
3116
+ # Handle value migration (no incoming connections)
3117
+ if not connections_result.has_incoming_connections():
3118
+ result = self._migrate_parameter_value(request)
3119
+ if isinstance(result, MigrateParameterResultFailure):
3120
+ return result
3121
+
3122
+ return MigrateParameterResultSuccess(
3123
+ result_details=f"Successfully migrated parameter '{request.source_parameter_name}' from '{request.source_node_name}' to '{request.target_parameter_name}' on '{request.target_node_name}'."
3124
+ )
3125
+
3126
+ def _break_parameter_connections(
3127
+ self,
3128
+ connections_result: GetConnectionsForParameterResultSuccess,
3129
+ source_node_name: str,
3130
+ source_parameter_name: str,
3131
+ ) -> None:
3132
+ """Break all incoming and outgoing connections for a parameter."""
3133
+ # Break incoming connections
3134
+ for incoming_connection in connections_result.incoming_connections:
3135
+ delete_result = GriptapeNodes.handle_request(
3136
+ DeleteConnectionRequest(
3137
+ source_node_name=incoming_connection.source_node_name,
3138
+ source_parameter_name=incoming_connection.source_parameter_name,
3139
+ target_node_name=source_node_name,
3140
+ target_parameter_name=source_parameter_name,
3141
+ )
3142
+ )
3143
+ if not isinstance(delete_result, DeleteConnectionResultSuccess):
3144
+ logger.warning(
3145
+ "Failed to break incoming connection from %s.%s: %s",
3146
+ incoming_connection.source_node_name,
3147
+ incoming_connection.source_parameter_name,
3148
+ delete_result,
3149
+ )
3150
+
3151
+ # Break outgoing connections
3152
+ for outgoing_connection in connections_result.outgoing_connections:
3153
+ delete_result = GriptapeNodes.handle_request(
3154
+ DeleteConnectionRequest(
3155
+ source_node_name=source_node_name,
3156
+ source_parameter_name=source_parameter_name,
3157
+ target_node_name=outgoing_connection.target_node_name,
3158
+ target_parameter_name=outgoing_connection.target_parameter_name,
3159
+ )
3160
+ )
3161
+ if not isinstance(delete_result, DeleteConnectionResultSuccess):
3162
+ logger.warning(
3163
+ "Failed to break outgoing connection to %s.%s: %s",
3164
+ outgoing_connection.target_node_name,
3165
+ outgoing_connection.target_parameter_name,
3166
+ delete_result,
3167
+ )
3168
+
3169
+ def _migrate_incoming_connections(
3170
+ self, request: MigrateParameterRequest, connections_result: GetConnectionsForParameterResultSuccess
3171
+ ) -> MigrateParameterResultFailure | None:
3172
+ """Handle migrating incoming connections with or without conversion."""
3173
+ if request.input_conversion:
3174
+ return self._create_input_conversion_node(request, connections_result)
3175
+ return self._create_direct_incoming_connections(request, connections_result)
3176
+
3177
+ def _migrate_outgoing_connections(
3178
+ self, request: MigrateParameterRequest, connections_result: GetConnectionsForParameterResultSuccess
3179
+ ) -> MigrateParameterResultFailure | None:
3180
+ """Handle migrating outgoing connections with or without conversion."""
3181
+ if request.output_conversion:
3182
+ return self._create_output_conversion_node(request, connections_result)
3183
+ return self._create_direct_outgoing_connections(request, connections_result)
3184
+
3185
+ def _migrate_parameter_value(self, request: MigrateParameterRequest) -> MigrateParameterResultFailure | None:
3186
+ """Handle migrating parameter value when no incoming connections exist."""
3187
+ # Get the current value from source
3188
+ get_value_result = GriptapeNodes.handle_request(
3189
+ GetParameterValueRequest(node_name=request.source_node_name, parameter_name=request.source_parameter_name)
3190
+ )
3191
+
3192
+ if not isinstance(get_value_result, GetParameterValueResultSuccess):
3193
+ return MigrateParameterResultFailure(
3194
+ result_details=f"Failed to get value for parameter '{request.source_parameter_name}' on node '{request.source_node_name}'."
3195
+ )
3196
+
3197
+ # Apply transformation if provided - this is user code that can raise exceptions
3198
+ value = get_value_result.value
3199
+ if request.value_transform:
3200
+ try:
3201
+ value = request.value_transform(value)
3202
+ except Exception as e:
3203
+ return MigrateParameterResultFailure(result_details=f"Failed to apply value transformation: {e!s}")
3204
+
3205
+ # Set the value on target
3206
+ set_value_result = GriptapeNodes.handle_request(
3207
+ SetParameterValueRequest(
3208
+ node_name=request.target_node_name, parameter_name=request.target_parameter_name, value=value
3209
+ )
3210
+ )
3211
+
3212
+ if not isinstance(set_value_result, SetParameterValueResultSuccess):
3213
+ return MigrateParameterResultFailure(
3214
+ result_details=f"Failed to set value for parameter '{request.target_parameter_name}' on node '{request.target_node_name}'."
3215
+ )
3216
+
3217
+ return None
3218
+
3219
+ def _create_input_conversion_node(
3220
+ self, request: MigrateParameterRequest, connections_result: GetConnectionsForParameterResultSuccess
3221
+ ) -> MigrateParameterResultFailure | None:
3222
+ """Create intermediate node for input conversion."""
3223
+ intermediate_node_name = f"{request.target_node_name}_{request.source_parameter_name}_input_converter"
3224
+ input_conversion = request.input_conversion
3225
+ if input_conversion is None:
3226
+ return MigrateParameterResultFailure(result_details="Input conversion configuration is required")
3227
+
3228
+ # Create the intermediate node
3229
+ offset_side = input_conversion.offset_side or "left"
3230
+ create_node_result = RetainedMode.create_node_relative_to(
3231
+ reference_node_name=request.target_node_name,
3232
+ new_node_type=input_conversion.node_type,
3233
+ new_node_name=intermediate_node_name,
3234
+ specific_library_name=input_conversion.library,
3235
+ offset_side=offset_side, # type: ignore[arg-type]
3236
+ offset_x=input_conversion.offset_x,
3237
+ offset_y=input_conversion.offset_y,
3238
+ )
3239
+
3240
+ if not isinstance(create_node_result, str):
3241
+ return MigrateParameterResultFailure(
3242
+ result_details=f"Failed to create intermediate node '{intermediate_node_name}': {create_node_result}"
3243
+ )
3244
+
3245
+ # Set additional parameters
3246
+ if input_conversion.additional_parameters:
3247
+ for param_name, param_value in input_conversion.additional_parameters.items():
3248
+ set_value_result = GriptapeNodes.handle_request(
3249
+ SetParameterValueRequest(
3250
+ node_name=intermediate_node_name, parameter_name=param_name, value=param_value
3251
+ )
3252
+ )
3253
+ if not isinstance(set_value_result, SetParameterValueResultSuccess):
3254
+ return MigrateParameterResultFailure(
3255
+ result_details=f"Failed to set parameter '{param_name}' on intermediate node '{intermediate_node_name}': {set_value_result}"
3256
+ )
3257
+
3258
+ # Connect all sources to intermediate node
3259
+ for incoming_connection in connections_result.incoming_connections:
3260
+ connection_result = GriptapeNodes.handle_request(
3261
+ CreateConnectionRequest(
3262
+ source_node_name=incoming_connection.source_node_name,
3263
+ source_parameter_name=incoming_connection.source_parameter_name,
3264
+ target_node_name=intermediate_node_name,
3265
+ target_parameter_name=input_conversion.input_parameter,
3266
+ )
3267
+ )
3268
+
3269
+ if not isinstance(connection_result, CreateConnectionResultSuccess):
3270
+ return MigrateParameterResultFailure(
3271
+ result_details=f"Failed to connect source '{incoming_connection.source_node_name}.{incoming_connection.source_parameter_name}' to intermediate node: {connection_result}"
3272
+ )
3273
+
3274
+ # Connect intermediate node to target
3275
+ connection_result = GriptapeNodes.handle_request(
3276
+ CreateConnectionRequest(
3277
+ source_node_name=intermediate_node_name,
3278
+ source_parameter_name=input_conversion.output_parameter,
3279
+ target_node_name=request.target_node_name,
3280
+ target_parameter_name=request.target_parameter_name,
3281
+ )
3282
+ )
3283
+
3284
+ if not isinstance(connection_result, CreateConnectionResultSuccess):
3285
+ return MigrateParameterResultFailure(
3286
+ result_details=f"Failed to connect intermediate node to target: {connection_result}"
3287
+ )
3288
+
3289
+ return None
3290
+
3291
+ def _create_direct_incoming_connections(
3292
+ self, request: MigrateParameterRequest, connections_result: GetConnectionsForParameterResultSuccess
3293
+ ) -> MigrateParameterResultFailure | None:
3294
+ """Create direct incoming connections without conversion."""
3295
+ for incoming_connection in connections_result.incoming_connections:
3296
+ connection_result = GriptapeNodes.handle_request(
3297
+ CreateConnectionRequest(
3298
+ source_node_name=incoming_connection.source_node_name,
3299
+ source_parameter_name=incoming_connection.source_parameter_name,
3300
+ target_node_name=request.target_node_name,
3301
+ target_parameter_name=request.target_parameter_name,
3302
+ )
3303
+ )
3304
+
3305
+ if not isinstance(connection_result, CreateConnectionResultSuccess):
3306
+ return MigrateParameterResultFailure(
3307
+ result_details=f"Failed to create direct connection from '{incoming_connection.source_node_name}.{incoming_connection.source_parameter_name}': {connection_result}"
3308
+ )
3309
+
3310
+ return None
3311
+
3312
+ def _create_output_conversion_node(
3313
+ self, request: MigrateParameterRequest, connections_result: GetConnectionsForParameterResultSuccess
3314
+ ) -> MigrateParameterResultFailure | None:
3315
+ """Create intermediate node for output conversion."""
3316
+ intermediate_node_name = f"{request.target_node_name}_{request.source_parameter_name}_output_converter"
3317
+ output_conversion = request.output_conversion
3318
+ if output_conversion is None:
3319
+ return MigrateParameterResultFailure(result_details="Output conversion configuration is required")
3320
+
3321
+ # Create the intermediate node
3322
+ offset_side = output_conversion.offset_side or "right"
3323
+ create_node_result = RetainedMode.create_node_relative_to(
3324
+ reference_node_name=request.target_node_name,
3325
+ new_node_type=output_conversion.node_type,
3326
+ new_node_name=intermediate_node_name,
3327
+ specific_library_name=output_conversion.library,
3328
+ offset_side=offset_side, # type: ignore[arg-type]
3329
+ offset_x=output_conversion.offset_x,
3330
+ offset_y=output_conversion.offset_y,
3331
+ )
3332
+
3333
+ if not isinstance(create_node_result, str):
3334
+ return MigrateParameterResultFailure(
3335
+ result_details=f"Failed to create intermediate node '{intermediate_node_name}': {create_node_result}"
3336
+ )
3337
+
3338
+ # Set additional parameters
3339
+ if output_conversion.additional_parameters:
3340
+ for param_name, param_value in output_conversion.additional_parameters.items():
3341
+ set_value_result = GriptapeNodes.handle_request(
3342
+ SetParameterValueRequest(
3343
+ node_name=intermediate_node_name, parameter_name=param_name, value=param_value
3344
+ )
3345
+ )
3346
+ if not isinstance(set_value_result, SetParameterValueResultSuccess):
3347
+ return MigrateParameterResultFailure(
3348
+ result_details=f"Failed to set parameter '{param_name}' on intermediate node '{intermediate_node_name}': {set_value_result}"
3349
+ )
3350
+
3351
+ # Connect target to intermediate node
3352
+ connection_result = GriptapeNodes.handle_request(
3353
+ CreateConnectionRequest(
3354
+ source_node_name=request.target_node_name,
3355
+ source_parameter_name=request.target_parameter_name,
3356
+ target_node_name=intermediate_node_name,
3357
+ target_parameter_name=output_conversion.input_parameter,
3358
+ )
3359
+ )
3360
+
3361
+ if not isinstance(connection_result, CreateConnectionResultSuccess):
3362
+ return MigrateParameterResultFailure(
3363
+ result_details=f"Failed to connect target to intermediate node: {connection_result}"
3364
+ )
3365
+
3366
+ # Connect intermediate node to all destinations
3367
+ for outgoing_connection in connections_result.outgoing_connections:
3368
+ connection_result = GriptapeNodes.handle_request(
3369
+ CreateConnectionRequest(
3370
+ source_node_name=intermediate_node_name,
3371
+ source_parameter_name=output_conversion.output_parameter,
3372
+ target_node_name=outgoing_connection.target_node_name,
3373
+ target_parameter_name=outgoing_connection.target_parameter_name,
3374
+ )
3375
+ )
3376
+
3377
+ if not isinstance(connection_result, CreateConnectionResultSuccess):
3378
+ return MigrateParameterResultFailure(
3379
+ result_details=f"Failed to connect intermediate node to destination '{outgoing_connection.target_node_name}.{outgoing_connection.target_parameter_name}': {connection_result}"
3380
+ )
3381
+
3382
+ return None
3383
+
3384
+ def _create_direct_outgoing_connections(
3385
+ self, request: MigrateParameterRequest, connections_result: GetConnectionsForParameterResultSuccess
3386
+ ) -> MigrateParameterResultFailure | None:
3387
+ """Create direct outgoing connections without conversion."""
3388
+ for outgoing_connection in connections_result.outgoing_connections:
3389
+ connection_result = GriptapeNodes.handle_request(
3390
+ CreateConnectionRequest(
3391
+ source_node_name=request.target_node_name,
3392
+ source_parameter_name=request.target_parameter_name,
3393
+ target_node_name=outgoing_connection.target_node_name,
3394
+ target_parameter_name=outgoing_connection.target_parameter_name,
3395
+ )
3396
+ )
3397
+
3398
+ if not isinstance(connection_result, CreateConnectionResultSuccess):
3399
+ return MigrateParameterResultFailure(
3400
+ result_details=f"Failed to create direct connection to '{outgoing_connection.target_node_name}.{outgoing_connection.target_parameter_name}': {connection_result}"
3401
+ )
3402
+
3403
+ return None
@@ -107,7 +107,7 @@ class ObjectManager:
107
107
  result_details = details
108
108
  return RenameObjectResultSuccess(final_name=final_name, result_details=result_details)
109
109
 
110
- def on_clear_all_object_state_request(self, request: ClearAllObjectStateRequest) -> ResultPayload: # noqa: C901
110
+ async def on_clear_all_object_state_request(self, request: ClearAllObjectStateRequest) -> ResultPayload: # noqa: C901
111
111
  if not request.i_know_what_im_doing:
112
112
  details = "Attempted to clear all object state and delete everything. Failed because they didn't know what they were doing."
113
113
  logger.warning(details)
@@ -117,7 +117,7 @@ class ObjectManager:
117
117
  flows = self.get_filtered_subset(type=ControlFlow)
118
118
  for flow_name in flows:
119
119
  if GriptapeNodes.FlowManager().check_for_existing_running_flow():
120
- result = GriptapeNodes.handle_request(CancelFlowRequest(flow_name=flow_name))
120
+ result = await GriptapeNodes.ahandle_request(CancelFlowRequest(flow_name=flow_name))
121
121
  if not result.succeeded():
122
122
  details = f"Attempted to clear all object state and delete everything. Failed because running flow '{flow_name}' could not cancel."
123
123
  logger.error(details)