griptape-nodes 0.64.11__py3-none-any.whl → 0.65.1__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.
- griptape_nodes/app/app.py +25 -5
- griptape_nodes/cli/commands/init.py +65 -54
- griptape_nodes/cli/commands/libraries.py +92 -85
- griptape_nodes/cli/commands/self.py +121 -0
- griptape_nodes/common/node_executor.py +2142 -101
- griptape_nodes/exe_types/base_iterative_nodes.py +1004 -0
- griptape_nodes/exe_types/connections.py +114 -19
- griptape_nodes/exe_types/core_types.py +225 -7
- griptape_nodes/exe_types/flow.py +3 -3
- griptape_nodes/exe_types/node_types.py +681 -225
- griptape_nodes/exe_types/param_components/README.md +414 -0
- griptape_nodes/exe_types/param_components/api_key_provider_parameter.py +200 -0
- griptape_nodes/exe_types/param_components/huggingface/huggingface_model_parameter.py +2 -0
- griptape_nodes/exe_types/param_components/huggingface/huggingface_repo_file_parameter.py +79 -5
- griptape_nodes/exe_types/param_types/parameter_button.py +443 -0
- griptape_nodes/machines/control_flow.py +84 -38
- griptape_nodes/machines/dag_builder.py +148 -70
- griptape_nodes/machines/parallel_resolution.py +61 -35
- griptape_nodes/machines/sequential_resolution.py +11 -113
- griptape_nodes/retained_mode/events/app_events.py +1 -0
- griptape_nodes/retained_mode/events/base_events.py +16 -13
- griptape_nodes/retained_mode/events/connection_events.py +3 -0
- griptape_nodes/retained_mode/events/execution_events.py +35 -0
- griptape_nodes/retained_mode/events/flow_events.py +15 -2
- griptape_nodes/retained_mode/events/library_events.py +347 -0
- griptape_nodes/retained_mode/events/node_events.py +48 -0
- griptape_nodes/retained_mode/events/os_events.py +86 -3
- griptape_nodes/retained_mode/events/project_events.py +15 -1
- griptape_nodes/retained_mode/events/workflow_events.py +48 -1
- griptape_nodes/retained_mode/griptape_nodes.py +6 -2
- griptape_nodes/retained_mode/managers/config_manager.py +10 -8
- griptape_nodes/retained_mode/managers/event_manager.py +168 -0
- griptape_nodes/retained_mode/managers/fitness_problems/libraries/__init__.py +2 -0
- griptape_nodes/retained_mode/managers/fitness_problems/libraries/old_xdg_location_warning_problem.py +43 -0
- griptape_nodes/retained_mode/managers/flow_manager.py +664 -123
- griptape_nodes/retained_mode/managers/library_manager.py +1142 -138
- griptape_nodes/retained_mode/managers/model_manager.py +2 -3
- griptape_nodes/retained_mode/managers/node_manager.py +148 -25
- griptape_nodes/retained_mode/managers/object_manager.py +3 -1
- griptape_nodes/retained_mode/managers/operation_manager.py +3 -1
- griptape_nodes/retained_mode/managers/os_manager.py +1158 -122
- griptape_nodes/retained_mode/managers/secrets_manager.py +2 -3
- griptape_nodes/retained_mode/managers/settings.py +21 -1
- griptape_nodes/retained_mode/managers/sync_manager.py +2 -3
- griptape_nodes/retained_mode/managers/workflow_manager.py +358 -104
- griptape_nodes/retained_mode/retained_mode.py +3 -3
- griptape_nodes/traits/button.py +44 -2
- griptape_nodes/traits/file_system_picker.py +2 -2
- griptape_nodes/utils/file_utils.py +101 -0
- griptape_nodes/utils/git_utils.py +1236 -0
- griptape_nodes/utils/library_utils.py +122 -0
- {griptape_nodes-0.64.11.dist-info → griptape_nodes-0.65.1.dist-info}/METADATA +2 -1
- {griptape_nodes-0.64.11.dist-info → griptape_nodes-0.65.1.dist-info}/RECORD +55 -47
- {griptape_nodes-0.64.11.dist-info → griptape_nodes-0.65.1.dist-info}/WHEEL +1 -1
- {griptape_nodes-0.64.11.dist-info → griptape_nodes-0.65.1.dist-info}/entry_points.txt +0 -0
|
@@ -41,6 +41,7 @@ from griptape_nodes.retained_mode.events.model_events import (
|
|
|
41
41
|
SearchModelsResultSuccess,
|
|
42
42
|
)
|
|
43
43
|
from griptape_nodes.retained_mode.griptape_nodes import GriptapeNodes
|
|
44
|
+
from griptape_nodes.retained_mode.managers.settings import MODELS_TO_DOWNLOAD_KEY
|
|
44
45
|
from griptape_nodes.utils.async_utils import cancel_subprocess
|
|
45
46
|
|
|
46
47
|
if TYPE_CHECKING:
|
|
@@ -675,9 +676,7 @@ class ModelManager:
|
|
|
675
676
|
"""
|
|
676
677
|
# Get models to download from configuration
|
|
677
678
|
config_manager = GriptapeNodes.ConfigManager()
|
|
678
|
-
models_to_download = config_manager.get_config_value(
|
|
679
|
-
"app_events.on_app_initialization_complete.models_to_download", default=[]
|
|
680
|
-
)
|
|
679
|
+
models_to_download = config_manager.get_config_value(MODELS_TO_DOWNLOAD_KEY, default=[])
|
|
681
680
|
|
|
682
681
|
# Find unfinished downloads to resume
|
|
683
682
|
unfinished_models = await asyncio.to_thread(self._find_unfinished_downloads)
|
|
@@ -4,6 +4,10 @@ import pickle
|
|
|
4
4
|
from typing import Any, NamedTuple, cast
|
|
5
5
|
from uuid import uuid4
|
|
6
6
|
|
|
7
|
+
from griptape_nodes.exe_types.base_iterative_nodes import (
|
|
8
|
+
BaseIterativeEndNode,
|
|
9
|
+
BaseIterativeStartNode,
|
|
10
|
+
)
|
|
7
11
|
from griptape_nodes.exe_types.core_types import (
|
|
8
12
|
BaseNodeElement,
|
|
9
13
|
Parameter,
|
|
@@ -16,13 +20,14 @@ from griptape_nodes.exe_types.core_types import (
|
|
|
16
20
|
)
|
|
17
21
|
from griptape_nodes.exe_types.flow import ControlFlow
|
|
18
22
|
from griptape_nodes.exe_types.node_types import (
|
|
23
|
+
LOCAL_EXECUTION,
|
|
24
|
+
PRIVATE_EXECUTION,
|
|
19
25
|
BaseNode,
|
|
20
|
-
EndLoopNode,
|
|
21
26
|
ErrorProxyNode,
|
|
22
27
|
NodeDependencies,
|
|
23
28
|
NodeGroupNode,
|
|
24
29
|
NodeResolutionState,
|
|
25
|
-
|
|
30
|
+
TransformedParameterValue,
|
|
26
31
|
)
|
|
27
32
|
from griptape_nodes.exe_types.type_validator import TypeValidator
|
|
28
33
|
from griptape_nodes.machines.sequential_resolution import SequentialResolutionMachine
|
|
@@ -105,6 +110,7 @@ from griptape_nodes.retained_mode.events.node_events import (
|
|
|
105
110
|
ListParametersOnNodeRequest,
|
|
106
111
|
ListParametersOnNodeResultFailure,
|
|
107
112
|
ListParametersOnNodeResultSuccess,
|
|
113
|
+
MoveNodeToNewFlowRequest,
|
|
108
114
|
RemoveNodeFromNodeGroupRequest,
|
|
109
115
|
RemoveNodeFromNodeGroupResultFailure,
|
|
110
116
|
RemoveNodeFromNodeGroupResultSuccess,
|
|
@@ -221,6 +227,7 @@ class NodeManager:
|
|
|
221
227
|
)
|
|
222
228
|
event_manager.assign_manager_to_request_type(DeleteNodeGroupRequest, self.on_delete_node_group_request)
|
|
223
229
|
event_manager.assign_manager_to_request_type(DeleteNodeRequest, self.on_delete_node_request)
|
|
230
|
+
event_manager.assign_manager_to_request_type(MoveNodeToNewFlowRequest, self.on_move_node_to_new_flow_request)
|
|
224
231
|
event_manager.assign_manager_to_request_type(
|
|
225
232
|
GetNodeResolutionStateRequest, self.on_get_node_resolution_state_request
|
|
226
233
|
)
|
|
@@ -438,7 +445,7 @@ class NodeManager:
|
|
|
438
445
|
details = f"{details}. WARNING: Had to rename from original node name requested '{request.node_name}' as an object with this name already existed."
|
|
439
446
|
|
|
440
447
|
# Special handling for paired classes (e.g., create a Start node and it automatically creates a corresponding End node already connected).
|
|
441
|
-
if isinstance(node,
|
|
448
|
+
if isinstance(node, BaseIterativeStartNode) and not request.initial_setup:
|
|
442
449
|
# If it's StartLoop, create an EndLoop and connect it to the StartLoop.
|
|
443
450
|
# Get the class name of the node
|
|
444
451
|
node_class_name = node.__class__.__name__
|
|
@@ -477,7 +484,7 @@ class NodeManager:
|
|
|
477
484
|
)
|
|
478
485
|
)
|
|
479
486
|
end_node = self.get_node_by_name(end_loop.node_name)
|
|
480
|
-
if not isinstance(end_node,
|
|
487
|
+
if not isinstance(end_node, BaseIterativeEndNode):
|
|
481
488
|
msg = f"Attempted to create a paried set of nodes for Node '{final_node_name}'. Failed because paired node '{end_loop.node_name}' was not a proper EndLoop instance. The corresponding node will have to be created by hand and attached manually."
|
|
482
489
|
logger.error(
|
|
483
490
|
msg
|
|
@@ -533,25 +540,25 @@ class NodeManager:
|
|
|
533
540
|
except Exception as err:
|
|
534
541
|
details = f"Could not create NodeGroup '{final_node_group_name}': {err}"
|
|
535
542
|
return CreateNodeGroupResultFailure(result_details=details)
|
|
536
|
-
|
|
543
|
+
# Add node to the flow so it is discoverable.
|
|
544
|
+
flow.add_node(node_group)
|
|
545
|
+
obj_mgr.add_object_by_name(node_group.name, node_group)
|
|
546
|
+
self._name_to_parent_flow_name[node_group.name] = flow_name
|
|
537
547
|
if request.node_names_to_add:
|
|
538
548
|
nodes_to_add = []
|
|
539
549
|
for node_name in request.node_names_to_add:
|
|
540
550
|
try:
|
|
541
551
|
node = self.get_node_by_name(node_name)
|
|
552
|
+
nodes_to_add.append(node)
|
|
542
553
|
except KeyError:
|
|
543
554
|
details = f"Attempted to add node '{node_name}' to NodeGroup '{final_node_group_name}'. Failed because node was not found."
|
|
544
|
-
|
|
545
|
-
nodes_to_add.append(node)
|
|
555
|
+
logger.warning(details)
|
|
546
556
|
# Add Nodes manually here, so we don't have to add the NodeGroup and remove it if it fails.
|
|
547
557
|
try:
|
|
548
558
|
node_group.add_nodes_to_group(nodes_to_add)
|
|
549
|
-
except Exception:
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
flow.add_node(node_group)
|
|
553
|
-
obj_mgr.add_object_by_name(node_group.name, node_group)
|
|
554
|
-
self._name_to_parent_flow_name[node_group.name] = flow_name
|
|
559
|
+
except Exception as err:
|
|
560
|
+
msg = f"Failed to add nodes to NodeGroup '{final_node_group_name}': {err}"
|
|
561
|
+
logger.warning(msg)
|
|
555
562
|
if request.flow_name is None:
|
|
556
563
|
details = (
|
|
557
564
|
f"Successfully created NodeGroup '{final_node_group_name}' in the Current Context (Flow '{flow_name}')"
|
|
@@ -766,6 +773,9 @@ class NodeManager:
|
|
|
766
773
|
details = f"Attempted to delete NodeGroup '{request.node_group_name}'. Failed to remove nodes from group: {err}"
|
|
767
774
|
return DeleteNodeGroupResultFailure(result_details=details)
|
|
768
775
|
|
|
776
|
+
# Get the subflow name before deleting the NodeGroup
|
|
777
|
+
subflow_name = node_group.metadata.get("subflow_name")
|
|
778
|
+
|
|
769
779
|
# Now delete the NodeGroup node itself
|
|
770
780
|
delete_node_request = DeleteNodeRequest(node_name=request.node_group_name)
|
|
771
781
|
delete_result = self.on_delete_node_request(delete_node_request)
|
|
@@ -774,6 +784,17 @@ class NodeManager:
|
|
|
774
784
|
details = f"Attempted to delete NodeGroup '{request.node_group_name}'. Failed to delete the NodeGroup node: {delete_result.result_details}"
|
|
775
785
|
return DeleteNodeGroupResultFailure(result_details=details)
|
|
776
786
|
|
|
787
|
+
# Delete the subflow last if it exists
|
|
788
|
+
if subflow_name is not None:
|
|
789
|
+
from griptape_nodes.retained_mode.events.flow_events import DeleteFlowRequest
|
|
790
|
+
|
|
791
|
+
delete_flow_request = DeleteFlowRequest(flow_name=subflow_name)
|
|
792
|
+
delete_flow_result = GriptapeNodes.handle_request(delete_flow_request)
|
|
793
|
+
|
|
794
|
+
if delete_flow_result.failed():
|
|
795
|
+
details = f"Attempted to delete NodeGroup '{request.node_group_name}'. Failed to delete subflow '{subflow_name}': {delete_flow_result.result_details}"
|
|
796
|
+
return DeleteNodeGroupResultFailure(result_details=details)
|
|
797
|
+
|
|
777
798
|
details = f"Successfully deleted NodeGroup '{request.node_group_name}'"
|
|
778
799
|
return DeleteNodeGroupResultSuccess(result_details=ResultDetails(message=details, level=logging.DEBUG))
|
|
779
800
|
|
|
@@ -812,7 +833,7 @@ class NodeManager:
|
|
|
812
833
|
if control_node in connected_nodes:
|
|
813
834
|
result = GriptapeNodes.handle_request(CancelFlowRequest(flow_name=parent_flow_name))
|
|
814
835
|
cancelled = True
|
|
815
|
-
if
|
|
836
|
+
if result.failed():
|
|
816
837
|
details = f"Attempted to delete a Node '{node.name}'. Failed because running flow could not cancel."
|
|
817
838
|
return DeleteNodeResultFailure(result_details=details)
|
|
818
839
|
if resolving_node_names is not None and not cancelled:
|
|
@@ -820,7 +841,7 @@ class NodeManager:
|
|
|
820
841
|
resolving_node = GriptapeNodes.ObjectManager().get_object_by_name(resolving_node_name)
|
|
821
842
|
if resolving_node in connected_nodes:
|
|
822
843
|
result = GriptapeNodes.handle_request(CancelFlowRequest(flow_name=parent_flow_name))
|
|
823
|
-
if
|
|
844
|
+
if result.failed():
|
|
824
845
|
details = f"Attempted to delete a Node '{node.name}'. Failed because running flow could not cancel."
|
|
825
846
|
return DeleteNodeResultFailure(result_details=details)
|
|
826
847
|
break # Only need to cancel once
|
|
@@ -828,7 +849,7 @@ class NodeManager:
|
|
|
828
849
|
parent_flow.clear_execution_queue()
|
|
829
850
|
return None
|
|
830
851
|
|
|
831
|
-
def on_delete_node_request(self, request: DeleteNodeRequest) -> ResultPayload: # noqa: C901, PLR0911, PLR0912 (
|
|
852
|
+
def on_delete_node_request(self, request: DeleteNodeRequest) -> ResultPayload: # noqa: C901, PLR0911, PLR0912, PLR0915 (Complex logic, lots of edge cases)
|
|
832
853
|
node_name = request.node_name
|
|
833
854
|
node = None
|
|
834
855
|
if node_name is None:
|
|
@@ -905,6 +926,13 @@ class NodeManager:
|
|
|
905
926
|
)
|
|
906
927
|
return DeleteNodeResultFailure(result_details=details)
|
|
907
928
|
|
|
929
|
+
# Check if it's in a node group
|
|
930
|
+
if isinstance(node.parent_group, NodeGroupNode):
|
|
931
|
+
try:
|
|
932
|
+
node.parent_group.delete_nodes_from_group([node])
|
|
933
|
+
except ValueError as e:
|
|
934
|
+
details = f"Attempted to delete a Node '{node_name}'. Failed to remove it from the node group: {e}"
|
|
935
|
+
return DeleteNodeResultFailure(result_details=details)
|
|
908
936
|
# Remove from the owning Flow
|
|
909
937
|
parent_flow.remove_node(node.name)
|
|
910
938
|
|
|
@@ -919,6 +947,74 @@ class NodeManager:
|
|
|
919
947
|
details = f"Successfully deleted Node '{node_name}'."
|
|
920
948
|
return DeleteNodeResultSuccess(result_details=details)
|
|
921
949
|
|
|
950
|
+
def on_move_node_to_new_flow_request(self, request: MoveNodeToNewFlowRequest) -> ResultPayload: # noqa: PLR0911
|
|
951
|
+
"""Move a node from one flow to another flow.
|
|
952
|
+
|
|
953
|
+
Args:
|
|
954
|
+
request: MoveNodeToNewFlowRequest containing node_name, target_flow_name, source_flow_name
|
|
955
|
+
|
|
956
|
+
Returns:
|
|
957
|
+
MoveNodeToNewFlowResultSuccess or MoveNodeToNewFlowResultFailure
|
|
958
|
+
"""
|
|
959
|
+
from griptape_nodes.retained_mode.events.node_events import (
|
|
960
|
+
MoveNodeToNewFlowResultFailure,
|
|
961
|
+
MoveNodeToNewFlowResultSuccess,
|
|
962
|
+
)
|
|
963
|
+
|
|
964
|
+
node_name = request.node_name
|
|
965
|
+
if node_name is None:
|
|
966
|
+
if not GriptapeNodes.ContextManager().has_current_node():
|
|
967
|
+
details = (
|
|
968
|
+
"Attempted to move a Node from the Current Context. Failed because the Current Context is empty."
|
|
969
|
+
)
|
|
970
|
+
return MoveNodeToNewFlowResultFailure(result_details=details)
|
|
971
|
+
node = GriptapeNodes.ContextManager().get_current_node()
|
|
972
|
+
node_name = node.name
|
|
973
|
+
|
|
974
|
+
node = GriptapeNodes.ObjectManager().attempt_get_object_by_name_as_type(node_name, BaseNode)
|
|
975
|
+
if node is None:
|
|
976
|
+
details = f"Attempted to move Node '{node_name}', but no such Node was found."
|
|
977
|
+
return MoveNodeToNewFlowResultFailure(result_details=details)
|
|
978
|
+
|
|
979
|
+
if not request.target_flow_name:
|
|
980
|
+
details = f"Attempted to move Node '{node_name}'. Failed because target_flow_name is required."
|
|
981
|
+
return MoveNodeToNewFlowResultFailure(result_details=details)
|
|
982
|
+
|
|
983
|
+
source_flow_name = request.source_flow_name
|
|
984
|
+
if source_flow_name is None:
|
|
985
|
+
if node_name not in self._name_to_parent_flow_name:
|
|
986
|
+
details = f"Attempted to move Node '{node_name}'. Failed because Node has no parent flow."
|
|
987
|
+
return MoveNodeToNewFlowResultFailure(result_details=details)
|
|
988
|
+
source_flow_name = self._name_to_parent_flow_name[node_name]
|
|
989
|
+
|
|
990
|
+
try:
|
|
991
|
+
source_flow = GriptapeNodes.FlowManager().get_flow_by_name(source_flow_name)
|
|
992
|
+
except KeyError:
|
|
993
|
+
details = f"Attempted to move Node '{node_name}' from Flow '{source_flow_name}'. Failed because source flow was not found."
|
|
994
|
+
return MoveNodeToNewFlowResultFailure(result_details=details)
|
|
995
|
+
|
|
996
|
+
try:
|
|
997
|
+
target_flow = GriptapeNodes.FlowManager().get_flow_by_name(request.target_flow_name)
|
|
998
|
+
except KeyError:
|
|
999
|
+
details = f"Attempted to move Node '{node_name}' to Flow '{request.target_flow_name}'. Failed because target flow was not found."
|
|
1000
|
+
return MoveNodeToNewFlowResultFailure(result_details=details)
|
|
1001
|
+
|
|
1002
|
+
if node_name not in source_flow.nodes:
|
|
1003
|
+
details = f"Attempted to move Node '{node_name}' from Flow '{source_flow_name}'. Failed because Node is not in source flow."
|
|
1004
|
+
return MoveNodeToNewFlowResultFailure(result_details=details)
|
|
1005
|
+
|
|
1006
|
+
source_flow.remove_node(node_name)
|
|
1007
|
+
target_flow.add_node(node)
|
|
1008
|
+
self._name_to_parent_flow_name[node_name] = request.target_flow_name
|
|
1009
|
+
|
|
1010
|
+
details = f"Successfully moved Node '{node_name}' from Flow '{source_flow_name}' to Flow '{request.target_flow_name}'."
|
|
1011
|
+
return MoveNodeToNewFlowResultSuccess(
|
|
1012
|
+
node_name=node_name,
|
|
1013
|
+
source_flow_name=source_flow_name,
|
|
1014
|
+
target_flow_name=request.target_flow_name,
|
|
1015
|
+
result_details=details,
|
|
1016
|
+
)
|
|
1017
|
+
|
|
922
1018
|
def on_get_node_resolution_state_request(self, request: GetNodeResolutionStateRequest) -> ResultPayload:
|
|
923
1019
|
node_name = request.node_name
|
|
924
1020
|
node = None
|
|
@@ -1974,16 +2070,31 @@ class NodeManager:
|
|
|
1974
2070
|
result = SetParameterValueResultFailure(result_details=details)
|
|
1975
2071
|
return result
|
|
1976
2072
|
|
|
2073
|
+
# Store original values in temp vars before calling before_value_set
|
|
2074
|
+
parameter_value = request.value
|
|
2075
|
+
parameter_value_type = request.data_type
|
|
2076
|
+
|
|
1977
2077
|
# Call before_value_set hook (allows nodes to modify values and temporarily control settable state)
|
|
1978
2078
|
try:
|
|
1979
|
-
modified_value = node.before_value_set(parameter,
|
|
2079
|
+
modified_value = node.before_value_set(parameter, parameter_value)
|
|
1980
2080
|
if modified_value is not None:
|
|
1981
|
-
|
|
2081
|
+
# Check if it's a TransformedParameterValue (value + type)
|
|
2082
|
+
if isinstance(modified_value, TransformedParameterValue):
|
|
2083
|
+
parameter_value = modified_value.value
|
|
2084
|
+
parameter_value_type = modified_value.parameter_type
|
|
2085
|
+
else:
|
|
2086
|
+
# Just a value, no type change
|
|
2087
|
+
parameter_value = modified_value
|
|
1982
2088
|
except Exception as err:
|
|
1983
2089
|
details = f"Attempted to set parameter value for '{node_name}.{request.parameter_name}'. Failed because before_value_set hook raised exception: {err}"
|
|
1984
2090
|
result = SetParameterValueResultFailure(result_details=details)
|
|
1985
2091
|
return result
|
|
1986
2092
|
|
|
2093
|
+
# Update request with potentially transformed values
|
|
2094
|
+
request.value = parameter_value
|
|
2095
|
+
if parameter_value_type is not None:
|
|
2096
|
+
request.data_type = parameter_value_type
|
|
2097
|
+
|
|
1987
2098
|
# Validate that parameters can be set at all (note: we want the value to be set during initial setup, but not after)
|
|
1988
2099
|
# We skip this if it's a passthru from a connection or if we're on initial setup; those always trump settable.
|
|
1989
2100
|
# This check comes *AFTER* before_value_set() to allow nodes to temporarily modify settable state
|
|
@@ -1991,7 +2102,7 @@ class NodeManager:
|
|
|
1991
2102
|
details = f"Attempted to set parameter value for '{node_name}.{request.parameter_name}'. Failed because that Parameter was flagged as not settable."
|
|
1992
2103
|
result = SetParameterValueResultFailure(result_details=details)
|
|
1993
2104
|
return result
|
|
1994
|
-
object_type =
|
|
2105
|
+
object_type = parameter_value_type if parameter_value_type else parameter.type
|
|
1995
2106
|
# If the parameter is control type, we shouldn't check the value being set, since it's just a marker for which path to take, not a real value, and will likely be a string, which doesn't match ControlType.
|
|
1996
2107
|
if parameter.type != ParameterTypeBuiltin.CONTROL_TYPE.value and not parameter.is_incoming_type_allowed(
|
|
1997
2108
|
object_type
|
|
@@ -2357,7 +2468,7 @@ class NodeManager:
|
|
|
2357
2468
|
# Validate here.
|
|
2358
2469
|
result = self.on_validate_node_dependencies_request(ValidateNodeDependenciesRequest(node_name=node_name))
|
|
2359
2470
|
try:
|
|
2360
|
-
if
|
|
2471
|
+
if result.failed():
|
|
2361
2472
|
details = f"Failed to resolve node '{node_name}'. Flow Validation Failed"
|
|
2362
2473
|
return StartFlowResultFailure(validation_exceptions=[], result_details=details)
|
|
2363
2474
|
result = cast("ValidateNodeDependenciesResultSuccess", result)
|
|
@@ -2430,13 +2541,21 @@ class NodeManager:
|
|
|
2430
2541
|
# This is our current dude.
|
|
2431
2542
|
with GriptapeNodes.ContextManager().node(node=node):
|
|
2432
2543
|
# Handle NodeGroupNode specially - skip library lookup entirely
|
|
2544
|
+
library_used = ""
|
|
2545
|
+
lookup_metadata = False
|
|
2546
|
+
library_details = None
|
|
2433
2547
|
if isinstance(node, NodeGroupNode):
|
|
2434
2548
|
# NodeGroupNode doesn't have a library dependency
|
|
2435
|
-
|
|
2549
|
+
execution_env = node.get_parameter_value(node.execution_environment.name)
|
|
2550
|
+
if execution_env not in (LOCAL_EXECUTION, PRIVATE_EXECUTION):
|
|
2551
|
+
library_used = execution_env
|
|
2552
|
+
lookup_metadata = True
|
|
2436
2553
|
else:
|
|
2437
2554
|
# Get the library and version details for regular nodes
|
|
2438
2555
|
library_used = node.metadata["library"]
|
|
2439
|
-
|
|
2556
|
+
lookup_metadata = True
|
|
2557
|
+
# Get the library metadata so we can get the version.
|
|
2558
|
+
if lookup_metadata:
|
|
2440
2559
|
library_metadata_request = GetLibraryMetadataRequest(library=library_used)
|
|
2441
2560
|
# Call LibraryManager directly to avoid error toasts when library is unavailable (expected for ErrorProxyNode)
|
|
2442
2561
|
# Per https://github.com/griptape-ai/griptape-nodes/issues/1940
|
|
@@ -2465,10 +2584,14 @@ class NodeManager:
|
|
|
2465
2584
|
|
|
2466
2585
|
# Handle NodeGroupNode specially - emit CreateNodeGroupRequest instead
|
|
2467
2586
|
if isinstance(node, NodeGroupNode):
|
|
2587
|
+
# Remove node_names_in_group from metadata - it's redundant and will be regenerated
|
|
2588
|
+
metadata_copy = copy.deepcopy(node.metadata)
|
|
2589
|
+
metadata_copy.pop("node_names_in_group", None)
|
|
2590
|
+
|
|
2468
2591
|
create_node_request = CreateNodeGroupRequest(
|
|
2469
2592
|
node_group_name=node_name,
|
|
2470
2593
|
node_names_to_add=list(node.nodes),
|
|
2471
|
-
metadata=
|
|
2594
|
+
metadata=metadata_copy,
|
|
2472
2595
|
)
|
|
2473
2596
|
else:
|
|
2474
2597
|
# For non-NodeGroupNode, library_details should always be set
|
|
@@ -2895,7 +3018,7 @@ class NodeManager:
|
|
|
2895
3018
|
target_parameter_name=connection_command.target_parameter_name,
|
|
2896
3019
|
)
|
|
2897
3020
|
result = GriptapeNodes.handle_request(connection_request)
|
|
2898
|
-
if
|
|
3021
|
+
if result.failed():
|
|
2899
3022
|
details = f"Failed to create a connection between {connection_request.source_node_name} and {connection_request.target_node_name}"
|
|
2900
3023
|
logger.warning(details)
|
|
2901
3024
|
return DeserializeSelectedNodesFromCommandsResultSuccess(
|
|
@@ -2907,7 +3030,7 @@ class NodeManager:
|
|
|
2907
3030
|
result = GriptapeNodes.handle_request(
|
|
2908
3031
|
SerializeSelectedNodesToCommandsRequest(nodes_to_serialize=request.nodes_to_duplicate)
|
|
2909
3032
|
)
|
|
2910
|
-
if
|
|
3033
|
+
if result.failed():
|
|
2911
3034
|
details = "Failed to serialized selected nodes."
|
|
2912
3035
|
return DuplicateSelectedNodesResultFailure(result_details=details)
|
|
2913
3036
|
result = GriptapeNodes.handle_request(DeserializeSelectedNodesFromCommandsRequest(positions=request.positions))
|
|
@@ -118,7 +118,7 @@ class ObjectManager:
|
|
|
118
118
|
for flow_name in flows:
|
|
119
119
|
if GriptapeNodes.FlowManager().check_for_existing_running_flow():
|
|
120
120
|
result = await GriptapeNodes.ahandle_request(CancelFlowRequest(flow_name=flow_name))
|
|
121
|
-
if
|
|
121
|
+
if result.failed():
|
|
122
122
|
details = f"Attempted to clear all object state and delete everything. Failed because running flow '{flow_name}' could not cancel."
|
|
123
123
|
logger.error(details)
|
|
124
124
|
return ClearAllObjectStateResultFailure(result_details=details)
|
|
@@ -153,6 +153,8 @@ class ObjectManager:
|
|
|
153
153
|
|
|
154
154
|
# Clear all local workflow variables
|
|
155
155
|
GriptapeNodes.VariablesManager().on_clear_object_state()
|
|
156
|
+
# Clear all event suppression
|
|
157
|
+
GriptapeNodes.EventManager().clear_event_suppression()
|
|
156
158
|
|
|
157
159
|
details = "Successfully cleared all object state (deleted everything)."
|
|
158
160
|
return ClearAllObjectStateResultSuccess(result_details=details)
|
|
@@ -2,6 +2,8 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from typing import TYPE_CHECKING, Any, Self
|
|
4
4
|
|
|
5
|
+
from griptape_nodes.retained_mode.managers.settings import EVENTS_TO_ECHO_KEY
|
|
6
|
+
|
|
5
7
|
if TYPE_CHECKING:
|
|
6
8
|
from types import TracebackType
|
|
7
9
|
|
|
@@ -438,7 +440,7 @@ class OperationDepthManager:
|
|
|
438
440
|
self.payload_converter = PayloadConverter()
|
|
439
441
|
|
|
440
442
|
# Ask the config manager for the list of events we want echoed.
|
|
441
|
-
config_events = config_mgr.get_config_value(
|
|
443
|
+
config_events = config_mgr.get_config_value(EVENTS_TO_ECHO_KEY)
|
|
442
444
|
self.events_to_echo = set(config_events)
|
|
443
445
|
|
|
444
446
|
def __enter__(self) -> Self:
|