griptape-nodes 0.65.1__py3-none-any.whl → 0.65.2__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/common/node_executor.py +14 -14
- griptape_nodes/exe_types/node_groups/__init__.py +6 -0
- griptape_nodes/exe_types/node_groups/base_node_group.py +31 -0
- griptape_nodes/exe_types/node_groups/subflow_node_group.py +826 -0
- griptape_nodes/exe_types/node_types.py +0 -805
- griptape_nodes/machines/control_flow.py +4 -4
- griptape_nodes/node_library/library_registry.py +1 -0
- griptape_nodes/node_library/workflow_registry.py +1 -1
- griptape_nodes/retained_mode/events/flow_events.py +1 -1
- griptape_nodes/retained_mode/events/node_events.py +11 -77
- griptape_nodes/retained_mode/managers/flow_manager.py +72 -79
- griptape_nodes/retained_mode/managers/node_manager.py +113 -193
- griptape_nodes/retained_mode/managers/workflow_manager.py +5 -8
- griptape_nodes/version_compatibility/versions/v0_63_8/deprecated_nodegroup_parameters.py +2 -2
- {griptape_nodes-0.65.1.dist-info → griptape_nodes-0.65.2.dist-info}/METADATA +1 -1
- {griptape_nodes-0.65.1.dist-info → griptape_nodes-0.65.2.dist-info}/RECORD +18 -15
- {griptape_nodes-0.65.1.dist-info → griptape_nodes-0.65.2.dist-info}/WHEEL +1 -1
- {griptape_nodes-0.65.1.dist-info → griptape_nodes-0.65.2.dist-info}/entry_points.txt +0 -0
|
@@ -15,13 +15,13 @@ from griptape_nodes.exe_types.base_iterative_nodes import (
|
|
|
15
15
|
BaseIterativeStartNode,
|
|
16
16
|
)
|
|
17
17
|
from griptape_nodes.exe_types.core_types import ParameterTypeBuiltin
|
|
18
|
+
from griptape_nodes.exe_types.node_groups import SubflowNodeGroup
|
|
18
19
|
from griptape_nodes.exe_types.node_types import (
|
|
19
20
|
CONTROL_INPUT_PARAMETER,
|
|
20
21
|
LOCAL_EXECUTION,
|
|
21
22
|
PRIVATE_EXECUTION,
|
|
22
23
|
BaseNode,
|
|
23
24
|
EndNode,
|
|
24
|
-
NodeGroupNode,
|
|
25
25
|
NodeResolutionState,
|
|
26
26
|
StartNode,
|
|
27
27
|
)
|
|
@@ -197,7 +197,7 @@ class NodeExecutor:
|
|
|
197
197
|
node: The BaseNode to execute
|
|
198
198
|
library_name: The library that the execute method should come from.
|
|
199
199
|
"""
|
|
200
|
-
if isinstance(node,
|
|
200
|
+
if isinstance(node, SubflowNodeGroup):
|
|
201
201
|
execution_type = node.get_parameter_value(node.execution_environment.name)
|
|
202
202
|
if execution_type == LOCAL_EXECUTION:
|
|
203
203
|
# Just execute the node normally! This means we aren't doing any special packaging.
|
|
@@ -216,7 +216,7 @@ class NodeExecutor:
|
|
|
216
216
|
await self.handle_loop_execution(node)
|
|
217
217
|
return
|
|
218
218
|
|
|
219
|
-
# We default to local execution if it is not a
|
|
219
|
+
# We default to local execution if it is not a SubflowNodeGroup or BaseIterativeEndNode!
|
|
220
220
|
await node.aprocess()
|
|
221
221
|
|
|
222
222
|
async def _execute_and_apply_workflow(
|
|
@@ -414,8 +414,8 @@ class NodeExecutor:
|
|
|
414
414
|
workflow_start_end_nodes = await self._get_workflow_start_end_nodes(library)
|
|
415
415
|
|
|
416
416
|
sanitized_library_name = library_name.replace(" ", "_")
|
|
417
|
-
# If we are packaging a
|
|
418
|
-
if isinstance(node,
|
|
417
|
+
# If we are packaging a SubflowNodeGroup, that means that we are packaging multiple nodes together, so we have to get the list of nodes from the group node.
|
|
418
|
+
if isinstance(node, SubflowNodeGroup):
|
|
419
419
|
node_names = list(node.get_all_nodes().keys())
|
|
420
420
|
else:
|
|
421
421
|
# Otherwise, it's a list of one node!
|
|
@@ -424,8 +424,8 @@ class NodeExecutor:
|
|
|
424
424
|
if len(node_names) == 0:
|
|
425
425
|
return None
|
|
426
426
|
|
|
427
|
-
# Pass node_group_name if we're packaging a
|
|
428
|
-
node_group_name = node.name if isinstance(node,
|
|
427
|
+
# Pass node_group_name if we're packaging a SubflowNodeGroup
|
|
428
|
+
node_group_name = node.name if isinstance(node, SubflowNodeGroup) else None
|
|
429
429
|
|
|
430
430
|
request = PackageNodesAsSerializedFlowRequest(
|
|
431
431
|
node_names=node_names,
|
|
@@ -618,7 +618,7 @@ class NodeExecutor:
|
|
|
618
618
|
if len(all_nodes) == 1:
|
|
619
619
|
node_inside = all_nodes.pop()
|
|
620
620
|
node_obj = node_manager.get_node_by_name(node_inside)
|
|
621
|
-
if isinstance(node_obj,
|
|
621
|
+
if isinstance(node_obj, SubflowNodeGroup):
|
|
622
622
|
execution_type = node_obj.get_parameter_value(node_obj.execution_environment.name)
|
|
623
623
|
all_nodes.update(node_obj.get_all_nodes())
|
|
624
624
|
node_group_name = node_obj.name
|
|
@@ -1327,7 +1327,7 @@ class NodeExecutor:
|
|
|
1327
1327
|
msg = f"Failed to get node {target_node_name} for connection {conn} from start node {start_node.name}. Can't get parameter value iterations."
|
|
1328
1328
|
logger.error(msg)
|
|
1329
1329
|
raise RuntimeError(msg) # noqa: B904
|
|
1330
|
-
if isinstance(target_node,
|
|
1330
|
+
if isinstance(target_node, SubflowNodeGroup):
|
|
1331
1331
|
# Get connections from this proxy parameter to find the actual internal target
|
|
1332
1332
|
connections = flow_manager.get_connections()
|
|
1333
1333
|
proxy_param = target_node.get_parameter_by_name(target_param_name)
|
|
@@ -1505,7 +1505,7 @@ class NodeExecutor:
|
|
|
1505
1505
|
source_node = node_manager.get_node_by_name(source_node_name)
|
|
1506
1506
|
except ValueError:
|
|
1507
1507
|
continue
|
|
1508
|
-
if isinstance(source_node,
|
|
1508
|
+
if isinstance(source_node, SubflowNodeGroup):
|
|
1509
1509
|
# Get connections to this proxy parameter to find the actual internal source
|
|
1510
1510
|
connections = flow_manager.get_connections()
|
|
1511
1511
|
proxy_param = source_node.get_parameter_by_name(source_param_name)
|
|
@@ -2434,7 +2434,7 @@ class NodeExecutor:
|
|
|
2434
2434
|
|
|
2435
2435
|
Sets parameter values on the node and updates parameter_output_values dictionary.
|
|
2436
2436
|
Uses parameter_name_mappings from package_result to map packaged parameters back to original nodes.
|
|
2437
|
-
Works for both single-node and multi-node packages (
|
|
2437
|
+
Works for both single-node and multi-node packages (SubflowNodeGroup).
|
|
2438
2438
|
"""
|
|
2439
2439
|
# If the packaged flow fails, the End Flow Node in the library published workflow will have entered from 'failed'
|
|
2440
2440
|
if "failed" in parameter_output_values and parameter_output_values["failed"] == CONTROL_INPUT_PARAMETER:
|
|
@@ -2455,11 +2455,11 @@ class NodeExecutor:
|
|
|
2455
2455
|
target_node_name = original_node_param.node_name
|
|
2456
2456
|
target_param_name = original_node_param.parameter_name
|
|
2457
2457
|
|
|
2458
|
-
# Determine the target node - if this is a
|
|
2459
|
-
if isinstance(node,
|
|
2458
|
+
# Determine the target node - if this is a SubflowNodeGroup, look up the child node
|
|
2459
|
+
if isinstance(node, SubflowNodeGroup):
|
|
2460
2460
|
if target_node_name not in node.nodes:
|
|
2461
2461
|
logger.warning(
|
|
2462
|
-
"Node '%s' not found in
|
|
2462
|
+
"Node '%s' not found in SubflowNodeGroup '%s', skipping value application",
|
|
2463
2463
|
target_node_name,
|
|
2464
2464
|
node.name,
|
|
2465
2465
|
)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from griptape_nodes.exe_types.node_types import BaseNode
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class BaseNodeGroup(BaseNode):
|
|
9
|
+
"""Base class for node group implementations.
|
|
10
|
+
|
|
11
|
+
Node groups are collections of nodes that are treated as a single unit.
|
|
12
|
+
This base class provides the core functionality for managing a group of
|
|
13
|
+
nodes, which may itself include other node groups.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
nodes: dict[str, BaseNode]
|
|
17
|
+
|
|
18
|
+
def __init__(
|
|
19
|
+
self,
|
|
20
|
+
name: str,
|
|
21
|
+
metadata: dict[Any, Any] | None = None,
|
|
22
|
+
) -> None:
|
|
23
|
+
"""Initialize the node group base.
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
name: The name of this node group
|
|
27
|
+
metadata: Optional metadata dictionary
|
|
28
|
+
"""
|
|
29
|
+
super().__init__(name, metadata)
|
|
30
|
+
self.nodes = {}
|
|
31
|
+
self.metadata["is_node_group"] = True
|