griptape-nodes 0.62.3__tar.gz → 0.63.1__tar.gz

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 (269) hide show
  1. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/PKG-INFO +3 -2
  2. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/pyproject.toml +3 -2
  3. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/cli/commands/libraries.py +6 -21
  4. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/cli/commands/models.py +21 -4
  5. griptape_nodes-0.63.1/src/griptape_nodes/drivers/thread_storage/__init__.py +15 -0
  6. griptape_nodes-0.63.1/src/griptape_nodes/drivers/thread_storage/base_thread_storage_driver.py +106 -0
  7. griptape_nodes-0.63.1/src/griptape_nodes/drivers/thread_storage/griptape_cloud_thread_storage_driver.py +213 -0
  8. griptape_nodes-0.63.1/src/griptape_nodes/drivers/thread_storage/local_thread_storage_driver.py +137 -0
  9. griptape_nodes-0.63.1/src/griptape_nodes/drivers/thread_storage/thread_storage_backend.py +10 -0
  10. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/node_library/library_registry.py +16 -9
  11. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/node_library/workflow_registry.py +1 -1
  12. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/events/agent_events.py +390 -0
  13. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/events/library_events.py +32 -3
  14. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/events/model_events.py +4 -4
  15. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/events/os_events.py +101 -1
  16. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/agent_manager.py +335 -135
  17. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/__init__.py +1 -0
  18. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/__init__.py +59 -0
  19. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/advanced_library_load_failure_problem.py +33 -0
  20. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/after_library_callback_problem.py +32 -0
  21. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/before_library_callback_problem.py +32 -0
  22. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/create_config_category_problem.py +32 -0
  23. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/dependency_installation_failed_problem.py +32 -0
  24. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/deprecated_node_warning_problem.py +83 -0
  25. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/duplicate_library_problem.py +28 -0
  26. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/duplicate_node_registration_problem.py +44 -0
  27. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/engine_version_error_problem.py +28 -0
  28. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/insufficient_disk_space_problem.py +33 -0
  29. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/invalid_version_string_problem.py +32 -0
  30. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/library_json_decode_problem.py +28 -0
  31. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/library_load_exception_problem.py +32 -0
  32. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/library_not_found_problem.py +30 -0
  33. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/library_problem.py +20 -0
  34. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/library_schema_exception_problem.py +32 -0
  35. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/library_schema_validation_problem.py +38 -0
  36. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/modified_parameters_set_deprecation_warning_problem.py +44 -0
  37. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/modified_parameters_set_removed_problem.py +44 -0
  38. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/node_class_not_base_node_problem.py +40 -0
  39. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/node_class_not_found_problem.py +38 -0
  40. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/node_module_import_problem.py +53 -0
  41. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/sandbox_directory_missing_problem.py +28 -0
  42. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/ui_options_field_modified_incompatible_problem.py +44 -0
  43. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/ui_options_field_modified_warning_problem.py +35 -0
  44. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/update_config_category_problem.py +32 -0
  45. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/venv_creation_failed_problem.py +32 -0
  46. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/workflows/__init__.py +75 -0
  47. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/workflows/deprecated_node_in_workflow_problem.py +83 -0
  48. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/workflows/invalid_dependency_version_string_problem.py +38 -0
  49. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/workflows/invalid_library_version_string_problem.py +38 -0
  50. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/workflows/invalid_metadata_schema_problem.py +31 -0
  51. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/workflows/invalid_metadata_section_count_problem.py +31 -0
  52. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/workflows/invalid_toml_format_problem.py +30 -0
  53. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/workflows/library_not_registered_problem.py +35 -0
  54. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/workflows/library_version_below_required_problem.py +41 -0
  55. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/workflows/library_version_large_difference_problem.py +41 -0
  56. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/workflows/library_version_major_mismatch_problem.py +41 -0
  57. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/workflows/library_version_minor_difference_problem.py +41 -0
  58. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/workflows/missing_creation_date_problem.py +30 -0
  59. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/workflows/missing_last_modified_date_problem.py +30 -0
  60. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/workflows/missing_toml_section_problem.py +30 -0
  61. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/workflows/node_type_not_found_problem.py +51 -0
  62. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/workflows/workflow_not_found_problem.py +27 -0
  63. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/workflows/workflow_problem.py +20 -0
  64. griptape_nodes-0.63.1/src/griptape_nodes/retained_mode/managers/fitness_problems/workflows/workflow_schema_version_problem.py +39 -0
  65. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/local_file.py +17 -3
  66. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/library_manager.py +159 -75
  67. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/model_manager.py +182 -205
  68. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/os_manager.py +172 -1
  69. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/settings.py +5 -0
  70. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/version_compatibility_manager.py +76 -51
  71. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/workflow_manager.py +154 -137
  72. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/servers/static.py +18 -19
  73. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/version_compatibility/versions/v0_39_0/modified_parameters_set_removal.py +16 -12
  74. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/version_compatibility/workflow_versions/v0_7_0/local_executor_argument_addition.py +6 -3
  75. griptape_nodes-0.62.3/src/griptape_nodes/retained_mode/events/agent_events.py +0 -167
  76. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/README.md +0 -0
  77. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/__init__.py +0 -0
  78. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/__main__.py +0 -0
  79. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/api_client/__init__.py +0 -0
  80. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/api_client/client.py +0 -0
  81. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/api_client/request_client.py +0 -0
  82. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/app/.python-version +0 -0
  83. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/app/__init__.py +0 -0
  84. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/app/app.py +0 -0
  85. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/app/watch.py +0 -0
  86. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/bootstrap/__init__.py +0 -0
  87. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/bootstrap/utils/__init__.py +0 -0
  88. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/bootstrap/utils/python_subprocess_executor.py +0 -0
  89. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/bootstrap/workflow_executors/__init__.py +0 -0
  90. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/bootstrap/workflow_executors/local_session_workflow_executor.py +0 -0
  91. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/bootstrap/workflow_executors/local_workflow_executor.py +0 -0
  92. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/bootstrap/workflow_executors/subprocess_workflow_executor.py +0 -0
  93. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/bootstrap/workflow_executors/utils/__init__.py +0 -0
  94. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/bootstrap/workflow_executors/utils/subprocess_script.py +0 -0
  95. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/bootstrap/workflow_executors/workflow_executor.py +0 -0
  96. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/bootstrap/workflow_publishers/__init__.py +0 -0
  97. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/bootstrap/workflow_publishers/local_workflow_publisher.py +0 -0
  98. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/bootstrap/workflow_publishers/subprocess_workflow_publisher.py +0 -0
  99. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/bootstrap/workflow_publishers/utils/__init__.py +0 -0
  100. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/bootstrap/workflow_publishers/utils/subprocess_script.py +0 -0
  101. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/cli/__init__.py +0 -0
  102. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/cli/commands/__init__.py +0 -0
  103. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/cli/commands/config.py +0 -0
  104. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/cli/commands/engine.py +0 -0
  105. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/cli/commands/init.py +0 -0
  106. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/cli/commands/self.py +0 -0
  107. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/cli/main.py +0 -0
  108. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/cli/shared.py +0 -0
  109. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/common/__init__.py +0 -0
  110. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/common/directed_graph.py +0 -0
  111. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/common/macro_parser/__init__.py +0 -0
  112. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/common/macro_parser/core.py +0 -0
  113. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/common/macro_parser/exceptions.py +0 -0
  114. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/common/macro_parser/formats.py +0 -0
  115. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/common/macro_parser/matching.py +0 -0
  116. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/common/macro_parser/parsing.py +0 -0
  117. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/common/macro_parser/resolution.py +0 -0
  118. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/common/macro_parser/segments.py +0 -0
  119. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/common/node_executor.py +0 -0
  120. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/common/project_templates/__init__.py +0 -0
  121. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/common/project_templates/default_project_template.py +0 -0
  122. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/common/project_templates/defaults/README.md +0 -0
  123. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/common/project_templates/directory.py +0 -0
  124. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/common/project_templates/loader.py +0 -0
  125. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/common/project_templates/project.py +0 -0
  126. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/common/project_templates/situation.py +0 -0
  127. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/common/project_templates/validation.py +0 -0
  128. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/drivers/__init__.py +0 -0
  129. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/drivers/storage/__init__.py +0 -0
  130. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/drivers/storage/base_storage_driver.py +0 -0
  131. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/drivers/storage/griptape_cloud_storage_driver.py +0 -0
  132. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/drivers/storage/local_storage_driver.py +0 -0
  133. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/drivers/storage/storage_backend.py +0 -0
  134. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/exe_types/__init__.py +0 -0
  135. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/exe_types/connections.py +0 -0
  136. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/exe_types/core_types.py +0 -0
  137. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/exe_types/flow.py +0 -0
  138. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/exe_types/node_types.py +0 -0
  139. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/exe_types/param_components/__init__.py +0 -0
  140. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/exe_types/param_components/execution_status_component.py +0 -0
  141. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/exe_types/param_components/huggingface/__init__.py +0 -0
  142. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/exe_types/param_components/huggingface/huggingface_model_parameter.py +0 -0
  143. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/exe_types/param_components/huggingface/huggingface_repo_file_parameter.py +0 -0
  144. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/exe_types/param_components/huggingface/huggingface_repo_parameter.py +0 -0
  145. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/exe_types/param_components/huggingface/huggingface_utils.py +0 -0
  146. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/exe_types/param_components/log_parameter.py +0 -0
  147. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/exe_types/param_components/progress_bar_component.py +0 -0
  148. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/exe_types/param_components/seed_parameter.py +0 -0
  149. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/exe_types/param_types/__init__.py +0 -0
  150. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/exe_types/param_types/parameter_audio.py +0 -0
  151. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/exe_types/param_types/parameter_bool.py +0 -0
  152. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/exe_types/param_types/parameter_float.py +0 -0
  153. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/exe_types/param_types/parameter_image.py +0 -0
  154. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/exe_types/param_types/parameter_int.py +0 -0
  155. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/exe_types/param_types/parameter_number.py +0 -0
  156. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/exe_types/param_types/parameter_string.py +0 -0
  157. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/exe_types/param_types/parameter_three_d.py +0 -0
  158. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/exe_types/param_types/parameter_video.py +0 -0
  159. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/exe_types/type_validator.py +0 -0
  160. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/machines/__init__.py +0 -0
  161. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/machines/control_flow.py +0 -0
  162. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/machines/dag_builder.py +0 -0
  163. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/machines/fsm.py +0 -0
  164. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/machines/parallel_resolution.py +0 -0
  165. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/machines/sequential_resolution.py +0 -0
  166. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/mcp_server/__init__.py +0 -0
  167. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/node_library/__init__.py +0 -0
  168. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/node_library/advanced_node_library.py +0 -0
  169. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/py.typed +0 -0
  170. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/__init__.py +0 -0
  171. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/events/__init__.py +0 -0
  172. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/events/app_events.py +0 -0
  173. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/events/arbitrary_python_events.py +0 -0
  174. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/events/base_events.py +0 -0
  175. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/events/config_events.py +0 -0
  176. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/events/connection_events.py +0 -0
  177. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/events/context_events.py +0 -0
  178. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/events/execution_events.py +0 -0
  179. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/events/flow_events.py +0 -0
  180. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/events/generate_request_payload_schemas.py +0 -0
  181. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/events/logger_events.py +0 -0
  182. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/events/mcp_events.py +0 -0
  183. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/events/node_events.py +0 -0
  184. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/events/object_events.py +0 -0
  185. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/events/parameter_events.py +0 -0
  186. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/events/payload_registry.py +0 -0
  187. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/events/project_events.py +0 -0
  188. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/events/resource_events.py +0 -0
  189. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/events/secrets_events.py +0 -0
  190. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/events/static_file_events.py +0 -0
  191. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/events/sync_events.py +0 -0
  192. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/events/validation_events.py +0 -0
  193. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/events/variable_events.py +0 -0
  194. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/events/workflow_events.py +0 -0
  195. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/griptape_nodes.py +0 -0
  196. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/__init__.py +0 -0
  197. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/arbitrary_code_exec_manager.py +0 -0
  198. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/config_manager.py +0 -0
  199. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/context_manager.py +0 -0
  200. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/engine_identity_manager.py +0 -0
  201. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/event_manager.py +0 -0
  202. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/flow_manager.py +0 -0
  203. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/library_lifecycle/__init__.py +0 -0
  204. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/library_lifecycle/data_models.py +0 -0
  205. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/library_lifecycle/library_directory.py +0 -0
  206. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/library_lifecycle/library_fsm.py +0 -0
  207. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/__init__.py +0 -0
  208. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/base.py +0 -0
  209. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/github.py +0 -0
  210. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/package.py +0 -0
  211. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/sandbox.py +0 -0
  212. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance.py +0 -0
  213. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/library_lifecycle/library_status.py +0 -0
  214. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/mcp_manager.py +0 -0
  215. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/node_manager.py +0 -0
  216. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/object_manager.py +0 -0
  217. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/operation_manager.py +0 -0
  218. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/project_manager.py +0 -0
  219. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/resource_components/__init__.py +0 -0
  220. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/resource_components/capability_field.py +0 -0
  221. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/resource_components/comparator.py +0 -0
  222. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/resource_components/resource_instance.py +0 -0
  223. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/resource_components/resource_type.py +0 -0
  224. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/resource_manager.py +0 -0
  225. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/resource_types/__init__.py +0 -0
  226. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/resource_types/cpu_resource.py +0 -0
  227. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/resource_types/os_resource.py +0 -0
  228. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/secrets_manager.py +0 -0
  229. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/session_manager.py +0 -0
  230. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/static_files_manager.py +0 -0
  231. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/sync_manager.py +0 -0
  232. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/user_manager.py +0 -0
  233. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/managers/variable_manager.py +0 -0
  234. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/retained_mode.py +0 -0
  235. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/utils/__init__.py +0 -0
  236. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/utils/name_generator.py +0 -0
  237. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/retained_mode/variable_types.py +0 -0
  238. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/servers/__init__.py +0 -0
  239. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/servers/mcp.py +0 -0
  240. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/traits/__init__.py +0 -0
  241. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/traits/add_param_button.py +0 -0
  242. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/traits/button.py +0 -0
  243. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/traits/clamp.py +0 -0
  244. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/traits/color_picker.py +0 -0
  245. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/traits/compare.py +0 -0
  246. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/traits/compare_images.py +0 -0
  247. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/traits/file_system_picker.py +0 -0
  248. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/traits/minmax.py +0 -0
  249. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/traits/multi_options.py +0 -0
  250. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/traits/numbers_selector.py +0 -0
  251. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/traits/options.py +0 -0
  252. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/traits/slider.py +0 -0
  253. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/traits/trait_registry.py +0 -0
  254. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/traits/traits.json +0 -0
  255. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/updater/__init__.py +0 -0
  256. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/updater/__main__.py +0 -0
  257. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/utils/__init__.py +0 -0
  258. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/utils/async_utils.py +0 -0
  259. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/utils/dict_utils.py +0 -0
  260. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/utils/huggingface_utils.py +0 -0
  261. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/utils/image_preview.py +0 -0
  262. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/utils/metaclasses.py +0 -0
  263. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/utils/uv_utils.py +0 -0
  264. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/utils/version_utils.py +0 -0
  265. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/version_compatibility/__init__.py +0 -0
  266. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/version_compatibility/versions/__init__.py +0 -0
  267. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/version_compatibility/versions/v0_39_0/__init__.py +0 -0
  268. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/version_compatibility/workflow_versions/__init__.py +0 -0
  269. {griptape_nodes-0.62.3 → griptape_nodes-0.63.1}/src/griptape_nodes/version_compatibility/workflow_versions/v0_7_0/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: griptape-nodes
3
- Version: 0.62.3
3
+ Version: 0.63.1
4
4
  Summary: Add your description here
5
5
  Requires-Dist: griptape>=1.8.12
6
6
  Requires-Dist: pydantic>=2.10.6
@@ -20,10 +20,11 @@ Requires-Dist: binaryornot>=0.4.4
20
20
  Requires-Dist: pillow>=11.3.0
21
21
  Requires-Dist: watchfiles>=1.1.0
22
22
  Requires-Dist: typer>=0.15.0
23
- Requires-Dist: huggingface-hub>=1.0.1
23
+ Requires-Dist: huggingface-hub>=1.1.0
24
24
  Requires-Dist: rich>=14.1.0
25
25
  Requires-Dist: semver>=3.0.4
26
26
  Requires-Dist: aiofiles>=25.1.0
27
+ Requires-Dist: aioshutil>=1.5
27
28
  Requires-Dist: ruamel-yaml>=0.18.15
28
29
  Requires-Dist: asyncio-thread-runner>=1.0
29
30
  Requires-Dist: austin-dist>=3.7.0 ; extra == 'profiling'
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "griptape-nodes"
3
- version = "0.62.3"
3
+ version = "0.63.1"
4
4
  description = "Add your description here"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12.0, <3.13"
@@ -24,10 +24,11 @@ dependencies = [
24
24
  "pillow>=11.3.0",
25
25
  "watchfiles>=1.1.0",
26
26
  "typer>=0.15.0",
27
- "huggingface-hub>=1.0.1",
27
+ "huggingface-hub>=1.1.0",
28
28
  "rich>=14.1.0",
29
29
  "semver>=3.0.4",
30
30
  "aiofiles>=25.1.0",
31
+ "aioshutil>=1.5",
31
32
  "ruamel.yaml>=0.18.15",
32
33
  "asyncio-thread-runner>=1.0",
33
34
  ]
@@ -2,7 +2,6 @@
2
2
 
3
3
  import asyncio
4
4
  import shutil
5
- import stat
6
5
  import tarfile
7
6
  import tempfile
8
7
  from pathlib import Path
@@ -17,6 +16,7 @@ from griptape_nodes.cli.shared import (
17
16
  NODES_TARBALL_URL,
18
17
  console,
19
18
  )
19
+ from griptape_nodes.retained_mode.events.os_events import DeleteFileRequest, DeleteFileResultSuccess
20
20
  from griptape_nodes.retained_mode.griptape_nodes import GriptapeNodes
21
21
  from griptape_nodes.utils.version_utils import get_current_version, get_install_source
22
22
 
@@ -81,7 +81,11 @@ async def _sync_libraries(*, load_libraries_from_config: bool = True) -> None:
81
81
  if library_dir.is_dir():
82
82
  dest_library_dir = dest_nodes / library_dir.name
83
83
  if dest_library_dir.exists():
84
- shutil.rmtree(dest_library_dir, onexc=_remove_readonly)
84
+ # Use DeleteFileRequest for centralized deletion with Windows compatibility
85
+ request = DeleteFileRequest(path=str(dest_library_dir), workspace_only=False)
86
+ result = await GriptapeNodes.OSManager().on_delete_file_request(request)
87
+ if not isinstance(result, DeleteFileResultSuccess):
88
+ console.print(f"[yellow]Warning: Failed to delete existing library {library_dir.name}[/yellow]")
85
89
  shutil.copytree(library_dir, dest_library_dir)
86
90
  console.print(f"[green]Synced library: {library_dir.name}[/green]")
87
91
 
@@ -95,22 +99,3 @@ async def _sync_libraries(*, load_libraries_from_config: bool = True) -> None:
95
99
  console.print(f"[red]Error initializing libraries: {e}[/red]")
96
100
 
97
101
  console.print("[bold green]Libraries synced.[/bold green]")
98
-
99
-
100
- def _remove_readonly(func, path, excinfo) -> None: # noqa: ANN001, ARG001
101
- """Handles read-only files and long paths on Windows during shutil.rmtree.
102
-
103
- https://stackoverflow.com/a/50924863
104
- """
105
- if not GriptapeNodes.OSManager().is_windows():
106
- return
107
-
108
- long_path = Path(GriptapeNodes.OSManager().normalize_path_for_platform(Path(path)))
109
-
110
- try:
111
- Path.chmod(long_path, stat.S_IWRITE)
112
- func(long_path)
113
- except Exception as e:
114
- console.print(f"[red]Error removing read-only file: {path}[/red]")
115
- console.print(f"[red]Details: {e}[/red]")
116
- raise
@@ -239,19 +239,36 @@ def _format_download_row(download: "ModelDownloadStatus") -> tuple[str, str, str
239
239
 
240
240
  def _format_progress(download: "ModelDownloadStatus") -> str:
241
241
  """Format download progress information."""
242
- if download.total_files is not None and download.completed_files is not None and download.total_files > 0:
243
- progress_percent = (download.completed_files / download.total_files) * 100
242
+ if download.total_bytes is not None and download.completed_bytes is not None and download.total_bytes > 0:
243
+ progress_percent = (download.completed_bytes / download.total_bytes) * 100
244
244
  return f"{progress_percent:.1f}%"
245
245
  return "Unknown"
246
246
 
247
247
 
248
248
  def _format_size(download: "ModelDownloadStatus") -> str:
249
249
  """Format download size information."""
250
- if download.total_files is not None and download.completed_files is not None:
251
- return f"{download.completed_files}/{download.total_files} files"
250
+ if download.total_bytes is not None and download.completed_bytes is not None:
251
+ return f"{_format_bytes(download.completed_bytes)}/{_format_bytes(download.total_bytes)}"
252
252
  return "Unknown"
253
253
 
254
254
 
255
+ def _format_bytes(num_bytes: int) -> str:
256
+ """Format bytes to human-readable string."""
257
+ if num_bytes == 0:
258
+ return "0 B"
259
+
260
+ bytes_per_unit = 1024.0
261
+ units = ["B", "KB", "MB", "GB", "TB"]
262
+ unit_index = 0
263
+ size = float(num_bytes)
264
+
265
+ while size >= bytes_per_unit and unit_index < len(units) - 1:
266
+ size /= bytes_per_unit
267
+ unit_index += 1
268
+
269
+ return f"{size:.2f} {units[unit_index]}"
270
+
271
+
255
272
  def _format_eta(download: "ModelDownloadStatus") -> str:
256
273
  """Format estimated time of arrival."""
257
274
  # ETA is not available in the current ModelDownloadStatus structure
@@ -0,0 +1,15 @@
1
+ """Thread storage drivers."""
2
+
3
+ from griptape_nodes.drivers.thread_storage.base_thread_storage_driver import BaseThreadStorageDriver
4
+ from griptape_nodes.drivers.thread_storage.griptape_cloud_thread_storage_driver import (
5
+ GriptapeCloudThreadStorageDriver,
6
+ )
7
+ from griptape_nodes.drivers.thread_storage.local_thread_storage_driver import LocalThreadStorageDriver
8
+ from griptape_nodes.drivers.thread_storage.thread_storage_backend import ThreadStorageBackend
9
+
10
+ __all__ = [
11
+ "BaseThreadStorageDriver",
12
+ "GriptapeCloudThreadStorageDriver",
13
+ "LocalThreadStorageDriver",
14
+ "ThreadStorageBackend",
15
+ ]
@@ -0,0 +1,106 @@
1
+ """Base thread storage driver abstract class."""
2
+
3
+ from abc import ABC, abstractmethod
4
+
5
+ from griptape.drivers.memory.conversation import BaseConversationMemoryDriver
6
+
7
+ from griptape_nodes.retained_mode.events.agent_events import ThreadMetadata
8
+ from griptape_nodes.retained_mode.managers.config_manager import ConfigManager
9
+ from griptape_nodes.retained_mode.managers.secrets_manager import SecretsManager
10
+
11
+
12
+ class BaseThreadStorageDriver(ABC):
13
+ """Abstract base class for thread storage backends."""
14
+
15
+ def __init__(self, config_manager: ConfigManager, secrets_manager: SecretsManager) -> None:
16
+ """Initialize the thread storage driver.
17
+
18
+ Args:
19
+ config_manager: Configuration manager instance
20
+ secrets_manager: Secrets manager instance
21
+ """
22
+ self.config_manager = config_manager
23
+ self.secrets_manager = secrets_manager
24
+
25
+ @abstractmethod
26
+ def create_thread(self, title: str | None = None, local_id: str | None = None) -> tuple[str, dict]:
27
+ """Create a new thread with metadata.
28
+
29
+ Args:
30
+ title: Optional thread title
31
+ local_id: Optional client-side identifier
32
+
33
+ Returns:
34
+ Tuple of (thread_id, metadata_dict)
35
+ """
36
+ ...
37
+
38
+ @abstractmethod
39
+ def get_thread_metadata(self, thread_id: str) -> dict:
40
+ """Get metadata for a thread.
41
+
42
+ Args:
43
+ thread_id: The thread identifier
44
+
45
+ Returns:
46
+ Metadata dictionary
47
+ """
48
+ ...
49
+
50
+ @abstractmethod
51
+ def update_thread_metadata(self, thread_id: str, **updates) -> dict:
52
+ """Update thread metadata.
53
+
54
+ Args:
55
+ thread_id: The thread identifier
56
+ **updates: Key-value pairs to update in metadata
57
+
58
+ Returns:
59
+ Updated metadata dictionary
60
+ """
61
+ ...
62
+
63
+ @abstractmethod
64
+ def list_threads(self) -> list[ThreadMetadata]:
65
+ """List all threads with metadata.
66
+
67
+ Returns:
68
+ List of ThreadMetadata objects
69
+ """
70
+ ...
71
+
72
+ @abstractmethod
73
+ def delete_thread(self, thread_id: str) -> None:
74
+ """Delete a thread.
75
+
76
+ Args:
77
+ thread_id: The thread identifier
78
+
79
+ Raises:
80
+ ValueError: If thread is not archived or doesn't exist
81
+ """
82
+ ...
83
+
84
+ @abstractmethod
85
+ def thread_exists(self, thread_id: str) -> bool:
86
+ """Check if a thread exists.
87
+
88
+ Args:
89
+ thread_id: The thread identifier
90
+
91
+ Returns:
92
+ True if thread exists, False otherwise
93
+ """
94
+ ...
95
+
96
+ @abstractmethod
97
+ def get_conversation_memory_driver(self, thread_id: str | None) -> BaseConversationMemoryDriver:
98
+ """Get the appropriate conversation memory driver for this thread.
99
+
100
+ Args:
101
+ thread_id: The thread identifier (can be None for GTC backend)
102
+
103
+ Returns:
104
+ Conversation memory driver instance
105
+ """
106
+ ...
@@ -0,0 +1,213 @@
1
+ """Griptape Cloud thread storage driver."""
2
+
3
+ import logging
4
+ import os
5
+ from datetime import UTC, datetime
6
+ from urllib.parse import urljoin
7
+
8
+ import httpx
9
+ from griptape.drivers.memory.conversation import BaseConversationMemoryDriver
10
+ from griptape.drivers.memory.conversation.griptape_cloud import GriptapeCloudConversationMemoryDriver
11
+
12
+ from griptape_nodes.drivers.thread_storage.base_thread_storage_driver import BaseThreadStorageDriver
13
+ from griptape_nodes.retained_mode.events.agent_events import ThreadMetadata
14
+
15
+ API_KEY_ENV_VAR = "GT_CLOUD_API_KEY"
16
+ HTTP_NOT_FOUND = 404
17
+ logger = logging.getLogger("griptape_nodes")
18
+
19
+
20
+ class GriptapeCloudThreadStorageDriver(BaseThreadStorageDriver):
21
+ """Griptape Cloud implementation of thread storage."""
22
+
23
+ @property
24
+ def base_url(self) -> str:
25
+ """Get the base URL for Griptape Cloud API."""
26
+ return os.environ.get("GT_CLOUD_BASE_URL", "https://cloud.griptape.ai")
27
+
28
+ @property
29
+ def _headers(self) -> dict:
30
+ """Get the authorization headers for API requests."""
31
+ api_key = self.secrets_manager.get_secret(API_KEY_ENV_VAR)
32
+ if not api_key:
33
+ msg = f"Secret '{API_KEY_ENV_VAR}' not found for Griptape Cloud thread storage"
34
+ raise ValueError(msg)
35
+ return {"Authorization": f"Bearer {api_key}"}
36
+
37
+ def _get_url(self, path: str) -> str:
38
+ """Construct full API URL from path."""
39
+ return urljoin(self.base_url, path)
40
+
41
+ def create_thread(self, title: str | None = None, local_id: str | None = None) -> tuple[str, dict]:
42
+ url = self._get_url("/api/threads")
43
+
44
+ now = datetime.now(UTC).isoformat()
45
+
46
+ # Build metadata for the request
47
+ metadata = {
48
+ "created_at": now,
49
+ "updated_at": now,
50
+ }
51
+ if local_id is not None:
52
+ metadata["local_id"] = local_id
53
+
54
+ # Build request body
55
+ request_body: dict[str, str | dict] = {"metadata": metadata}
56
+ if title is not None:
57
+ request_body["name"] = title
58
+
59
+ try:
60
+ response = httpx.post(url, json=request_body, headers=self._headers)
61
+ response.raise_for_status()
62
+ except httpx.HTTPStatusError as e:
63
+ msg = f"Failed to create thread in Griptape Cloud: {e}"
64
+ logger.error(msg)
65
+ raise RuntimeError(msg) from e
66
+
67
+ response_data = response.json()
68
+ thread_id = response_data["thread_id"]
69
+
70
+ # Build metadata dict to return (matching local driver behavior)
71
+ result_metadata = response_data.get("metadata", {})
72
+ if title is not None:
73
+ result_metadata["title"] = title
74
+
75
+ return thread_id, result_metadata
76
+
77
+ def get_thread_metadata(self, thread_id: str) -> dict:
78
+ url = self._get_url(f"/api/threads/{thread_id}")
79
+
80
+ try:
81
+ response = httpx.get(url, headers=self._headers)
82
+ response.raise_for_status()
83
+ except httpx.HTTPStatusError as e:
84
+ if e.response.status_code == HTTP_NOT_FOUND:
85
+ return {}
86
+ msg = f"Failed to get thread {thread_id} from Griptape Cloud: {e}"
87
+ logger.error(msg)
88
+ raise RuntimeError(msg) from e
89
+
90
+ response_data = response.json()
91
+
92
+ # Extract metadata from response
93
+ metadata = response_data.get("metadata", {})
94
+
95
+ # Map GTC's "name" field to our "title" field for consistency
96
+ if response_data.get("name"):
97
+ metadata["title"] = response_data["name"]
98
+
99
+ return metadata
100
+
101
+ def update_thread_metadata(self, thread_id: str, **updates) -> dict:
102
+ # First, get current metadata
103
+ current_metadata = self.get_thread_metadata(thread_id)
104
+
105
+ now = datetime.now(UTC).isoformat()
106
+
107
+ # Merge updates into current metadata
108
+ for key, value in updates.items():
109
+ if value is not None:
110
+ current_metadata[key] = value
111
+
112
+ current_metadata["updated_at"] = now
113
+
114
+ if "created_at" not in current_metadata:
115
+ current_metadata["created_at"] = now
116
+
117
+ url = self._get_url(f"/api/threads/{thread_id}")
118
+
119
+ # Build request body
120
+ request_body: dict[str, str | dict] = {"metadata": current_metadata}
121
+
122
+ # If title was updated, also set the name field
123
+ if "title" in updates and updates["title"] is not None:
124
+ request_body["name"] = updates["title"]
125
+
126
+ try:
127
+ response = httpx.patch(url, json=request_body, headers=self._headers)
128
+ response.raise_for_status()
129
+ except httpx.HTTPStatusError as e:
130
+ msg = f"Failed to update thread {thread_id} in Griptape Cloud: {e}"
131
+ logger.error(msg)
132
+ raise RuntimeError(msg) from e
133
+
134
+ response_data = response.json()
135
+
136
+ # Return updated metadata
137
+ result_metadata = response_data.get("metadata", {})
138
+ if response_data.get("name"):
139
+ result_metadata["title"] = response_data["name"]
140
+
141
+ return result_metadata
142
+
143
+ def list_threads(self) -> list[ThreadMetadata]:
144
+ url = self._get_url("/api/threads")
145
+
146
+ try:
147
+ response = httpx.get(url, headers=self._headers)
148
+ response.raise_for_status()
149
+ except httpx.HTTPStatusError as e:
150
+ msg = f"Failed to list threads from Griptape Cloud: {e}"
151
+ logger.error(msg)
152
+ raise RuntimeError(msg) from e
153
+
154
+ response_data = response.json()
155
+ threads_data = response_data.get("threads", [])
156
+
157
+ threads = []
158
+ for thread_data in threads_data:
159
+ thread_id = thread_data.get("thread_id")
160
+ if not thread_id:
161
+ continue
162
+
163
+ metadata = thread_data.get("metadata", {})
164
+
165
+ thread_metadata = ThreadMetadata(
166
+ thread_id=thread_id,
167
+ title=thread_data.get("name"),
168
+ created_at=metadata.get("created_at"),
169
+ updated_at=metadata.get("updated_at"),
170
+ message_count=thread_data.get("message_count", 0),
171
+ archived=metadata.get("archived", False),
172
+ local_id=metadata.get("local_id"),
173
+ )
174
+ threads.append(thread_metadata)
175
+
176
+ # Sort by updated_at descending (most recent first)
177
+ threads.sort(key=lambda t: t.updated_at or "", reverse=True)
178
+
179
+ return threads
180
+
181
+ def delete_thread(self, thread_id: str) -> None:
182
+ if not self.thread_exists(thread_id):
183
+ msg = f"Thread {thread_id} not found"
184
+ raise ValueError(msg)
185
+
186
+ meta = self.get_thread_metadata(thread_id)
187
+ if not meta.get("archived", False):
188
+ msg = f"Cannot delete thread {thread_id}. Archive it first."
189
+ raise ValueError(msg)
190
+
191
+ url = self._get_url(f"/api/threads/{thread_id}")
192
+
193
+ try:
194
+ response = httpx.delete(url, headers=self._headers)
195
+ response.raise_for_status()
196
+ except httpx.HTTPStatusError as e:
197
+ msg = f"Failed to delete thread {thread_id} from Griptape Cloud: {e}"
198
+ logger.error(msg)
199
+ raise RuntimeError(msg) from e
200
+
201
+ def thread_exists(self, thread_id: str) -> bool:
202
+ try:
203
+ meta = self.get_thread_metadata(thread_id)
204
+ return bool(meta)
205
+ except Exception:
206
+ return False
207
+
208
+ def get_conversation_memory_driver(self, thread_id: str | None) -> BaseConversationMemoryDriver:
209
+ api_key = self.secrets_manager.get_secret(API_KEY_ENV_VAR)
210
+ if not api_key:
211
+ msg = f"Secret '{API_KEY_ENV_VAR}' not found for Griptape Cloud thread storage"
212
+ raise ValueError(msg)
213
+ return GriptapeCloudConversationMemoryDriver(api_key=api_key, thread_id=thread_id)
@@ -0,0 +1,137 @@
1
+ """Local filesystem thread storage driver."""
2
+
3
+ import uuid
4
+ from datetime import UTC, datetime
5
+ from pathlib import Path
6
+
7
+ from griptape.drivers.memory.conversation import BaseConversationMemoryDriver
8
+ from griptape.drivers.memory.conversation.local import LocalConversationMemoryDriver
9
+ from griptape.memory.structure import ConversationMemory
10
+
11
+ from griptape_nodes.drivers.thread_storage.base_thread_storage_driver import BaseThreadStorageDriver
12
+ from griptape_nodes.retained_mode.events.agent_events import ThreadMetadata
13
+ from griptape_nodes.retained_mode.managers.config_manager import ConfigManager
14
+ from griptape_nodes.retained_mode.managers.secrets_manager import SecretsManager
15
+
16
+
17
+ class LocalThreadStorageDriver(BaseThreadStorageDriver):
18
+ """Local filesystem implementation of thread storage."""
19
+
20
+ def __init__(self, threads_directory: Path, config_manager: ConfigManager, secrets_manager: SecretsManager) -> None:
21
+ """Initialize the local thread storage driver.
22
+
23
+ Args:
24
+ threads_directory: Directory for storing thread data
25
+ config_manager: Configuration manager instance
26
+ secrets_manager: Secrets manager instance
27
+ """
28
+ super().__init__(config_manager, secrets_manager)
29
+ self.threads_directory = threads_directory
30
+
31
+ def create_thread(self, title: str | None = None, local_id: str | None = None) -> tuple[str, dict]:
32
+ thread_id = str(uuid.uuid4())
33
+
34
+ conversation_memory = self._get_or_create_conversation_memory(thread_id)
35
+
36
+ now = datetime.now(UTC).isoformat()
37
+ conversation_memory.meta = {
38
+ "created_at": now,
39
+ "updated_at": now,
40
+ }
41
+
42
+ if title is not None:
43
+ conversation_memory.meta["title"] = title
44
+ if local_id is not None:
45
+ conversation_memory.meta["local_id"] = local_id
46
+
47
+ conversation_memory.conversation_memory_driver.store(conversation_memory.runs, conversation_memory.meta)
48
+
49
+ return thread_id, conversation_memory.meta
50
+
51
+ def get_thread_metadata(self, thread_id: str) -> dict:
52
+ conversation_memory = self._get_or_create_conversation_memory(thread_id)
53
+ if conversation_memory.meta is None:
54
+ return {}
55
+ return conversation_memory.meta
56
+
57
+ def update_thread_metadata(self, thread_id: str, **updates) -> dict:
58
+ conversation_memory = self._get_or_create_conversation_memory(thread_id)
59
+ now = datetime.now(UTC).isoformat()
60
+
61
+ if conversation_memory.meta is None:
62
+ conversation_memory.meta = {}
63
+
64
+ for key, value in updates.items():
65
+ if value is not None:
66
+ conversation_memory.meta[key] = value
67
+
68
+ conversation_memory.meta["updated_at"] = now
69
+
70
+ if "created_at" not in conversation_memory.meta:
71
+ conversation_memory.meta["created_at"] = now
72
+
73
+ conversation_memory.conversation_memory_driver.store(conversation_memory.runs, conversation_memory.meta)
74
+
75
+ return conversation_memory.meta
76
+
77
+ def list_threads(self) -> list[ThreadMetadata]:
78
+ threads = []
79
+
80
+ if not self.threads_directory.exists():
81
+ return threads
82
+
83
+ thread_ids = [
84
+ thread_file.stem.replace("thread_", "") for thread_file in self.threads_directory.glob("thread_*.json")
85
+ ]
86
+
87
+ for thread_id in thread_ids:
88
+ meta = self.get_thread_metadata(thread_id)
89
+ conversation_memory = self._get_or_create_conversation_memory(thread_id)
90
+ message_count = len(conversation_memory.runs)
91
+
92
+ threads.append(
93
+ ThreadMetadata(
94
+ thread_id=thread_id,
95
+ title=meta.get("title"),
96
+ created_at=meta.get("created_at", ""),
97
+ updated_at=meta.get("updated_at", ""),
98
+ message_count=message_count,
99
+ archived=meta.get("archived", False),
100
+ local_id=meta.get("local_id"),
101
+ )
102
+ )
103
+
104
+ threads.sort(key=lambda t: t.updated_at, reverse=True)
105
+
106
+ return threads
107
+
108
+ def delete_thread(self, thread_id: str) -> None:
109
+ thread_file = self.threads_directory / f"thread_{thread_id}.json"
110
+
111
+ if not thread_file.exists():
112
+ msg = f"Thread {thread_id} not found"
113
+ raise ValueError(msg)
114
+
115
+ meta = self.get_thread_metadata(thread_id)
116
+ if not meta.get("archived", False):
117
+ msg = f"Cannot delete thread {thread_id}. Archive it first."
118
+ raise ValueError(msg)
119
+
120
+ thread_file.unlink()
121
+
122
+ def thread_exists(self, thread_id: str) -> bool:
123
+ thread_file = self.threads_directory / f"thread_{thread_id}.json"
124
+ return thread_file.exists()
125
+
126
+ def get_conversation_memory_driver(self, thread_id: str | None) -> BaseConversationMemoryDriver:
127
+ if thread_id is None:
128
+ msg = "thread_id is required for local storage backend"
129
+ raise ValueError(msg)
130
+
131
+ thread_file = self.threads_directory / f"thread_{thread_id}.json"
132
+ return LocalConversationMemoryDriver(persist_file=str(thread_file))
133
+
134
+ def _get_or_create_conversation_memory(self, thread_id: str) -> ConversationMemory:
135
+ """Get or create ConversationMemory instance for a thread."""
136
+ driver = self.get_conversation_memory_driver(thread_id)
137
+ return ConversationMemory(conversation_memory_driver=driver)
@@ -0,0 +1,10 @@
1
+ """Thread storage backend enumeration."""
2
+
3
+ from enum import StrEnum
4
+
5
+
6
+ class ThreadStorageBackend(StrEnum):
7
+ """Enumeration of available thread storage backends."""
8
+
9
+ LOCAL = "local"
10
+ GTC = "gtc"