griptape-nodes 0.41.0__py3-none-any.whl → 0.43.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 (133) hide show
  1. griptape_nodes/__init__.py +0 -0
  2. griptape_nodes/app/.python-version +0 -0
  3. griptape_nodes/app/__init__.py +1 -10
  4. griptape_nodes/app/api.py +199 -0
  5. griptape_nodes/app/app.py +140 -222
  6. griptape_nodes/app/watch.py +4 -2
  7. griptape_nodes/bootstrap/__init__.py +0 -0
  8. griptape_nodes/bootstrap/bootstrap_script.py +0 -0
  9. griptape_nodes/bootstrap/register_libraries_script.py +0 -0
  10. griptape_nodes/bootstrap/structure_config.yaml +0 -0
  11. griptape_nodes/bootstrap/workflow_executors/__init__.py +0 -0
  12. griptape_nodes/bootstrap/workflow_executors/local_workflow_executor.py +0 -0
  13. griptape_nodes/bootstrap/workflow_executors/workflow_executor.py +0 -0
  14. griptape_nodes/bootstrap/workflow_runners/__init__.py +0 -0
  15. griptape_nodes/bootstrap/workflow_runners/bootstrap_workflow_runner.py +0 -0
  16. griptape_nodes/bootstrap/workflow_runners/local_workflow_runner.py +0 -0
  17. griptape_nodes/bootstrap/workflow_runners/subprocess_workflow_runner.py +6 -2
  18. griptape_nodes/bootstrap/workflow_runners/workflow_runner.py +0 -0
  19. griptape_nodes/drivers/__init__.py +0 -0
  20. griptape_nodes/drivers/storage/__init__.py +0 -0
  21. griptape_nodes/drivers/storage/base_storage_driver.py +0 -0
  22. griptape_nodes/drivers/storage/griptape_cloud_storage_driver.py +0 -0
  23. griptape_nodes/drivers/storage/local_storage_driver.py +5 -3
  24. griptape_nodes/drivers/storage/storage_backend.py +0 -0
  25. griptape_nodes/exe_types/__init__.py +0 -0
  26. griptape_nodes/exe_types/connections.py +0 -0
  27. griptape_nodes/exe_types/core_types.py +0 -0
  28. griptape_nodes/exe_types/flow.py +68 -368
  29. griptape_nodes/exe_types/node_types.py +17 -1
  30. griptape_nodes/exe_types/type_validator.py +0 -0
  31. griptape_nodes/machines/__init__.py +0 -0
  32. griptape_nodes/machines/control_flow.py +52 -20
  33. griptape_nodes/machines/fsm.py +16 -2
  34. griptape_nodes/machines/node_resolution.py +16 -14
  35. griptape_nodes/mcp_server/__init__.py +1 -0
  36. griptape_nodes/mcp_server/server.py +126 -0
  37. griptape_nodes/mcp_server/ws_request_manager.py +268 -0
  38. griptape_nodes/node_library/__init__.py +0 -0
  39. griptape_nodes/node_library/advanced_node_library.py +0 -0
  40. griptape_nodes/node_library/library_registry.py +0 -0
  41. griptape_nodes/node_library/workflow_registry.py +2 -2
  42. griptape_nodes/py.typed +0 -0
  43. griptape_nodes/retained_mode/__init__.py +0 -0
  44. griptape_nodes/retained_mode/events/__init__.py +0 -0
  45. griptape_nodes/retained_mode/events/agent_events.py +70 -8
  46. griptape_nodes/retained_mode/events/app_events.py +137 -12
  47. griptape_nodes/retained_mode/events/arbitrary_python_events.py +23 -0
  48. griptape_nodes/retained_mode/events/base_events.py +13 -31
  49. griptape_nodes/retained_mode/events/config_events.py +87 -11
  50. griptape_nodes/retained_mode/events/connection_events.py +56 -5
  51. griptape_nodes/retained_mode/events/context_events.py +27 -4
  52. griptape_nodes/retained_mode/events/execution_events.py +99 -14
  53. griptape_nodes/retained_mode/events/flow_events.py +165 -7
  54. griptape_nodes/retained_mode/events/generate_request_payload_schemas.py +0 -0
  55. griptape_nodes/retained_mode/events/library_events.py +195 -17
  56. griptape_nodes/retained_mode/events/logger_events.py +11 -0
  57. griptape_nodes/retained_mode/events/node_events.py +242 -22
  58. griptape_nodes/retained_mode/events/object_events.py +40 -4
  59. griptape_nodes/retained_mode/events/os_events.py +116 -3
  60. griptape_nodes/retained_mode/events/parameter_events.py +212 -8
  61. griptape_nodes/retained_mode/events/payload_registry.py +0 -0
  62. griptape_nodes/retained_mode/events/secrets_events.py +59 -7
  63. griptape_nodes/retained_mode/events/static_file_events.py +57 -4
  64. griptape_nodes/retained_mode/events/validation_events.py +39 -4
  65. griptape_nodes/retained_mode/events/workflow_events.py +188 -17
  66. griptape_nodes/retained_mode/griptape_nodes.py +89 -363
  67. griptape_nodes/retained_mode/managers/__init__.py +0 -0
  68. griptape_nodes/retained_mode/managers/agent_manager.py +49 -23
  69. griptape_nodes/retained_mode/managers/arbitrary_code_exec_manager.py +0 -0
  70. griptape_nodes/retained_mode/managers/config_manager.py +0 -0
  71. griptape_nodes/retained_mode/managers/context_manager.py +0 -0
  72. griptape_nodes/retained_mode/managers/engine_identity_manager.py +146 -0
  73. griptape_nodes/retained_mode/managers/event_manager.py +14 -2
  74. griptape_nodes/retained_mode/managers/flow_manager.py +751 -64
  75. griptape_nodes/retained_mode/managers/library_lifecycle/__init__.py +45 -0
  76. griptape_nodes/retained_mode/managers/library_lifecycle/data_models.py +191 -0
  77. griptape_nodes/retained_mode/managers/library_lifecycle/library_directory.py +346 -0
  78. griptape_nodes/retained_mode/managers/library_lifecycle/library_fsm.py +439 -0
  79. griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/__init__.py +17 -0
  80. griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/base.py +82 -0
  81. griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/github.py +116 -0
  82. griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/local_file.py +352 -0
  83. griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/package.py +104 -0
  84. griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/sandbox.py +155 -0
  85. griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance.py +18 -0
  86. griptape_nodes/retained_mode/managers/library_lifecycle/library_status.py +12 -0
  87. griptape_nodes/retained_mode/managers/library_manager.py +255 -40
  88. griptape_nodes/retained_mode/managers/node_manager.py +120 -103
  89. griptape_nodes/retained_mode/managers/object_manager.py +11 -3
  90. griptape_nodes/retained_mode/managers/operation_manager.py +0 -0
  91. griptape_nodes/retained_mode/managers/os_manager.py +582 -8
  92. griptape_nodes/retained_mode/managers/secrets_manager.py +4 -0
  93. griptape_nodes/retained_mode/managers/session_manager.py +328 -0
  94. griptape_nodes/retained_mode/managers/settings.py +7 -0
  95. griptape_nodes/retained_mode/managers/static_files_manager.py +0 -0
  96. griptape_nodes/retained_mode/managers/version_compatibility_manager.py +2 -2
  97. griptape_nodes/retained_mode/managers/workflow_manager.py +722 -456
  98. griptape_nodes/retained_mode/retained_mode.py +44 -0
  99. griptape_nodes/retained_mode/utils/__init__.py +0 -0
  100. griptape_nodes/retained_mode/utils/engine_identity.py +141 -27
  101. griptape_nodes/retained_mode/utils/name_generator.py +0 -0
  102. griptape_nodes/traits/__init__.py +0 -0
  103. griptape_nodes/traits/add_param_button.py +0 -0
  104. griptape_nodes/traits/button.py +0 -0
  105. griptape_nodes/traits/clamp.py +0 -0
  106. griptape_nodes/traits/compare.py +0 -0
  107. griptape_nodes/traits/compare_images.py +0 -0
  108. griptape_nodes/traits/file_system_picker.py +127 -0
  109. griptape_nodes/traits/minmax.py +0 -0
  110. griptape_nodes/traits/options.py +0 -0
  111. griptape_nodes/traits/slider.py +0 -0
  112. griptape_nodes/traits/trait_registry.py +0 -0
  113. griptape_nodes/traits/traits.json +0 -0
  114. griptape_nodes/updater/__init__.py +2 -2
  115. griptape_nodes/updater/__main__.py +0 -0
  116. griptape_nodes/utils/__init__.py +0 -0
  117. griptape_nodes/utils/dict_utils.py +0 -0
  118. griptape_nodes/utils/image_preview.py +128 -0
  119. griptape_nodes/utils/metaclasses.py +0 -0
  120. griptape_nodes/version_compatibility/__init__.py +0 -0
  121. griptape_nodes/version_compatibility/versions/__init__.py +0 -0
  122. griptape_nodes/version_compatibility/versions/v0_39_0/__init__.py +0 -0
  123. griptape_nodes/version_compatibility/versions/v0_39_0/modified_parameters_set_removal.py +5 -5
  124. griptape_nodes-0.43.0.dist-info/METADATA +90 -0
  125. griptape_nodes-0.43.0.dist-info/RECORD +129 -0
  126. griptape_nodes-0.43.0.dist-info/WHEEL +4 -0
  127. {griptape_nodes-0.41.0.dist-info → griptape_nodes-0.43.0.dist-info}/entry_points.txt +1 -0
  128. griptape_nodes/app/app_sessions.py +0 -458
  129. griptape_nodes/retained_mode/utils/session_persistence.py +0 -105
  130. griptape_nodes-0.41.0.dist-info/METADATA +0 -78
  131. griptape_nodes-0.41.0.dist-info/RECORD +0 -112
  132. griptape_nodes-0.41.0.dist-info/WHEEL +0 -4
  133. griptape_nodes-0.41.0.dist-info/licenses/LICENSE +0 -201
@@ -185,23 +185,24 @@ class NodeManager:
185
185
  # Get all connections for this node and update them.
186
186
  flow_name = self.get_node_parent_flow_by_name(old_name)
187
187
  flow = GriptapeNodes.FlowManager().get_flow_by_name(flow_name)
188
+ connections = GriptapeNodes.FlowManager().get_connections()
188
189
  # Get all incoming and outgoing connections and update them.
189
- if old_name in flow.connections.incoming_index:
190
- incoming_connections = flow.connections.incoming_index[old_name]
190
+ if old_name in connections.incoming_index:
191
+ incoming_connections = connections.incoming_index[old_name]
191
192
  for connection_ids in incoming_connections.values():
192
193
  for connection_id in connection_ids:
193
- connection = flow.connections.connections[connection_id]
194
+ connection = connections.connections[connection_id]
194
195
  connection.target_node.name = new_name
195
- temp = flow.connections.incoming_index.pop(old_name)
196
- flow.connections.incoming_index[new_name] = temp
197
- if old_name in flow.connections.outgoing_index:
198
- outgoing_connections = flow.connections.outgoing_index[old_name]
196
+ temp = connections.incoming_index.pop(old_name)
197
+ connections.incoming_index[new_name] = temp
198
+ if old_name in connections.outgoing_index:
199
+ outgoing_connections = connections.outgoing_index[old_name]
199
200
  for connection_ids in outgoing_connections.values():
200
201
  for connection_id in connection_ids:
201
- connection = flow.connections.connections[connection_id]
202
+ connection = connections.connections[connection_id]
202
203
  connection.source_node.name = new_name
203
- temp = flow.connections.outgoing_index.pop(old_name)
204
- flow.connections.outgoing_index[new_name] = temp
204
+ temp = connections.outgoing_index.pop(old_name)
205
+ connections.outgoing_index[new_name] = temp
205
206
  # update the node in the flow!
206
207
  flow.remove_node(old_name)
207
208
  node.name = new_name
@@ -217,7 +218,7 @@ class NodeManager:
217
218
  if parent_flow_name == old_name:
218
219
  self._name_to_parent_flow_name[node_name] = new_name
219
220
 
220
- def on_create_node_request(self, request: CreateNodeRequest) -> ResultPayload: # noqa: C901, PLR0911, PLR0912, PLR0915
221
+ def on_create_node_request(self, request: CreateNodeRequest) -> ResultPayload: # noqa: C901, PLR0912, PLR0915
221
222
  # Validate as much as possible before we actually create one.
222
223
  parent_flow_name = request.override_parent_flow_name
223
224
  parent_flow = None
@@ -319,6 +320,7 @@ class NodeManager:
319
320
 
320
321
  logger.log(level=log_level, msg=details)
321
322
 
323
+ # Special handling for paired classes (e.g., create a Start node and it automatically creates a corresponding End node already connected).
322
324
  if isinstance(node, StartLoopNode) and not request.initial_setup:
323
325
  # If it's StartLoop, create an EndLoop and connect it to the StartLoop.
324
326
  # Get the class name of the node
@@ -331,43 +333,42 @@ class NodeManager:
331
333
  # Check and see if the class exists
332
334
  libraries_with_node_type = LibraryRegistry.get_libraries_with_node_type(end_class_name)
333
335
  if not libraries_with_node_type:
334
- msg = f"End class '{end_class_name}' does not exist for start class '{node_class_name}'"
335
- logger.error(msg)
336
- return CreateNodeResultFailure()
337
-
338
- # Create the EndNode
339
- end_loop = GriptapeNodes.handle_request(
340
- CreateNodeRequest(
341
- node_type=end_class_name,
342
- metadata={
343
- "position": {"x": node.metadata["position"]["x"] + 650, "y": node.metadata["position"]["y"]}
344
- },
345
- override_parent_flow_name=parent_flow_name,
346
- )
347
- )
348
- if not isinstance(end_loop, CreateNodeResultSuccess):
349
- msg = f"Failed to create EndLoop node for StartLoop node '{node.name}'"
350
- logger.error(msg)
351
- return CreateNodeResultFailure()
352
-
353
- # Create Loop between output and input to the start node.
354
- GriptapeNodes.handle_request(
355
- CreateConnectionRequest(
356
- source_node_name=node.name,
357
- source_parameter_name="loop",
358
- target_node_name=end_loop.node_name,
359
- target_parameter_name="from_start",
336
+ msg = f"Attempted to create a paried set of nodes for Node '{final_node_name}'. Failed because paired class '{end_class_name}' does not exist for start class '{node_class_name}'. The corresponding node will have to be created by hand and attached manually."
337
+ logger.error(msg) # while this is bad, it's not unsalvageable, so we'll consider this a success.
338
+ else:
339
+ # Create the EndNode
340
+ end_loop = GriptapeNodes.handle_request(
341
+ CreateNodeRequest(
342
+ node_type=end_class_name,
343
+ metadata={
344
+ "position": {"x": node.metadata["position"]["x"] + 650, "y": node.metadata["position"]["y"]}
345
+ },
346
+ override_parent_flow_name=parent_flow_name,
347
+ )
360
348
  )
361
- )
362
- end_node = self.get_node_by_name(end_loop.node_name)
363
- if not isinstance(end_node, EndLoopNode):
364
- msg = f"End node '{end_loop.node_name}' is not a valid EndLoopNode"
365
- logger.error(msg)
366
- return CreateNodeResultFailure()
367
-
368
- # create the connection
369
- node.end_node = end_node
370
- end_node.start_node = node
349
+ if not isinstance(end_loop, CreateNodeResultSuccess):
350
+ msg = f"Attempted to create a paried set of nodes for Node '{final_node_name}'. Failed because paired class '{end_class_name}' failed to get created. The corresponding node will have to be created by hand and attached manually."
351
+ logger.error(msg) # while this is bad, it's not unsalvageable, so we'll consider this a success.
352
+ else:
353
+ # Create Loop between output and input to the start node.
354
+ GriptapeNodes.handle_request(
355
+ CreateConnectionRequest(
356
+ source_node_name=node.name,
357
+ source_parameter_name="loop",
358
+ target_node_name=end_loop.node_name,
359
+ target_parameter_name="from_start",
360
+ )
361
+ )
362
+ end_node = self.get_node_by_name(end_loop.node_name)
363
+ if not isinstance(end_node, EndLoopNode):
364
+ msg = f"Attempted to create a paried set of nodes for Node '{final_node_name}'. Failed because paired node '{end_loop.node_name}' was not a proper EndLoop instance. The corresponding node will have to be created by hand and attached manually."
365
+ logger.error(
366
+ msg
367
+ ) # while this is bad, it's not unsalvageable, so we'll consider this a success.
368
+ else:
369
+ # create the connection - only when we've confirmed correct types
370
+ node.end_node = end_node
371
+ end_node.start_node = node
371
372
 
372
373
  return CreateNodeResultSuccess(
373
374
  node_name=node.name, node_type=node.__class__.__name__, specific_library_name=request.specific_library_name
@@ -395,11 +396,11 @@ class NodeManager:
395
396
  This method also clears the flow queue regardless of whether cancellation occurred,
396
397
  to ensure the specified node is not processed in the future.
397
398
  """
398
- if parent_flow.check_for_existing_running_flow():
399
+ if GriptapeNodes.FlowManager().check_for_existing_running_flow():
399
400
  # get the current node executing / resolving
400
401
  # if it's in connected nodes, cancel flow.
401
402
  # otherwise, leave it.
402
- control_node_name, resolving_node_name = parent_flow.flow_state()
403
+ control_node_name, resolving_node_name = GriptapeNodes.FlowManager().flow_state(parent_flow)
403
404
  connected_nodes = parent_flow.get_all_connected_nodes(node)
404
405
  cancelled = False
405
406
  if control_node_name is not None:
@@ -423,11 +424,11 @@ class NodeManager:
423
424
  )
424
425
  logger.error(details)
425
426
  return DeleteNodeResultFailure()
426
- # Clear the queue, because we don't want to his this node eventually.
427
- parent_flow.clear_flow_queue()
427
+ # Clear the execution queue, because we don't want to hit this node eventually.
428
+ parent_flow.clear_execution_queue()
428
429
  return None
429
430
 
430
- def on_delete_node_request(self, request: DeleteNodeRequest) -> ResultPayload: # noqa: C901, PLR0911 (complex logic, lots of edge cases)
431
+ def on_delete_node_request(self, request: DeleteNodeRequest) -> ResultPayload: # noqa: C901, PLR0911, PLR0912, PLR0915 (complex logic, lots of edge cases)
431
432
  node_name = request.node_name
432
433
  node = None
433
434
  if node_name is None:
@@ -460,41 +461,55 @@ class NodeManager:
460
461
  cancel_result = self.cancel_conditionally(parent_flow, parent_flow_name, node)
461
462
  if cancel_result is not None:
462
463
  return cancel_result
463
- # Remove all connections from this Node.
464
- list_node_connections_request = ListConnectionsForNodeRequest(node_name=node_name)
465
- list_connections_result = GriptapeNodes.handle_request(request=list_node_connections_request)
466
- if not isinstance(list_connections_result, ListConnectionsForNodeResultSuccess):
467
- details = f"Attempted to delete a Node '{node_name}'. Failed because it could not gather Connections to the Node."
468
- logger.error(details)
469
- return DeleteNodeResultFailure()
470
-
471
- # Destroy all the incoming Connections
472
- for incoming_connection in list_connections_result.incoming_connections:
473
- delete_request = DeleteConnectionRequest(
474
- source_node_name=incoming_connection.source_node_name,
475
- source_parameter_name=incoming_connection.source_parameter_name,
476
- target_node_name=node_name,
477
- target_parameter_name=incoming_connection.target_parameter_name,
478
- )
479
- delete_result = GriptapeNodes.handle_request(delete_request)
480
- if isinstance(delete_result, ResultPayloadFailure):
481
- details = f"Attempted to delete a Node '{node_name}'. Failed when attempting to delete Connection."
464
+ # Remove all connections from this Node using a loop to handle cascading deletions
465
+ any_connections_remain = True
466
+ while any_connections_remain:
467
+ # Assume we're done
468
+ any_connections_remain = False
469
+
470
+ list_node_connections_request = ListConnectionsForNodeRequest(node_name=node_name)
471
+ list_connections_result = GriptapeNodes.handle_request(request=list_node_connections_request)
472
+ if not isinstance(list_connections_result, ListConnectionsForNodeResultSuccess):
473
+ details = f"Attempted to delete a Node '{node_name}'. Failed because it could not gather Connections to the Node."
482
474
  logger.error(details)
483
475
  return DeleteNodeResultFailure()
484
476
 
485
- # Destroy all the outgoing Connections
486
- for outgoing_connection in list_connections_result.outgoing_connections:
487
- delete_request = DeleteConnectionRequest(
488
- source_node_name=node_name,
489
- source_parameter_name=outgoing_connection.source_parameter_name,
490
- target_node_name=outgoing_connection.target_node_name,
491
- target_parameter_name=outgoing_connection.target_parameter_name,
492
- )
493
- delete_result = GriptapeNodes.handle_request(delete_request)
494
- if isinstance(delete_result, ResultPayloadFailure):
495
- details = f"Attempted to delete a Node '{node_name}'. Failed when attempting to delete Connection."
496
- logger.error(details)
497
- return DeleteNodeResultFailure()
477
+ # Check incoming connections
478
+ if list_connections_result.incoming_connections:
479
+ any_connections_remain = True
480
+ connection = list_connections_result.incoming_connections[0]
481
+ delete_request = DeleteConnectionRequest(
482
+ source_node_name=connection.source_node_name,
483
+ source_parameter_name=connection.source_parameter_name,
484
+ target_node_name=node_name,
485
+ target_parameter_name=connection.target_parameter_name,
486
+ )
487
+ delete_result = GriptapeNodes.handle_request(delete_request)
488
+ if isinstance(delete_result, ResultPayloadFailure):
489
+ details = (
490
+ f"Attempted to delete a Node '{node_name}'. Failed when attempting to delete Connection."
491
+ )
492
+ logger.error(details)
493
+ return DeleteNodeResultFailure()
494
+ continue # Refresh connection list after cascading deletions
495
+
496
+ # Check outgoing connections
497
+ if list_connections_result.outgoing_connections:
498
+ any_connections_remain = True
499
+ connection = list_connections_result.outgoing_connections[0]
500
+ delete_request = DeleteConnectionRequest(
501
+ source_node_name=node_name,
502
+ source_parameter_name=connection.source_parameter_name,
503
+ target_node_name=connection.target_node_name,
504
+ target_parameter_name=connection.target_parameter_name,
505
+ )
506
+ delete_result = GriptapeNodes.handle_request(delete_request)
507
+ if isinstance(delete_result, ResultPayloadFailure):
508
+ details = (
509
+ f"Attempted to delete a Node '{node_name}'. Failed when attempting to delete Connection."
510
+ )
511
+ logger.error(details)
512
+ return DeleteNodeResultFailure()
498
513
 
499
514
  # Remove from the owning Flow
500
515
  parent_flow.remove_node(node.name)
@@ -640,7 +655,7 @@ class NodeManager:
640
655
 
641
656
  parent_flow_name = self._name_to_parent_flow_name[node_name]
642
657
  try:
643
- parent_flow = GriptapeNodes.FlowManager().get_flow_by_name(parent_flow_name)
658
+ GriptapeNodes.FlowManager().get_flow_by_name(parent_flow_name)
644
659
  except KeyError as err:
645
660
  details = f"Attempted to list Connections for a Node '{node_name}'. Error: {err}"
646
661
  logger.error(details)
@@ -649,7 +664,7 @@ class NodeManager:
649
664
  return result
650
665
 
651
666
  # Kinda gross, but let's do it
652
- connection_mgr = parent_flow.connections
667
+ connection_mgr = GriptapeNodes.FlowManager().get_connections()
653
668
  # get outgoing connections
654
669
  outgoing_connections_list = []
655
670
  if node_name in connection_mgr.outgoing_index:
@@ -1429,7 +1444,7 @@ class NodeManager:
1429
1444
  return SetParameterValueResultFailure()
1430
1445
  if not request.initial_setup and modified:
1431
1446
  try:
1432
- parent_flow.connections.unresolve_future_nodes(node)
1447
+ GriptapeNodes.FlowManager().get_connections().unresolve_future_nodes(node)
1433
1448
  except Exception as err:
1434
1449
  details = f"Attempted to set parameter value for '{node_name}.{request.parameter_name}'. Failed because Exception: {err}"
1435
1450
  logger.error(details)
@@ -1752,12 +1767,12 @@ class NodeManager:
1752
1767
  details = f'Failed to fetch parent flow for "{node_name}"'
1753
1768
  logger.error(details)
1754
1769
  return ResolveNodeResultFailure(validation_exceptions=[])
1755
- if flow.check_for_existing_running_flow():
1770
+ if GriptapeNodes.FlowManager().check_for_existing_running_flow():
1756
1771
  details = f"Failed to resolve from node '{node_name}'. Flow is already running."
1757
1772
  logger.error(details)
1758
1773
  return ResolveNodeResultFailure(validation_exceptions=[])
1759
1774
  try:
1760
- flow.connections.unresolve_future_nodes(node)
1775
+ GriptapeNodes.FlowManager().get_connections().unresolve_future_nodes(node)
1761
1776
  except Exception as e:
1762
1777
  details = f'Failed to mark future nodes dirty. Unable to kick off flow from "{node_name}": {e}'
1763
1778
  logger.error(details)
@@ -1783,7 +1798,7 @@ class NodeManager:
1783
1798
  logger.error(details)
1784
1799
  return StartFlowResultFailure(validation_exceptions=[e])
1785
1800
  try:
1786
- flow.resolve_singular_node(node, debug_mode)
1801
+ GriptapeNodes.FlowManager().resolve_singular_node(flow, node, debug_mode)
1787
1802
  except Exception as e:
1788
1803
  details = f'Failed to resolve "{node_name}". Error: {e}'
1789
1804
  logger.error(details)
@@ -2098,15 +2113,16 @@ class NodeManager:
2098
2113
  parameter_commands[result.serialized_node_commands.node_uuid] = result.set_parameter_value_commands
2099
2114
  try:
2100
2115
  flow_name = self.get_node_parent_flow_by_name(node_name)
2101
- flow = GriptapeNodes.FlowManager().get_flow_by_name(flow_name)
2116
+ GriptapeNodes.FlowManager().get_flow_by_name(flow_name)
2102
2117
  except Exception:
2103
2118
  details = f"Attempted to serialize a selection of Nodes. Failed to get the flow of node {node_name}. Cannot serialize connections for this node."
2104
2119
  logger.warning(details)
2105
2120
  continue
2106
- if node_name in flow.connections.outgoing_index:
2121
+ connections = GriptapeNodes.FlowManager().get_connections()
2122
+ if node_name in connections.outgoing_index:
2107
2123
  node_connections = [
2108
- flow.connections.connections[connection_id]
2109
- for category_dict in flow.connections.outgoing_index[node_name].values()
2124
+ connections.connections[connection_id]
2125
+ for category_dict in connections.outgoing_index[node_name].values()
2110
2126
  for connection_id in category_dict
2111
2127
  ]
2112
2128
  for connection in node_connections:
@@ -2353,7 +2369,7 @@ class NodeManager:
2353
2369
  node_name=node.name,
2354
2370
  )
2355
2371
  if internal_command is None:
2356
- details = f"Attempted to serialize set value for parameter'{parameter.name}' on node '{node.name}'. The set value will not be restored in anything that attempts to deserialize or save this node. The value for this parameter was not serialized because it did not match Griptape Nodes' criteria for serializability. To remedy, either update the value's type to support serializaibilty or mark the parameter as not serializable."
2372
+ details = f"Attempted to serialize set value for parameter '{parameter.name}' on node '{node.name}'. The set value will not be restored in anything that attempts to deserialize or save this node. The value for this parameter was not serialized because it did not match Griptape Nodes' criteria for serializability. To remedy, either update the value's type to support serializability or mark the parameter as not serializable."
2357
2373
  logger.warning(details)
2358
2374
  else:
2359
2375
  commands.append(internal_command)
@@ -2367,7 +2383,7 @@ class NodeManager:
2367
2383
  node_name=node.name,
2368
2384
  )
2369
2385
  if output_command is None:
2370
- details = f"Attempted to serialize output value for parameter '{parameter.name}' on node '{node.name}'. The output value will not be restored in anything that attempts to deserialize or save this node. The value for this parameter was not serialized because it did not match Griptape Nodes' criteria for serializability. To remedy, either update the value's type to support serializaibilty or mark the parameter as not serializable."
2386
+ details = f"Attempted to serialize output value for parameter '{parameter.name}' on node '{node.name}'. The output value will not be restored in anything that attempts to deserialize or save this node. The value for this parameter was not serialized because it did not match Griptape Nodes' criteria for serializability. To remedy, either update the value's type to support serializability or mark the parameter as not serializable."
2371
2387
  logger.warning(details)
2372
2388
  else:
2373
2389
  commands.append(output_command)
@@ -2420,22 +2436,23 @@ class NodeManager:
2420
2436
 
2421
2437
  # Get all connections for this node
2422
2438
  flow_name = self.get_node_parent_flow_by_name(node_name)
2423
- flow = GriptapeNodes.FlowManager().get_flow_by_name(flow_name)
2439
+ GriptapeNodes.FlowManager().get_flow_by_name(flow_name)
2440
+ connections = GriptapeNodes.FlowManager().get_connections()
2424
2441
 
2425
2442
  # Update connections that reference this parameter
2426
- if node_name in flow.connections.incoming_index:
2427
- incoming_connections = flow.connections.incoming_index[node_name]
2443
+ if node_name in connections.incoming_index:
2444
+ incoming_connections = connections.incoming_index[node_name]
2428
2445
  for connection_ids in incoming_connections.values():
2429
2446
  for connection_id in connection_ids:
2430
- connection = flow.connections.connections[connection_id]
2447
+ connection = connections.connections[connection_id]
2431
2448
  if connection.target_parameter.name == request.parameter_name:
2432
2449
  connection.target_parameter.name = request.new_parameter_name
2433
2450
 
2434
- if node_name in flow.connections.outgoing_index:
2435
- outgoing_connections = flow.connections.outgoing_index[node_name]
2451
+ if node_name in connections.outgoing_index:
2452
+ outgoing_connections = connections.outgoing_index[node_name]
2436
2453
  for connection_ids in outgoing_connections.values():
2437
2454
  for connection_id in connection_ids:
2438
- connection = flow.connections.connections[connection_id]
2455
+ connection = connections.connections[connection_id]
2439
2456
  if connection.source_parameter.name == request.parameter_name:
2440
2457
  connection.source_parameter.name = request.new_parameter_name
2441
2458
 
@@ -100,7 +100,7 @@ class ObjectManager:
100
100
  logger.log(level=log_level, msg=details)
101
101
  return RenameObjectResultSuccess(final_name=final_name)
102
102
 
103
- def on_clear_all_object_state_request(self, request: ClearAllObjectStateRequest) -> ResultPayload:
103
+ def on_clear_all_object_state_request(self, request: ClearAllObjectStateRequest) -> ResultPayload: # noqa: C901
104
104
  if not request.i_know_what_im_doing:
105
105
  logger.warning(
106
106
  "Attempted to clear all object state and delete everything. Failed because they didn't know what they were doing."
@@ -109,14 +109,22 @@ class ObjectManager:
109
109
  # Let's try and clear it all.
110
110
  # Cancel any running flows.
111
111
  flows = self.get_filtered_subset(type=ControlFlow)
112
- for flow_name, flow in flows.items():
113
- if flow.check_for_existing_running_flow():
112
+ for flow_name in flows:
113
+ if GriptapeNodes.FlowManager().check_for_existing_running_flow():
114
114
  result = GriptapeNodes.handle_request(CancelFlowRequest(flow_name=flow_name))
115
115
  if not result.succeeded():
116
116
  details = f"Attempted to clear all object state and delete everything. Failed because running flow '{flow_name}' could not cancel."
117
117
  logger.error(details)
118
118
  return ClearAllObjectStateResultFailure()
119
119
 
120
+ try:
121
+ # Reset global execution state first to eliminate all references before deletion
122
+ GriptapeNodes.FlowManager().reset_global_execution_state()
123
+ except Exception as e:
124
+ details = f"Attempted to reset global execution state. Failed with exception: {e}"
125
+ logger.error(details)
126
+ return ClearAllObjectStateResultFailure()
127
+
120
128
  try:
121
129
  # Delete the existing flows, which will clear all nodes and connections.
122
130
  GriptapeNodes.clear_data()