griptape-nodes 0.66.2__py3-none-any.whl → 0.67.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 (30) hide show
  1. griptape_nodes/common/node_executor.py +77 -0
  2. griptape_nodes/exe_types/core_types.py +28 -1
  3. griptape_nodes/exe_types/node_groups/base_iterative_node_group.py +27 -8
  4. griptape_nodes/exe_types/node_groups/base_node_group.py +64 -1
  5. griptape_nodes/exe_types/node_groups/subflow_node_group.py +0 -34
  6. griptape_nodes/exe_types/param_components/seed_parameter.py +3 -2
  7. griptape_nodes/exe_types/param_types/parameter_audio.py +3 -0
  8. griptape_nodes/exe_types/param_types/parameter_bool.py +3 -0
  9. griptape_nodes/exe_types/param_types/parameter_button.py +3 -0
  10. griptape_nodes/exe_types/param_types/parameter_dict.py +151 -0
  11. griptape_nodes/exe_types/param_types/parameter_float.py +3 -0
  12. griptape_nodes/exe_types/param_types/parameter_image.py +3 -0
  13. griptape_nodes/exe_types/param_types/parameter_int.py +3 -0
  14. griptape_nodes/exe_types/param_types/parameter_json.py +268 -0
  15. griptape_nodes/exe_types/param_types/parameter_number.py +3 -0
  16. griptape_nodes/exe_types/param_types/parameter_range.py +393 -0
  17. griptape_nodes/exe_types/param_types/parameter_string.py +3 -0
  18. griptape_nodes/exe_types/param_types/parameter_three_d.py +3 -0
  19. griptape_nodes/exe_types/param_types/parameter_video.py +3 -0
  20. griptape_nodes/retained_mode/events/library_events.py +2 -0
  21. griptape_nodes/retained_mode/events/parameter_events.py +89 -1
  22. griptape_nodes/retained_mode/managers/event_manager.py +176 -10
  23. griptape_nodes/retained_mode/managers/library_manager.py +14 -4
  24. griptape_nodes/retained_mode/managers/node_manager.py +187 -7
  25. griptape_nodes/retained_mode/managers/workflow_manager.py +58 -16
  26. griptape_nodes/utils/file_utils.py +58 -0
  27. {griptape_nodes-0.66.2.dist-info → griptape_nodes-0.67.0.dist-info}/METADATA +1 -1
  28. {griptape_nodes-0.66.2.dist-info → griptape_nodes-0.67.0.dist-info}/RECORD +30 -27
  29. {griptape_nodes-0.66.2.dist-info → griptape_nodes-0.67.0.dist-info}/WHEEL +1 -1
  30. {griptape_nodes-0.66.2.dist-info → griptape_nodes-0.67.0.dist-info}/entry_points.txt +0 -0
@@ -1772,6 +1772,12 @@ class NodeExecutor:
1772
1772
  Returns:
1773
1773
  The upstream value if criteria met, None otherwise
1774
1774
  """
1775
+ # If upstream is a BaseIterativeNodeGroup (e.g., ForEach Group) that's currently executing,
1776
+ # we need to trace through its proxy parameter to find the actual resolved source.
1777
+ # This handles the case where: ExternalNode -> ForEachGroup.proxy_param -> InternalNode
1778
+ if isinstance(upstream_node, BaseIterativeNodeGroup) and upstream_node.state != NodeResolutionState.RESOLVED:
1779
+ return self._get_value_through_iterative_group_proxy(upstream_node, upstream_param, packaged_node_names)
1780
+
1775
1781
  if upstream_node.state != NodeResolutionState.RESOLVED:
1776
1782
  return None
1777
1783
 
@@ -1783,6 +1789,77 @@ class NodeExecutor:
1783
1789
 
1784
1790
  return upstream_node.get_parameter_value(upstream_param.name)
1785
1791
 
1792
+ def _get_value_through_iterative_group_proxy(
1793
+ self,
1794
+ iterative_group: BaseIterativeNodeGroup,
1795
+ proxy_param: Any,
1796
+ packaged_node_names: list[str],
1797
+ ) -> Any | None:
1798
+ """Trace through an iterative group's proxy parameter to get value from the actual resolved source.
1799
+
1800
+ When a packaged node inside a ForEach Group has an incoming connection from the group's
1801
+ proxy parameter, we need to find the external node that connects TO that proxy parameter
1802
+ and get the value from there.
1803
+
1804
+ Connection chain: ResolvedExternalNode -> IterativeGroup.proxy_param -> PackagedInternalNode
1805
+ We want to get the value from ResolvedExternalNode.
1806
+
1807
+ Args:
1808
+ iterative_group: The BaseIterativeNodeGroup with the proxy parameter
1809
+ proxy_param: The proxy parameter on the iterative group
1810
+ packaged_node_names: List of packaged node names to exclude
1811
+
1812
+ Returns:
1813
+ The value from the resolved external source, or None if not found
1814
+ """
1815
+ flow_manager = GriptapeNodes.FlowManager()
1816
+ connections = flow_manager.get_connections()
1817
+
1818
+ # Find the incoming connection TO the proxy parameter on the iterative group
1819
+ # This will give us the actual external source node
1820
+ incoming_to_proxy = connections.get_incoming_connections_to_parameter(iterative_group, proxy_param)
1821
+
1822
+ for conn in incoming_to_proxy:
1823
+ # Skip internal connections (from nodes inside the group)
1824
+ if conn.is_node_group_internal:
1825
+ continue
1826
+
1827
+ source_node = conn.source_node
1828
+ source_param = conn.source_parameter
1829
+
1830
+ # Skip if the source is also inside the packaged nodes
1831
+ if source_node.name in packaged_node_names:
1832
+ continue
1833
+
1834
+ # The source must be resolved for us to get its value
1835
+ if source_node.state != NodeResolutionState.RESOLVED:
1836
+ logger.debug(
1837
+ "Source node '%s' for proxy param '%s.%s' is not resolved (state: %s)",
1838
+ source_node.name,
1839
+ iterative_group.name,
1840
+ proxy_param.name,
1841
+ source_node.state,
1842
+ )
1843
+ continue
1844
+
1845
+ # Get the value from the resolved source node
1846
+ if source_param.name in source_node.parameter_output_values:
1847
+ value = source_node.parameter_output_values[source_param.name]
1848
+ else:
1849
+ value = source_node.get_parameter_value(source_param.name)
1850
+
1851
+ logger.debug(
1852
+ "Traced through proxy: %s.%s -> %s.%s (value type: %s)",
1853
+ source_node.name,
1854
+ source_param.name,
1855
+ iterative_group.name,
1856
+ proxy_param.name,
1857
+ type(value).__name__ if value is not None else "None",
1858
+ )
1859
+ return value
1860
+
1861
+ return None
1862
+
1786
1863
  def _map_to_startflow_parameter(
1787
1864
  self,
1788
1865
  packaged_node_name: str,
@@ -908,7 +908,15 @@ class DeprecationMessage(ParameterMessage):
908
908
  class ParameterGroup(BaseNodeElement, UIOptionsMixin):
909
909
  """UI element for a group of parameters."""
910
910
 
911
- def __init__(self, name: str, ui_options: dict | None = None, *, collapsed: bool = False, **kwargs):
911
+ def __init__(
912
+ self,
913
+ name: str,
914
+ ui_options: dict | None = None,
915
+ *,
916
+ collapsed: bool = False,
917
+ user_defined: bool = False,
918
+ **kwargs,
919
+ ):
912
920
  super().__init__(name=name, **kwargs)
913
921
  if ui_options is None:
914
922
  ui_options = {}
@@ -920,6 +928,7 @@ class ParameterGroup(BaseNodeElement, UIOptionsMixin):
920
928
  ui_options["collapsed"] = collapsed
921
929
 
922
930
  self._ui_options = ui_options
931
+ self.user_defined = user_defined
923
932
 
924
933
  @property
925
934
  def ui_options(self) -> dict:
@@ -1181,6 +1190,7 @@ class Parameter(BaseNodeElement, UIOptionsMixin):
1181
1190
  serializable: bool = True
1182
1191
 
1183
1192
  user_defined: bool = False
1193
+ private: bool = False
1184
1194
  _allowed_modes: set = field(
1185
1195
  default_factory=lambda: {
1186
1196
  ParameterMode.OUTPUT,
@@ -1222,6 +1232,7 @@ class Parameter(BaseNodeElement, UIOptionsMixin):
1222
1232
  settable: bool = True,
1223
1233
  serializable: bool = True,
1224
1234
  user_defined: bool = False,
1235
+ private: bool = False,
1225
1236
  element_id: str | None = None,
1226
1237
  element_type: str | None = None,
1227
1238
  parent_container_name: str | None = None,
@@ -1246,6 +1257,7 @@ class Parameter(BaseNodeElement, UIOptionsMixin):
1246
1257
  self._settable = settable
1247
1258
  self.serializable = serializable
1248
1259
  self.user_defined = user_defined
1260
+ self.private = private
1249
1261
 
1250
1262
  # Process allowed_modes - use convenience parameters if allowed_modes not explicitly set
1251
1263
  if allowed_modes is None:
@@ -1401,6 +1413,7 @@ class Parameter(BaseNodeElement, UIOptionsMixin):
1401
1413
  our_dict["is_user_defined"] = self.user_defined
1402
1414
  our_dict["settable"] = self.settable
1403
1415
  our_dict["serializable"] = self.serializable
1416
+ our_dict["private"] = self.private
1404
1417
  our_dict["ui_options"] = self.ui_options
1405
1418
 
1406
1419
  # Let's bundle up the mode details.
@@ -1838,6 +1851,7 @@ class ControlParameter(Parameter, ABC):
1838
1851
  ui_options: dict | None = None,
1839
1852
  *,
1840
1853
  user_defined: bool = False,
1854
+ private: bool = False,
1841
1855
  ):
1842
1856
  # Call parent with a few explicit tweaks.
1843
1857
  super().__init__(
@@ -1857,6 +1871,7 @@ class ControlParameter(Parameter, ABC):
1857
1871
  validators=validators,
1858
1872
  ui_options=ui_options,
1859
1873
  user_defined=user_defined,
1874
+ private=private,
1860
1875
  element_type=self.__class__.__name__,
1861
1876
  )
1862
1877
 
@@ -1875,6 +1890,7 @@ class ControlParameterInput(ControlParameter):
1875
1890
  validators: list[Callable[[Parameter, Any], None]] | None = None,
1876
1891
  *,
1877
1892
  user_defined: bool = False,
1893
+ private: bool = False,
1878
1894
  ):
1879
1895
  allowed_modes = {ParameterMode.INPUT}
1880
1896
  input_types = [ParameterTypeBuiltin.CONTROL_TYPE.value]
@@ -1899,6 +1915,7 @@ class ControlParameterInput(ControlParameter):
1899
1915
  validators=validators,
1900
1916
  ui_options=ui_options,
1901
1917
  user_defined=user_defined,
1918
+ private=private,
1902
1919
  )
1903
1920
 
1904
1921
 
@@ -1916,6 +1933,7 @@ class ControlParameterOutput(ControlParameter):
1916
1933
  validators: list[Callable[[Parameter, Any], None]] | None = None,
1917
1934
  *,
1918
1935
  user_defined: bool = False,
1936
+ private: bool = False,
1919
1937
  ):
1920
1938
  allowed_modes = {ParameterMode.OUTPUT}
1921
1939
  output_type = ParameterTypeBuiltin.CONTROL_TYPE.value
@@ -1940,6 +1958,7 @@ class ControlParameterOutput(ControlParameter):
1940
1958
  validators=validators,
1941
1959
  ui_options=ui_options,
1942
1960
  user_defined=user_defined,
1961
+ private=private,
1943
1962
  )
1944
1963
 
1945
1964
 
@@ -1970,6 +1989,7 @@ class ParameterContainer(Parameter, ABC):
1970
1989
  hide: bool | None = None,
1971
1990
  settable: bool = True,
1972
1991
  user_defined: bool = False,
1992
+ private: bool = False,
1973
1993
  element_id: str | None = None,
1974
1994
  element_type: str | None = None,
1975
1995
  ):
@@ -1991,6 +2011,7 @@ class ParameterContainer(Parameter, ABC):
1991
2011
  hide=hide,
1992
2012
  settable=settable,
1993
2013
  user_defined=user_defined,
2014
+ private=private,
1994
2015
  element_id=element_id,
1995
2016
  element_type=element_type,
1996
2017
  )
@@ -2040,6 +2061,7 @@ class ParameterList(ParameterContainer):
2040
2061
  hide: bool | None = None,
2041
2062
  settable: bool = True,
2042
2063
  user_defined: bool = False,
2064
+ private: bool = False,
2043
2065
  element_id: str | None = None,
2044
2066
  element_type: str | None = None,
2045
2067
  max_items: int | None = None,
@@ -2080,6 +2102,7 @@ class ParameterList(ParameterContainer):
2080
2102
  hide=hide,
2081
2103
  settable=settable,
2082
2104
  user_defined=user_defined,
2105
+ private=private,
2083
2106
  element_id=element_id,
2084
2107
  element_type=element_type,
2085
2108
  )
@@ -2418,6 +2441,7 @@ class ParameterKeyValuePair(Parameter):
2418
2441
  *,
2419
2442
  settable: bool = True,
2420
2443
  user_defined: bool = False,
2444
+ private: bool = False,
2421
2445
  element_id: str | None = None,
2422
2446
  element_type: str | None = None,
2423
2447
  ):
@@ -2437,6 +2461,7 @@ class ParameterKeyValuePair(Parameter):
2437
2461
  validators=validators,
2438
2462
  settable=settable,
2439
2463
  user_defined=user_defined,
2464
+ private=private,
2440
2465
  element_id=element_id,
2441
2466
  element_type=element_type,
2442
2467
  )
@@ -2538,6 +2563,7 @@ class ParameterDictionary(ParameterContainer):
2538
2563
  *,
2539
2564
  settable: bool = True,
2540
2565
  user_defined: bool = False,
2566
+ private: bool = False,
2541
2567
  element_id: str | None = None,
2542
2568
  element_type: str | None = None,
2543
2569
  ):
@@ -2557,6 +2583,7 @@ class ParameterDictionary(ParameterContainer):
2557
2583
  validators=validators,
2558
2584
  settable=settable,
2559
2585
  user_defined=user_defined,
2586
+ private=private,
2560
2587
  element_id=element_id,
2561
2588
  element_type=element_type,
2562
2589
  )
@@ -2,7 +2,6 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- import logging
6
5
  from abc import abstractmethod
7
6
  from typing import Any
8
7
 
@@ -12,8 +11,16 @@ from griptape_nodes.exe_types.core_types import (
12
11
  ParameterTypeBuiltin,
13
12
  )
14
13
  from griptape_nodes.exe_types.node_groups.subflow_node_group import SubflowNodeGroup
14
+ from griptape_nodes.traits.options import Options
15
15
 
16
- logger = logging.getLogger("griptape_nodes")
16
+ # Execution mode choices and their corresponding boolean values (True = run in order)
17
+ EXECUTION_MODE_ONE_AT_A_TIME = "Run Group Items One at a Time"
18
+ EXECUTION_MODE_ALL_AT_ONCE = "Run Group Items All at Once"
19
+ EXECUTION_MODE_CHOICES = [EXECUTION_MODE_ONE_AT_A_TIME, EXECUTION_MODE_ALL_AT_ONCE]
20
+ EXECUTION_MODE_VALUE_LOOKUP = {
21
+ EXECUTION_MODE_ONE_AT_A_TIME: True,
22
+ EXECUTION_MODE_ALL_AT_ONCE: False,
23
+ }
17
24
 
18
25
 
19
26
  class BaseIterativeNodeGroup(SubflowNodeGroup):
@@ -37,7 +44,6 @@ class BaseIterativeNodeGroup(SubflowNodeGroup):
37
44
  _items: list[Any]
38
45
  _current_iteration_count: int
39
46
  _total_iterations: int
40
- is_parallel: bool
41
47
 
42
48
  # Results storage
43
49
  _results_list: list[Any]
@@ -53,20 +59,31 @@ class BaseIterativeNodeGroup(SubflowNodeGroup):
53
59
  self._items = []
54
60
  self._current_iteration_count = 0
55
61
  self._total_iterations = 0
56
- self.is_parallel = False
57
62
  self._results_list = []
58
63
 
59
- # Add parallel execution control parameter
64
+ # Hidden boolean parameter used by node_executor for execution logic
60
65
  self.run_in_order = Parameter(
61
66
  name="run_in_order",
62
67
  tooltip="Execute all iterations in order or concurrently",
63
68
  type=ParameterTypeBuiltin.BOOL.value,
64
69
  allowed_modes={ParameterMode.PROPERTY},
65
70
  default_value=True,
66
- ui_options={"display_name": "Run in Order"},
71
+ hide=True,
67
72
  )
68
73
  self.add_parameter(self.run_in_order)
69
74
 
75
+ # User selection that controls run_in_order
76
+ self.execution_mode = Parameter(
77
+ name="execution_mode",
78
+ tooltip="Execute all iterations in order or concurrently",
79
+ type=ParameterTypeBuiltin.STR.value,
80
+ allowed_modes={ParameterMode.PROPERTY},
81
+ default_value=EXECUTION_MODE_ONE_AT_A_TIME,
82
+ traits={Options(choices=EXECUTION_MODE_CHOICES, show_search=False)},
83
+ ui_options={"display_name": "Execution Mode"},
84
+ )
85
+ self.add_parameter(self.execution_mode)
86
+
70
87
  # Index parameter - available in all iterative nodes (left side - feeds into group)
71
88
  self.index_param = Parameter(
72
89
  name="index",
@@ -108,8 +125,10 @@ class BaseIterativeNodeGroup(SubflowNodeGroup):
108
125
  def after_value_set(self, parameter: Parameter, value: Any) -> None:
109
126
  """Handle parameter value changes."""
110
127
  super().after_value_set(parameter, value)
111
- if parameter == self.run_in_order:
112
- self.is_parallel = not value
128
+ if parameter == self.execution_mode:
129
+ # Convert string choice to boolean and update run_in_order parameter
130
+ run_in_order = EXECUTION_MODE_VALUE_LOOKUP.get(value, True)
131
+ self.set_parameter_value("run_in_order", run_in_order)
113
132
 
114
133
  @abstractmethod
115
134
  def _get_iteration_items(self) -> list[Any]:
@@ -2,7 +2,15 @@ from __future__ import annotations
2
2
 
3
3
  from typing import Any
4
4
 
5
- from griptape_nodes.exe_types.node_types import BaseNode
5
+ from griptape_nodes.exe_types.core_types import (
6
+ Parameter,
7
+ ParameterMode,
8
+ )
9
+ from griptape_nodes.exe_types.node_types import (
10
+ BaseNode,
11
+ )
12
+
13
+ GROUP_SETTINGS_PARAMS_METADATA_KEY = "group_settings_params"
6
14
 
7
15
 
8
16
  class BaseNodeGroup(BaseNode):
@@ -30,3 +38,58 @@ class BaseNodeGroup(BaseNode):
30
38
  self.nodes = {}
31
39
  self.metadata["is_node_group"] = True
32
40
  self.metadata["executable"] = False
41
+
42
+ def add_parameter_to_group_settings(self, parameter: Parameter) -> None:
43
+ """Add a parameter to the Group settings panel.
44
+
45
+ Group settings parameters are determined by metadata in the frontend.
46
+
47
+ Args:
48
+ parameter: The parameter to add to settings
49
+ """
50
+ if ParameterMode.PROPERTY not in parameter.allowed_modes:
51
+ msg = f"Parameter '{parameter.name}' must allow PROPERTY mode to be added to settings."
52
+ raise ValueError(msg)
53
+
54
+ if GROUP_SETTINGS_PARAMS_METADATA_KEY not in self.metadata:
55
+ self.metadata[GROUP_SETTINGS_PARAMS_METADATA_KEY] = []
56
+
57
+ group_settings_params: list[str] = self.metadata.get(GROUP_SETTINGS_PARAMS_METADATA_KEY, [])
58
+ if parameter.name not in group_settings_params:
59
+ group_settings_params.append(parameter.name)
60
+ self.metadata[GROUP_SETTINGS_PARAMS_METADATA_KEY] = group_settings_params
61
+
62
+ def add_nodes_to_group(self, nodes: list[BaseNode]) -> None:
63
+ """Add nodes to this group.
64
+
65
+ Args:
66
+ nodes: A list of nodes to add to this group
67
+ """
68
+ for node in nodes:
69
+ self.nodes[node.name] = node
70
+
71
+ node_names_in_group = set(self.nodes.keys())
72
+ self.metadata["node_names_in_group"] = list(node_names_in_group)
73
+
74
+ def remove_nodes_from_group(self, nodes: list[BaseNode]) -> None:
75
+ """Remove nodes from this group.
76
+
77
+ Args:
78
+ nodes: A list of nodes to remove from this group
79
+ """
80
+ for node in nodes:
81
+ if node.name in self.nodes:
82
+ del self.nodes[node.name]
83
+
84
+ def _add_nodes_to_group_dict(self, nodes: list[BaseNode]) -> None:
85
+ """Add nodes to the group's node dictionary."""
86
+ for node in nodes:
87
+ node.parent_group = self
88
+ self.nodes[node.name] = node
89
+
90
+ def _validate_nodes_in_group(self, nodes: list[BaseNode]) -> None:
91
+ """Validate that all nodes are in the group."""
92
+ for node in nodes:
93
+ if node.name not in self.nodes:
94
+ msg = f"Node {node.name} is not in node group {self.name}"
95
+ raise ValueError(msg)
@@ -14,7 +14,6 @@ from griptape_nodes.exe_types.core_types import (
14
14
  from griptape_nodes.exe_types.node_groups.base_node_group import BaseNodeGroup
15
15
  from griptape_nodes.exe_types.node_types import (
16
16
  LOCAL_EXECUTION,
17
- PRIVATE_EXECUTION,
18
17
  get_library_names_with_publish_handlers,
19
18
  )
20
19
  from griptape_nodes.retained_mode.events.connection_events import (
@@ -300,26 +299,6 @@ class SubflowNodeGroup(BaseNodeGroup, ABC):
300
299
 
301
300
  return proxy_param
302
301
 
303
- def add_parameter_to_group_settings(self, parameter: Parameter) -> None:
304
- """Add a parameter to the Group settings panel.
305
-
306
- Args:
307
- parameter: The parameter to add to settings
308
- """
309
- if ParameterMode.PROPERTY not in parameter.allowed_modes:
310
- msg = f"Parameter '{parameter.name}' must allow PROPERTY mode to be added to settings."
311
- raise ValueError(msg)
312
-
313
- execution_environment: dict = self.metadata.get("execution_environment", {})
314
- if LOCAL_EXECUTION not in execution_environment:
315
- execution_environment[LOCAL_EXECUTION] = {"parameter_names": []}
316
- if PRIVATE_EXECUTION not in execution_environment:
317
- execution_environment[PRIVATE_EXECUTION] = {"parameter_names": []}
318
-
319
- for library in execution_environment:
320
- parameter_names = self.metadata["execution_environment"][library].get("parameter_names", [])
321
- self.metadata["execution_environment"][library]["parameter_names"] = [parameter.name, *parameter_names]
322
-
323
302
  def get_all_nodes(self) -> dict[str, BaseNode]:
324
303
  all_nodes = {}
325
304
  for node_name, node in self.nodes.items():
@@ -478,12 +457,6 @@ class SubflowNodeGroup(BaseNodeGroup, ABC):
478
457
  for parent_group, node_list in child_nodes.items():
479
458
  parent_group.remove_nodes_from_group(node_list)
480
459
 
481
- def _add_nodes_to_group_dict(self, nodes: list[BaseNode]) -> None:
482
- """Add nodes to the group's node dictionary."""
483
- for node in nodes:
484
- node.parent_group = self
485
- self.nodes[node.name] = node
486
-
487
460
  def _cleanup_proxy_parameter(self, proxy_parameter: Parameter, metadata_key: str) -> None:
488
461
  """Clean up proxy parameter if it has no more connections.
489
462
 
@@ -892,13 +865,6 @@ class SubflowNodeGroup(BaseNodeGroup, ABC):
892
865
  GriptapeNodes.handle_request(create_first_connection)
893
866
  GriptapeNodes.handle_request(create_second_connection)
894
867
 
895
- def _validate_nodes_in_group(self, nodes: list[BaseNode]) -> None:
896
- """Validate that all nodes are in the group."""
897
- for node in nodes:
898
- if node.name not in self.nodes:
899
- msg = f"Node {node.name} is not in node group {self.name}"
900
- raise ValueError(msg)
901
-
902
868
  def delete_nodes_from_group(self, nodes: list[BaseNode]) -> None:
903
869
  """Delete nodes from the group and untrack their connections.
904
870
 
@@ -6,8 +6,9 @@ from griptape_nodes.exe_types.node_types import BaseNode
6
6
 
7
7
 
8
8
  class SeedParameter:
9
- def __init__(self, node: BaseNode):
9
+ def __init__(self, node: BaseNode, max_seed: int = 2**32 - 1) -> None:
10
10
  self._node = node
11
+ self._max_seed = max_seed
11
12
 
12
13
  def add_input_parameters(self) -> None:
13
14
  self._node.add_parameter(
@@ -51,7 +52,7 @@ class SeedParameter:
51
52
  def preprocess(self) -> None:
52
53
  if self._node.get_parameter_value("randomize_seed"):
53
54
  # Not using for cryptographic purposes
54
- seed = random.randint(0, 2**32 - 1) # noqa: S311
55
+ seed = random.randint(0, self._max_seed) # noqa: S311
55
56
  self._node.set_parameter_value("seed", seed)
56
57
  self._node.publish_update_to_parameter("seed", seed)
57
58
 
@@ -55,6 +55,7 @@ class ParameterAudio(Parameter):
55
55
  settable: bool = True,
56
56
  serializable: bool = True,
57
57
  user_defined: bool = False,
58
+ private: bool = False,
58
59
  element_id: str | None = None,
59
60
  element_type: str | None = None,
60
61
  parent_container_name: str | None = None,
@@ -90,6 +91,7 @@ class ParameterAudio(Parameter):
90
91
  settable: Whether the parameter is settable
91
92
  serializable: Whether the parameter is serializable
92
93
  user_defined: Whether the parameter is user-defined
94
+ private: Whether this parameter is private
93
95
  element_id: Element ID
94
96
  element_type: Element type
95
97
  parent_container_name: Name of parent container
@@ -145,6 +147,7 @@ class ParameterAudio(Parameter):
145
147
  settable=settable,
146
148
  serializable=serializable,
147
149
  user_defined=user_defined,
150
+ private=private,
148
151
  element_id=element_id,
149
152
  element_type=element_type,
150
153
  parent_container_name=parent_container_name,
@@ -51,6 +51,7 @@ class ParameterBool(Parameter):
51
51
  settable: bool = True,
52
52
  serializable: bool = True,
53
53
  user_defined: bool = False,
54
+ private: bool = False,
54
55
  element_id: str | None = None,
55
56
  element_type: str | None = None,
56
57
  parent_container_name: str | None = None,
@@ -82,6 +83,7 @@ class ParameterBool(Parameter):
82
83
  settable: Whether the parameter is settable
83
84
  serializable: Whether the parameter is serializable
84
85
  user_defined: Whether the parameter is user-defined
86
+ private: Whether this parameter is private
85
87
  element_id: Element ID
86
88
  element_type: Element type
87
89
  parent_container_name: Name of parent container
@@ -136,6 +138,7 @@ class ParameterBool(Parameter):
136
138
  settable=settable,
137
139
  serializable=serializable,
138
140
  user_defined=user_defined,
141
+ private=private,
139
142
  element_id=element_id,
140
143
  element_type=element_type,
141
144
  parent_container_name=parent_container_name,
@@ -97,6 +97,7 @@ class ParameterButton(Parameter):
97
97
  settable: bool = True,
98
98
  serializable: bool = True,
99
99
  user_defined: bool = False,
100
+ private: bool = False,
100
101
  element_id: str | None = None,
101
102
  element_type: str | None = None,
102
103
  parent_container_name: str | None = None,
@@ -139,6 +140,7 @@ class ParameterButton(Parameter):
139
140
  settable: Whether the parameter is settable
140
141
  serializable: Whether the parameter is serializable
141
142
  user_defined: Whether the parameter is user-defined
143
+ private: Whether this parameter is private
142
144
  element_id: Element ID
143
145
  element_type: Element type
144
146
  parent_container_name: Name of parent container
@@ -212,6 +214,7 @@ class ParameterButton(Parameter):
212
214
  settable=settable,
213
215
  serializable=serializable,
214
216
  user_defined=user_defined,
217
+ private=private,
215
218
  element_id=element_id,
216
219
  element_type=element_type,
217
220
  parent_container_name=parent_container_name,