griptape-nodes 0.57.1__py3-none-any.whl → 0.58.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.
Files changed (51) hide show
  1. griptape_nodes/api_client/__init__.py +9 -0
  2. griptape_nodes/api_client/client.py +279 -0
  3. griptape_nodes/api_client/request_client.py +273 -0
  4. griptape_nodes/app/app.py +57 -150
  5. griptape_nodes/bootstrap/utils/python_subprocess_executor.py +1 -1
  6. griptape_nodes/bootstrap/workflow_executors/local_session_workflow_executor.py +22 -50
  7. griptape_nodes/bootstrap/workflow_executors/local_workflow_executor.py +6 -1
  8. griptape_nodes/bootstrap/workflow_executors/subprocess_workflow_executor.py +27 -46
  9. griptape_nodes/bootstrap/workflow_executors/utils/subprocess_script.py +7 -0
  10. griptape_nodes/bootstrap/workflow_publishers/local_workflow_publisher.py +3 -1
  11. griptape_nodes/bootstrap/workflow_publishers/subprocess_workflow_publisher.py +3 -1
  12. griptape_nodes/bootstrap/workflow_publishers/utils/subprocess_script.py +16 -1
  13. griptape_nodes/common/node_executor.py +466 -0
  14. griptape_nodes/drivers/storage/base_storage_driver.py +0 -11
  15. griptape_nodes/drivers/storage/griptape_cloud_storage_driver.py +7 -25
  16. griptape_nodes/drivers/storage/local_storage_driver.py +2 -2
  17. griptape_nodes/exe_types/connections.py +37 -9
  18. griptape_nodes/exe_types/core_types.py +1 -1
  19. griptape_nodes/exe_types/node_types.py +115 -22
  20. griptape_nodes/machines/control_flow.py +48 -7
  21. griptape_nodes/machines/parallel_resolution.py +98 -29
  22. griptape_nodes/machines/sequential_resolution.py +61 -22
  23. griptape_nodes/node_library/library_registry.py +24 -1
  24. griptape_nodes/node_library/workflow_registry.py +38 -2
  25. griptape_nodes/retained_mode/events/execution_events.py +8 -1
  26. griptape_nodes/retained_mode/events/flow_events.py +90 -3
  27. griptape_nodes/retained_mode/events/node_events.py +17 -10
  28. griptape_nodes/retained_mode/events/workflow_events.py +5 -0
  29. griptape_nodes/retained_mode/griptape_nodes.py +16 -219
  30. griptape_nodes/retained_mode/managers/config_manager.py +0 -46
  31. griptape_nodes/retained_mode/managers/engine_identity_manager.py +225 -74
  32. griptape_nodes/retained_mode/managers/flow_manager.py +1276 -230
  33. griptape_nodes/retained_mode/managers/library_manager.py +7 -8
  34. griptape_nodes/retained_mode/managers/node_manager.py +197 -9
  35. griptape_nodes/retained_mode/managers/secrets_manager.py +26 -0
  36. griptape_nodes/retained_mode/managers/session_manager.py +264 -227
  37. griptape_nodes/retained_mode/managers/settings.py +4 -38
  38. griptape_nodes/retained_mode/managers/static_files_manager.py +3 -3
  39. griptape_nodes/retained_mode/managers/version_compatibility_manager.py +135 -6
  40. griptape_nodes/retained_mode/managers/workflow_manager.py +206 -78
  41. griptape_nodes/servers/mcp.py +23 -15
  42. griptape_nodes/utils/async_utils.py +36 -0
  43. griptape_nodes/utils/dict_utils.py +8 -2
  44. griptape_nodes/version_compatibility/versions/v0_39_0/modified_parameters_set_removal.py +11 -6
  45. griptape_nodes/version_compatibility/workflow_versions/v0_7_0/local_executor_argument_addition.py +12 -5
  46. {griptape_nodes-0.57.1.dist-info → griptape_nodes-0.58.1.dist-info}/METADATA +4 -3
  47. {griptape_nodes-0.57.1.dist-info → griptape_nodes-0.58.1.dist-info}/RECORD +49 -47
  48. {griptape_nodes-0.57.1.dist-info → griptape_nodes-0.58.1.dist-info}/WHEEL +1 -1
  49. griptape_nodes/retained_mode/utils/engine_identity.py +0 -245
  50. griptape_nodes/servers/ws_request_manager.py +0 -268
  51. {griptape_nodes-0.57.1.dist-info → griptape_nodes-0.58.1.dist-info}/entry_points.txt +0 -0
@@ -109,7 +109,7 @@ class StaticFilesManager:
109
109
 
110
110
  try:
111
111
  url = self.save_static_file(content_bytes, file_name)
112
- except ValueError as e:
112
+ except Exception as e:
113
113
  msg = f"Failed to create static file for file {file_name}: {e}"
114
114
  logger.error(msg)
115
115
  return CreateStaticFileResultFailure(error=msg, result_details=msg)
@@ -135,7 +135,7 @@ class StaticFilesManager:
135
135
 
136
136
  try:
137
137
  response = self.storage_driver.create_signed_upload_url(full_file_path)
138
- except ValueError as e:
138
+ except Exception as e:
139
139
  msg = f"Failed to create presigned URL for file {file_name}: {e}"
140
140
  logger.error(msg)
141
141
  return CreateStaticFileUploadUrlResultFailure(error=msg, result_details=msg)
@@ -166,7 +166,7 @@ class StaticFilesManager:
166
166
 
167
167
  try:
168
168
  url = self.storage_driver.create_signed_download_url(full_file_path)
169
- except ValueError as e:
169
+ except Exception as e:
170
170
  msg = f"Failed to create presigned URL for file {file_name}: {e}"
171
171
  logger.error(msg)
172
172
  return CreateStaticFileDownloadUrlResultFailure(error=msg, result_details=msg)
@@ -6,17 +6,25 @@ from abc import ABC, abstractmethod
6
6
  from pathlib import Path
7
7
  from typing import TYPE_CHECKING, NamedTuple
8
8
 
9
+ import semver
10
+
9
11
  from griptape_nodes.retained_mode.events.app_events import (
10
12
  GetEngineVersionRequest,
11
13
  GetEngineVersionResultSuccess,
12
14
  )
13
- from griptape_nodes.retained_mode.griptape_nodes import GriptapeNodes, Version
15
+ from griptape_nodes.retained_mode.events.library_events import (
16
+ GetLibraryMetadataRequest,
17
+ GetLibraryMetadataResultSuccess,
18
+ GetNodeMetadataFromLibraryRequest,
19
+ GetNodeMetadataFromLibraryResultSuccess,
20
+ )
21
+ from griptape_nodes.retained_mode.griptape_nodes import GriptapeNodes
22
+ from griptape_nodes.retained_mode.managers.library_lifecycle.library_status import LibraryStatus
14
23
 
15
24
  if TYPE_CHECKING:
16
25
  from griptape_nodes.node_library.library_registry import LibrarySchema
17
26
  from griptape_nodes.node_library.workflow_registry import WorkflowMetadata
18
27
  from griptape_nodes.retained_mode.managers.event_manager import EventManager
19
- from griptape_nodes.retained_mode.managers.library_lifecycle.library_status import LibraryStatus
20
28
  from griptape_nodes.retained_mode.managers.workflow_manager import WorkflowManager
21
29
 
22
30
  logger = logging.getLogger("griptape_nodes")
@@ -151,11 +159,24 @@ class VersionCompatibilityManager:
151
159
  self._workflow_compatibility_checks.append(check_instance)
152
160
  logger.debug("Registered workflow version compatibility check: %s", attr_name)
153
161
 
162
+ def _check_library_for_deprecated_nodes(
163
+ self, library_data: LibrarySchema
164
+ ) -> list[LibraryVersionCompatibilityIssue]:
165
+ """Check a library for deprecated nodes."""
166
+ return [
167
+ LibraryVersionCompatibilityIssue(
168
+ message=f"Node '{node.metadata.display_name}' (class: {node.class_name}) is deprecated and {'will be removed in version ' + node.metadata.deprecation.removal_version if node.metadata.deprecation.removal_version else 'may be removed in future versions'}. {node.metadata.deprecation.deprecation_message or ''}".strip(),
169
+ severity=LibraryStatus.FLAWED,
170
+ )
171
+ for node in library_data.nodes
172
+ if node.metadata.deprecation is not None
173
+ ] or []
174
+
154
175
  def check_library_version_compatibility(
155
176
  self, library_data: LibrarySchema
156
177
  ) -> list[LibraryVersionCompatibilityIssue]:
157
178
  """Check a library for version compatibility issues."""
158
- version_issues = []
179
+ version_issues: list[LibraryVersionCompatibilityIssue] = []
159
180
 
160
181
  # Run all discovered compatibility checks
161
182
  for check_instance in self._compatibility_checks:
@@ -163,13 +184,15 @@ class VersionCompatibilityManager:
163
184
  issues = check_instance.check_library(library_data)
164
185
  version_issues.extend(issues)
165
186
 
187
+ version_issues.extend(self._check_library_for_deprecated_nodes(library_data))
188
+
166
189
  return version_issues
167
190
 
168
191
  def check_workflow_version_compatibility(
169
192
  self, workflow_metadata: WorkflowMetadata
170
193
  ) -> list[WorkflowVersionCompatibilityIssue]:
171
194
  """Check a workflow for version compatibility issues."""
172
- version_issues = []
195
+ version_issues: list[WorkflowVersionCompatibilityIssue] = []
173
196
 
174
197
  # Run all discovered workflow compatibility checks
175
198
  for check_instance in self._workflow_compatibility_checks:
@@ -177,12 +200,118 @@ class VersionCompatibilityManager:
177
200
  issues = check_instance.check_workflow(workflow_metadata)
178
201
  version_issues.extend(issues)
179
202
 
203
+ # Check for deprecated nodes in the workflow
204
+ version_issues.extend(self._check_workflow_for_deprecated_nodes(workflow_metadata))
205
+
180
206
  return version_issues
181
207
 
182
- def _get_current_engine_version(self) -> Version:
208
+ def _check_workflow_for_deprecated_nodes( # noqa: C901, PLR0912
209
+ self, workflow_metadata: WorkflowMetadata
210
+ ) -> list[WorkflowVersionCompatibilityIssue]:
211
+ """Check a workflow for deprecated nodes.
212
+
213
+ Examines each node type used in the workflow to determine if any are deprecated
214
+ in their respective libraries. Returns warnings for deprecated nodes.
215
+ """
216
+ issues: list[WorkflowVersionCompatibilityIssue] = []
217
+
218
+ for library_name_and_node_type in workflow_metadata.node_types_used:
219
+ library_name = library_name_and_node_type.library_name
220
+ node_type = library_name_and_node_type.node_type
221
+
222
+ # Get library metadata to check if library exists and get version
223
+ library_metadata_request = GetLibraryMetadataRequest(library=library_name)
224
+ library_metadata_result = GriptapeNodes.LibraryManager().get_library_metadata_request(
225
+ library_metadata_request
226
+ )
227
+
228
+ if not isinstance(library_metadata_result, GetLibraryMetadataResultSuccess):
229
+ # Library not found - skip this node, other checks handle missing libraries
230
+ continue
231
+
232
+ current_library_version = library_metadata_result.metadata.library_version
233
+
234
+ # Get workflow's saved library version
235
+ workflow_library_version = None
236
+ for lib_ref in workflow_metadata.node_libraries_referenced:
237
+ if lib_ref.library_name == library_name:
238
+ workflow_library_version = lib_ref.library_version
239
+ break
240
+
241
+ # Get node metadata from library
242
+ node_metadata_request = GetNodeMetadataFromLibraryRequest(library=library_name, node_type=node_type)
243
+ node_metadata_result = GriptapeNodes.LibraryManager().get_node_metadata_from_library_request(
244
+ node_metadata_request
245
+ )
246
+
247
+ if not isinstance(node_metadata_result, GetNodeMetadataFromLibraryResultSuccess):
248
+ # Node type doesn't exist in current library version
249
+ message = f"This workflow uses node type '{node_type}' from library '{library_name}', but this node type is not found in the current library version {current_library_version}"
250
+
251
+ if workflow_library_version:
252
+ message += f". The workflow was saved with library version {workflow_library_version}"
253
+
254
+ message += ". This node may have been removed or renamed. Contact the library author for more details."
255
+
256
+ issues.append(
257
+ WorkflowVersionCompatibilityIssue(
258
+ message=message,
259
+ severity=GriptapeNodes.WorkflowManager().WorkflowStatus.FLAWED,
260
+ )
261
+ )
262
+ continue
263
+
264
+ node_metadata = node_metadata_result.metadata
265
+
266
+ if node_metadata.deprecation is None:
267
+ continue
268
+
269
+ deprecation = node_metadata.deprecation
270
+
271
+ removal_version_reached = False
272
+ if deprecation.removal_version:
273
+ try:
274
+ current_version = semver.VersionInfo.parse(current_library_version)
275
+ removal_version = semver.VersionInfo.parse(deprecation.removal_version)
276
+ removal_version_reached = current_version >= removal_version
277
+ except Exception:
278
+ # Errored out trying to parse the version strings; assume not reached.
279
+ removal_version_reached = False
280
+
281
+ # Build the complete message
282
+ message = f"This workflow uses node '{node_metadata.display_name}' (class: {node_type}) from library '{library_name}', which is deprecated"
283
+
284
+ if deprecation.removal_version:
285
+ if removal_version_reached:
286
+ message += f" and was removed in version {deprecation.removal_version}"
287
+ else:
288
+ message += f" and will be removed in version {deprecation.removal_version}"
289
+ else:
290
+ message += " and may be removed in future versions"
291
+
292
+ message += f". You are currently using library version: {current_library_version}"
293
+
294
+ if workflow_library_version:
295
+ message += f", and the workflow was saved with library version: {workflow_library_version}"
296
+
297
+ if deprecation.deprecation_message:
298
+ message += f". The library author provided the following message for this deprecation: {deprecation.deprecation_message}"
299
+ else:
300
+ message += ". The library author did not provide a message explaining the deprecation. Contact the library author for details on how to remedy this."
301
+
302
+ issues.append(
303
+ WorkflowVersionCompatibilityIssue(
304
+ message=message,
305
+ severity=GriptapeNodes.WorkflowManager().WorkflowStatus.FLAWED,
306
+ )
307
+ )
308
+
309
+ return issues
310
+
311
+ def _get_current_engine_version(self) -> semver.VersionInfo:
183
312
  """Get the current engine version."""
184
313
  result = GriptapeNodes.handle_request(GetEngineVersionRequest())
185
314
  if isinstance(result, GetEngineVersionResultSuccess):
186
- return Version(major=result.major, minor=result.minor, patch=result.patch)
315
+ return semver.VersionInfo(major=result.major, minor=result.minor, patch=result.patch)
187
316
  msg = "Failed to get engine version"
188
317
  raise RuntimeError(msg)