griptape-nodes 0.66.2__py3-none-any.whl → 0.68.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 (34) hide show
  1. griptape_nodes/bootstrap/utils/python_subprocess_executor.py +17 -4
  2. griptape_nodes/common/node_executor.py +295 -18
  3. griptape_nodes/exe_types/core_types.py +28 -1
  4. griptape_nodes/exe_types/node_groups/__init__.py +2 -2
  5. griptape_nodes/exe_types/node_groups/base_iterative_node_group.py +81 -10
  6. griptape_nodes/exe_types/node_groups/base_node_group.py +64 -1
  7. griptape_nodes/exe_types/node_groups/subflow_node_group.py +0 -34
  8. griptape_nodes/exe_types/param_components/huggingface/huggingface_repo_variant_parameter.py +152 -0
  9. griptape_nodes/exe_types/param_components/seed_parameter.py +3 -2
  10. griptape_nodes/exe_types/param_types/parameter_audio.py +3 -0
  11. griptape_nodes/exe_types/param_types/parameter_bool.py +3 -0
  12. griptape_nodes/exe_types/param_types/parameter_button.py +3 -0
  13. griptape_nodes/exe_types/param_types/parameter_dict.py +151 -0
  14. griptape_nodes/exe_types/param_types/parameter_float.py +3 -0
  15. griptape_nodes/exe_types/param_types/parameter_image.py +3 -0
  16. griptape_nodes/exe_types/param_types/parameter_int.py +3 -0
  17. griptape_nodes/exe_types/param_types/parameter_json.py +268 -0
  18. griptape_nodes/exe_types/param_types/parameter_number.py +3 -0
  19. griptape_nodes/exe_types/param_types/parameter_range.py +393 -0
  20. griptape_nodes/exe_types/param_types/parameter_string.py +3 -0
  21. griptape_nodes/exe_types/param_types/parameter_three_d.py +3 -0
  22. griptape_nodes/exe_types/param_types/parameter_video.py +3 -0
  23. griptape_nodes/retained_mode/events/library_events.py +2 -0
  24. griptape_nodes/retained_mode/events/parameter_events.py +89 -1
  25. griptape_nodes/retained_mode/managers/event_manager.py +176 -10
  26. griptape_nodes/retained_mode/managers/flow_manager.py +2 -1
  27. griptape_nodes/retained_mode/managers/library_manager.py +14 -4
  28. griptape_nodes/retained_mode/managers/node_manager.py +187 -7
  29. griptape_nodes/retained_mode/managers/workflow_manager.py +58 -16
  30. griptape_nodes/utils/file_utils.py +58 -0
  31. {griptape_nodes-0.66.2.dist-info → griptape_nodes-0.68.0.dist-info}/METADATA +1 -1
  32. {griptape_nodes-0.66.2.dist-info → griptape_nodes-0.68.0.dist-info}/RECORD +34 -30
  33. {griptape_nodes-0.66.2.dist-info → griptape_nodes-0.68.0.dist-info}/WHEEL +1 -1
  34. {griptape_nodes-0.66.2.dist-info → griptape_nodes-0.68.0.dist-info}/entry_points.txt +0 -0
@@ -2,18 +2,35 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- import logging
6
5
  from abc import abstractmethod
6
+ from enum import StrEnum
7
7
  from typing import Any
8
8
 
9
9
  from griptape_nodes.exe_types.core_types import (
10
+ ControlParameterInput,
10
11
  Parameter,
11
12
  ParameterMode,
12
13
  ParameterTypeBuiltin,
13
14
  )
14
15
  from griptape_nodes.exe_types.node_groups.subflow_node_group import SubflowNodeGroup
16
+ from griptape_nodes.traits.options import Options
15
17
 
16
- logger = logging.getLogger("griptape_nodes")
18
+ # Execution mode choices and their corresponding boolean values (True = run in order)
19
+ EXECUTION_MODE_ONE_AT_A_TIME = "Run Group Items One at a Time"
20
+ EXECUTION_MODE_ALL_AT_ONCE = "Run Group Items All at Once"
21
+ EXECUTION_MODE_CHOICES = [EXECUTION_MODE_ONE_AT_A_TIME, EXECUTION_MODE_ALL_AT_ONCE]
22
+ EXECUTION_MODE_VALUE_LOOKUP = {
23
+ EXECUTION_MODE_ONE_AT_A_TIME: True,
24
+ EXECUTION_MODE_ALL_AT_ONCE: False,
25
+ }
26
+
27
+
28
+ class IterationControlParam(StrEnum):
29
+ """Parameter names for iteration control on iterative node groups."""
30
+
31
+ LOOP_COMPLETE = "loop_complete"
32
+ SKIP_ITERATION = "skip_iteration"
33
+ BREAK_LOOP = "break_loop"
17
34
 
18
35
 
19
36
  class BaseIterativeNodeGroup(SubflowNodeGroup):
@@ -37,7 +54,6 @@ class BaseIterativeNodeGroup(SubflowNodeGroup):
37
54
  _items: list[Any]
38
55
  _current_iteration_count: int
39
56
  _total_iterations: int
40
- is_parallel: bool
41
57
 
42
58
  # Results storage
43
59
  _results_list: list[Any]
@@ -53,20 +69,31 @@ class BaseIterativeNodeGroup(SubflowNodeGroup):
53
69
  self._items = []
54
70
  self._current_iteration_count = 0
55
71
  self._total_iterations = 0
56
- self.is_parallel = False
57
72
  self._results_list = []
58
73
 
59
- # Add parallel execution control parameter
74
+ # Hidden boolean parameter used by node_executor for execution logic
60
75
  self.run_in_order = Parameter(
61
76
  name="run_in_order",
62
77
  tooltip="Execute all iterations in order or concurrently",
63
78
  type=ParameterTypeBuiltin.BOOL.value,
64
79
  allowed_modes={ParameterMode.PROPERTY},
65
80
  default_value=True,
66
- ui_options={"display_name": "Run in Order"},
81
+ hide=True,
67
82
  )
68
83
  self.add_parameter(self.run_in_order)
69
84
 
85
+ # User selection that controls run_in_order
86
+ self.execution_mode = Parameter(
87
+ name="execution_mode",
88
+ tooltip="Execute all iterations in order or concurrently",
89
+ type=ParameterTypeBuiltin.STR.value,
90
+ allowed_modes={ParameterMode.PROPERTY},
91
+ default_value=EXECUTION_MODE_ONE_AT_A_TIME,
92
+ traits={Options(choices=EXECUTION_MODE_CHOICES, show_search=False)},
93
+ ui_options={"display_name": "Execution Mode"},
94
+ )
95
+ self.add_parameter(self.execution_mode)
96
+
70
97
  # Index parameter - available in all iterative nodes (left side - feeds into group)
71
98
  self.index_param = Parameter(
72
99
  name="index",
@@ -83,7 +110,15 @@ class BaseIterativeNodeGroup(SubflowNodeGroup):
83
110
  self.metadata["left_parameters"] = []
84
111
  self.metadata["left_parameters"].append("index")
85
112
 
86
- # Results collection parameters (right side - collects from group)
113
+ # Control input for loop completion (right side - primary loop completion path)
114
+ self.loop_complete = ControlParameterInput(
115
+ tooltip="Signal that this iteration is complete and continue to next iteration",
116
+ name=IterationControlParam.LOOP_COMPLETE.value,
117
+ )
118
+ self.loop_complete.ui_options = {"display_name": "Loop Complete"}
119
+ self.add_parameter(self.loop_complete)
120
+
121
+ # Data parameter for the item to add (right side - collects from group)
87
122
  self.new_item_to_add = Parameter(
88
123
  name="new_item_to_add",
89
124
  tooltip="Item to add to results list for each iteration",
@@ -92,6 +127,21 @@ class BaseIterativeNodeGroup(SubflowNodeGroup):
92
127
  )
93
128
  self.add_parameter(self.new_item_to_add)
94
129
 
130
+ # Skip and Break control inputs (right side - for loop control)
131
+ self.skip_iteration = ControlParameterInput(
132
+ tooltip="Skip current item and continue to next iteration",
133
+ name=IterationControlParam.SKIP_ITERATION.value,
134
+ )
135
+ self.skip_iteration.ui_options = {"display_name": "Skip to Next Iteration"}
136
+ self.add_parameter(self.skip_iteration)
137
+
138
+ self.break_loop = ControlParameterInput(
139
+ tooltip="Break out of loop immediately",
140
+ name=IterationControlParam.BREAK_LOOP.value,
141
+ )
142
+ self.break_loop.ui_options = {"display_name": "Break Out of Loop"}
143
+ self.add_parameter(self.break_loop)
144
+
95
145
  self.results = Parameter(
96
146
  name="results",
97
147
  tooltip="Collected results from all iterations",
@@ -103,13 +153,34 @@ class BaseIterativeNodeGroup(SubflowNodeGroup):
103
153
  # Track right parameters for UI layout
104
154
  if "right_parameters" not in self.metadata:
105
155
  self.metadata["right_parameters"] = []
106
- self.metadata["right_parameters"].extend(["new_item_to_add", "results"])
156
+ self.metadata["right_parameters"].extend(
157
+ [
158
+ IterationControlParam.LOOP_COMPLETE.value,
159
+ "new_item_to_add",
160
+ IterationControlParam.SKIP_ITERATION.value,
161
+ IterationControlParam.BREAK_LOOP.value,
162
+ "results",
163
+ ]
164
+ )
107
165
 
108
166
  def after_value_set(self, parameter: Parameter, value: Any) -> None:
109
167
  """Handle parameter value changes."""
110
168
  super().after_value_set(parameter, value)
111
- if parameter == self.run_in_order:
112
- self.is_parallel = not value
169
+ if parameter == self.execution_mode:
170
+ # Convert string choice to boolean and update run_in_order parameter
171
+ run_in_order = EXECUTION_MODE_VALUE_LOOKUP.get(value, True)
172
+ self.set_parameter_value("run_in_order", run_in_order)
173
+
174
+ # Hide or show skip/break controls based on execution mode
175
+ # Skip and Break are only supported in sequential mode (run_in_order=True)
176
+ if run_in_order:
177
+ # Show controls when running sequentially
178
+ self.show_parameter_by_name(self.skip_iteration.name)
179
+ self.show_parameter_by_name(self.break_loop.name)
180
+ else:
181
+ # Hide controls when running in parallel (not supported)
182
+ self.hide_parameter_by_name(self.skip_iteration.name)
183
+ self.hide_parameter_by_name(self.break_loop.name)
113
184
 
114
185
  @abstractmethod
115
186
  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
 
@@ -0,0 +1,152 @@
1
+ """HuggingFace parameter class that supports repo + variant/subfolder selection."""
2
+
3
+ import logging
4
+ from pathlib import Path
5
+
6
+ from huggingface_hub.constants import HF_HUB_CACHE
7
+
8
+ from griptape_nodes.exe_types.node_types import BaseNode
9
+ from griptape_nodes.exe_types.param_components.huggingface.huggingface_model_parameter import HuggingFaceModelParameter
10
+
11
+ logger = logging.getLogger("griptape_nodes")
12
+
13
+
14
+ def _get_repo_cache_path(repo_id: str) -> Path | None:
15
+ """Get the cache path for a repo if it exists."""
16
+ cache_path = Path(HF_HUB_CACHE)
17
+ if not cache_path.exists():
18
+ return None
19
+
20
+ # Convert repo_id to cache folder format: owner/repo -> models--owner--repo
21
+ folder_name = f"models--{repo_id.replace('/', '--')}"
22
+ repo_path = cache_path / folder_name
23
+
24
+ if repo_path.exists():
25
+ return repo_path
26
+ return None
27
+
28
+
29
+ def _get_snapshot_path(repo_path: Path) -> Path | None:
30
+ """Get the latest snapshot path for a repo."""
31
+ snapshots_dir = repo_path / "snapshots"
32
+ if not snapshots_dir.exists():
33
+ return None
34
+
35
+ snapshots = [p for p in snapshots_dir.iterdir() if p.is_dir()]
36
+ if not snapshots:
37
+ return None
38
+
39
+ # Return the most recent snapshot
40
+ return max(snapshots, key=lambda p: p.stat().st_mtime)
41
+
42
+
43
+ def _list_variants_in_cache(repo_id: str, variants: list[str]) -> list[tuple[str, str, str]]:
44
+ """List (repo_id, variant, revision) tuples for variants that exist in cache.
45
+
46
+ Args:
47
+ repo_id: The HuggingFace repo ID (e.g., "Lightricks/LTX-2")
48
+ variants: List of variant/subfolder names to check for (e.g., ["ltx-2-19b-dev", "ltx-2-19b-dev-fp8"])
49
+
50
+ Returns:
51
+ List of (repo_id, variant, revision) tuples for variants found in cache
52
+ """
53
+ repo_path = _get_repo_cache_path(repo_id)
54
+ if repo_path is None:
55
+ return []
56
+
57
+ snapshot_path = _get_snapshot_path(repo_path)
58
+ if snapshot_path is None:
59
+ return []
60
+
61
+ revision = snapshot_path.name
62
+ results = []
63
+
64
+ for variant in variants:
65
+ # Check for variant as a directory (subfolder model structure)
66
+ variant_dir_path = snapshot_path / variant
67
+ if variant_dir_path.exists() and variant_dir_path.is_dir():
68
+ results.append((repo_id, variant, revision))
69
+ continue
70
+
71
+ # Check for variant as a .safetensors file (single-file model structure)
72
+ variant_file_path = snapshot_path / f"{variant}.safetensors"
73
+ if variant_file_path.exists() and variant_file_path.is_file():
74
+ results.append((repo_id, variant, revision))
75
+
76
+ return results
77
+
78
+
79
+ class HuggingFaceRepoVariantParameter(HuggingFaceModelParameter):
80
+ """Parameter class for selecting a variant/subfolder within a HuggingFace repo.
81
+
82
+ Use this when a single repo contains multiple model variants as subfolders.
83
+ For example, Lightricks/LTX-2 contains:
84
+ - ltx-2-19b-dev
85
+ - ltx-2-19b-dev-fp8
86
+ - ltx-2-19b-dev-fp4
87
+ """
88
+
89
+ def __init__(
90
+ self,
91
+ node: BaseNode,
92
+ repo_id: str,
93
+ variants: list[str],
94
+ parameter_name: str = "model",
95
+ ):
96
+ """Initialize the parameter.
97
+
98
+ Args:
99
+ node: The node this parameter belongs to
100
+ repo_id: The HuggingFace repo ID (e.g., "Lightricks/LTX-2")
101
+ variants: List of variant/subfolder names (e.g., ["ltx-2-19b-dev", "ltx-2-19b-dev-fp8"])
102
+ parameter_name: Name of the parameter (default: "model")
103
+ """
104
+ super().__init__(node, parameter_name)
105
+ self._repo_id = repo_id
106
+ self._variants = variants
107
+ self.refresh_parameters()
108
+
109
+ @classmethod
110
+ def _repo_variant_to_key(cls, repo_id: str, variant: str) -> str:
111
+ """Convert repo_id and variant to a display key."""
112
+ return f"{repo_id}/{variant}"
113
+
114
+ @classmethod
115
+ def _key_to_repo_variant(cls, key: str) -> tuple[str, str]:
116
+ """Parse a display key back to repo_id and variant.
117
+
118
+ Key format: "owner/repo/variant"
119
+ """
120
+ parts = key.rsplit("/", 1)
121
+ if len(parts) == 2: # noqa: PLR2004
122
+ return parts[0], parts[1]
123
+ # Fallback: treat entire key as repo_id with empty variant
124
+ return key, ""
125
+
126
+ def fetch_repo_revisions(self) -> list[tuple[str, str]]:
127
+ """Fetch available variants from cache.
128
+
129
+ Returns list of (display_key, revision) tuples where display_key is "repo_id/variant".
130
+ """
131
+ variant_revisions = _list_variants_in_cache(self._repo_id, self._variants)
132
+ return [
133
+ (self._repo_variant_to_key(repo_id, variant), revision) for repo_id, variant, revision in variant_revisions
134
+ ]
135
+
136
+ def get_download_commands(self) -> list[str]:
137
+ """Return download commands for the repo."""
138
+ return [f'huggingface-cli download "{self._repo_id}"']
139
+
140
+ def get_download_models(self) -> list[str]:
141
+ """Return list of model names for download."""
142
+ return [self._repo_id]
143
+
144
+ def get_repo_variant_revision(self) -> tuple[str, str, str]:
145
+ """Get the selected repo_id, variant, and revision.
146
+
147
+ Returns:
148
+ Tuple of (repo_id, variant, revision)
149
+ """
150
+ repo_key, revision = self.get_repo_revision()
151
+ repo_id, variant = self._key_to_repo_variant(repo_key)
152
+ return repo_id, variant, revision
@@ -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,