griptape-nodes 0.34.3__py3-none-any.whl → 0.35.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 (31) hide show
  1. griptape_nodes/__init__.py +56 -41
  2. griptape_nodes/app/app.py +3 -3
  3. griptape_nodes/bootstrap/bootstrap_script.py +5 -3
  4. griptape_nodes/drivers/__init__.py +1 -0
  5. griptape_nodes/drivers/storage/__init__.py +4 -0
  6. griptape_nodes/drivers/storage/base_storage_driver.py +38 -0
  7. griptape_nodes/drivers/storage/griptape_cloud_storage_driver.py +85 -0
  8. griptape_nodes/drivers/storage/local_storage_driver.py +49 -0
  9. griptape_nodes/exe_types/core_types.py +57 -1
  10. griptape_nodes/exe_types/flow.py +3 -1
  11. griptape_nodes/exe_types/node_types.py +34 -0
  12. griptape_nodes/machines/node_resolution.py +9 -1
  13. griptape_nodes/node_library/library_registry.py +2 -0
  14. griptape_nodes/retained_mode/events/execution_events.py +2 -0
  15. griptape_nodes/retained_mode/events/generate_request_payload_schemas.py +1 -1
  16. griptape_nodes/retained_mode/events/node_events.py +13 -16
  17. griptape_nodes/retained_mode/events/parameter_events.py +10 -3
  18. griptape_nodes/retained_mode/events/static_file_events.py +26 -0
  19. griptape_nodes/retained_mode/griptape_nodes.py +3 -1
  20. griptape_nodes/retained_mode/managers/context_manager.py +123 -87
  21. griptape_nodes/retained_mode/managers/flow_manager.py +126 -86
  22. griptape_nodes/retained_mode/managers/library_manager.py +279 -95
  23. griptape_nodes/retained_mode/managers/node_manager.py +230 -159
  24. griptape_nodes/retained_mode/managers/settings.py +6 -1
  25. griptape_nodes/retained_mode/managers/static_files_manager.py +77 -54
  26. griptape_nodes/retained_mode/managers/workflow_manager.py +51 -12
  27. {griptape_nodes-0.34.3.dist-info → griptape_nodes-0.35.0.dist-info}/METADATA +1 -1
  28. {griptape_nodes-0.34.3.dist-info → griptape_nodes-0.35.0.dist-info}/RECORD +31 -26
  29. {griptape_nodes-0.34.3.dist-info → griptape_nodes-0.35.0.dist-info}/WHEEL +0 -0
  30. {griptape_nodes-0.34.3.dist-info → griptape_nodes-0.35.0.dist-info}/entry_points.txt +0 -0
  31. {griptape_nodes-0.34.3.dist-info → griptape_nodes-0.35.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,6 +1,6 @@
1
+ import copy
1
2
  import logging
2
3
  import pickle
3
- from datetime import datetime
4
4
  from typing import Any, cast
5
5
  from uuid import uuid4
6
6
 
@@ -194,6 +194,7 @@ class NodeManager:
194
194
  def on_create_node_request(self, request: CreateNodeRequest) -> ResultPayload:
195
195
  # Validate as much as possible before we actually create one.
196
196
  parent_flow_name = request.override_parent_flow_name
197
+ parent_flow = None
197
198
  if parent_flow_name is None:
198
199
  # Try to get the current context flow
199
200
  if not GriptapeNodes.ContextManager().has_current_flow():
@@ -202,16 +203,18 @@ class NodeManager:
202
203
  )
203
204
  logger.error(details)
204
205
  return CreateNodeResultFailure()
205
- parent_flow_name = GriptapeNodes.ContextManager().get_current_flow_name()
206
+ parent_flow = GriptapeNodes.ContextManager().get_current_flow()
207
+ parent_flow_name = parent_flow.name
206
208
 
207
209
  # Does this flow actually exist?
208
- flow_mgr = GriptapeNodes.FlowManager()
209
- try:
210
- flow = flow_mgr.get_flow_by_name(parent_flow_name)
211
- except KeyError as err:
212
- details = f"Could not create Node of type '{request.node_type}'. Error: {err}"
213
- logger.error(details)
214
- return CreateNodeResultFailure()
210
+ if parent_flow is None:
211
+ flow_mgr = GriptapeNodes.FlowManager()
212
+ try:
213
+ parent_flow = flow_mgr.get_flow_by_name(parent_flow_name)
214
+ except KeyError as err:
215
+ details = f"Could not create Node of type '{request.node_type}'. Error: {err}"
216
+ logger.error(details)
217
+ return CreateNodeResultFailure()
215
218
 
216
219
  # Now ensure that we're giving a valid name.
217
220
  obj_mgr = GriptapeNodes.ObjectManager()
@@ -239,7 +242,7 @@ class NodeManager:
239
242
  return CreateNodeResultFailure()
240
243
 
241
244
  # Add it to the Flow.
242
- flow.add_node(node)
245
+ parent_flow.add_node(node)
243
246
 
244
247
  # Record keeping.
245
248
  obj_mgr.add_object_by_name(node.name, node)
@@ -256,7 +259,7 @@ class NodeManager:
256
259
 
257
260
  # See if we want to push this into the context of the current flow.
258
261
  if request.set_as_new_context:
259
- GriptapeNodes.ContextManager().push_node(final_node_name)
262
+ GriptapeNodes.ContextManager().push_node(node=node)
260
263
 
261
264
  # Success message based on whether we used Current Context or explicit flow
262
265
  if request.override_parent_flow_name is None:
@@ -273,7 +276,9 @@ class NodeManager:
273
276
 
274
277
  logger.log(level=log_level, msg=details)
275
278
 
276
- return CreateNodeResultSuccess(node_name=node.name)
279
+ return CreateNodeResultSuccess(
280
+ node_name=node.name, node_type=node.__class__.__name__, specific_library_name=request.specific_library_name
281
+ )
277
282
 
278
283
  def cancel_conditionally(
279
284
  self, parent_flow: ControlFlow, parent_flow_name: str, node: BaseNode
@@ -331,6 +336,7 @@ class NodeManager:
331
336
 
332
337
  def on_delete_node_request(self, request: DeleteNodeRequest) -> ResultPayload: # noqa: C901, PLR0911 (complex logic, lots of edge cases)
333
338
  node_name = request.node_name
339
+ node = None
334
340
  if node_name is None:
335
341
  # Get from the current context.
336
342
  if not GriptapeNodes.ContextManager().has_current_node():
@@ -340,18 +346,16 @@ class NodeManager:
340
346
  logger.error(details)
341
347
  return DeleteNodeResultFailure()
342
348
 
343
- node_name = GriptapeNodes.ContextManager().get_current_node_name()
344
-
345
- with GriptapeNodes.ContextManager().node(node_name=node_name):
346
- # Does this node exist?
347
- obj_mgr = GriptapeNodes.ObjectManager()
348
-
349
- node = obj_mgr.attempt_get_object_by_name_as_type(node_name, BaseNode)
350
- if node is None:
351
- details = f"Attempted to delete a Node '{node_name}', but no such Node was found."
352
- logger.error(details)
353
- return DeleteNodeResultFailure()
349
+ node = GriptapeNodes.ContextManager().get_current_node()
350
+ node_name = node.name
351
+ if node is None:
352
+ node = GriptapeNodes.ObjectManager().attempt_get_object_by_name_as_type(node_name, BaseNode)
353
+ if node is None:
354
+ details = f"Attempted to delete a Node '{node_name}', but no such Node was found."
355
+ logger.error(details)
356
+ return DeleteNodeResultFailure()
354
357
 
358
+ with GriptapeNodes.ContextManager().node(node=node):
355
359
  parent_flow_name = self._name_to_parent_flow_name[node_name]
356
360
  try:
357
361
  parent_flow = GriptapeNodes.FlowManager().get_flow_by_name(parent_flow_name)
@@ -403,7 +407,7 @@ class NodeManager:
403
407
  parent_flow.remove_node(node.name)
404
408
 
405
409
  # Now remove the record keeping
406
- obj_mgr.del_obj_by_name(node_name)
410
+ GriptapeNodes.ObjectManager().del_obj_by_name(node_name)
407
411
  del self._name_to_parent_flow_name[node_name]
408
412
 
409
413
  # If we were part of the Current Context, pop it.
@@ -417,6 +421,7 @@ class NodeManager:
417
421
 
418
422
  def on_get_node_resolution_state_request(self, request: GetNodeResolutionStateRequest) -> ResultPayload:
419
423
  node_name = request.node_name
424
+ node = None
420
425
  if node_name is None:
421
426
  # Get from the current context.
422
427
  if not GriptapeNodes.ContextManager().has_current_node():
@@ -424,17 +429,18 @@ class NodeManager:
424
429
  logger.error(details)
425
430
  return GetNodeResolutionStateResultFailure()
426
431
 
427
- node_name = GriptapeNodes.ContextManager().get_current_node_name()
428
-
429
- # Does this node exist?
430
- obj_mgr = GriptapeNodes.ObjectManager()
432
+ node = GriptapeNodes.ContextManager().get_current_node()
433
+ node_name = node.name
431
434
 
432
- node = obj_mgr.attempt_get_object_by_name_as_type(node_name, BaseNode)
433
435
  if node is None:
434
- details = f"Attempted to get resolution state for a Node '{node_name}', but no such Node was found."
435
- logger.error(details)
436
- result = GetNodeResolutionStateResultFailure()
437
- return result
436
+ # Does this node exist?
437
+ obj_mgr = GriptapeNodes.ObjectManager()
438
+ node = obj_mgr.attempt_get_object_by_name_as_type(node_name, BaseNode)
439
+ if node is None:
440
+ details = f"Attempted to get resolution state for a Node '{node_name}', but no such Node was found."
441
+ logger.error(details)
442
+ result = GetNodeResolutionStateResultFailure()
443
+ return result
438
444
 
439
445
  node_state = node.state
440
446
 
@@ -448,6 +454,7 @@ class NodeManager:
448
454
 
449
455
  def on_get_node_metadata_request(self, request: GetNodeMetadataRequest) -> ResultPayload:
450
456
  node_name = request.node_name
457
+ node = None
451
458
  if node_name is None:
452
459
  # Get from the current context.
453
460
  if not GriptapeNodes.ContextManager().has_current_node():
@@ -455,18 +462,20 @@ class NodeManager:
455
462
  logger.error(details)
456
463
  return GetNodeMetadataResultFailure()
457
464
 
458
- node_name = GriptapeNodes.ContextManager().get_current_node_name()
465
+ node = GriptapeNodes.ContextManager().get_current_node()
466
+ node_name = node.name
459
467
 
460
468
  # Does this node exist?
461
- obj_mgr = GriptapeNodes.ObjectManager()
462
-
463
- node = obj_mgr.attempt_get_object_by_name_as_type(node_name, BaseNode)
464
469
  if node is None:
465
- details = f"Attempted to get metadata for a Node '{node_name}', but no such Node was found."
466
- logger.error(details)
470
+ obj_mgr = GriptapeNodes.ObjectManager()
467
471
 
468
- result = GetNodeMetadataResultFailure()
469
- return result
472
+ node = obj_mgr.attempt_get_object_by_name_as_type(node_name, BaseNode)
473
+ if node is None:
474
+ details = f"Attempted to get metadata for a Node '{node_name}', but no such Node was found."
475
+ logger.error(details)
476
+
477
+ result = GetNodeMetadataResultFailure()
478
+ return result
470
479
 
471
480
  metadata = node.metadata
472
481
  details = f"Successfully retrieved metadata for a Node '{node_name}'."
@@ -479,6 +488,7 @@ class NodeManager:
479
488
 
480
489
  def on_set_node_metadata_request(self, request: SetNodeMetadataRequest) -> ResultPayload:
481
490
  node_name = request.node_name
491
+ node = None
482
492
  if node_name is None:
483
493
  # Get from the current context.
484
494
  if not GriptapeNodes.ContextManager().has_current_node():
@@ -486,18 +496,21 @@ class NodeManager:
486
496
  logger.error(details)
487
497
  return SetNodeMetadataResultFailure()
488
498
 
489
- node_name = GriptapeNodes.ContextManager().get_current_node_name()
499
+ node = GriptapeNodes.ContextManager().get_current_node()
500
+ node_name = node.name
490
501
 
491
502
  # Does this node exist?
492
- obj_mgr = GriptapeNodes.ObjectManager()
493
-
494
- node = obj_mgr.attempt_get_object_by_name_as_type(node_name, BaseNode)
495
503
  if node is None:
496
- details = f"Attempted to set metadata for a Node '{node_name}', but no such Node was found."
497
- logger.error(details)
504
+ obj_mgr = GriptapeNodes.ObjectManager()
505
+
506
+ node = obj_mgr.attempt_get_object_by_name_as_type(node_name, BaseNode)
507
+ if node is None:
508
+ details = f"Attempted to set metadata for a Node '{node_name}', but no such Node was found."
509
+ logger.error(details)
510
+
511
+ result = SetNodeMetadataResultFailure()
512
+ return result
498
513
 
499
- result = SetNodeMetadataResultFailure()
500
- return result
501
514
  # We can't completely overwrite metadata.
502
515
  for key, value in request.metadata.items():
503
516
  node.metadata[key] = value
@@ -509,6 +522,7 @@ class NodeManager:
509
522
 
510
523
  def on_list_connections_for_node_request(self, request: ListConnectionsForNodeRequest) -> ResultPayload:
511
524
  node_name = request.node_name
525
+ node = None
512
526
  if node_name is None:
513
527
  # Get from the current context.
514
528
  if not GriptapeNodes.ContextManager().has_current_node():
@@ -516,18 +530,20 @@ class NodeManager:
516
530
  logger.error(details)
517
531
  return ListConnectionsForNodeResultFailure()
518
532
 
519
- node_name = GriptapeNodes.ContextManager().get_current_node_name()
533
+ node = GriptapeNodes.ContextManager().get_current_node()
534
+ node_name = node.name
520
535
 
521
536
  # Does this node exist?
522
- obj_mgr = GriptapeNodes.ObjectManager()
523
-
524
- node = obj_mgr.attempt_get_object_by_name_as_type(node_name, BaseNode)
525
537
  if node is None:
526
- details = f"Attempted to list Connections for a Node '{node_name}', but no such Node was found."
527
- logger.error(details)
538
+ obj_mgr = GriptapeNodes.ObjectManager()
528
539
 
529
- result = ListConnectionsForNodeResultFailure()
530
- return result
540
+ node = obj_mgr.attempt_get_object_by_name_as_type(node_name, BaseNode)
541
+ if node is None:
542
+ details = f"Attempted to list Connections for a Node '{node_name}', but no such Node was found."
543
+ logger.error(details)
544
+
545
+ result = ListConnectionsForNodeResultFailure()
546
+ return result
531
547
 
532
548
  parent_flow_name = self._name_to_parent_flow_name[node_name]
533
549
  try:
@@ -581,6 +597,7 @@ class NodeManager:
581
597
 
582
598
  def on_list_parameters_on_node_request(self, request: ListParametersOnNodeRequest) -> ResultPayload:
583
599
  node_name = request.node_name
600
+ node = None
584
601
 
585
602
  if node_name is None:
586
603
  # Get from the current context.
@@ -589,17 +606,19 @@ class NodeManager:
589
606
  logger.error(details)
590
607
  return ListParametersOnNodeResultFailure()
591
608
 
592
- node_name = GriptapeNodes.ContextManager().get_current_node_name()
609
+ node = GriptapeNodes.ContextManager().get_current_node()
610
+ node_name = node.name
593
611
 
594
612
  # Does this node exist?
595
- obj_mgr = GriptapeNodes.ObjectManager()
596
- node = obj_mgr.attempt_get_object_by_name_as_type(node_name, BaseNode)
597
613
  if node is None:
598
- details = f"Attempted to list Parameters for a Node '{node_name}', but no such Node was found."
599
- logger.error(details)
614
+ obj_mgr = GriptapeNodes.ObjectManager()
615
+ node = obj_mgr.attempt_get_object_by_name_as_type(node_name, BaseNode)
616
+ if node is None:
617
+ details = f"Attempted to list Parameters for a Node '{node_name}', but no such Node was found."
618
+ logger.error(details)
600
619
 
601
- result = ListParametersOnNodeResultFailure()
602
- return result
620
+ result = ListParametersOnNodeResultFailure()
621
+ return result
603
622
 
604
623
  ret_list = [param.name for param in node.parameters]
605
624
 
@@ -613,6 +632,7 @@ class NodeManager:
613
632
 
614
633
  def on_add_parameter_to_node_request(self, request: AddParameterToNodeRequest) -> ResultPayload: # noqa: C901, PLR0911, PLR0912, PLR0915
615
634
  node_name = request.node_name
635
+ node = None
616
636
 
617
637
  if node_name is None:
618
638
  # Get from the current context.
@@ -621,18 +641,19 @@ class NodeManager:
621
641
  logger.error(details)
622
642
  return AddParameterToNodeResultFailure()
623
643
 
624
- node_name = GriptapeNodes.ContextManager().get_current_node_name()
644
+ node = GriptapeNodes.ContextManager().get_current_node()
645
+ node_name = node.name
625
646
 
626
647
  # Does this node exist?
627
- obj_mgr = GriptapeNodes.ObjectManager()
628
-
629
- node = obj_mgr.attempt_get_object_by_name_as_type(node_name, BaseNode)
630
648
  if node is None:
631
- details = f"Attempted to add Parameter '{request.parameter_name}' to a Node '{node_name}', but no such Node was found."
632
- logger.error(details)
649
+ obj_mgr = GriptapeNodes.ObjectManager()
650
+ node = obj_mgr.attempt_get_object_by_name_as_type(node_name, BaseNode)
651
+ if node is None:
652
+ details = f"Attempted to add Parameter '{request.parameter_name}' to a Node '{node_name}', but no such Node was found."
653
+ logger.error(details)
633
654
 
634
- result = AddParameterToNodeResultFailure()
635
- return result
655
+ result = AddParameterToNodeResultFailure()
656
+ return result
636
657
 
637
658
  if request.parent_container_name and not request.initial_setup:
638
659
  parameter = node.get_parameter_by_name(request.parent_container_name)
@@ -745,6 +766,7 @@ class NodeManager:
745
766
 
746
767
  def on_remove_parameter_from_node_request(self, request: RemoveParameterFromNodeRequest) -> ResultPayload: # noqa: C901, PLR0911, PLR0912, PLR0915
747
768
  node_name = request.node_name
769
+ node = None
748
770
 
749
771
  if node_name is None:
750
772
  # Get the Current Context
@@ -755,18 +777,19 @@ class NodeManager:
755
777
  result = RemoveParameterFromNodeResultFailure()
756
778
  return result
757
779
 
758
- node_name = GriptapeNodes.ContextManager().get_current_node_name()
780
+ node = GriptapeNodes.ContextManager().get_current_node()
781
+ node_name = node.name
759
782
 
760
783
  # Does this node exist?
761
- obj_mgr = GriptapeNodes.ObjectManager()
762
-
763
- node = obj_mgr.attempt_get_object_by_name_as_type(node_name, BaseNode)
764
784
  if node is None:
765
- details = f"Attempted to remove Parameter '{request.parameter_name}' from a Node '{node_name}', but no such Node was found."
766
- logger.error(details)
785
+ obj_mgr = GriptapeNodes.ObjectManager()
786
+ node = obj_mgr.attempt_get_object_by_name_as_type(node_name, BaseNode)
787
+ if node is None:
788
+ details = f"Attempted to remove Parameter '{request.parameter_name}' from a Node '{node_name}', but no such Node was found."
789
+ logger.error(details)
767
790
 
768
- result = RemoveParameterFromNodeResultFailure()
769
- return result
791
+ result = RemoveParameterFromNodeResultFailure()
792
+ return result
770
793
 
771
794
  # Does the Parameter actually exist on the Node?
772
795
  parameter = node.get_parameter_by_name(request.parameter_name)
@@ -852,6 +875,8 @@ class NodeManager:
852
875
 
853
876
  def on_get_parameter_details_request(self, request: GetParameterDetailsRequest) -> ResultPayload:
854
877
  node_name = request.node_name
878
+ node = None
879
+
855
880
  if node_name is None:
856
881
  if not GriptapeNodes.ContextManager().has_current_node():
857
882
  details = f"Attempted to get details for Parameter '{request.parameter_name}' from a Node, but no Current Context was found."
@@ -859,18 +884,19 @@ class NodeManager:
859
884
 
860
885
  result = GetParameterDetailsResultFailure()
861
886
  return result
862
- node_name = GriptapeNodes.ContextManager().get_current_node_name()
887
+ node = GriptapeNodes.ContextManager().get_current_node()
888
+ node_name = node.name
863
889
 
864
890
  # Does this node exist?
865
- obj_mgr = GriptapeNodes.ObjectManager()
866
-
867
- node = obj_mgr.attempt_get_object_by_name_as_type(node_name, BaseNode)
868
891
  if node is None:
869
- details = f"Attempted to get details for Parameter '{request.parameter_name}' from a Node '{node_name}', but no such Node was found."
870
- logger.error(details)
892
+ obj_mgr = GriptapeNodes.ObjectManager()
893
+ node = obj_mgr.attempt_get_object_by_name_as_type(node_name, BaseNode)
894
+ if node is None:
895
+ details = f"Attempted to get details for Parameter '{request.parameter_name}' from a Node '{node_name}', but no such Node was found."
896
+ logger.error(details)
871
897
 
872
- result = GetParameterDetailsResultFailure()
873
- return result
898
+ result = GetParameterDetailsResultFailure()
899
+ return result
874
900
 
875
901
  # Does the Parameter actually exist on the Node?
876
902
  parameter = node.get_parameter_by_name(request.parameter_name)
@@ -910,23 +936,26 @@ class NodeManager:
910
936
 
911
937
  def on_get_node_element_details_request(self, request: GetNodeElementDetailsRequest) -> ResultPayload:
912
938
  node_name = request.node_name
939
+ node = None
940
+
913
941
  if node_name is None:
914
942
  if not GriptapeNodes.ContextManager().has_current_node():
915
943
  details = f"Attempted to get element details for element '{request.specific_element_id}` from a Node, but no Current Context was found."
916
944
  logger.error(details)
917
945
 
918
946
  return GetNodeElementDetailsResultFailure()
919
- node_name = GriptapeNodes.ContextManager().get_current_node_name()
947
+ node = GriptapeNodes.ContextManager().get_current_node()
948
+ node_name = node.name
920
949
 
921
950
  # Does this node exist?
922
- obj_mgr = GriptapeNodes.ObjectManager()
923
-
924
- node = obj_mgr.attempt_get_object_by_name_as_type(node_name, BaseNode)
925
951
  if node is None:
926
- details = f"Attempted to get element details for Node '{node_name}', but no such Node was found."
927
- logger.error(details)
952
+ obj_mgr = GriptapeNodes.ObjectManager()
953
+ node = obj_mgr.attempt_get_object_by_name_as_type(node_name, BaseNode)
954
+ if node is None:
955
+ details = f"Attempted to get element details for Node '{node_name}', but no such Node was found."
956
+ logger.error(details)
928
957
 
929
- return GetNodeElementDetailsResultFailure()
958
+ return GetNodeElementDetailsResultFailure()
930
959
 
931
960
  # Did they ask for a specific element ID?
932
961
  if request.specific_element_id is None:
@@ -1017,6 +1046,7 @@ class NodeManager:
1017
1046
 
1018
1047
  def on_alter_parameter_details_request(self, request: AlterParameterDetailsRequest) -> ResultPayload:
1019
1048
  node_name = request.node_name
1049
+ node = None
1020
1050
 
1021
1051
  if node_name is None:
1022
1052
  if not GriptapeNodes.ContextManager().has_current_node():
@@ -1024,16 +1054,18 @@ class NodeManager:
1024
1054
  logger.error(details)
1025
1055
 
1026
1056
  return AlterParameterDetailsResultFailure()
1027
- node_name = GriptapeNodes.ContextManager().get_current_node_name()
1057
+ node = GriptapeNodes.ContextManager().get_current_node()
1058
+ node_name = node.name
1028
1059
 
1029
1060
  # Does this node exist?
1030
- obj_mgr = GriptapeNodes.ObjectManager()
1031
- node = obj_mgr.attempt_get_object_by_name_as_type(node_name, BaseNode)
1032
1061
  if node is None:
1033
- details = f"Attempted to alter details for Parameter '{request.parameter_name}' from Node '{node_name}', but no such Node was found."
1034
- logger.error(details)
1062
+ obj_mgr = GriptapeNodes.ObjectManager()
1063
+ node = obj_mgr.attempt_get_object_by_name_as_type(node_name, BaseNode)
1064
+ if node is None:
1065
+ details = f"Attempted to alter details for Parameter '{request.parameter_name}' from Node '{node_name}', but no such Node was found."
1066
+ logger.error(details)
1035
1067
 
1036
- return AlterParameterDetailsResultFailure()
1068
+ return AlterParameterDetailsResultFailure()
1037
1069
 
1038
1070
  # Does the Parameter actually exist on the Node?
1039
1071
  parameter = node.get_parameter_by_name(request.parameter_name)
@@ -1073,6 +1105,7 @@ class NodeManager:
1073
1105
  # For C901 (too complex): Need to give customers explicit reasons for failure on each case.
1074
1106
  def on_get_parameter_value_request(self, request: GetParameterValueRequest) -> ResultPayload:
1075
1107
  node_name = request.node_name
1108
+ node = None
1076
1109
 
1077
1110
  if node_name is None:
1078
1111
  if not GriptapeNodes.ContextManager().has_current_node():
@@ -1080,20 +1113,20 @@ class NodeManager:
1080
1113
  logger.error(details)
1081
1114
 
1082
1115
  return GetParameterValueResultFailure()
1083
- node_name = GriptapeNodes.ContextManager().get_current_node_name()
1084
-
1085
- # Does this node exist?
1086
- obj_mgr = GriptapeNodes.ObjectManager()
1116
+ node = GriptapeNodes.ContextManager().get_current_node()
1117
+ node_name = node.name
1087
1118
 
1088
1119
  # Parse the parameter name to check for list indexing
1089
1120
  param_name = request.parameter_name
1090
1121
 
1091
- # Get the node
1092
- node = obj_mgr.attempt_get_object_by_name_as_type(node_name, BaseNode)
1122
+ # Does this node exist?
1093
1123
  if node is None:
1094
- details = f'"{node_name}" not found'
1095
- logger.error(details)
1096
- return GetParameterValueResultFailure()
1124
+ obj_mgr = GriptapeNodes.ObjectManager()
1125
+ node = obj_mgr.attempt_get_object_by_name_as_type(node_name, BaseNode)
1126
+ if node is None:
1127
+ details = f'"{node_name}" not found'
1128
+ logger.error(details)
1129
+ return GetParameterValueResultFailure()
1097
1130
 
1098
1131
  # Does the Parameter actually exist on the Node?
1099
1132
  parameter = node.get_parameter_by_name(param_name)
@@ -1128,25 +1161,27 @@ class NodeManager:
1128
1161
  # added ignoring C901 since this method is overly long because of granular error checking, not actual complexity.
1129
1162
  def on_set_parameter_value_request(self, request: SetParameterValueRequest) -> ResultPayload: # noqa: C901, PLR0911, PLR0912, PLR0915
1130
1163
  node_name = request.node_name
1164
+ node = None
1165
+
1131
1166
  if node_name is None:
1132
1167
  if not GriptapeNodes.ContextManager().has_current_node():
1133
1168
  details = f"Attempted to set parameter '{request.parameter_name}' value. Failed because no Node was found in the Current Context."
1134
1169
  logger.error(details)
1135
1170
  return SetParameterValueResultFailure()
1136
- node_name = GriptapeNodes.ContextManager().get_current_node_name()
1137
-
1138
- # Does this node exist?
1139
- obj_mgr = GriptapeNodes.ObjectManager()
1171
+ node = GriptapeNodes.ContextManager().get_current_node()
1172
+ node_name = node.name
1140
1173
 
1141
1174
  # Parse the parameter name to check for list indexing
1142
1175
  param_name = request.parameter_name
1143
1176
 
1144
- # Get the node
1145
- node = obj_mgr.attempt_get_object_by_name_as_type(node_name, BaseNode)
1177
+ # Does this node exist?
1146
1178
  if node is None:
1147
- details = f"Attempted to set parameter '{param_name}' value on node '{node_name}'. Failed because no such Node could be found."
1148
- logger.error(details)
1149
- return SetParameterValueResultFailure()
1179
+ obj_mgr = GriptapeNodes.ObjectManager()
1180
+ node = obj_mgr.attempt_get_object_by_name_as_type(node_name, BaseNode)
1181
+ if node is None:
1182
+ details = f"Attempted to set parameter '{param_name}' value on node '{node_name}'. Failed because no such Node could be found."
1183
+ logger.error(details)
1184
+ return SetParameterValueResultFailure()
1150
1185
 
1151
1186
  # Does the Parameter actually exist on the Node?
1152
1187
  parameter = node.get_parameter_by_name(param_name)
@@ -1180,6 +1215,8 @@ class NodeManager:
1180
1215
  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."
1181
1216
  logger.error(details)
1182
1217
  return SetParameterValueResultFailure()
1218
+
1219
+ obj_mgr = GriptapeNodes.ObjectManager()
1183
1220
  parent_flow = obj_mgr.attempt_get_object_by_name_as_type(parent_flow_name, ControlFlow)
1184
1221
  if not parent_flow:
1185
1222
  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."
@@ -1246,7 +1283,7 @@ class NodeManager:
1246
1283
  for modified_parameter_name in modified_parameters:
1247
1284
  modified_parameter = node.get_parameter_by_name(modified_parameter_name)
1248
1285
  if modified_parameter is not None:
1249
- modified_request = AlterParameterEvent.create(node_name=node.name, parameter=modified_parameter)
1286
+ modified_request = AlterParameterEvent.create(node=node, parameter=modified_parameter)
1250
1287
  EventBus.publish_event(ExecutionGriptapeNodeEvent(ExecutionEvent(payload=modified_request)))
1251
1288
  return finalized_value
1252
1289
 
@@ -1257,6 +1294,8 @@ class NodeManager:
1257
1294
  # make debugger use friendly.
1258
1295
  def on_get_all_node_info_request(self, request: GetAllNodeInfoRequest) -> ResultPayload: # noqa: C901, PLR0911, PLR0915
1259
1296
  node_name = request.node_name
1297
+ node = None
1298
+
1260
1299
  # Get from the current context.
1261
1300
  if node_name is None:
1262
1301
  if not GriptapeNodes.ContextManager().has_current_node():
@@ -1264,18 +1303,19 @@ class NodeManager:
1264
1303
  logger.error(details)
1265
1304
  return GetAllNodeInfoResultFailure()
1266
1305
 
1267
- node_name = GriptapeNodes.ContextManager().get_current_node_name()
1306
+ node = GriptapeNodes.ContextManager().get_current_node()
1307
+ node_name = node.name
1268
1308
 
1269
1309
  # Does this node exist?
1270
- obj_mgr = GriptapeNodes.ObjectManager()
1271
-
1272
- node = obj_mgr.attempt_get_object_by_name_as_type(node_name, BaseNode)
1273
1310
  if node is None:
1274
- details = f"Attempted to get all info for Node named '{node_name}', but no such Node was found."
1275
- logger.error(details)
1311
+ obj_mgr = GriptapeNodes.ObjectManager()
1312
+ node = obj_mgr.attempt_get_object_by_name_as_type(node_name, BaseNode)
1313
+ if node is None:
1314
+ details = f"Attempted to get all info for Node named '{node_name}', but no such Node was found."
1315
+ logger.error(details)
1276
1316
 
1277
- result = GetAllNodeInfoResultFailure()
1278
- return result
1317
+ result = GetAllNodeInfoResultFailure()
1318
+ return result
1279
1319
 
1280
1320
  get_metadata_request = GetNodeMetadataRequest(node_name=node_name)
1281
1321
  get_metadata_result = self.on_get_node_metadata_request(get_metadata_request)
@@ -1350,20 +1390,26 @@ class NodeManager:
1350
1390
 
1351
1391
  def on_get_compatible_parameters_request(self, request: GetCompatibleParametersRequest) -> ResultPayload: # noqa: C901, PLR0911, PLR0912, PLR0915
1352
1392
  node_name = request.node_name
1393
+ node = None
1394
+
1353
1395
  if node_name is None:
1354
1396
  if not GriptapeNodes.ContextManager().has_current_node():
1355
1397
  details = "Attempted to get compatible parameters for node, but no current node was found."
1356
1398
  logger.error(details)
1357
1399
  return GetCompatibleParametersResultFailure()
1358
- node_name = GriptapeNodes.ContextManager().get_current_node_name()
1400
+ node = GriptapeNodes.ContextManager().get_current_node()
1401
+ node_name = node.name
1359
1402
 
1360
1403
  # Vet the node
1361
- try:
1362
- node = self.get_node_by_name(node_name)
1363
- except ValueError as err:
1364
- details = f"Attempted to get compatible parameters for node '{node_name}', but that node does not exist. Error: {err}."
1365
- logger.error(details)
1366
- return GetCompatibleParametersResultFailure()
1404
+ if node is None:
1405
+ obj_mgr = GriptapeNodes.ObjectManager()
1406
+ node = obj_mgr.attempt_get_object_by_name_as_type(node_name, BaseNode)
1407
+ if node is None:
1408
+ details = (
1409
+ f"Attempted to get compatible parameters for node '{node_name}', but that node does not exist."
1410
+ )
1411
+ logger.error(details)
1412
+ return GetCompatibleParametersResultFailure()
1367
1413
 
1368
1414
  # Vet the parameter.
1369
1415
  request_param = node.get_parameter_by_name(request.parameter_name)
@@ -1579,23 +1625,27 @@ class NodeManager:
1579
1625
 
1580
1626
  def on_serialize_node_to_commands(self, request: SerializeNodeToCommandsRequest) -> ResultPayload: # noqa: C901, PLR0912
1581
1627
  node_name = request.node_name
1628
+ node = None
1629
+
1582
1630
  if node_name is None:
1583
- if GriptapeNodes.ContextManager().has_current_node():
1584
- node_name = GriptapeNodes.ContextManager().get_current_node_name()
1585
- else:
1631
+ if not GriptapeNodes.ContextManager().has_current_node():
1586
1632
  details = "Attempted to serialize a Node to commands from the Current Context. Failed because the Current Context is empty."
1587
1633
  logger.error(details)
1588
1634
  return SerializeNodeToCommandsResultFailure()
1635
+ node = GriptapeNodes.ContextManager().get_current_node()
1636
+ node_name = node.name
1589
1637
 
1590
1638
  # Does this node exist?
1591
- node = GriptapeNodes.ObjectManager().attempt_get_object_by_name_as_type(node_name, BaseNode)
1592
1639
  if node is None:
1593
- details = f"Attempted to serialize Node '{node_name}' to commands. Failed because no Node with that name could be found."
1594
- logger.error(details)
1595
- return SerializeNodeToCommandsResultFailure()
1640
+ obj_mgr = GriptapeNodes.ObjectManager()
1641
+ node = obj_mgr.attempt_get_object_by_name_as_type(node_name, BaseNode)
1642
+ if node is None:
1643
+ details = f"Attempted to serialize Node '{node_name}' to commands. Failed because no Node with that name could be found."
1644
+ logger.error(details)
1645
+ return SerializeNodeToCommandsResultFailure()
1596
1646
 
1597
1647
  # This is our current dude.
1598
- with GriptapeNodes.ContextManager().node(node_name=node_name):
1648
+ with GriptapeNodes.ContextManager().node(node=node):
1599
1649
  # Get the library and version details.
1600
1650
  library_used = node.metadata["library"]
1601
1651
  # Get the library metadata so we can get the version.
@@ -1614,7 +1664,7 @@ class NodeManager:
1614
1664
  node_type=node.__class__.__name__,
1615
1665
  node_name=node_name,
1616
1666
  specific_library_name=library_details.library_name,
1617
- metadata=node.metadata.copy(),
1667
+ metadata=copy.deepcopy(node.metadata),
1618
1668
  # If it is actively resolving, mark as unresolved.
1619
1669
  resolution=node.state.value,
1620
1670
  )
@@ -1684,7 +1734,12 @@ class NodeManager:
1684
1734
 
1685
1735
  # Adopt the newly-created node as our current context.
1686
1736
  node_name = create_node_result.node_name
1687
- with GriptapeNodes.ContextManager().node(node_name=node_name):
1737
+ node = GriptapeNodes.ObjectManager().attempt_get_object_by_name_as_type(node_name, BaseNode)
1738
+ if node is None:
1739
+ details = f"Attempted to deserialize a serialized set of Node Creation commands. Failed to get node '{node_name}'."
1740
+ logger.error(details)
1741
+ return DeserializeNodeFromCommandsResultFailure()
1742
+ with GriptapeNodes.ContextManager().node(node=node):
1688
1743
  for element_command in request.serialized_node_commands.element_modification_commands:
1689
1744
  if isinstance(
1690
1745
  element_command, (AlterParameterDetailsRequest, AddParameterToNodeRequest)
@@ -1704,9 +1759,8 @@ class NodeManager:
1704
1759
  self, request: SerializeSelectedNodesToCommandsRequest
1705
1760
  ) -> ResultPayload:
1706
1761
  """This will take the selected nodes in the Object manager and serialize them into commands."""
1762
+ # These have already been sorted by the time they were selected.
1707
1763
  nodes_to_serialize = request.nodes_to_serialize
1708
- # Sorts tuples in order based on the timestamp
1709
- sorted_nodes = sorted(nodes_to_serialize, key=lambda x: datetime.fromisoformat(x[1]))
1710
1764
  # This is node_uuid to the serialization command.
1711
1765
  node_commands = {}
1712
1766
  # Node Name to UUID
@@ -1718,8 +1772,8 @@ class NodeManager:
1718
1772
  unique_uuid_to_values = {}
1719
1773
  # And track how values map into that map.
1720
1774
  serialized_parameter_value_tracker = SerializedParameterValueTracker()
1721
- selected_node_names = [values[0] for values in sorted_nodes]
1722
- for node_name, _ in sorted_nodes:
1775
+ selected_node_names = [values[0] for values in nodes_to_serialize]
1776
+ for node_name, _ in nodes_to_serialize:
1723
1777
  result = self.on_serialize_node_to_commands(
1724
1778
  SerializeNodeToCommandsRequest(
1725
1779
  node_name=node_name,
@@ -1774,16 +1828,29 @@ class NodeManager:
1774
1828
  GriptapeNodes.ContextManager()._clipboard.parameter_uuid_to_values = unique_uuid_to_values
1775
1829
  return SerializeSelectedNodesToCommandsResultSuccess(final_result)
1776
1830
 
1777
- def on_deserialize_selected_nodes_from_commands(
1831
+ def on_deserialize_selected_nodes_from_commands( # noqa: C901, PLR0912
1778
1832
  self,
1779
- request: DeserializeSelectedNodesFromCommandsRequest, # noqa: ARG002
1833
+ request: DeserializeSelectedNodesFromCommandsRequest,
1780
1834
  ) -> ResultPayload:
1781
1835
  commands = GriptapeNodes.ContextManager()._clipboard.node_commands
1782
1836
  if commands is None:
1783
1837
  return DeserializeSelectedNodesFromCommandsResultFailure()
1784
1838
  connections = commands.serialized_connection_commands
1785
1839
  node_uuid_to_name = {}
1786
- for node_command in commands.serialized_node_commands:
1840
+ # Enumerate because positions is in the same order as the node commands.
1841
+ for i, node_command in enumerate(commands.serialized_node_commands):
1842
+ # Create a deepcopy of the metadata so the nodes don't all share the same position.
1843
+ node_command.create_node_command.metadata = copy.deepcopy(node_command.create_node_command.metadata)
1844
+ if request.positions is not None and len(request.positions) > i:
1845
+ if node_command.create_node_command.metadata is None:
1846
+ node_command.create_node_command.metadata = {
1847
+ "position": {"x": request.positions[i][0], "y": request.positions[i][1]}
1848
+ }
1849
+ else:
1850
+ node_command.create_node_command.metadata["position"] = {
1851
+ "x": request.positions[i][0],
1852
+ "y": request.positions[i][1],
1853
+ }
1787
1854
  result = self.on_deserialize_node_from_commands(
1788
1855
  DeserializeNodeFromCommandsRequest(serialized_node_commands=node_command)
1789
1856
  )
@@ -1791,7 +1858,11 @@ class NodeManager:
1791
1858
  logger.error("Attempted to deserialize node but ran into an error on node serialization.")
1792
1859
  return DeserializeSelectedNodesFromCommandsResultFailure()
1793
1860
  node_uuid_to_name[node_command.node_uuid] = result.node_name
1794
- with GriptapeNodes.ContextManager().node(result.node_name):
1861
+ node = GriptapeNodes.ObjectManager().attempt_get_object_by_name_as_type(result.node_name, BaseNode)
1862
+ if node is None:
1863
+ logger.error("Attempted to deserialize node but ran into an error on node serialization.")
1864
+ return DeserializeSelectedNodesFromCommandsResultFailure()
1865
+ with GriptapeNodes.ContextManager().node(node=node):
1795
1866
  parameter_commands = commands.set_parameter_value_commands[node_command.node_uuid]
1796
1867
  for parameter_command in parameter_commands:
1797
1868
  param_request = parameter_command.set_parameter_value_command
@@ -1804,7 +1875,7 @@ class NodeManager:
1804
1875
  # Using try-except-pass instead of contextlib.suppress because it's clearer.
1805
1876
  try: # noqa: SIM105
1806
1877
  # If we're pasting multiple times - we need to create a new copy for each paste so they don't all have the same reference.
1807
- value = value.copy()
1878
+ value = copy.deepcopy(value)
1808
1879
  except Exception: # noqa: S110
1809
1880
  pass
1810
1881
  param_request.value = value
@@ -1836,12 +1907,12 @@ class NodeManager:
1836
1907
  details = "Failed to serialized selected nodes."
1837
1908
  logger.error(details)
1838
1909
  return DuplicateSelectedNodesResultFailure()
1839
- GriptapeNodes.handle_request(DeserializeSelectedNodesFromCommandsRequest())
1840
- if not result.succeeded():
1910
+ result = GriptapeNodes.handle_request(DeserializeSelectedNodesFromCommandsRequest(positions=None))
1911
+ if not isinstance(result, DeserializeSelectedNodesFromCommandsResultSuccess):
1841
1912
  details = "Failed to deserialize selected nodes."
1842
1913
  logger.error(details)
1843
1914
  return DuplicateSelectedNodesResultFailure()
1844
- return DuplicateSelectedNodesResultSuccess()
1915
+ return DuplicateSelectedNodesResultSuccess(result.node_names)
1845
1916
 
1846
1917
  @staticmethod
1847
1918
  def _manage_alter_details(parameter: Parameter, base_node_obj: BaseNode) -> dict:
@@ -1894,9 +1965,9 @@ class NodeManager:
1894
1965
  # The value should be serialized. Add it to the map of uniques.
1895
1966
  unique_uuid = SerializedNodeCommands.UniqueParameterValueUUID(str(uuid4()))
1896
1967
  try:
1897
- unique_parameter_uuid_to_values[unique_uuid] = value.copy()
1968
+ unique_parameter_uuid_to_values[unique_uuid] = copy.deepcopy(value)
1898
1969
  except Exception:
1899
- details = f"Attempted to serialize parameter '{parameter_name}` on node '{node_name}'. The parameter value could not be copied. It will be serialized by value. If problems arise from this, ensure the type '{type(value)}' properly implements copy()."
1970
+ details = f"Attempted to serialize parameter '{parameter_name}` on node '{node_name}'. The parameter value could not be copied. It will be serialized by value. If problems arise from this, ensure the type '{type(value)}' works with copy.deepcopy()."
1900
1971
  logger.warning(details)
1901
1972
  unique_parameter_uuid_to_values[unique_uuid] = value
1902
1973
  serialized_parameter_value_tracker.add_as_serializable(value_id, unique_uuid)