griptape-nodes 0.65.6__py3-none-any.whl → 0.66.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.
- griptape_nodes/common/node_executor.py +352 -27
- griptape_nodes/drivers/storage/base_storage_driver.py +12 -3
- griptape_nodes/drivers/storage/griptape_cloud_storage_driver.py +18 -2
- griptape_nodes/drivers/storage/local_storage_driver.py +42 -5
- griptape_nodes/exe_types/base_iterative_nodes.py +0 -1
- griptape_nodes/exe_types/connections.py +42 -0
- griptape_nodes/exe_types/core_types.py +2 -2
- griptape_nodes/exe_types/node_groups/__init__.py +2 -1
- griptape_nodes/exe_types/node_groups/base_iterative_node_group.py +177 -0
- griptape_nodes/exe_types/node_groups/base_node_group.py +1 -0
- griptape_nodes/exe_types/node_groups/subflow_node_group.py +35 -2
- griptape_nodes/exe_types/param_types/parameter_audio.py +1 -1
- griptape_nodes/exe_types/param_types/parameter_bool.py +1 -1
- griptape_nodes/exe_types/param_types/parameter_button.py +1 -1
- griptape_nodes/exe_types/param_types/parameter_float.py +1 -1
- griptape_nodes/exe_types/param_types/parameter_image.py +1 -1
- griptape_nodes/exe_types/param_types/parameter_int.py +1 -1
- griptape_nodes/exe_types/param_types/parameter_number.py +1 -1
- griptape_nodes/exe_types/param_types/parameter_string.py +1 -1
- griptape_nodes/exe_types/param_types/parameter_three_d.py +1 -1
- griptape_nodes/exe_types/param_types/parameter_video.py +1 -1
- griptape_nodes/machines/control_flow.py +5 -4
- griptape_nodes/machines/dag_builder.py +121 -55
- griptape_nodes/machines/fsm.py +10 -0
- griptape_nodes/machines/parallel_resolution.py +39 -38
- griptape_nodes/machines/sequential_resolution.py +29 -3
- griptape_nodes/node_library/library_registry.py +41 -2
- griptape_nodes/retained_mode/events/library_events.py +147 -8
- griptape_nodes/retained_mode/events/os_events.py +12 -4
- griptape_nodes/retained_mode/managers/fitness_problems/libraries/__init__.py +2 -0
- griptape_nodes/retained_mode/managers/fitness_problems/libraries/incompatible_requirements_problem.py +34 -0
- griptape_nodes/retained_mode/managers/flow_manager.py +133 -20
- griptape_nodes/retained_mode/managers/library_manager.py +1324 -564
- griptape_nodes/retained_mode/managers/node_manager.py +9 -3
- griptape_nodes/retained_mode/managers/os_manager.py +429 -65
- griptape_nodes/retained_mode/managers/resource_types/compute_resource.py +82 -0
- griptape_nodes/retained_mode/managers/resource_types/os_resource.py +17 -0
- griptape_nodes/retained_mode/managers/static_files_manager.py +21 -8
- griptape_nodes/retained_mode/managers/version_compatibility_manager.py +3 -3
- griptape_nodes/utils/git_utils.py +2 -17
- griptape_nodes/version_compatibility/versions/v0_39_0/modified_parameters_set_removal.py +5 -5
- griptape_nodes/version_compatibility/versions/v0_65_4/__init__.py +5 -0
- griptape_nodes/version_compatibility/versions/v0_65_4/run_in_parallel_to_run_in_order.py +79 -0
- griptape_nodes/version_compatibility/versions/v0_65_5/__init__.py +5 -0
- griptape_nodes/version_compatibility/versions/v0_65_5/flux_2_removed_parameters.py +85 -0
- {griptape_nodes-0.65.6.dist-info → griptape_nodes-0.66.0.dist-info}/METADATA +1 -1
- {griptape_nodes-0.65.6.dist-info → griptape_nodes-0.66.0.dist-info}/RECORD +49 -54
- griptape_nodes/retained_mode/managers/library_lifecycle/__init__.py +0 -45
- griptape_nodes/retained_mode/managers/library_lifecycle/data_models.py +0 -191
- griptape_nodes/retained_mode/managers/library_lifecycle/library_directory.py +0 -346
- griptape_nodes/retained_mode/managers/library_lifecycle/library_fsm.py +0 -439
- griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/__init__.py +0 -17
- griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/base.py +0 -82
- griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/github.py +0 -116
- griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/local_file.py +0 -367
- griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/package.py +0 -104
- griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/sandbox.py +0 -155
- griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance.py +0 -18
- griptape_nodes/retained_mode/managers/library_lifecycle/library_status.py +0 -12
- {griptape_nodes-0.65.6.dist-info → griptape_nodes-0.66.0.dist-info}/WHEEL +0 -0
- {griptape_nodes-0.65.6.dist-info → griptape_nodes-0.66.0.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from enum import StrEnum
|
|
3
|
+
from typing import TYPE_CHECKING, Any, Literal
|
|
4
|
+
|
|
5
|
+
from griptape_nodes.retained_mode.managers.resource_components.capability_field import (
|
|
6
|
+
CapabilityField,
|
|
7
|
+
validate_capabilities,
|
|
8
|
+
)
|
|
9
|
+
from griptape_nodes.retained_mode.managers.resource_components.resource_instance import ResourceInstance
|
|
10
|
+
from griptape_nodes.retained_mode.managers.resource_components.resource_type import ResourceType
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from griptape_nodes.retained_mode.managers.resource_components.resource_instance import Requirements
|
|
14
|
+
|
|
15
|
+
logger = logging.getLogger("griptape_nodes")
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class ComputeBackend(StrEnum):
|
|
19
|
+
"""Supported compute backends."""
|
|
20
|
+
|
|
21
|
+
CPU = "cpu"
|
|
22
|
+
CUDA = "cuda" # NVIDIA GPU
|
|
23
|
+
MPS = "mps" # Apple Metal Performance Shaders
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
# Compute capability field names
|
|
27
|
+
ComputeCapability = Literal[
|
|
28
|
+
"compute", # List of available compute backends: ["cpu", "cuda", "mps"]
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class ComputeInstance(ResourceInstance):
|
|
33
|
+
"""Resource instance representing available compute backends."""
|
|
34
|
+
|
|
35
|
+
def can_be_freed(self) -> bool:
|
|
36
|
+
"""Compute resources can be freed when no longer needed."""
|
|
37
|
+
return True
|
|
38
|
+
|
|
39
|
+
def free(self) -> None:
|
|
40
|
+
"""Free compute resource instance."""
|
|
41
|
+
logger.debug("Freeing compute resource instance %s", self.get_instance_id())
|
|
42
|
+
|
|
43
|
+
def get_capability_typed(self, key: ComputeCapability) -> Any:
|
|
44
|
+
"""Type-safe capability getter using Literal types."""
|
|
45
|
+
return self.get_capability_value(key)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class ComputeResourceType(ResourceType):
|
|
49
|
+
"""Resource type for compute backend availability."""
|
|
50
|
+
|
|
51
|
+
def get_capability_schema(self) -> list[CapabilityField]:
|
|
52
|
+
"""Get the capability schema for compute resources."""
|
|
53
|
+
return [
|
|
54
|
+
CapabilityField(
|
|
55
|
+
name="compute",
|
|
56
|
+
type_hint=list,
|
|
57
|
+
description="List of available compute backends: 'cpu', 'cuda', 'mps'",
|
|
58
|
+
required=True,
|
|
59
|
+
),
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
def create_instance(self, capabilities: dict[str, Any]) -> ResourceInstance:
|
|
63
|
+
"""Create a new compute resource instance."""
|
|
64
|
+
# Validate capabilities against schema
|
|
65
|
+
validation_errors = validate_capabilities(self.get_capability_schema(), capabilities)
|
|
66
|
+
if validation_errors:
|
|
67
|
+
error_msg = f"Invalid compute capabilities: {', '.join(validation_errors)}"
|
|
68
|
+
raise ValueError(error_msg)
|
|
69
|
+
|
|
70
|
+
return ComputeInstance(resource_type=self, instance_id_prefix="compute", capabilities=capabilities)
|
|
71
|
+
|
|
72
|
+
def select_best_compatible_instance(
|
|
73
|
+
self, compatible_instances: list[ResourceInstance], _requirements: "Requirements | None" = None
|
|
74
|
+
) -> ResourceInstance | None:
|
|
75
|
+
"""Select the best compute instance from compatible ones.
|
|
76
|
+
|
|
77
|
+
Returns the first compatible instance (no special selection criteria).
|
|
78
|
+
"""
|
|
79
|
+
if not compatible_instances:
|
|
80
|
+
return None
|
|
81
|
+
|
|
82
|
+
return compatible_instances[0]
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
|
+
from enum import StrEnum
|
|
2
3
|
from typing import TYPE_CHECKING, Any, Literal
|
|
3
4
|
|
|
4
5
|
from griptape_nodes.retained_mode.managers.resource_components.capability_field import (
|
|
@@ -14,6 +15,22 @@ if TYPE_CHECKING:
|
|
|
14
15
|
logger = logging.getLogger("griptape_nodes")
|
|
15
16
|
|
|
16
17
|
|
|
18
|
+
class Platform(StrEnum):
|
|
19
|
+
"""Supported operating system platforms."""
|
|
20
|
+
|
|
21
|
+
WINDOWS = "windows"
|
|
22
|
+
DARWIN = "darwin" # macOS
|
|
23
|
+
LINUX = "linux"
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class Architecture(StrEnum):
|
|
27
|
+
"""Supported system architectures."""
|
|
28
|
+
|
|
29
|
+
X86_64 = "x86_64" # Also known as amd64
|
|
30
|
+
ARM64 = "arm64"
|
|
31
|
+
AARCH64 = "aarch64" # ARM64 on Linux
|
|
32
|
+
|
|
33
|
+
|
|
17
34
|
# OS capability field names
|
|
18
35
|
OSCapability = Literal[
|
|
19
36
|
"platform",
|
|
@@ -11,6 +11,7 @@ from griptape_nodes.drivers.storage import StorageBackend
|
|
|
11
11
|
from griptape_nodes.drivers.storage.griptape_cloud_storage_driver import GriptapeCloudStorageDriver
|
|
12
12
|
from griptape_nodes.drivers.storage.local_storage_driver import LocalStorageDriver
|
|
13
13
|
from griptape_nodes.retained_mode.events.app_events import AppInitializationComplete
|
|
14
|
+
from griptape_nodes.retained_mode.events.os_events import ExistingFilePolicy
|
|
14
15
|
from griptape_nodes.retained_mode.events.static_file_events import (
|
|
15
16
|
CreateStaticFileDownloadUrlRequest,
|
|
16
17
|
CreateStaticFileDownloadUrlResultFailure,
|
|
@@ -182,7 +183,9 @@ class StaticFilesManager:
|
|
|
182
183
|
if isinstance(self.storage_driver, LocalStorageDriver):
|
|
183
184
|
threading.Thread(target=start_static_server, daemon=True, name="static-server").start()
|
|
184
185
|
|
|
185
|
-
def save_static_file(
|
|
186
|
+
def save_static_file(
|
|
187
|
+
self, data: bytes, file_name: str, existing_file_policy: ExistingFilePolicy = ExistingFilePolicy.OVERWRITE
|
|
188
|
+
) -> str:
|
|
186
189
|
"""Saves a static file to the workspace directory.
|
|
187
190
|
|
|
188
191
|
This is used to save files that are generated by the node, such as images or other artifacts.
|
|
@@ -190,27 +193,37 @@ class StaticFilesManager:
|
|
|
190
193
|
Args:
|
|
191
194
|
data: The file data to save.
|
|
192
195
|
file_name: The name of the file to save.
|
|
196
|
+
existing_file_policy: How to handle existing files. Defaults to OVERWRITE for backward compatibility.
|
|
197
|
+
- OVERWRITE: Replace existing file content (default)
|
|
198
|
+
- CREATE_NEW: Auto-generate unique filename (e.g., file_1.txt, file_2.txt)
|
|
199
|
+
- FAIL: Raise FileExistsError if file exists
|
|
193
200
|
|
|
194
201
|
Returns:
|
|
195
|
-
The URL of the saved file.
|
|
202
|
+
The URL of the saved file. Note: the actual filename may differ from the requested
|
|
203
|
+
file_name when using CREATE_NEW policy.
|
|
204
|
+
|
|
205
|
+
Raises:
|
|
206
|
+
FileExistsError: When existing_file_policy is FAIL and file already exists.
|
|
196
207
|
"""
|
|
197
208
|
resolved_directory = self._get_static_files_directory()
|
|
198
209
|
file_path = Path(resolved_directory) / file_name
|
|
199
210
|
|
|
200
|
-
|
|
211
|
+
# Pass the existing_file_policy to the storage driver
|
|
212
|
+
response = self.storage_driver.create_signed_upload_url(file_path, existing_file_policy)
|
|
213
|
+
|
|
214
|
+
resolved_file_path = Path(response["file_path"])
|
|
201
215
|
|
|
202
216
|
try:
|
|
203
|
-
|
|
217
|
+
upload_response = httpx.request(
|
|
204
218
|
response["method"], response["url"], content=data, headers=response["headers"], timeout=60
|
|
205
219
|
)
|
|
206
|
-
|
|
220
|
+
upload_response.raise_for_status()
|
|
207
221
|
except httpx.HTTPStatusError as e:
|
|
208
|
-
msg = str(e.response.json())
|
|
222
|
+
msg = str(e.response.json()) if hasattr(e, "response") else str(e)
|
|
209
223
|
logger.error(msg)
|
|
210
224
|
raise ValueError(msg) from e
|
|
211
225
|
|
|
212
|
-
url = self.storage_driver.create_signed_download_url(
|
|
213
|
-
|
|
226
|
+
url = self.storage_driver.create_signed_download_url(resolved_file_path)
|
|
214
227
|
return url
|
|
215
228
|
|
|
216
229
|
def _get_static_files_directory(self) -> str:
|
|
@@ -32,7 +32,7 @@ from griptape_nodes.retained_mode.managers.fitness_problems.workflows.deprecated
|
|
|
32
32
|
from griptape_nodes.retained_mode.managers.fitness_problems.workflows.node_type_not_found_problem import (
|
|
33
33
|
NodeTypeNotFoundProblem,
|
|
34
34
|
)
|
|
35
|
-
from griptape_nodes.retained_mode.managers.
|
|
35
|
+
from griptape_nodes.retained_mode.managers.library_manager import LibraryManager
|
|
36
36
|
|
|
37
37
|
if TYPE_CHECKING:
|
|
38
38
|
from griptape_nodes.exe_types.node_types import BaseNode
|
|
@@ -54,7 +54,7 @@ class LibraryVersionCompatibilityIssue(NamedTuple):
|
|
|
54
54
|
"""Represents a library version compatibility issue found in a library."""
|
|
55
55
|
|
|
56
56
|
problem: LibraryProblem
|
|
57
|
-
severity:
|
|
57
|
+
severity: LibraryManager.LibraryFitness
|
|
58
58
|
|
|
59
59
|
|
|
60
60
|
class LibraryVersionCompatibilityCheck(ABC):
|
|
@@ -208,7 +208,7 @@ class VersionCompatibilityManager:
|
|
|
208
208
|
removal_version=node.metadata.deprecation.removal_version,
|
|
209
209
|
deprecation_message=node.metadata.deprecation.deprecation_message,
|
|
210
210
|
),
|
|
211
|
-
severity=
|
|
211
|
+
severity=LibraryManager.LibraryFitness.FLAWED,
|
|
212
212
|
)
|
|
213
213
|
for node in library_data.nodes
|
|
214
214
|
if node.metadata.deprecation is not None
|
|
@@ -1171,34 +1171,19 @@ def _shallow_clone_with_pygit2(remote_url: str, ref: str) -> tuple[str, str, dic
|
|
|
1171
1171
|
callbacks = _get_ssh_callbacks()
|
|
1172
1172
|
|
|
1173
1173
|
# Shallow clone with depth=1
|
|
1174
|
-
|
|
1175
|
-
# not tags or commit SHAs. Instead, we'll fetch and checkout the ref manually.
|
|
1174
|
+
checkout_branch = ref if ref != "HEAD" else None
|
|
1176
1175
|
repo = pygit2.clone_repository(
|
|
1177
1176
|
remote_url,
|
|
1178
1177
|
str(temp_path),
|
|
1179
1178
|
callbacks=callbacks,
|
|
1180
1179
|
depth=1,
|
|
1180
|
+
checkout_branch=checkout_branch,
|
|
1181
1181
|
)
|
|
1182
1182
|
|
|
1183
1183
|
if repo is None:
|
|
1184
1184
|
msg = f"Failed to clone repository from {remote_url}"
|
|
1185
1185
|
raise GitCloneError(msg)
|
|
1186
1186
|
|
|
1187
|
-
# If a specific ref was requested (not HEAD), fetch and checkout that ref
|
|
1188
|
-
if ref != "HEAD":
|
|
1189
|
-
try:
|
|
1190
|
-
# Fetch the specific ref (works for branches, tags, and commits)
|
|
1191
|
-
remote = repo.remotes["origin"]
|
|
1192
|
-
remote.fetch([ref], callbacks=callbacks, depth=1)
|
|
1193
|
-
|
|
1194
|
-
# Now resolve and checkout the ref
|
|
1195
|
-
resolved_ref = repo.revparse_single(ref)
|
|
1196
|
-
repo.checkout_tree(resolved_ref)
|
|
1197
|
-
repo.set_head(resolved_ref.id)
|
|
1198
|
-
except (KeyError, pygit2.GitError) as e:
|
|
1199
|
-
msg = f"Failed to fetch and checkout ref '{ref}' in clone from {remote_url}: {e}"
|
|
1200
|
-
raise GitCloneError(msg) from e
|
|
1201
|
-
|
|
1202
1187
|
# Find the library JSON file
|
|
1203
1188
|
library_json_path = find_file_in_directory(temp_path, "griptape[-_]nodes[-_]library.json")
|
|
1204
1189
|
if library_json_path is None:
|
|
@@ -21,7 +21,7 @@ from griptape_nodes.retained_mode.managers.fitness_problems.libraries.ui_options
|
|
|
21
21
|
from griptape_nodes.retained_mode.managers.fitness_problems.libraries.ui_options_field_modified_warning_problem import (
|
|
22
22
|
UiOptionsFieldModifiedWarningProblem,
|
|
23
23
|
)
|
|
24
|
-
from griptape_nodes.retained_mode.managers.
|
|
24
|
+
from griptape_nodes.retained_mode.managers.library_manager import LibraryManager
|
|
25
25
|
from griptape_nodes.retained_mode.managers.version_compatibility_manager import (
|
|
26
26
|
LibraryVersionCompatibilityCheck,
|
|
27
27
|
LibraryVersionCompatibilityIssue,
|
|
@@ -62,11 +62,11 @@ class ModifiedParametersSetRemovalCheck(LibraryVersionCompatibilityCheck):
|
|
|
62
62
|
return [
|
|
63
63
|
LibraryVersionCompatibilityIssue(
|
|
64
64
|
problem=ModifiedParametersSetRemovedProblem(library_engine_version=library_version_str),
|
|
65
|
-
severity=
|
|
65
|
+
severity=LibraryManager.LibraryFitness.UNUSABLE,
|
|
66
66
|
),
|
|
67
67
|
LibraryVersionCompatibilityIssue(
|
|
68
68
|
problem=UiOptionsFieldModifiedIncompatibleProblem(library_engine_version=library_version_str),
|
|
69
|
-
severity=
|
|
69
|
+
severity=LibraryManager.LibraryFitness.UNUSABLE,
|
|
70
70
|
),
|
|
71
71
|
]
|
|
72
72
|
if current_engine_version >= semver.VersionInfo(0, 38, 0):
|
|
@@ -74,11 +74,11 @@ class ModifiedParametersSetRemovalCheck(LibraryVersionCompatibilityCheck):
|
|
|
74
74
|
return [
|
|
75
75
|
LibraryVersionCompatibilityIssue(
|
|
76
76
|
problem=ModifiedParametersSetDeprecationWarningProblem(library_engine_version=library_version_str),
|
|
77
|
-
severity=
|
|
77
|
+
severity=LibraryManager.LibraryFitness.FLAWED,
|
|
78
78
|
),
|
|
79
79
|
LibraryVersionCompatibilityIssue(
|
|
80
80
|
problem=UiOptionsFieldModifiedWarningProblem(),
|
|
81
|
-
severity=
|
|
81
|
+
severity=LibraryManager.LibraryFitness.FLAWED,
|
|
82
82
|
),
|
|
83
83
|
]
|
|
84
84
|
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"""Backward compatibility for run_in_parallel to run_in_order parameter change.
|
|
2
|
+
|
|
3
|
+
This module handles the parameter name change from 'run_in_parallel' to 'run_in_order'
|
|
4
|
+
in ForLoopStartNode and ForEachStartNode. The logic is inverted: run_in_parallel=True
|
|
5
|
+
becomes run_in_order=False (run in parallel means NOT run in order).
|
|
6
|
+
|
|
7
|
+
TODO: Remove this compatibility check once all workflows have been migrated and we no
|
|
8
|
+
longer need to support loading old workflows with the run_in_parallel parameter.
|
|
9
|
+
Link: https://github.com/griptape-ai/griptape-nodes/issues/XXXX
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
from typing import TYPE_CHECKING, Any
|
|
15
|
+
|
|
16
|
+
from griptape_nodes.retained_mode.events.parameter_events import SetParameterValueResultSuccess
|
|
17
|
+
from griptape_nodes.retained_mode.managers.version_compatibility_manager import (
|
|
18
|
+
SetParameterVersionCompatibilityCheck,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
if TYPE_CHECKING:
|
|
22
|
+
from griptape_nodes.exe_types.node_types import BaseNode
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class RunInParallelToRunInOrderCheck(SetParameterVersionCompatibilityCheck):
|
|
26
|
+
"""Handle migration from run_in_parallel to run_in_order parameter.
|
|
27
|
+
|
|
28
|
+
This check intercepts attempts to set the old 'run_in_parallel' parameter
|
|
29
|
+
and converts it to the new 'run_in_order' parameter with inverted boolean logic.
|
|
30
|
+
|
|
31
|
+
Applies to:
|
|
32
|
+
- ForLoopStartNode
|
|
33
|
+
- ForEachStartNode
|
|
34
|
+
|
|
35
|
+
Migration logic:
|
|
36
|
+
- run_in_parallel=True → run_in_order=False (run in parallel)
|
|
37
|
+
- run_in_parallel=False → run_in_order=True (run sequentially)
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
def applies_to_set_parameter(self, node: BaseNode, parameter_name: str, _value: Any) -> bool:
|
|
41
|
+
"""Return True if this is the old run_in_parallel parameter on an affected node.
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
node: The node instance
|
|
45
|
+
parameter_name: Name of the parameter being set
|
|
46
|
+
_value: The value being set (unused)
|
|
47
|
+
|
|
48
|
+
Returns:
|
|
49
|
+
True if this check should handle this parameter
|
|
50
|
+
"""
|
|
51
|
+
if parameter_name != "run_in_parallel":
|
|
52
|
+
return False
|
|
53
|
+
|
|
54
|
+
node_type_name = type(node).__name__
|
|
55
|
+
return node_type_name in ("ForLoopStartNode", "ForEachStartNode")
|
|
56
|
+
|
|
57
|
+
def set_parameter_value(self, node: BaseNode, parameter_name: str, value: Any) -> SetParameterValueResultSuccess:
|
|
58
|
+
"""Migrate run_in_parallel to run_in_order with inverted boolean value.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
node: The node instance
|
|
62
|
+
parameter_name: Name of the parameter being set (should be "run_in_parallel")
|
|
63
|
+
value: The value being set (boolean)
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
SetParameterValueResultSuccess indicating the migration was successful
|
|
67
|
+
"""
|
|
68
|
+
if value is None:
|
|
69
|
+
inverted_value = True
|
|
70
|
+
else:
|
|
71
|
+
inverted_value = not bool(value)
|
|
72
|
+
|
|
73
|
+
node.set_parameter_value("run_in_order", inverted_value)
|
|
74
|
+
|
|
75
|
+
return SetParameterValueResultSuccess(
|
|
76
|
+
finalized_value=inverted_value,
|
|
77
|
+
data_type="bool",
|
|
78
|
+
result_details=f"Migrated deprecated '{parameter_name}' parameter to 'run_in_order' with inverted value",
|
|
79
|
+
)
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"""Backward compatibility for removed Flux2ImageGeneration parameters.
|
|
2
|
+
|
|
3
|
+
This module handles removed parameters from Flux2ImageGeneration when adding
|
|
4
|
+
FLUX.2[max] support:
|
|
5
|
+
- prompt_upsampling: removed entirely
|
|
6
|
+
- aspect_ratio: replaced with explicit width/height parameters
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import logging
|
|
12
|
+
from typing import TYPE_CHECKING, Any, ClassVar
|
|
13
|
+
|
|
14
|
+
from griptape_nodes.retained_mode.events.parameter_events import SetParameterValueResultSuccess
|
|
15
|
+
from griptape_nodes.retained_mode.griptape_nodes import GriptapeNodes
|
|
16
|
+
from griptape_nodes.retained_mode.managers.version_compatibility_manager import (
|
|
17
|
+
SetParameterVersionCompatibilityCheck,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
if TYPE_CHECKING:
|
|
21
|
+
from griptape_nodes.exe_types.node_types import BaseNode
|
|
22
|
+
|
|
23
|
+
logger = logging.getLogger("griptape_nodes")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class Flux2RemovedParametersCheck(SetParameterVersionCompatibilityCheck):
|
|
27
|
+
"""Handle removed prompt_upsampling and aspect_ratio parameters.
|
|
28
|
+
|
|
29
|
+
These parameters were removed in engine version 0.65.5 when adding FLUX.2[max] support.
|
|
30
|
+
This check intercepts attempts to set these parameters and logs a warning prompting
|
|
31
|
+
users to resave their workflows.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
REMOVED_PARAMETERS: ClassVar[set[str]] = {"prompt_upsampling", "aspect_ratio"}
|
|
35
|
+
|
|
36
|
+
def __init__(self) -> None:
|
|
37
|
+
"""Initialize the check with an empty set of warned workflows."""
|
|
38
|
+
super().__init__()
|
|
39
|
+
self._warned_workflows: set[str] = set()
|
|
40
|
+
|
|
41
|
+
def applies_to_set_parameter(self, node: BaseNode, parameter_name: str, _value: Any) -> bool:
|
|
42
|
+
"""Return True if this is a removed parameter on a Flux2ImageGeneration node.
|
|
43
|
+
|
|
44
|
+
Args:
|
|
45
|
+
node: The node instance
|
|
46
|
+
parameter_name: Name of the parameter being set
|
|
47
|
+
_value: The value being set (unused)
|
|
48
|
+
|
|
49
|
+
Returns:
|
|
50
|
+
True if this check should handle this parameter
|
|
51
|
+
"""
|
|
52
|
+
if parameter_name not in self.REMOVED_PARAMETERS:
|
|
53
|
+
return False
|
|
54
|
+
|
|
55
|
+
return type(node).__name__ == "Flux2ImageGeneration"
|
|
56
|
+
|
|
57
|
+
def set_parameter_value(self, _node: BaseNode, parameter_name: str, _value: Any) -> SetParameterValueResultSuccess:
|
|
58
|
+
"""Handle the removed parameter by logging a warning and returning success.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
_node: The node instance (unused)
|
|
62
|
+
parameter_name: Name of the parameter being set
|
|
63
|
+
_value: The value being set (unused)
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
SetParameterValueResultSuccess with None value
|
|
67
|
+
"""
|
|
68
|
+
workflow_name = GriptapeNodes.ContextManager().get_current_workflow_name()
|
|
69
|
+
|
|
70
|
+
if workflow_name not in self._warned_workflows:
|
|
71
|
+
self._warned_workflows.add(workflow_name)
|
|
72
|
+
|
|
73
|
+
removed_params_list = ", ".join(f"'{param}'" for param in self.REMOVED_PARAMETERS)
|
|
74
|
+
logger.warning(
|
|
75
|
+
"This workflow uses removed Flux2ImageGeneration parameters (%s) that were "
|
|
76
|
+
"replaced in engine version 0.65.5. Please resave your workflow and this "
|
|
77
|
+
"warning will go away.",
|
|
78
|
+
removed_params_list,
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
return SetParameterValueResultSuccess(
|
|
82
|
+
finalized_value=None,
|
|
83
|
+
data_type="any",
|
|
84
|
+
result_details=f"Parameter '{parameter_name}' was removed in v0.65.5. Please resave this workflow.",
|
|
85
|
+
)
|