griptape-nodes 0.46.0__py3-none-any.whl → 0.48.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 (25) hide show
  1. griptape_nodes/app/app.py +1 -1
  2. griptape_nodes/exe_types/core_types.py +129 -10
  3. griptape_nodes/exe_types/node_types.py +9 -3
  4. griptape_nodes/machines/node_resolution.py +10 -8
  5. griptape_nodes/mcp_server/ws_request_manager.py +6 -6
  6. griptape_nodes/retained_mode/events/base_events.py +74 -1
  7. griptape_nodes/retained_mode/events/secrets_events.py +2 -0
  8. griptape_nodes/retained_mode/griptape_nodes.py +17 -13
  9. griptape_nodes/retained_mode/managers/agent_manager.py +8 -6
  10. griptape_nodes/retained_mode/managers/arbitrary_code_exec_manager.py +1 -1
  11. griptape_nodes/retained_mode/managers/config_manager.py +36 -45
  12. griptape_nodes/retained_mode/managers/flow_manager.py +98 -98
  13. griptape_nodes/retained_mode/managers/library_manager.py +57 -57
  14. griptape_nodes/retained_mode/managers/node_manager.py +121 -124
  15. griptape_nodes/retained_mode/managers/object_manager.py +9 -10
  16. griptape_nodes/retained_mode/managers/os_manager.py +31 -31
  17. griptape_nodes/retained_mode/managers/secrets_manager.py +5 -5
  18. griptape_nodes/retained_mode/managers/static_files_manager.py +19 -21
  19. griptape_nodes/retained_mode/managers/sync_manager.py +3 -2
  20. griptape_nodes/retained_mode/managers/workflow_manager.py +153 -174
  21. griptape_nodes/retained_mode/retained_mode.py +25 -47
  22. {griptape_nodes-0.46.0.dist-info → griptape_nodes-0.48.0.dist-info}/METADATA +1 -1
  23. {griptape_nodes-0.46.0.dist-info → griptape_nodes-0.48.0.dist-info}/RECORD +25 -25
  24. {griptape_nodes-0.46.0.dist-info → griptape_nodes-0.48.0.dist-info}/WHEEL +1 -1
  25. {griptape_nodes-0.46.0.dist-info → griptape_nodes-0.48.0.dist-info}/entry_points.txt +0 -0
@@ -233,7 +233,7 @@ class NodeManager:
233
233
  "Attempted to create Node in the Current Context. Failed because the Current Context was empty."
234
234
  )
235
235
  logger.error(details)
236
- return CreateNodeResultFailure()
236
+ return CreateNodeResultFailure(result_details=details)
237
237
  parent_flow = GriptapeNodes.ContextManager().get_current_flow()
238
238
  parent_flow_name = parent_flow.name
239
239
 
@@ -245,7 +245,7 @@ class NodeManager:
245
245
  except KeyError as err:
246
246
  details = f"Attempted to create Node of type '{request.node_type}'. Failed when attempting to find the parent Flow. Error: {err}"
247
247
  logger.error(details)
248
- return CreateNodeResultFailure()
248
+ return CreateNodeResultFailure(result_details=details)
249
249
 
250
250
  # Now ensure that we're giving a valid name.
251
251
  requested_node_name = request.node_name
@@ -258,7 +258,7 @@ class NodeManager:
258
258
  except KeyError as err:
259
259
  details = f"Attempted to create Node of type '{request.node_type}'. Failed when attempting to find the library this node type was in. Error: {err}"
260
260
  logger.error(details)
261
- return CreateNodeResultFailure()
261
+ return CreateNodeResultFailure(result_details=details)
262
262
 
263
263
  node_metadata = dest_library.get_node_metadata(request.node_type)
264
264
  requested_node_name = node_metadata.display_name
@@ -288,7 +288,7 @@ class NodeManager:
288
288
  traceback.print_exc()
289
289
  details = f"Could not create Node '{final_node_name}' of type '{request.node_type}': {err}"
290
290
  logger.error(details)
291
- return CreateNodeResultFailure()
291
+ return CreateNodeResultFailure(result_details=details)
292
292
  # Add it to the Flow.
293
293
  parent_flow.add_node(node)
294
294
 
@@ -417,7 +417,7 @@ class NodeManager:
417
417
  f"Attempted to delete a Node '{node.name}'. Failed because running flow could not cancel."
418
418
  )
419
419
  logger.error(details)
420
- return DeleteNodeResultFailure()
420
+ return DeleteNodeResultFailure(result_details=details)
421
421
  if resolving_node_name is not None and not cancelled:
422
422
  resolving_node = GriptapeNodes.ObjectManager().get_object_by_name(resolving_node_name)
423
423
  if resolving_node in connected_nodes:
@@ -427,7 +427,7 @@ class NodeManager:
427
427
  f"Attempted to delete a Node '{node.name}'. Failed because running flow could not cancel."
428
428
  )
429
429
  logger.error(details)
430
- return DeleteNodeResultFailure()
430
+ return DeleteNodeResultFailure(result_details=details)
431
431
  # Clear the execution queue, because we don't want to hit this node eventually.
432
432
  parent_flow.clear_execution_queue()
433
433
  return None
@@ -442,7 +442,7 @@ class NodeManager:
442
442
  "Attempted to delete a Node from the Current Context. Failed because the Current Context is empty."
443
443
  )
444
444
  logger.error(details)
445
- return DeleteNodeResultFailure()
445
+ return DeleteNodeResultFailure(result_details=details)
446
446
 
447
447
  node = GriptapeNodes.ContextManager().get_current_node()
448
448
  node_name = node.name
@@ -451,7 +451,7 @@ class NodeManager:
451
451
  if node is None:
452
452
  details = f"Attempted to delete a Node '{node_name}', but no such Node was found."
453
453
  logger.error(details)
454
- return DeleteNodeResultFailure()
454
+ return DeleteNodeResultFailure(result_details=details)
455
455
 
456
456
  with GriptapeNodes.ContextManager().node(node=node):
457
457
  parent_flow_name = self._name_to_parent_flow_name[node_name]
@@ -460,7 +460,7 @@ class NodeManager:
460
460
  except KeyError as err:
461
461
  details = f"Attempted to delete a Node '{node_name}'. Error: {err}"
462
462
  logger.error(details)
463
- return DeleteNodeResultFailure()
463
+ return DeleteNodeResultFailure(result_details=details)
464
464
 
465
465
  cancel_result = self.cancel_conditionally(parent_flow, parent_flow_name, node)
466
466
  if cancel_result is not None:
@@ -476,7 +476,7 @@ class NodeManager:
476
476
  if not isinstance(list_connections_result, ListConnectionsForNodeResultSuccess):
477
477
  details = f"Attempted to delete a Node '{node_name}'. Failed because it could not gather Connections to the Node."
478
478
  logger.error(details)
479
- return DeleteNodeResultFailure()
479
+ return DeleteNodeResultFailure(result_details=details)
480
480
 
481
481
  # Check incoming connections
482
482
  if list_connections_result.incoming_connections:
@@ -494,7 +494,7 @@ class NodeManager:
494
494
  f"Attempted to delete a Node '{node_name}'. Failed when attempting to delete Connection."
495
495
  )
496
496
  logger.error(details)
497
- return DeleteNodeResultFailure()
497
+ return DeleteNodeResultFailure(result_details=details)
498
498
  continue # Refresh connection list after cascading deletions
499
499
 
500
500
  # Check outgoing connections
@@ -513,7 +513,7 @@ class NodeManager:
513
513
  f"Attempted to delete a Node '{node_name}'. Failed when attempting to delete Connection."
514
514
  )
515
515
  logger.error(details)
516
- return DeleteNodeResultFailure()
516
+ return DeleteNodeResultFailure(result_details=details)
517
517
 
518
518
  # Remove from the owning Flow
519
519
  parent_flow.remove_node(node.name)
@@ -539,7 +539,7 @@ class NodeManager:
539
539
  if not GriptapeNodes.ContextManager().has_current_node():
540
540
  details = "Attempted to get resolution state for a Node from the Current Context. Failed because the Current Context is empty."
541
541
  logger.error(details)
542
- return GetNodeResolutionStateResultFailure()
542
+ return GetNodeResolutionStateResultFailure(result_details=details)
543
543
 
544
544
  node = GriptapeNodes.ContextManager().get_current_node()
545
545
  node_name = node.name
@@ -551,7 +551,7 @@ class NodeManager:
551
551
  if node is None:
552
552
  details = f"Attempted to get resolution state for a Node '{node_name}', but no such Node was found."
553
553
  logger.error(details)
554
- result = GetNodeResolutionStateResultFailure()
554
+ result = GetNodeResolutionStateResultFailure(result_details=details)
555
555
  return result
556
556
 
557
557
  node_state = node.state
@@ -572,7 +572,7 @@ class NodeManager:
572
572
  if not GriptapeNodes.ContextManager().has_current_node():
573
573
  details = "Attempted to get metadata for a Node from the Current Context. Failed because the Current Context is empty."
574
574
  logger.error(details)
575
- return GetNodeMetadataResultFailure()
575
+ return GetNodeMetadataResultFailure(result_details=details)
576
576
 
577
577
  node = GriptapeNodes.ContextManager().get_current_node()
578
578
  node_name = node.name
@@ -586,7 +586,7 @@ class NodeManager:
586
586
  details = f"Attempted to get metadata for a Node '{node_name}', but no such Node was found."
587
587
  logger.error(details)
588
588
 
589
- result = GetNodeMetadataResultFailure()
589
+ result = GetNodeMetadataResultFailure(result_details=details)
590
590
  return result
591
591
 
592
592
  metadata = node.metadata
@@ -606,7 +606,7 @@ class NodeManager:
606
606
  if not GriptapeNodes.ContextManager().has_current_node():
607
607
  details = "Attempted to set metadata for a Node from the Current Context. Failed because the Current Context is empty."
608
608
  logger.error(details)
609
- return SetNodeMetadataResultFailure()
609
+ return SetNodeMetadataResultFailure(result_details=details)
610
610
 
611
611
  node = GriptapeNodes.ContextManager().get_current_node()
612
612
  node_name = node.name
@@ -620,7 +620,7 @@ class NodeManager:
620
620
  details = f"Attempted to set metadata for a Node '{node_name}', but no such Node was found."
621
621
  logger.error(details)
622
622
 
623
- result = SetNodeMetadataResultFailure()
623
+ result = SetNodeMetadataResultFailure(result_details=details)
624
624
  return result
625
625
 
626
626
  # We can't completely overwrite metadata.
@@ -640,7 +640,7 @@ class NodeManager:
640
640
  if not GriptapeNodes.ContextManager().has_current_node():
641
641
  details = "Attempted to list Connections for a Node from the Current Context. Failed because the Current Context is empty."
642
642
  logger.error(details)
643
- return ListConnectionsForNodeResultFailure()
643
+ return ListConnectionsForNodeResultFailure(result_details=details)
644
644
 
645
645
  node = GriptapeNodes.ContextManager().get_current_node()
646
646
  node_name = node.name
@@ -654,7 +654,7 @@ class NodeManager:
654
654
  details = f"Attempted to list Connections for a Node '{node_name}', but no such Node was found."
655
655
  logger.error(details)
656
656
 
657
- result = ListConnectionsForNodeResultFailure()
657
+ result = ListConnectionsForNodeResultFailure(result_details=details)
658
658
  return result
659
659
 
660
660
  parent_flow_name = self._name_to_parent_flow_name[node_name]
@@ -664,7 +664,7 @@ class NodeManager:
664
664
  details = f"Attempted to list Connections for a Node '{node_name}'. Error: {err}"
665
665
  logger.error(details)
666
666
 
667
- result = ListConnectionsForNodeResultFailure()
667
+ result = ListConnectionsForNodeResultFailure(result_details=details)
668
668
  return result
669
669
 
670
670
  # Kinda gross, but let's do it
@@ -716,7 +716,7 @@ class NodeManager:
716
716
  if not GriptapeNodes.ContextManager().has_current_node():
717
717
  details = "Attempted to list Parameters for a Node from the Current Context. Failed because the Current Context is empty."
718
718
  logger.error(details)
719
- return ListParametersOnNodeResultFailure()
719
+ return ListParametersOnNodeResultFailure(result_details=details)
720
720
 
721
721
  node = GriptapeNodes.ContextManager().get_current_node()
722
722
  node_name = node.name
@@ -729,7 +729,7 @@ class NodeManager:
729
729
  details = f"Attempted to list Parameters for a Node '{node_name}', but no such Node was found."
730
730
  logger.error(details)
731
731
 
732
- result = ListParametersOnNodeResultFailure()
732
+ result = ListParametersOnNodeResultFailure(result_details=details)
733
733
  return result
734
734
 
735
735
  ret_list = [param.name for param in node.parameters]
@@ -769,7 +769,7 @@ class NodeManager:
769
769
  if not GriptapeNodes.ContextManager().has_current_node():
770
770
  details = "Attempted to add Parameter to a Node from the Current Context. Failed because the Current Context is empty."
771
771
  logger.error(details)
772
- return AddParameterToNodeResultFailure()
772
+ return AddParameterToNodeResultFailure(result_details=details)
773
773
 
774
774
  node = GriptapeNodes.ContextManager().get_current_node()
775
775
  node_name = node.name
@@ -782,14 +782,14 @@ class NodeManager:
782
782
  details = f"Attempted to add Parameter '{request.parameter_name}' to a Node '{node_name}', but no such Node was found."
783
783
  logger.error(details)
784
784
 
785
- result = AddParameterToNodeResultFailure()
785
+ result = AddParameterToNodeResultFailure(result_details=details)
786
786
  return result
787
787
 
788
788
  # Check if node is locked
789
789
  if node.lock:
790
790
  details = f"Attempted to add Parameter '{request.parameter_name}' to Node '{node_name}'. Failed because the Node was locked."
791
791
  logger.error(details)
792
- result = AddParameterToNodeResultFailure()
792
+ result = AddParameterToNodeResultFailure(result_details=details)
793
793
  return result
794
794
 
795
795
  if request.parent_container_name and not request.initial_setup:
@@ -797,19 +797,19 @@ class NodeManager:
797
797
  if parameter is None:
798
798
  details = f"Attempted to add Parameter to Container Parameter '{request.parent_container_name}' in node '{node_name}'. Failed because parameter didn't exist."
799
799
  logger.error(details)
800
- result = AddParameterToNodeResultFailure()
800
+ result = AddParameterToNodeResultFailure(result_details=details)
801
801
  return result
802
802
  if not isinstance(parameter, ParameterContainer):
803
803
  details = f"Attempted to add Parameter to Container Parameter '{request.parent_container_name}' in node '{node_name}'. Failed because parameter wasn't a container."
804
804
  logger.error(details)
805
- result = AddParameterToNodeResultFailure()
805
+ result = AddParameterToNodeResultFailure(result_details=details)
806
806
  return result
807
807
  try:
808
808
  new_param = parameter.add_child_parameter()
809
809
  except Exception as e:
810
810
  details = f"Attempted to add Parameter to Container Parameter '{request.parent_container_name}' in node '{node_name}'. Failed: {e}."
811
811
  logger.exception(details)
812
- result = AddParameterToNodeResultFailure()
812
+ result = AddParameterToNodeResultFailure(result_details=details)
813
813
  return result
814
814
 
815
815
  return AddParameterToNodeResultSuccess(
@@ -818,7 +818,7 @@ class NodeManager:
818
818
  if request.parameter_name is None or request.tooltip is None:
819
819
  details = f"Attempted to add Parameter to node '{node_name}'. Failed because default_value, tooltip, or parameter_name was not defined."
820
820
  logger.error(details)
821
- result = AddParameterToNodeResultFailure()
821
+ result = AddParameterToNodeResultFailure(result_details=details)
822
822
  return result
823
823
 
824
824
  # Generate a unique parameter name if needed
@@ -855,7 +855,7 @@ class NodeManager:
855
855
  details = f"Attempted to add Parameter '{request.parameter_name}' to Node '{node_name}'. Failed because it had 'ParameterControlType' AND at least one other non-control type. If a Parameter is intended for control, it must only accept that type."
856
856
  logger.error(details)
857
857
 
858
- result = AddParameterToNodeResultFailure()
858
+ result = AddParameterToNodeResultFailure(result_details=details)
859
859
  return result
860
860
 
861
861
  allowed_modes = set()
@@ -893,7 +893,7 @@ class NodeManager:
893
893
  except Exception as e:
894
894
  details = f"Couldn't add parameter with name {request.parameter_name} to Node '{node_name}'. Error: {e}"
895
895
  logger.error(details)
896
- return AddParameterToNodeResultFailure()
896
+ return AddParameterToNodeResultFailure(result_details=details)
897
897
 
898
898
  details = f"Successfully added Parameter '{final_param_name}' to Node '{node_name}'."
899
899
  log_level = logging.DEBUG
@@ -918,7 +918,7 @@ class NodeManager:
918
918
  details = f"Attempted to remove Parameter '{request.parameter_name}' from a Node, but no Current Context was found."
919
919
  logger.error(details)
920
920
 
921
- result = RemoveParameterFromNodeResultFailure()
921
+ result = RemoveParameterFromNodeResultFailure(result_details=details)
922
922
  return result
923
923
 
924
924
  node = GriptapeNodes.ContextManager().get_current_node()
@@ -932,14 +932,14 @@ class NodeManager:
932
932
  details = f"Attempted to remove Parameter '{request.parameter_name}' from a Node '{node_name}', but no such Node was found."
933
933
  logger.error(details)
934
934
 
935
- result = RemoveParameterFromNodeResultFailure()
935
+ result = RemoveParameterFromNodeResultFailure(result_details=details)
936
936
  return result
937
937
  # Check if the node is locked
938
938
  if node.lock:
939
939
  details = f"Attempted to remove Element '{request.parameter_name}' from Node '{node_name}'. Failed because the Node was locked."
940
940
  logger.error(details)
941
941
 
942
- result = RemoveParameterFromNodeResultFailure()
942
+ result = RemoveParameterFromNodeResultFailure(result_details=details)
943
943
  return result
944
944
  # Does the Element actually exist on the Node?
945
945
  element = node.get_element_by_name_and_type(request.parameter_name)
@@ -947,7 +947,7 @@ class NodeManager:
947
947
  details = f"Attempted to remove Element '{request.parameter_name}' from Node '{node_name}'. Failed because it didn't have an Element with that name on it."
948
948
  logger.error(details)
949
949
 
950
- result = RemoveParameterFromNodeResultFailure()
950
+ result = RemoveParameterFromNodeResultFailure(result_details=details)
951
951
  return result
952
952
 
953
953
  # If it's a ParameterGroup, we need to remove all the Parameters inside it.
@@ -964,7 +964,7 @@ class NodeManager:
964
964
  details = f"Attempted to remove Element '{request.parameter_name}' from Node '{node_name}'. Failed because the Element was not user-defined (i.e., critical to the Node implementation). Only user-defined Elements can be removed from a Node."
965
965
  logger.error(details)
966
966
 
967
- result = RemoveParameterFromNodeResultFailure()
967
+ result = RemoveParameterFromNodeResultFailure(result_details=details)
968
968
  return result
969
969
 
970
970
  # Get all the connections to/from this Parameter.
@@ -975,7 +975,7 @@ class NodeManager:
975
975
  details = f"Attempted to remove Parameter '{request.parameter_name}' from Node '{node_name}'. Failed because we were unable to get a list of Connections for the Parameter's Node."
976
976
  logger.error(details)
977
977
 
978
- result = RemoveParameterFromNodeResultFailure()
978
+ result = RemoveParameterFromNodeResultFailure(result_details=details)
979
979
  return result
980
980
 
981
981
  # We have a list of all connections to the NODE. Sift down to just those that are about this PARAMETER.
@@ -994,7 +994,7 @@ class NodeManager:
994
994
  details = f"Attempted to remove Parameter '{request.parameter_name}' from Node '{node_name}'. Failed because we were unable to delete a Connection for that Parameter."
995
995
  logger.error(details)
996
996
 
997
- result = RemoveParameterFromNodeResultFailure()
997
+ result = RemoveParameterFromNodeResultFailure(result_details=details)
998
998
 
999
999
  # Destroy all the outgoing Connections from this PARAMETER
1000
1000
  for outgoing_connection in list_connections_result.outgoing_connections:
@@ -1010,7 +1010,7 @@ class NodeManager:
1010
1010
  details = f"Attempted to remove Parameter '{request.parameter_name}' from Node '{node_name}'. Failed because we were unable to delete a Connection for that Parameter."
1011
1011
  logger.error(details)
1012
1012
 
1013
- result = RemoveParameterFromNodeResultFailure()
1013
+ result = RemoveParameterFromNodeResultFailure(result_details=details)
1014
1014
 
1015
1015
  # Delete the Element itself.
1016
1016
  if element is not None:
@@ -1019,7 +1019,7 @@ class NodeManager:
1019
1019
  details = f"Attempted to remove Element '{request.parameter_name}' from Node '{node_name}'. Failed because element didn't exist."
1020
1020
  logger.error(details)
1021
1021
 
1022
- result = RemoveParameterFromNodeResultFailure()
1022
+ result = RemoveParameterFromNodeResultFailure(result_details=details)
1023
1023
 
1024
1024
  details = f"Successfully removed Element '{request.parameter_name}' from Node '{node_name}'."
1025
1025
  logger.debug(details)
@@ -1036,7 +1036,7 @@ class NodeManager:
1036
1036
  details = f"Attempted to get details for Parameter '{request.parameter_name}' from a Node, but no Current Context was found."
1037
1037
  logger.error(details)
1038
1038
 
1039
- result = GetParameterDetailsResultFailure()
1039
+ result = GetParameterDetailsResultFailure(result_details=details)
1040
1040
  return result
1041
1041
  node = GriptapeNodes.ContextManager().get_current_node()
1042
1042
  node_name = node.name
@@ -1049,7 +1049,7 @@ class NodeManager:
1049
1049
  details = f"Attempted to get details for Parameter '{request.parameter_name}' from a Node '{node_name}', but no such Node was found."
1050
1050
  logger.error(details)
1051
1051
 
1052
- result = GetParameterDetailsResultFailure()
1052
+ result = GetParameterDetailsResultFailure(result_details=details)
1053
1053
  return result
1054
1054
 
1055
1055
  # Does the Element actually exist on the Node?
@@ -1058,7 +1058,7 @@ class NodeManager:
1058
1058
  if element is None:
1059
1059
  details = f"Attempted to get details for Element '{request.parameter_name}' from Node '{node_name}'. Failed because it didn't have an Element with that name on it."
1060
1060
  logger.error(details)
1061
- return GetParameterDetailsResultFailure()
1061
+ return GetParameterDetailsResultFailure(result_details=details)
1062
1062
 
1063
1063
  # Let's bundle up the details.
1064
1064
  allows_input = False
@@ -1101,7 +1101,7 @@ class NodeManager:
1101
1101
  details = f"Attempted to get element details for element '{request.specific_element_id}` from a Node, but no Current Context was found."
1102
1102
  logger.error(details)
1103
1103
 
1104
- return GetNodeElementDetailsResultFailure()
1104
+ return GetNodeElementDetailsResultFailure(result_details=details)
1105
1105
  node = GriptapeNodes.ContextManager().get_current_node()
1106
1106
  node_name = node.name
1107
1107
 
@@ -1113,7 +1113,7 @@ class NodeManager:
1113
1113
  details = f"Attempted to get element details for Node '{node_name}', but no such Node was found."
1114
1114
  logger.error(details)
1115
1115
 
1116
- return GetNodeElementDetailsResultFailure()
1116
+ return GetNodeElementDetailsResultFailure(result_details=details)
1117
1117
 
1118
1118
  # Did they ask for a specific element ID?
1119
1119
  if request.specific_element_id is None:
@@ -1125,7 +1125,7 @@ class NodeManager:
1125
1125
  details = f"Attempted to get element details for element '{request.specific_element_id}' from Node '{node_name}'. Failed because it didn't have an element with that ID on it."
1126
1126
  logger.error(details)
1127
1127
 
1128
- return GetNodeElementDetailsResultFailure()
1128
+ return GetNodeElementDetailsResultFailure(result_details=details)
1129
1129
 
1130
1130
  element_details = element.to_dict()
1131
1131
  # We need to get element values from here
@@ -1240,7 +1240,7 @@ class NodeManager:
1240
1240
  if isinstance(delete_result, ResultPayloadFailure):
1241
1241
  details = f"Failed to delete incompatible incoming connection from {conn.source_node_name}.{conn.source_parameter_name} to {node_name}.{request.parameter_name}: {delete_result}"
1242
1242
  logger.error(details)
1243
- return AlterParameterDetailsResultFailure()
1243
+ return AlterParameterDetailsResultFailure(result_details=details)
1244
1244
 
1245
1245
  # Check and break invalid outgoing connections
1246
1246
  for conn in list_connections_result.outgoing_connections:
@@ -1259,7 +1259,7 @@ class NodeManager:
1259
1259
  if isinstance(delete_result, ResultPayloadFailure):
1260
1260
  details = f"Failed to delete incompatible outgoing connection from {node_name}.{request.parameter_name} to {conn.target_node_name}.{conn.target_parameter_name}: {delete_result}"
1261
1261
  logger.error(details)
1262
- return AlterParameterDetailsResultFailure()
1262
+ return AlterParameterDetailsResultFailure(result_details=details)
1263
1263
 
1264
1264
  return None
1265
1265
 
@@ -1272,7 +1272,7 @@ class NodeManager:
1272
1272
  details = f"Attempted to alter details for Parameter '{request.parameter_name}' from node in the Current Context. Failed because there was no such Node."
1273
1273
  logger.error(details)
1274
1274
 
1275
- return AlterParameterDetailsResultFailure()
1275
+ return AlterParameterDetailsResultFailure(result_details=details)
1276
1276
  node = GriptapeNodes.ContextManager().get_current_node()
1277
1277
  node_name = node.name
1278
1278
 
@@ -1284,20 +1284,20 @@ class NodeManager:
1284
1284
  details = f"Attempted to alter details for Parameter '{request.parameter_name}' from Node '{node_name}', but no such Node was found."
1285
1285
  logger.error(details)
1286
1286
 
1287
- return AlterParameterDetailsResultFailure()
1287
+ return AlterParameterDetailsResultFailure(result_details=details)
1288
1288
 
1289
1289
  # Is the node locked?
1290
1290
  if node.lock:
1291
1291
  details = f"Attempted to alter details for Parameter '{request.parameter_name}' from Node '{node_name}'. Failed because the Node was locked."
1292
1292
  logger.error(details)
1293
- return AlterParameterDetailsResultFailure()
1293
+ return AlterParameterDetailsResultFailure(result_details=details)
1294
1294
 
1295
1295
  # Does the Element actually exist on the Node?
1296
1296
  element = node.get_element_by_name_and_type(request.parameter_name)
1297
1297
  if element is None:
1298
1298
  details = f"Attempted to alter details for Element '{request.parameter_name}' from Node '{node_name}'. Failed because it didn't have an Element with that name on it."
1299
1299
  logger.error(details)
1300
- return AlterParameterDetailsResultFailure()
1300
+ return AlterParameterDetailsResultFailure(result_details=details)
1301
1301
  if request.ui_options is not None:
1302
1302
  element.ui_options = request.ui_options # type: ignore[attr-defined]
1303
1303
 
@@ -1343,7 +1343,7 @@ class NodeManager:
1343
1343
  details = f"Attempted to get value for Parameter '{request.parameter_name}' from node in the Current Context. Failed because there was no such Node."
1344
1344
  logger.error(details)
1345
1345
 
1346
- return GetParameterValueResultFailure()
1346
+ return GetParameterValueResultFailure(result_details=details)
1347
1347
  node = GriptapeNodes.ContextManager().get_current_node()
1348
1348
  node_name = node.name
1349
1349
 
@@ -1357,14 +1357,14 @@ class NodeManager:
1357
1357
  if node is None:
1358
1358
  details = f'"{node_name}" not found'
1359
1359
  logger.error(details)
1360
- return GetParameterValueResultFailure()
1360
+ return GetParameterValueResultFailure(result_details=details)
1361
1361
 
1362
1362
  # Does the Parameter actually exist on the Node?
1363
1363
  parameter = node.get_parameter_by_name(param_name)
1364
1364
  if parameter is None:
1365
1365
  details = f'"{node_name}.{param_name}" not found'
1366
1366
  logger.error(details)
1367
- return GetParameterValueResultFailure()
1367
+ return GetParameterValueResultFailure(result_details=details)
1368
1368
 
1369
1369
  # Values are actually stored on the NODE, so let's ask them.
1370
1370
  if param_name not in node.parameter_values:
@@ -1404,7 +1404,7 @@ class NodeManager:
1404
1404
  if not GriptapeNodes.ContextManager().has_current_node():
1405
1405
  details = f"Attempted to set parameter '{request.parameter_name}' value. Failed because no Node was found in the Current Context."
1406
1406
  logger.error(details)
1407
- return SetParameterValueResultFailure()
1407
+ return SetParameterValueResultFailure(result_details=details)
1408
1408
  node = GriptapeNodes.ContextManager().get_current_node()
1409
1409
  node_name = node.name
1410
1410
 
@@ -1418,13 +1418,13 @@ class NodeManager:
1418
1418
  if node is None:
1419
1419
  details = f"Attempted to set parameter '{param_name}' value on node '{node_name}'. Failed because no such Node could be found."
1420
1420
  logger.error(details)
1421
- return SetParameterValueResultFailure()
1421
+ return SetParameterValueResultFailure(result_details=details)
1422
1422
 
1423
1423
  # Is the node locked?
1424
1424
  if node.lock:
1425
1425
  details = f"Attempted to set parameter '{param_name}' value on node '{node_name}'. Failed because the Node was locked."
1426
1426
  logger.error(details)
1427
- return SetParameterValueResultFailure()
1427
+ return SetParameterValueResultFailure(result_details=details)
1428
1428
 
1429
1429
  # Does the Parameter actually exist on the Node?
1430
1430
  parameter = node.get_parameter_by_name(param_name)
@@ -1432,14 +1432,14 @@ class NodeManager:
1432
1432
  details = f"Attempted to set parameter value for '{node_name}.{param_name}'. Failed because no parameter with that name could be found."
1433
1433
  logger.error(details)
1434
1434
 
1435
- result = SetParameterValueResultFailure()
1435
+ result = SetParameterValueResultFailure(result_details=details)
1436
1436
  return result
1437
1437
 
1438
1438
  # Validate that parameters can be set at all (note: we want the value to be set during initial setup, but not after)
1439
1439
  if not parameter.settable and not request.initial_setup:
1440
1440
  details = f"Attempted to set parameter value for '{node_name}.{request.parameter_name}'. Failed because that Parameter was flagged as not settable."
1441
1441
  logger.error(details)
1442
- result = SetParameterValueResultFailure()
1442
+ result = SetParameterValueResultFailure(result_details=details)
1443
1443
  return result
1444
1444
 
1445
1445
  # Well this seems kind of stupid
@@ -1449,7 +1449,7 @@ class NodeManager:
1449
1449
  details = f"Attempted to set parameter value for '{node_name}.{request.parameter_name}'. Failed because the value's type of '{object_type}' was not in the Parameter's list of allowed types: {parameter.input_types}."
1450
1450
  logger.error(details)
1451
1451
 
1452
- result = SetParameterValueResultFailure()
1452
+ result = SetParameterValueResultFailure(result_details=details)
1453
1453
  return result
1454
1454
 
1455
1455
  try:
@@ -1457,27 +1457,27 @@ class NodeManager:
1457
1457
  except KeyError:
1458
1458
  details = f"Attempted to set parameter value for '{node_name}.{request.parameter_name}'. Failed because the node's parent flow does not exist. Could not unresolve future nodes."
1459
1459
  logger.error(details)
1460
- return SetParameterValueResultFailure()
1460
+ return SetParameterValueResultFailure(result_details=details)
1461
1461
 
1462
1462
  obj_mgr = GriptapeNodes.ObjectManager()
1463
1463
  parent_flow = obj_mgr.attempt_get_object_by_name_as_type(parent_flow_name, ControlFlow)
1464
1464
  if not parent_flow:
1465
1465
  details = f"Attempted to set parameter value for '{node_name}.{request.parameter_name}'. Failed because the node's parent flow does not exist. Could not unresolve future nodes."
1466
1466
  logger.error(details)
1467
- return SetParameterValueResultFailure()
1467
+ return SetParameterValueResultFailure(result_details=details)
1468
1468
  try:
1469
1469
  finalized_value, modified = self._set_and_pass_through_values(request, node)
1470
1470
  except Exception as err:
1471
1471
  details = f"Attempted to set parameter value for '{node_name}.{request.parameter_name}'. Failed because Exception: {err}"
1472
1472
  logger.error(details)
1473
- return SetParameterValueResultFailure()
1473
+ return SetParameterValueResultFailure(result_details=details)
1474
1474
  if not request.initial_setup and modified:
1475
1475
  try:
1476
1476
  GriptapeNodes.FlowManager().get_connections().unresolve_future_nodes(node)
1477
1477
  except Exception as err:
1478
1478
  details = f"Attempted to set parameter value for '{node_name}.{request.parameter_name}'. Failed because Exception: {err}"
1479
1479
  logger.error(details)
1480
- return SetParameterValueResultFailure()
1480
+ return SetParameterValueResultFailure(result_details=details)
1481
1481
  if request.initial_setup is False and not request.is_output and modified:
1482
1482
  # Mark node as unresolved, broadcast an event
1483
1483
  node.make_node_unresolved(current_states_to_trigger_change_event=set({NodeResolutionState.RESOLVED}))
@@ -1540,7 +1540,7 @@ class NodeManager:
1540
1540
  if not GriptapeNodes.ContextManager().has_current_node():
1541
1541
  details = "Attempted to get all info for a Node from the Current Context. Failed because the Current Context is empty."
1542
1542
  logger.error(details)
1543
- return GetAllNodeInfoResultFailure()
1543
+ return GetAllNodeInfoResultFailure(result_details=details)
1544
1544
 
1545
1545
  node = GriptapeNodes.ContextManager().get_current_node()
1546
1546
  node_name = node.name
@@ -1552,18 +1552,14 @@ class NodeManager:
1552
1552
  if node is None:
1553
1553
  details = f"Attempted to get all info for Node named '{node_name}', but no such Node was found."
1554
1554
  logger.error(details)
1555
-
1556
- result = GetAllNodeInfoResultFailure()
1557
- return result
1555
+ return GetAllNodeInfoResultFailure(result_details=details)
1558
1556
 
1559
1557
  get_metadata_request = GetNodeMetadataRequest(node_name=node_name)
1560
1558
  get_metadata_result = self.on_get_node_metadata_request(get_metadata_request)
1561
1559
  if not get_metadata_result.succeeded():
1562
1560
  details = f"Attempted to get all info for Node named '{node_name}', but failed getting the metadata."
1563
1561
  logger.error(details)
1564
-
1565
- result = GetAllNodeInfoResultFailure()
1566
- return GetAllNodeInfoResultFailure()
1562
+ return GetAllNodeInfoResultFailure(result_details=details)
1567
1563
 
1568
1564
  get_resolution_state_request = GetNodeResolutionStateRequest(node_name=node_name)
1569
1565
  get_resolution_state_result = self.on_get_node_resolution_state_request(get_resolution_state_request)
@@ -1572,8 +1568,7 @@ class NodeManager:
1572
1568
  f"Attempted to get all info for Node named '{node_name}', but failed getting the resolution state."
1573
1569
  )
1574
1570
  logger.error(details)
1575
-
1576
- return GetAllNodeInfoResultFailure()
1571
+ return GetAllNodeInfoResultFailure(result_details=details)
1577
1572
 
1578
1573
  list_connections_request = ListConnectionsForNodeRequest(node_name=node_name)
1579
1574
  list_connections_result = self.on_list_connections_for_node_request(list_connections_request)
@@ -1583,7 +1578,7 @@ class NodeManager:
1583
1578
  )
1584
1579
  logger.error(details)
1585
1580
 
1586
- return GetAllNodeInfoResultFailure()
1581
+ return GetAllNodeInfoResultFailure(result_details=details)
1587
1582
  # Cast everything to get the linter off our back.
1588
1583
  try:
1589
1584
  get_metadata_success = cast("GetNodeMetadataResultSuccess", get_metadata_result)
@@ -1593,7 +1588,7 @@ class NodeManager:
1593
1588
  details = f"Attempted to get all info for Node named '{node_name}'. Failed due to error: {err}."
1594
1589
  logger.error(details)
1595
1590
 
1596
- return GetAllNodeInfoResultFailure()
1591
+ return GetAllNodeInfoResultFailure(result_details=details)
1597
1592
  get_node_elements_request = GetNodeElementDetailsRequest(node_name=node_name)
1598
1593
  get_node_elements_result = self.on_get_node_element_details_request(get_node_elements_request)
1599
1594
  if not get_node_elements_result.succeeded():
@@ -1601,13 +1596,13 @@ class NodeManager:
1601
1596
  f"Attempted to get all info for Node named '{node_name}', but failed getting details for elements."
1602
1597
  )
1603
1598
  logger.error(details)
1604
- return GetAllNodeInfoResultFailure()
1599
+ return GetAllNodeInfoResultFailure(result_details=details)
1605
1600
  try:
1606
1601
  get_element_details_success = cast("GetNodeElementDetailsResultSuccess", get_node_elements_result)
1607
1602
  except Exception as err:
1608
1603
  details = f"Attempted to get all info for Node named '{node_name}'. Failed due to error: {err}."
1609
- logger.exception(details)
1610
- return GetAllNodeInfoResultFailure()
1604
+ logger.error(details)
1605
+ return GetAllNodeInfoResultFailure(result_details=details)
1611
1606
 
1612
1607
  # this will return the node element and the value
1613
1608
  element_details = get_element_details_success.element_details
@@ -1636,7 +1631,7 @@ class NodeManager:
1636
1631
  if not GriptapeNodes.ContextManager().has_current_node():
1637
1632
  details = "Attempted to get compatible parameters for node, but no current node was found."
1638
1633
  logger.error(details)
1639
- return GetCompatibleParametersResultFailure()
1634
+ return GetCompatibleParametersResultFailure(result_details=details)
1640
1635
  node = GriptapeNodes.ContextManager().get_current_node()
1641
1636
  node_name = node.name
1642
1637
 
@@ -1649,14 +1644,14 @@ class NodeManager:
1649
1644
  f"Attempted to get compatible parameters for node '{node_name}', but that node does not exist."
1650
1645
  )
1651
1646
  logger.error(details)
1652
- return GetCompatibleParametersResultFailure()
1647
+ return GetCompatibleParametersResultFailure(result_details=details)
1653
1648
 
1654
1649
  # Vet the parameter.
1655
1650
  request_param = node.get_parameter_by_name(request.parameter_name)
1656
1651
  if request_param is None:
1657
1652
  details = f"Attempted to get compatible parameters for '{node_name}.{request.parameter_name}', but that no Parameter with that name could not be found."
1658
1653
  logger.error(details)
1659
- return GetCompatibleParametersResultFailure()
1654
+ return GetCompatibleParametersResultFailure(result_details=details)
1660
1655
 
1661
1656
  # Figure out the mode we're going for, and if this parameter supports the mode.
1662
1657
  request_mode = ParameterMode.OUTPUT if request.is_output else ParameterMode.INPUT
@@ -1664,7 +1659,7 @@ class NodeManager:
1664
1659
  if request_mode not in request_param.allowed_modes:
1665
1660
  details = f"Attempted to get compatible parameters for '{node_name}.{request.parameter_name}' as '{request_mode}', but the Parameter didn't support that type of input/output."
1666
1661
  logger.error(details)
1667
- return GetCompatibleParametersResultFailure()
1662
+ return GetCompatibleParametersResultFailure(result_details=details)
1668
1663
 
1669
1664
  # Get the parent flows.
1670
1665
  try:
@@ -1672,7 +1667,7 @@ class NodeManager:
1672
1667
  except KeyError as err:
1673
1668
  details = f"Attempted to get compatible parameters for '{node_name}.{request.parameter_name}', but the node's parent flow could not be found: {err}"
1674
1669
  logger.error(details)
1675
- return GetCompatibleParametersResultFailure()
1670
+ return GetCompatibleParametersResultFailure(result_details=details)
1676
1671
 
1677
1672
  # Iterate through all nodes in this Flow (yes, this restriction still sucks)
1678
1673
  list_nodes_in_flow_request = ListNodesInFlowRequest(flow_name=flow_name)
@@ -1682,14 +1677,14 @@ class NodeManager:
1682
1677
  if not list_nodes_in_flow_result.succeeded():
1683
1678
  details = f"Attempted to get compatible parameters for '{node_name}.{request.parameter_name}'. Failed due to inability to list nodes in parent flow '{flow_name}'."
1684
1679
  logger.error(details)
1685
- return GetCompatibleParametersResultFailure()
1680
+ return GetCompatibleParametersResultFailure(result_details=details)
1686
1681
 
1687
1682
  try:
1688
1683
  list_nodes_in_flow_success = cast("ListNodesInFlowResultSuccess", list_nodes_in_flow_result)
1689
1684
  except Exception as err:
1690
1685
  details = f"Attempted to get compatible parameters for '{node_name}.{request.parameter_name}'. Failed due to {err}"
1691
1686
  logger.error(details)
1692
- return GetCompatibleParametersResultFailure()
1687
+ return GetCompatibleParametersResultFailure(result_details=details)
1693
1688
 
1694
1689
  # Walk through all nodes that are NOT us to find compatible Parameters.
1695
1690
  valid_parameters_by_node = {}
@@ -1701,7 +1696,7 @@ class NodeManager:
1701
1696
  except ValueError as err:
1702
1697
  details = f"Attempted to get compatible parameters for node '{node_name}', and sought to test against {test_node_name}, but that node does not exist. Error: {err}."
1703
1698
  logger.error(details)
1704
- return GetCompatibleParametersResultFailure()
1699
+ return GetCompatibleParametersResultFailure(result_details=details)
1705
1700
 
1706
1701
  # Get Parameters from Node
1707
1702
  for test_param in test_node.parameters:
@@ -1764,14 +1759,14 @@ class NodeManager:
1764
1759
  details = "No Node name was provided. Failed to resolve node."
1765
1760
  logger.error(details)
1766
1761
 
1767
- return ResolveNodeResultFailure(validation_exceptions=[])
1762
+ return ResolveNodeResultFailure(validation_exceptions=[], result_details=details)
1768
1763
  try:
1769
1764
  node = self.get_node_by_name(node_name)
1770
1765
  except ValueError as e:
1771
1766
  details = f'Resolve failure. "{node_name}" does not exist. {e}'
1772
1767
  logger.error(details)
1773
1768
 
1774
- return ResolveNodeResultFailure(validation_exceptions=[e])
1769
+ return ResolveNodeResultFailure(validation_exceptions=[e], result_details=details)
1775
1770
  # try to get the flow parent of this node
1776
1771
  try:
1777
1772
  flow_name = self._name_to_parent_flow_name[node_name]
@@ -1779,7 +1774,7 @@ class NodeManager:
1779
1774
  details = f'Failed to fetch parent flow for "{node_name}": {e}'
1780
1775
  logger.error(details)
1781
1776
 
1782
- return ResolveNodeResultFailure(validation_exceptions=[e])
1777
+ return ResolveNodeResultFailure(validation_exceptions=[e], result_details=details)
1783
1778
  try:
1784
1779
  obj_mgr = GriptapeNodes.ObjectManager()
1785
1780
  flow = obj_mgr.attempt_get_object_by_name_as_type(flow_name, ControlFlow)
@@ -1787,29 +1782,29 @@ class NodeManager:
1787
1782
  details = f'Failed to fetch parent flow for "{node_name}": {e}'
1788
1783
  logger.error(details)
1789
1784
 
1790
- return ResolveNodeResultFailure(validation_exceptions=[e])
1785
+ return ResolveNodeResultFailure(validation_exceptions=[e], result_details=details)
1791
1786
 
1792
1787
  if flow is None:
1793
1788
  details = f'Failed to fetch parent flow for "{node_name}"'
1794
1789
  logger.error(details)
1795
- return ResolveNodeResultFailure(validation_exceptions=[])
1790
+ return ResolveNodeResultFailure(validation_exceptions=[], result_details=details)
1796
1791
  if GriptapeNodes.FlowManager().check_for_existing_running_flow():
1797
1792
  details = f"Failed to resolve from node '{node_name}'. Flow is already running."
1798
1793
  logger.error(details)
1799
- return ResolveNodeResultFailure(validation_exceptions=[])
1794
+ return ResolveNodeResultFailure(validation_exceptions=[], result_details=details)
1800
1795
  try:
1801
1796
  GriptapeNodes.FlowManager().get_connections().unresolve_future_nodes(node)
1802
1797
  except Exception as e:
1803
1798
  details = f'Failed to mark future nodes dirty. Unable to kick off flow from "{node_name}": {e}'
1804
1799
  logger.error(details)
1805
- return ResolveNodeResultFailure(validation_exceptions=[e])
1800
+ return ResolveNodeResultFailure(validation_exceptions=[e], result_details=details)
1806
1801
  # Validate here.
1807
1802
  result = self.on_validate_node_dependencies_request(ValidateNodeDependenciesRequest(node_name=node_name))
1808
1803
  try:
1809
1804
  if not result.succeeded():
1810
1805
  details = f"Failed to resolve node '{node_name}'. Flow Validation Failed"
1811
1806
  logger.error(details)
1812
- return StartFlowResultFailure(validation_exceptions=[])
1807
+ return StartFlowResultFailure(validation_exceptions=[], result_details=details)
1813
1808
  result = cast("ValidateNodeDependenciesResultSuccess", result)
1814
1809
 
1815
1810
  if not result.validation_succeeded:
@@ -1818,17 +1813,17 @@ class NodeManager:
1818
1813
  for exception in result.exceptions:
1819
1814
  details = f"{details}\n\t{exception}"
1820
1815
  logger.error(details)
1821
- return StartFlowResultFailure(validation_exceptions=result.exceptions)
1816
+ return StartFlowResultFailure(validation_exceptions=result.exceptions, result_details=details)
1822
1817
  except Exception as e:
1823
1818
  details = f"Failed to resolve node '{node_name}'. Flow Validation Failed. Error: {e}"
1824
1819
  logger.error(details)
1825
- return StartFlowResultFailure(validation_exceptions=[e])
1820
+ return StartFlowResultFailure(validation_exceptions=[e], result_details=details)
1826
1821
  try:
1827
1822
  GriptapeNodes.FlowManager().resolve_singular_node(flow, node, debug_mode)
1828
1823
  except Exception as e:
1829
1824
  details = f'Failed to resolve "{node_name}". Error: {e}'
1830
1825
  logger.error(details)
1831
- return ResolveNodeResultFailure(validation_exceptions=[e])
1826
+ return ResolveNodeResultFailure(validation_exceptions=[e], result_details=details)
1832
1827
  details = f'Starting to resolve "{node_name}" in "{flow_name}"'
1833
1828
  logger.debug(details)
1834
1829
  return ResolveNodeResultSuccess()
@@ -1840,18 +1835,18 @@ class NodeManager:
1840
1835
  if node is None:
1841
1836
  details = f'Failed to validate node dependencies. Node with "{node_name}" does not exist.'
1842
1837
  logger.error(details)
1843
- return ValidateNodeDependenciesResultFailure()
1838
+ return ValidateNodeDependenciesResultFailure(result_details=details)
1844
1839
  try:
1845
1840
  flow_name = self.get_node_parent_flow_by_name(node_name)
1846
1841
  except Exception as e:
1847
1842
  details = f'Failed to validate node dependencies. Node with "{node_name}" has no parent flow. Error: {e}'
1848
1843
  logger.error(details)
1849
- return ValidateNodeDependenciesResultFailure()
1844
+ return ValidateNodeDependenciesResultFailure(result_details=details)
1850
1845
  flow = GriptapeNodes.ObjectManager().attempt_get_object_by_name_as_type(flow_name, ControlFlow)
1851
1846
  if not flow:
1852
1847
  details = f'Failed to validate node dependencies. Flow with "{flow_name}" does not exist.'
1853
1848
  logger.error(details)
1854
- return ValidateNodeDependenciesResultFailure()
1849
+ return ValidateNodeDependenciesResultFailure(result_details=details)
1855
1850
  # Gets all dependent nodes
1856
1851
  nodes = flow.get_node_dependencies(node)
1857
1852
  all_exceptions = []
@@ -1871,7 +1866,7 @@ class NodeManager:
1871
1866
  if not GriptapeNodes.ContextManager().has_current_node():
1872
1867
  details = "Attempted to serialize a Node to commands from the Current Context. Failed because the Current Context is empty."
1873
1868
  logger.error(details)
1874
- return SerializeNodeToCommandsResultFailure()
1869
+ return SerializeNodeToCommandsResultFailure(result_details=details)
1875
1870
  node = GriptapeNodes.ContextManager().get_current_node()
1876
1871
  node_name = node.name
1877
1872
 
@@ -1882,7 +1877,7 @@ class NodeManager:
1882
1877
  if node is None:
1883
1878
  details = f"Attempted to serialize Node '{node_name}' to commands. Failed because no Node with that name could be found."
1884
1879
  logger.error(details)
1885
- return SerializeNodeToCommandsResultFailure()
1880
+ return SerializeNodeToCommandsResultFailure(result_details=details)
1886
1881
 
1887
1882
  # This is our current dude.
1888
1883
  with GriptapeNodes.ContextManager().node(node=node):
@@ -1894,7 +1889,7 @@ class NodeManager:
1894
1889
  if not isinstance(library_metadata_result, GetLibraryMetadataResultSuccess):
1895
1890
  details = f"Attempted to serialize Node '{node_name}' to commands. Failed to get metadata for library '{library_used}'."
1896
1891
  logger.error(details)
1897
- return SerializeNodeToCommandsResultFailure()
1892
+ return SerializeNodeToCommandsResultFailure(result_details=details)
1898
1893
 
1899
1894
  library_version = library_metadata_result.metadata.library_version
1900
1895
  library_details = LibraryNameAndVersion(library_name=library_used, library_version=library_version)
@@ -2086,7 +2081,7 @@ class NodeManager:
2086
2081
  if not isinstance(create_node_result, CreateNodeResultSuccess):
2087
2082
  details = f"Attempted to deserialize a serialized set of Node Creation commands. Failed to create node '{create_node_request.node_name}'."
2088
2083
  logger.error(details)
2089
- return DeserializeNodeFromCommandsResultFailure()
2084
+ return DeserializeNodeFromCommandsResultFailure(result_details=details)
2090
2085
 
2091
2086
  # Adopt the newly-created node as our current context.
2092
2087
  node_name = create_node_result.node_name
@@ -2094,7 +2089,7 @@ class NodeManager:
2094
2089
  if node is None:
2095
2090
  details = f"Attempted to deserialize a serialized set of Node Creation commands. Failed to get node '{node_name}'."
2096
2091
  logger.error(details)
2097
- return DeserializeNodeFromCommandsResultFailure()
2092
+ return DeserializeNodeFromCommandsResultFailure(result_details=details)
2098
2093
  with GriptapeNodes.ContextManager().node(node=node):
2099
2094
  for element_command in request.serialized_node_commands.element_modification_commands:
2100
2095
  if isinstance(
@@ -2105,7 +2100,7 @@ class NodeManager:
2105
2100
  if element_result.failed():
2106
2101
  details = f"Attempted to deserialize a serialized set of Node Creation commands. Failed to execute an element command for node '{node_name}'."
2107
2102
  logger.error(details)
2108
- return DeserializeNodeFromCommandsResultFailure()
2103
+ return DeserializeNodeFromCommandsResultFailure(result_details=details)
2109
2104
  details = f"Successfully deserialized a serialized set of Node Creation commands for node '{node_name}'."
2110
2105
  logger.debug(details)
2111
2106
  return DeserializeNodeFromCommandsResultSuccess(node_name=node_name)
@@ -2141,7 +2136,7 @@ class NodeManager:
2141
2136
  if not isinstance(result, SerializeNodeToCommandsResultSuccess):
2142
2137
  details = f"Attempted to serialize a selection of Nodes. Failed to serialize {node_name}."
2143
2138
  logger.error(details)
2144
- return SerializeNodeToCommandsResultFailure()
2139
+ return SerializeNodeToCommandsResultFailure(result_details=details)
2145
2140
  node_commands[node_name] = result.serialized_node_commands
2146
2141
  node_name_to_uuid[node_name] = result.serialized_node_commands.node_uuid
2147
2142
  parameter_commands[result.serialized_node_commands.node_uuid] = result.set_parameter_value_commands
@@ -2194,7 +2189,7 @@ class NodeManager:
2194
2189
  ) -> ResultPayload:
2195
2190
  commands = GriptapeNodes.ContextManager()._clipboard.node_commands
2196
2191
  if commands is None:
2197
- return DeserializeSelectedNodesFromCommandsResultFailure()
2192
+ return DeserializeSelectedNodesFromCommandsResultFailure(result_details="No Node Commands Found")
2198
2193
  connections = commands.serialized_connection_commands
2199
2194
  node_uuid_to_name = {}
2200
2195
  # Enumerate because positions is in the same order as the node commands.
@@ -2215,13 +2210,15 @@ class NodeManager:
2215
2210
  DeserializeNodeFromCommandsRequest(serialized_node_commands=node_command)
2216
2211
  )
2217
2212
  if not isinstance(result, DeserializeNodeFromCommandsResultSuccess):
2218
- logger.error("Attempted to deserialize node but ran into an error on node serialization.")
2219
- return DeserializeSelectedNodesFromCommandsResultFailure()
2213
+ details = "Attempted to deserialize node but ran into an error on node serialization."
2214
+ logger.error(details)
2215
+ return DeserializeSelectedNodesFromCommandsResultFailure(result_details=details)
2220
2216
  node_uuid_to_name[node_command.node_uuid] = result.node_name
2221
2217
  node = GriptapeNodes.ObjectManager().attempt_get_object_by_name_as_type(result.node_name, BaseNode)
2222
2218
  if node is None:
2223
- logger.error("Attempted to deserialize node but ran into an error on node serialization.")
2224
- return DeserializeSelectedNodesFromCommandsResultFailure()
2219
+ details = "Attempted to deserialize node but ran into an error on node serialization."
2220
+ logger.error(details)
2221
+ return DeserializeSelectedNodesFromCommandsResultFailure(result_details=details)
2225
2222
  with GriptapeNodes.ContextManager().node(node=node):
2226
2223
  parameter_commands = commands.set_parameter_value_commands[node_command.node_uuid]
2227
2224
  for parameter_command in parameter_commands:
@@ -2272,12 +2269,12 @@ class NodeManager:
2272
2269
  if not result.succeeded():
2273
2270
  details = "Failed to serialized selected nodes."
2274
2271
  logger.error(details)
2275
- return DuplicateSelectedNodesResultFailure()
2272
+ return DuplicateSelectedNodesResultFailure(result_details=details)
2276
2273
  result = GriptapeNodes.handle_request(DeserializeSelectedNodesFromCommandsRequest(positions=request.positions))
2277
2274
  if not isinstance(result, DeserializeSelectedNodesFromCommandsResultSuccess):
2278
2275
  details = "Failed to deserialize selected nodes."
2279
2276
  logger.error(details)
2280
- return DuplicateSelectedNodesResultFailure()
2277
+ return DuplicateSelectedNodesResultFailure(result_details=details)
2281
2278
 
2282
2279
  # Remake duplicate connections of node
2283
2280
  # request.nodes_to_duplicate is in this format: ['nodes_to_duplicate1', 'time'], ['nodes_to_duplicate2', 'time']
@@ -2446,7 +2443,7 @@ class NodeManager:
2446
2443
  if not GriptapeNodes.ContextManager().has_current_node():
2447
2444
  details = "Attempted to rename Parameter in the Current Context. Failed because the Current Context was empty."
2448
2445
  logger.error(details)
2449
- return RenameParameterResultFailure()
2446
+ return RenameParameterResultFailure(result_details=details)
2450
2447
  node = GriptapeNodes.ContextManager().get_current_node()
2451
2448
  node_name = node.name
2452
2449
  else:
@@ -2455,32 +2452,32 @@ class NodeManager:
2455
2452
  except KeyError as err:
2456
2453
  details = f"Attempted to rename Parameter '{request.parameter_name}' on Node '{node_name}'. Failed because the Node could not be found. Error: {err}"
2457
2454
  logger.error(details)
2458
- return RenameParameterResultFailure()
2455
+ return RenameParameterResultFailure(result_details=details)
2459
2456
 
2460
2457
  # Is the node locked?
2461
2458
  if node.lock:
2462
2459
  details = f"Attempted to rename Parameter '{request.parameter_name}' on Node '{node_name}'. Failed because the Node is locked."
2463
2460
  logger.error(details)
2464
- return RenameParameterResultFailure()
2461
+ return RenameParameterResultFailure(result_details=details)
2465
2462
 
2466
2463
  # Get the parameter
2467
2464
  parameter = node.get_parameter_by_name(request.parameter_name)
2468
2465
  if parameter is None:
2469
2466
  details = f"Attempted to rename Parameter '{request.parameter_name}' on Node '{node_name}'. Failed because the Parameter could not be found."
2470
2467
  logger.error(details)
2471
- return RenameParameterResultFailure()
2468
+ return RenameParameterResultFailure(result_details=details)
2472
2469
 
2473
2470
  # Validate the new parameter name
2474
2471
  if any(char.isspace() for char in request.new_parameter_name):
2475
2472
  details = f"Failed to rename Parameter '{request.parameter_name}' to '{request.new_parameter_name}'. Parameter names cannot contain any whitespace characters."
2476
2473
  logger.error(details)
2477
- return RenameParameterResultFailure()
2474
+ return RenameParameterResultFailure(result_details=details)
2478
2475
 
2479
2476
  # Check for duplicate names
2480
2477
  if node.does_name_exist(request.new_parameter_name):
2481
2478
  details = f"Failed to rename Parameter '{request.parameter_name}' to '{request.new_parameter_name}'. A Parameter with that name already exists."
2482
2479
  logger.error(details)
2483
- return RenameParameterResultFailure()
2480
+ return RenameParameterResultFailure(result_details=details)
2484
2481
 
2485
2482
  # Get all connections for this node
2486
2483
  flow_name = self.get_node_parent_flow_by_name(node_name)
@@ -2524,7 +2521,7 @@ class NodeManager:
2524
2521
  if not GriptapeNodes.ContextManager().has_current_node():
2525
2522
  details = "Attempted to lock node in the Current Context. Failed because the Current Context was empty."
2526
2523
  logger.error(details)
2527
- return SetLockNodeStateResultFailure()
2524
+ return SetLockNodeStateResultFailure(result_details=details)
2528
2525
  node = GriptapeNodes.ContextManager().get_current_node()
2529
2526
  node_name = node.name
2530
2527
  else:
@@ -2533,6 +2530,6 @@ class NodeManager:
2533
2530
  except ValueError as err:
2534
2531
  details = f"Attempted to lock node '{request.node_name}'. Failed because the Node could not be found. Error: {err}"
2535
2532
  logger.error(details)
2536
- return SetLockNodeStateResultFailure()
2533
+ return SetLockNodeStateResultFailure(result_details=details)
2537
2534
  node.lock = request.lock
2538
2535
  return SetLockNodeStateResultSuccess(node_name=node_name, locked=node.lock)