griptape-nodes 0.62.3__py3-none-any.whl → 0.63.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/cli/commands/libraries.py +6 -21
- griptape_nodes/cli/commands/models.py +21 -4
- griptape_nodes/drivers/thread_storage/__init__.py +15 -0
- griptape_nodes/drivers/thread_storage/base_thread_storage_driver.py +106 -0
- griptape_nodes/drivers/thread_storage/griptape_cloud_thread_storage_driver.py +213 -0
- griptape_nodes/drivers/thread_storage/local_thread_storage_driver.py +137 -0
- griptape_nodes/drivers/thread_storage/thread_storage_backend.py +10 -0
- griptape_nodes/node_library/library_registry.py +16 -9
- griptape_nodes/node_library/workflow_registry.py +1 -1
- griptape_nodes/retained_mode/events/agent_events.py +232 -9
- griptape_nodes/retained_mode/events/library_events.py +32 -3
- griptape_nodes/retained_mode/events/model_events.py +4 -4
- griptape_nodes/retained_mode/events/os_events.py +101 -1
- griptape_nodes/retained_mode/managers/agent_manager.py +335 -135
- griptape_nodes/retained_mode/managers/fitness_problems/__init__.py +1 -0
- griptape_nodes/retained_mode/managers/fitness_problems/libraries/__init__.py +59 -0
- griptape_nodes/retained_mode/managers/fitness_problems/libraries/advanced_library_load_failure_problem.py +33 -0
- griptape_nodes/retained_mode/managers/fitness_problems/libraries/after_library_callback_problem.py +32 -0
- griptape_nodes/retained_mode/managers/fitness_problems/libraries/before_library_callback_problem.py +32 -0
- griptape_nodes/retained_mode/managers/fitness_problems/libraries/create_config_category_problem.py +32 -0
- griptape_nodes/retained_mode/managers/fitness_problems/libraries/dependency_installation_failed_problem.py +32 -0
- griptape_nodes/retained_mode/managers/fitness_problems/libraries/deprecated_node_warning_problem.py +83 -0
- griptape_nodes/retained_mode/managers/fitness_problems/libraries/duplicate_library_problem.py +28 -0
- griptape_nodes/retained_mode/managers/fitness_problems/libraries/duplicate_node_registration_problem.py +44 -0
- griptape_nodes/retained_mode/managers/fitness_problems/libraries/engine_version_error_problem.py +28 -0
- griptape_nodes/retained_mode/managers/fitness_problems/libraries/insufficient_disk_space_problem.py +33 -0
- griptape_nodes/retained_mode/managers/fitness_problems/libraries/invalid_version_string_problem.py +32 -0
- griptape_nodes/retained_mode/managers/fitness_problems/libraries/library_json_decode_problem.py +28 -0
- griptape_nodes/retained_mode/managers/fitness_problems/libraries/library_load_exception_problem.py +32 -0
- griptape_nodes/retained_mode/managers/fitness_problems/libraries/library_not_found_problem.py +30 -0
- griptape_nodes/retained_mode/managers/fitness_problems/libraries/library_problem.py +20 -0
- griptape_nodes/retained_mode/managers/fitness_problems/libraries/library_schema_exception_problem.py +32 -0
- griptape_nodes/retained_mode/managers/fitness_problems/libraries/library_schema_validation_problem.py +38 -0
- griptape_nodes/retained_mode/managers/fitness_problems/libraries/modified_parameters_set_deprecation_warning_problem.py +44 -0
- griptape_nodes/retained_mode/managers/fitness_problems/libraries/modified_parameters_set_removed_problem.py +44 -0
- griptape_nodes/retained_mode/managers/fitness_problems/libraries/node_class_not_base_node_problem.py +40 -0
- griptape_nodes/retained_mode/managers/fitness_problems/libraries/node_class_not_found_problem.py +38 -0
- griptape_nodes/retained_mode/managers/fitness_problems/libraries/node_module_import_problem.py +53 -0
- griptape_nodes/retained_mode/managers/fitness_problems/libraries/sandbox_directory_missing_problem.py +28 -0
- griptape_nodes/retained_mode/managers/fitness_problems/libraries/ui_options_field_modified_incompatible_problem.py +44 -0
- griptape_nodes/retained_mode/managers/fitness_problems/libraries/ui_options_field_modified_warning_problem.py +35 -0
- griptape_nodes/retained_mode/managers/fitness_problems/libraries/update_config_category_problem.py +32 -0
- griptape_nodes/retained_mode/managers/fitness_problems/libraries/venv_creation_failed_problem.py +32 -0
- griptape_nodes/retained_mode/managers/fitness_problems/workflows/__init__.py +75 -0
- griptape_nodes/retained_mode/managers/fitness_problems/workflows/deprecated_node_in_workflow_problem.py +83 -0
- griptape_nodes/retained_mode/managers/fitness_problems/workflows/invalid_dependency_version_string_problem.py +38 -0
- griptape_nodes/retained_mode/managers/fitness_problems/workflows/invalid_library_version_string_problem.py +38 -0
- griptape_nodes/retained_mode/managers/fitness_problems/workflows/invalid_metadata_schema_problem.py +31 -0
- griptape_nodes/retained_mode/managers/fitness_problems/workflows/invalid_metadata_section_count_problem.py +31 -0
- griptape_nodes/retained_mode/managers/fitness_problems/workflows/invalid_toml_format_problem.py +30 -0
- griptape_nodes/retained_mode/managers/fitness_problems/workflows/library_not_registered_problem.py +35 -0
- griptape_nodes/retained_mode/managers/fitness_problems/workflows/library_version_below_required_problem.py +41 -0
- griptape_nodes/retained_mode/managers/fitness_problems/workflows/library_version_large_difference_problem.py +41 -0
- griptape_nodes/retained_mode/managers/fitness_problems/workflows/library_version_major_mismatch_problem.py +41 -0
- griptape_nodes/retained_mode/managers/fitness_problems/workflows/library_version_minor_difference_problem.py +41 -0
- griptape_nodes/retained_mode/managers/fitness_problems/workflows/missing_creation_date_problem.py +30 -0
- griptape_nodes/retained_mode/managers/fitness_problems/workflows/missing_last_modified_date_problem.py +30 -0
- griptape_nodes/retained_mode/managers/fitness_problems/workflows/missing_toml_section_problem.py +30 -0
- griptape_nodes/retained_mode/managers/fitness_problems/workflows/node_type_not_found_problem.py +51 -0
- griptape_nodes/retained_mode/managers/fitness_problems/workflows/workflow_not_found_problem.py +27 -0
- griptape_nodes/retained_mode/managers/fitness_problems/workflows/workflow_problem.py +20 -0
- griptape_nodes/retained_mode/managers/fitness_problems/workflows/workflow_schema_version_problem.py +39 -0
- griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/local_file.py +17 -3
- griptape_nodes/retained_mode/managers/library_manager.py +159 -75
- griptape_nodes/retained_mode/managers/model_manager.py +182 -205
- griptape_nodes/retained_mode/managers/os_manager.py +172 -1
- griptape_nodes/retained_mode/managers/settings.py +5 -0
- griptape_nodes/retained_mode/managers/version_compatibility_manager.py +76 -51
- griptape_nodes/retained_mode/managers/workflow_manager.py +154 -137
- griptape_nodes/servers/static.py +18 -19
- griptape_nodes/version_compatibility/versions/v0_39_0/modified_parameters_set_removal.py +16 -12
- griptape_nodes/version_compatibility/workflow_versions/v0_7_0/local_executor_argument_addition.py +6 -3
- {griptape_nodes-0.62.3.dist-info → griptape_nodes-0.63.1.dist-info}/METADATA +3 -2
- {griptape_nodes-0.62.3.dist-info → griptape_nodes-0.63.1.dist-info}/RECORD +76 -23
- {griptape_nodes-0.62.3.dist-info → griptape_nodes-0.63.1.dist-info}/WHEEL +0 -0
- {griptape_nodes-0.62.3.dist-info → griptape_nodes-0.63.1.dist-info}/entry_points.txt +0 -0
griptape_nodes/retained_mode/managers/fitness_problems/libraries/before_library_callback_problem.py
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
|
|
6
|
+
from griptape_nodes.retained_mode.managers.fitness_problems.libraries.library_problem import LibraryProblem
|
|
7
|
+
|
|
8
|
+
logger = logging.getLogger(__name__)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass
|
|
12
|
+
class BeforeLibraryCallbackProblem(LibraryProblem):
|
|
13
|
+
"""Problem indicating an error calling the before_library_nodes_loaded callback."""
|
|
14
|
+
|
|
15
|
+
error_message: str
|
|
16
|
+
|
|
17
|
+
@classmethod
|
|
18
|
+
def collate_problems_for_display(cls, instances: list[BeforeLibraryCallbackProblem]) -> str:
|
|
19
|
+
"""Display before library callback problem.
|
|
20
|
+
|
|
21
|
+
There should only be one instance per library since there's only one
|
|
22
|
+
before_library_nodes_loaded callback per library.
|
|
23
|
+
"""
|
|
24
|
+
if len(instances) > 1:
|
|
25
|
+
logger.error(
|
|
26
|
+
"BeforeLibraryCallbackProblem: Expected 1 instance but got %s. Each LibraryInfo should only have one BeforeLibraryCallbackProblem.",
|
|
27
|
+
len(instances),
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
# Use the first instance's error message
|
|
31
|
+
error_msg = instances[0].error_message
|
|
32
|
+
return f"Error calling before_library_nodes_loaded callback: {error_msg}"
|
griptape_nodes/retained_mode/managers/fitness_problems/libraries/create_config_category_problem.py
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
|
|
6
|
+
from griptape_nodes.retained_mode.managers.fitness_problems.libraries.library_problem import LibraryProblem
|
|
7
|
+
|
|
8
|
+
logger = logging.getLogger(__name__)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass
|
|
12
|
+
class CreateConfigCategoryProblem(LibraryProblem):
|
|
13
|
+
"""Problem indicating a config category failed to be created."""
|
|
14
|
+
|
|
15
|
+
category_name: str
|
|
16
|
+
|
|
17
|
+
@classmethod
|
|
18
|
+
def collate_problems_for_display(cls, instances: list[CreateConfigCategoryProblem]) -> str:
|
|
19
|
+
"""Display config category creation problem.
|
|
20
|
+
|
|
21
|
+
There should only be one instance per library since each LibraryInfo
|
|
22
|
+
is already associated with a specific library path.
|
|
23
|
+
"""
|
|
24
|
+
if len(instances) > 1:
|
|
25
|
+
logger.error(
|
|
26
|
+
"CreateConfigCategoryProblem: Expected 1 instance but got %s. Each LibraryInfo should only have one CreateConfigCategoryProblem.",
|
|
27
|
+
len(instances),
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
# Use the first instance's category name
|
|
31
|
+
category = instances[0].category_name
|
|
32
|
+
return f"Failed to create new config category '{category}'."
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
|
|
6
|
+
from griptape_nodes.retained_mode.managers.fitness_problems.libraries.library_problem import LibraryProblem
|
|
7
|
+
|
|
8
|
+
logger = logging.getLogger(__name__)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass
|
|
12
|
+
class DependencyInstallationFailedProblem(LibraryProblem):
|
|
13
|
+
"""Problem indicating dependency installation failed."""
|
|
14
|
+
|
|
15
|
+
error_details: str
|
|
16
|
+
|
|
17
|
+
@classmethod
|
|
18
|
+
def collate_problems_for_display(cls, instances: list[DependencyInstallationFailedProblem]) -> str:
|
|
19
|
+
"""Display dependency installation failed problem.
|
|
20
|
+
|
|
21
|
+
There should only be one instance per library since each LibraryInfo
|
|
22
|
+
is already associated with a specific library path.
|
|
23
|
+
"""
|
|
24
|
+
if len(instances) > 1:
|
|
25
|
+
logger.error(
|
|
26
|
+
"DependencyInstallationFailedProblem: Expected 1 instance but got %s. Each LibraryInfo should only have one DependencyInstallationFailedProblem.",
|
|
27
|
+
len(instances),
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
# Use the first instance's error details
|
|
31
|
+
details = instances[0].error_details
|
|
32
|
+
return f"Dependency installation failed: {details}"
|
griptape_nodes/retained_mode/managers/fitness_problems/libraries/deprecated_node_warning_problem.py
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from collections import defaultdict
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
|
|
7
|
+
from griptape_nodes.retained_mode.managers.fitness_problems.libraries.library_problem import LibraryProblem
|
|
8
|
+
|
|
9
|
+
logger = logging.getLogger(__name__)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass
|
|
13
|
+
class DeprecatedNodeWarningProblem(LibraryProblem):
|
|
14
|
+
"""Problem indicating a library contains deprecated nodes.
|
|
15
|
+
|
|
16
|
+
This is stackable - multiple nodes can be deprecated.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
display_name: str
|
|
20
|
+
class_name: str
|
|
21
|
+
removal_version: str | None
|
|
22
|
+
deprecation_message: str | None
|
|
23
|
+
|
|
24
|
+
@classmethod
|
|
25
|
+
def collate_problems_for_display(cls, instances: list[DeprecatedNodeWarningProblem]) -> str:
|
|
26
|
+
"""Display deprecated node warnings.
|
|
27
|
+
|
|
28
|
+
Groups by removal version, then lists nodes within each group.
|
|
29
|
+
"""
|
|
30
|
+
if len(instances) == 1:
|
|
31
|
+
problem = instances[0]
|
|
32
|
+
removal_info = (
|
|
33
|
+
f"will be removed in version {problem.removal_version}"
|
|
34
|
+
if problem.removal_version
|
|
35
|
+
else "may be removed in future versions"
|
|
36
|
+
)
|
|
37
|
+
message = f"Node '{problem.display_name}' is deprecated and {removal_info}."
|
|
38
|
+
if problem.deprecation_message:
|
|
39
|
+
message += f" {problem.deprecation_message}"
|
|
40
|
+
return message
|
|
41
|
+
|
|
42
|
+
# Group by removal version
|
|
43
|
+
by_version = defaultdict(list)
|
|
44
|
+
for problem in instances:
|
|
45
|
+
by_version[problem.removal_version].append(problem)
|
|
46
|
+
|
|
47
|
+
# Sort versions (None comes last)
|
|
48
|
+
sorted_versions = sorted(by_version.keys(), key=lambda v: (v is None, v or ""))
|
|
49
|
+
|
|
50
|
+
output_lines = []
|
|
51
|
+
output_lines.append(f"Encountered {len(instances)} deprecated nodes:")
|
|
52
|
+
|
|
53
|
+
for version in sorted_versions:
|
|
54
|
+
nodes = by_version[version]
|
|
55
|
+
|
|
56
|
+
if version is None:
|
|
57
|
+
output_lines.append(" Nodes that may be removed in future versions:")
|
|
58
|
+
else:
|
|
59
|
+
output_lines.append(f" Nodes to be removed in version {version}:")
|
|
60
|
+
|
|
61
|
+
# Group nodes within this version by deprecation_message
|
|
62
|
+
by_message = defaultdict(list)
|
|
63
|
+
for node in nodes:
|
|
64
|
+
# Use empty string as key if no message
|
|
65
|
+
message_key = node.deprecation_message if node.deprecation_message else ""
|
|
66
|
+
by_message[message_key].append(node)
|
|
67
|
+
|
|
68
|
+
# Sort messages alphabetically (empty string first)
|
|
69
|
+
sorted_messages = sorted(by_message.keys(), key=lambda m: (m != "", m))
|
|
70
|
+
|
|
71
|
+
for message in sorted_messages:
|
|
72
|
+
message_nodes = by_message[message]
|
|
73
|
+
# Sort nodes by display_name within each message group
|
|
74
|
+
message_nodes.sort(key=lambda p: p.display_name)
|
|
75
|
+
|
|
76
|
+
if message:
|
|
77
|
+
output_lines.append(f" {message}:")
|
|
78
|
+
output_lines.extend(f" - {node.display_name}" for node in message_nodes)
|
|
79
|
+
else:
|
|
80
|
+
# No deprecation message provided
|
|
81
|
+
output_lines.extend(f" - {node.display_name}" for node in message_nodes)
|
|
82
|
+
|
|
83
|
+
return "\n".join(output_lines)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
|
|
6
|
+
from griptape_nodes.retained_mode.managers.fitness_problems.libraries.library_problem import LibraryProblem
|
|
7
|
+
|
|
8
|
+
logger = logging.getLogger(__name__)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass
|
|
12
|
+
class DuplicateLibraryProblem(LibraryProblem):
|
|
13
|
+
"""Problem indicating a library with this name was already registered."""
|
|
14
|
+
|
|
15
|
+
@classmethod
|
|
16
|
+
def collate_problems_for_display(cls, instances: list[DuplicateLibraryProblem]) -> str:
|
|
17
|
+
"""Display duplicate library problem.
|
|
18
|
+
|
|
19
|
+
There should only be one instance per library since each LibraryInfo
|
|
20
|
+
is already associated with a specific library path.
|
|
21
|
+
"""
|
|
22
|
+
if len(instances) > 1:
|
|
23
|
+
logger.error(
|
|
24
|
+
"DuplicateLibraryProblem: Expected 1 instance but got %s. Each LibraryInfo should only have one DuplicateLibraryProblem.",
|
|
25
|
+
len(instances),
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
return "Failed because a library with this name was already registered. Check the Settings to ensure duplicate libraries are not being loaded."
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
|
|
6
|
+
from griptape_nodes.retained_mode.managers.fitness_problems.libraries.library_problem import LibraryProblem
|
|
7
|
+
|
|
8
|
+
logger = logging.getLogger(__name__)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass
|
|
12
|
+
class DuplicateNodeRegistrationProblem(LibraryProblem):
|
|
13
|
+
"""Problem indicating a node class was already registered.
|
|
14
|
+
|
|
15
|
+
This is stackable - multiple duplicate registrations can occur.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
class_name: str
|
|
19
|
+
library_name: str
|
|
20
|
+
|
|
21
|
+
@classmethod
|
|
22
|
+
def collate_problems_for_display(cls, instances: list[DuplicateNodeRegistrationProblem]) -> str:
|
|
23
|
+
"""Display duplicate node registration problems.
|
|
24
|
+
|
|
25
|
+
Can handle multiple duplicates - they will be listed out sorted by class_name.
|
|
26
|
+
"""
|
|
27
|
+
if len(instances) == 1:
|
|
28
|
+
problem = instances[0]
|
|
29
|
+
return (
|
|
30
|
+
f"Attempted to register node class '{problem.class_name}' from library '{problem.library_name}', "
|
|
31
|
+
f"but a node with that name from that library was already registered. "
|
|
32
|
+
"Check to ensure you aren't re-adding the same libraries multiple times."
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
# Multiple duplicate registrations - list them sorted by class_name
|
|
36
|
+
sorted_instances = sorted(instances, key=lambda p: p.class_name)
|
|
37
|
+
error_lines = []
|
|
38
|
+
for i, problem in enumerate(sorted_instances, 1):
|
|
39
|
+
error_lines.append(
|
|
40
|
+
f" {i}. Node '{problem.class_name}' from library '{problem.library_name}' already registered"
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
header = f"Encountered {len(instances)} duplicate node registrations:"
|
|
44
|
+
return header + "\n" + "\n".join(error_lines)
|
griptape_nodes/retained_mode/managers/fitness_problems/libraries/engine_version_error_problem.py
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
|
|
6
|
+
from griptape_nodes.retained_mode.managers.fitness_problems.libraries.library_problem import LibraryProblem
|
|
7
|
+
|
|
8
|
+
logger = logging.getLogger(__name__)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass
|
|
12
|
+
class EngineVersionErrorProblem(LibraryProblem):
|
|
13
|
+
"""Problem indicating the engine version could not be retrieved for sandbox library generation."""
|
|
14
|
+
|
|
15
|
+
@classmethod
|
|
16
|
+
def collate_problems_for_display(cls, instances: list[EngineVersionErrorProblem]) -> str:
|
|
17
|
+
"""Display engine version error problem.
|
|
18
|
+
|
|
19
|
+
There should only be one instance per library since each LibraryInfo
|
|
20
|
+
is already associated with a specific library path.
|
|
21
|
+
"""
|
|
22
|
+
if len(instances) > 1:
|
|
23
|
+
logger.error(
|
|
24
|
+
"EngineVersionErrorProblem: Expected 1 instance but got %s. Each LibraryInfo should only have one EngineVersionErrorProblem.",
|
|
25
|
+
len(instances),
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
return "Could not get engine version for sandbox library generation."
|
griptape_nodes/retained_mode/managers/fitness_problems/libraries/insufficient_disk_space_problem.py
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
|
|
6
|
+
from griptape_nodes.retained_mode.managers.fitness_problems.libraries.library_problem import LibraryProblem
|
|
7
|
+
|
|
8
|
+
logger = logging.getLogger(__name__)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass
|
|
12
|
+
class InsufficientDiskSpaceProblem(LibraryProblem):
|
|
13
|
+
"""Problem indicating insufficient disk space for dependencies."""
|
|
14
|
+
|
|
15
|
+
min_space_gb: float
|
|
16
|
+
error_message: str
|
|
17
|
+
|
|
18
|
+
@classmethod
|
|
19
|
+
def collate_problems_for_display(cls, instances: list[InsufficientDiskSpaceProblem]) -> str:
|
|
20
|
+
"""Display insufficient disk space problem.
|
|
21
|
+
|
|
22
|
+
There should only be one instance per library since each LibraryInfo
|
|
23
|
+
is already associated with a specific library path.
|
|
24
|
+
"""
|
|
25
|
+
if len(instances) > 1:
|
|
26
|
+
logger.error(
|
|
27
|
+
"InsufficientDiskSpaceProblem: Expected 1 instance but got %s. Each LibraryInfo should only have one InsufficientDiskSpaceProblem.",
|
|
28
|
+
len(instances),
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
# Use the first instance's details
|
|
32
|
+
problem = instances[0]
|
|
33
|
+
return f"Insufficient disk space for dependencies (requires {problem.min_space_gb} GB): {problem.error_message}"
|
griptape_nodes/retained_mode/managers/fitness_problems/libraries/invalid_version_string_problem.py
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
|
|
6
|
+
from griptape_nodes.retained_mode.managers.fitness_problems.libraries.library_problem import LibraryProblem
|
|
7
|
+
|
|
8
|
+
logger = logging.getLogger(__name__)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass
|
|
12
|
+
class InvalidVersionStringProblem(LibraryProblem):
|
|
13
|
+
"""Problem indicating a library's version string is not valid (must be major.minor.patch format)."""
|
|
14
|
+
|
|
15
|
+
version_string: str
|
|
16
|
+
|
|
17
|
+
@classmethod
|
|
18
|
+
def collate_problems_for_display(cls, instances: list[InvalidVersionStringProblem]) -> str:
|
|
19
|
+
"""Display invalid version string problem.
|
|
20
|
+
|
|
21
|
+
There should only be one instance per library since each LibraryInfo
|
|
22
|
+
is already associated with a specific library path.
|
|
23
|
+
"""
|
|
24
|
+
if len(instances) > 1:
|
|
25
|
+
logger.error(
|
|
26
|
+
"InvalidVersionStringProblem: Expected 1 instance but got %s. Each LibraryInfo should only have one InvalidVersionStringProblem.",
|
|
27
|
+
len(instances),
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
# Use the first instance's version string
|
|
31
|
+
version = instances[0].version_string
|
|
32
|
+
return f"Library's version string '{version}' wasn't valid. Must be in major.minor.patch format."
|
griptape_nodes/retained_mode/managers/fitness_problems/libraries/library_json_decode_problem.py
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
|
|
6
|
+
from griptape_nodes.retained_mode.managers.fitness_problems.libraries.library_problem import LibraryProblem
|
|
7
|
+
|
|
8
|
+
logger = logging.getLogger(__name__)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass
|
|
12
|
+
class LibraryJsonDecodeProblem(LibraryProblem):
|
|
13
|
+
"""Problem indicating a library file is not properly formatted JSON."""
|
|
14
|
+
|
|
15
|
+
@classmethod
|
|
16
|
+
def collate_problems_for_display(cls, instances: list[LibraryJsonDecodeProblem]) -> str:
|
|
17
|
+
"""Display library JSON decode problem.
|
|
18
|
+
|
|
19
|
+
There should only be one instance per library since each LibraryInfo
|
|
20
|
+
is already associated with a specific library path.
|
|
21
|
+
"""
|
|
22
|
+
if len(instances) > 1:
|
|
23
|
+
logger.error(
|
|
24
|
+
"LibraryJsonDecodeProblem: Expected 1 instance but got %s. Each LibraryInfo should only have one LibraryJsonDecodeProblem.",
|
|
25
|
+
len(instances),
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
return "Library file not formatted as proper JSON."
|
griptape_nodes/retained_mode/managers/fitness_problems/libraries/library_load_exception_problem.py
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
|
|
6
|
+
from griptape_nodes.retained_mode.managers.fitness_problems.libraries.library_problem import LibraryProblem
|
|
7
|
+
|
|
8
|
+
logger = logging.getLogger(__name__)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass
|
|
12
|
+
class LibraryLoadExceptionProblem(LibraryProblem):
|
|
13
|
+
"""Problem indicating an exception occurred while loading the library file."""
|
|
14
|
+
|
|
15
|
+
error_message: str
|
|
16
|
+
|
|
17
|
+
@classmethod
|
|
18
|
+
def collate_problems_for_display(cls, instances: list[LibraryLoadExceptionProblem]) -> str:
|
|
19
|
+
"""Display library load exception problem.
|
|
20
|
+
|
|
21
|
+
There should only be one instance per library since each LibraryInfo
|
|
22
|
+
is already associated with a specific library path.
|
|
23
|
+
"""
|
|
24
|
+
if len(instances) > 1:
|
|
25
|
+
logger.error(
|
|
26
|
+
"LibraryLoadExceptionProblem: Expected 1 instance but got %s. Each LibraryInfo should only have one LibraryLoadExceptionProblem.",
|
|
27
|
+
len(instances),
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
# Use the first instance's error message
|
|
31
|
+
error_msg = instances[0].error_message
|
|
32
|
+
return f"Exception occurred when attempting to load the library: {error_msg}."
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
|
|
6
|
+
from griptape_nodes.retained_mode.managers.fitness_problems.libraries.library_problem import LibraryProblem
|
|
7
|
+
|
|
8
|
+
logger = logging.getLogger(__name__)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass
|
|
12
|
+
class LibraryNotFoundProblem(LibraryProblem):
|
|
13
|
+
"""Problem indicating a library file could not be found at the specified path."""
|
|
14
|
+
|
|
15
|
+
library_path: str
|
|
16
|
+
|
|
17
|
+
@classmethod
|
|
18
|
+
def collate_problems_for_display(cls, instances: list[LibraryNotFoundProblem]) -> str:
|
|
19
|
+
"""Display library not found problem.
|
|
20
|
+
|
|
21
|
+
There should only be one instance per library since each LibraryInfo
|
|
22
|
+
is already associated with a specific library path.
|
|
23
|
+
"""
|
|
24
|
+
if len(instances) > 1:
|
|
25
|
+
logger.error(
|
|
26
|
+
"LibraryNotFoundProblem: Expected 1 instance but got %s. Each LibraryInfo should only have one LibraryNotFoundProblem.",
|
|
27
|
+
len(instances),
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
return "Library could not be found at the file path specified. It will be removed from the configuration."
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
from typing import Self
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class LibraryProblem(ABC):
|
|
6
|
+
"""Base class for all library fitness problems."""
|
|
7
|
+
|
|
8
|
+
@classmethod
|
|
9
|
+
@abstractmethod
|
|
10
|
+
def collate_problems_for_display(cls, instances: list[Self]) -> str:
|
|
11
|
+
"""Display one or more instances of this problem type.
|
|
12
|
+
|
|
13
|
+
Handles both single and multiple instances with appropriate formatting.
|
|
14
|
+
|
|
15
|
+
Args:
|
|
16
|
+
instances: List of problem instances of this type to display.
|
|
17
|
+
|
|
18
|
+
Returns:
|
|
19
|
+
Formatted string describing the problem(s).
|
|
20
|
+
"""
|
griptape_nodes/retained_mode/managers/fitness_problems/libraries/library_schema_exception_problem.py
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
|
|
6
|
+
from griptape_nodes.retained_mode.managers.fitness_problems.libraries.library_problem import LibraryProblem
|
|
7
|
+
|
|
8
|
+
logger = logging.getLogger(__name__)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass
|
|
12
|
+
class LibrarySchemaExceptionProblem(LibraryProblem):
|
|
13
|
+
"""Problem indicating an unexpected exception during schema validation."""
|
|
14
|
+
|
|
15
|
+
error_message: str
|
|
16
|
+
|
|
17
|
+
@classmethod
|
|
18
|
+
def collate_problems_for_display(cls, instances: list[LibrarySchemaExceptionProblem]) -> str:
|
|
19
|
+
"""Display library schema exception problem.
|
|
20
|
+
|
|
21
|
+
There should only be one instance per library since each LibraryInfo
|
|
22
|
+
is already associated with a specific library path.
|
|
23
|
+
"""
|
|
24
|
+
if len(instances) > 1:
|
|
25
|
+
logger.error(
|
|
26
|
+
"LibrarySchemaExceptionProblem: Expected 1 instance but got %s. Each LibraryInfo should only have one LibrarySchemaExceptionProblem.",
|
|
27
|
+
len(instances),
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
# Use the first instance's error message
|
|
31
|
+
error_msg = instances[0].error_message
|
|
32
|
+
return f"Library file did not match the library schema specified due to: {error_msg}"
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
|
|
6
|
+
from griptape_nodes.retained_mode.managers.fitness_problems.libraries.library_problem import LibraryProblem
|
|
7
|
+
|
|
8
|
+
logger = logging.getLogger(__name__)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass
|
|
12
|
+
class LibrarySchemaValidationProblem(LibraryProblem):
|
|
13
|
+
"""Problem indicating a library schema validation error.
|
|
14
|
+
|
|
15
|
+
This is stackable - multiple validation errors can occur when validating a library schema.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
location: str
|
|
19
|
+
error_type: str
|
|
20
|
+
message: str
|
|
21
|
+
|
|
22
|
+
@classmethod
|
|
23
|
+
def collate_problems_for_display(cls, instances: list[LibrarySchemaValidationProblem]) -> str:
|
|
24
|
+
"""Display library schema validation problems.
|
|
25
|
+
|
|
26
|
+
Can handle multiple validation errors - they will be listed out.
|
|
27
|
+
"""
|
|
28
|
+
if len(instances) == 1:
|
|
29
|
+
problem = instances[0]
|
|
30
|
+
return f"Error in section '{problem.location}': {problem.error_type}, {problem.message}"
|
|
31
|
+
|
|
32
|
+
# Multiple validation errors - list them
|
|
33
|
+
error_lines = []
|
|
34
|
+
for i, problem in enumerate(instances, 1):
|
|
35
|
+
error_lines.append(f" {i}. Error in section '{problem.location}': {problem.error_type}, {problem.message}")
|
|
36
|
+
|
|
37
|
+
header = f"Encountered {len(instances)} schema validation errors:"
|
|
38
|
+
return header + "\n" + "\n".join(error_lines)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
|
|
6
|
+
from griptape_nodes.retained_mode.managers.fitness_problems.libraries.library_problem import LibraryProblem
|
|
7
|
+
|
|
8
|
+
logger = logging.getLogger(__name__)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass
|
|
12
|
+
class ModifiedParametersSetDeprecationWarningProblem(LibraryProblem):
|
|
13
|
+
"""Problem warning that a library will be incompatible in the next version due to modified_parameters_set removal.
|
|
14
|
+
|
|
15
|
+
This is stackable - multiple libraries can have this warning.
|
|
16
|
+
This severity is FLAWED - the library can be loaded but has warnings.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
library_engine_version: str
|
|
20
|
+
|
|
21
|
+
@classmethod
|
|
22
|
+
def collate_problems_for_display(cls, instances: list[ModifiedParametersSetDeprecationWarningProblem]) -> str:
|
|
23
|
+
"""Display modified_parameters_set deprecation warnings.
|
|
24
|
+
|
|
25
|
+
Can handle multiple instances - they will be listed out sorted by library_engine_version.
|
|
26
|
+
"""
|
|
27
|
+
if len(instances) == 1:
|
|
28
|
+
version = instances[0].library_engine_version
|
|
29
|
+
return (
|
|
30
|
+
f"WARNING: The 'modified_parameters_set' parameter will be removed in Griptape Nodes 0.39 from BaseNode methods: 'after_incoming_connection', 'after_outgoing_connection', 'after_incoming_connection_removed', 'after_outgoing_connection_removed', 'before_value_set', and 'after_value_set'. "
|
|
31
|
+
f"This library (built for engine version {version}) must be updated before the 0.39 release. "
|
|
32
|
+
"If this library overrides any of these methods, it will fail to load in 0.39. If not, no action is necessary. Please contact the library author to confirm whether this library is impacted."
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
# Multiple libraries with this warning - list them sorted by version
|
|
36
|
+
sorted_instances = sorted(instances, key=lambda p: p.library_engine_version)
|
|
37
|
+
error_lines = []
|
|
38
|
+
for i, problem in enumerate(sorted_instances, 1):
|
|
39
|
+
error_lines.append(
|
|
40
|
+
f" {i}. Library built for engine version {problem.library_engine_version} may be impacted by upcoming modified_parameters_set removal"
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
header = f"Encountered {len(instances)} libraries with modified_parameters_set deprecation warnings:"
|
|
44
|
+
return header + "\n" + "\n".join(error_lines)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
|
|
6
|
+
from griptape_nodes.retained_mode.managers.fitness_problems.libraries.library_problem import LibraryProblem
|
|
7
|
+
|
|
8
|
+
logger = logging.getLogger(__name__)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass
|
|
12
|
+
class ModifiedParametersSetRemovedProblem(LibraryProblem):
|
|
13
|
+
"""Problem indicating a library is incompatible due to modified_parameters_set removal.
|
|
14
|
+
|
|
15
|
+
This is stackable - multiple libraries can have this issue.
|
|
16
|
+
This severity is UNUSABLE - the library cannot be loaded.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
library_engine_version: str
|
|
20
|
+
|
|
21
|
+
@classmethod
|
|
22
|
+
def collate_problems_for_display(cls, instances: list[ModifiedParametersSetRemovedProblem]) -> str:
|
|
23
|
+
"""Display modified_parameters_set removal problems.
|
|
24
|
+
|
|
25
|
+
Can handle multiple instances - they will be listed out sorted by library_engine_version.
|
|
26
|
+
"""
|
|
27
|
+
if len(instances) == 1:
|
|
28
|
+
version = instances[0].library_engine_version
|
|
29
|
+
return (
|
|
30
|
+
f"This library (built for engine version {version}) is incompatible with Griptape Nodes 0.39+. "
|
|
31
|
+
"The 'modified_parameters_set' parameter has been removed from BaseNode methods: 'after_incoming_connection', 'after_outgoing_connection', 'after_incoming_connection_removed', 'after_outgoing_connection_removed', 'before_value_set', and 'after_value_set'. "
|
|
32
|
+
"If this library overrides any of these methods, it will not load or function properly. Please update to a newer version of this library or contact the library author immediately."
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
# Multiple libraries with this issue - list them sorted by version
|
|
36
|
+
sorted_instances = sorted(instances, key=lambda p: p.library_engine_version)
|
|
37
|
+
error_lines = []
|
|
38
|
+
for i, problem in enumerate(sorted_instances, 1):
|
|
39
|
+
error_lines.append(
|
|
40
|
+
f" {i}. Library built for engine version {problem.library_engine_version} is incompatible due to modified_parameters_set removal"
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
header = f"Encountered {len(instances)} libraries incompatible due to modified_parameters_set removal:"
|
|
44
|
+
return header + "\n" + "\n".join(error_lines)
|
griptape_nodes/retained_mode/managers/fitness_problems/libraries/node_class_not_base_node_problem.py
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
|
|
6
|
+
from griptape_nodes.retained_mode.managers.fitness_problems.libraries.library_problem import LibraryProblem
|
|
7
|
+
|
|
8
|
+
logger = logging.getLogger(__name__)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass
|
|
12
|
+
class NodeClassNotBaseNodeProblem(LibraryProblem):
|
|
13
|
+
"""Problem indicating a node class doesn't inherit from BaseNode.
|
|
14
|
+
|
|
15
|
+
This is stackable - multiple node classes can have incorrect inheritance.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
class_name: str
|
|
19
|
+
file_path: str
|
|
20
|
+
|
|
21
|
+
@classmethod
|
|
22
|
+
def collate_problems_for_display(cls, instances: list[NodeClassNotBaseNodeProblem]) -> str:
|
|
23
|
+
"""Display node class inheritance problems.
|
|
24
|
+
|
|
25
|
+
Can handle multiple non-BaseNode classes - they will be listed out sorted by class_name.
|
|
26
|
+
"""
|
|
27
|
+
if len(instances) == 1:
|
|
28
|
+
problem = instances[0]
|
|
29
|
+
return f"Class '{problem.class_name}' from {problem.file_path} must inherit from BaseNode"
|
|
30
|
+
|
|
31
|
+
# Multiple inheritance issues - list them sorted by class_name
|
|
32
|
+
sorted_instances = sorted(instances, key=lambda p: p.class_name)
|
|
33
|
+
error_lines = []
|
|
34
|
+
for i, problem in enumerate(sorted_instances, 1):
|
|
35
|
+
error_lines.append(
|
|
36
|
+
f" {i}. Class '{problem.class_name}' from {problem.file_path} must inherit from BaseNode"
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
header = f"Encountered {len(instances)} node classes that don't inherit from BaseNode:"
|
|
40
|
+
return header + "\n" + "\n".join(error_lines)
|