griptape-nodes 0.70.0__tar.gz → 0.71.0__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 (288) hide show
  1. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/PKG-INFO +1 -1
  2. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/pyproject.toml +1 -1
  3. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/api_client/client.py +8 -5
  4. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/bootstrap/utils/python_subprocess_executor.py +48 -9
  5. griptape_nodes-0.71.0/src/griptape_nodes/bootstrap/utils/subprocess_websocket_base.py +88 -0
  6. griptape_nodes-0.71.0/src/griptape_nodes/bootstrap/utils/subprocess_websocket_listener.py +126 -0
  7. griptape_nodes-0.71.0/src/griptape_nodes/bootstrap/utils/subprocess_websocket_sender.py +121 -0
  8. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/bootstrap/workflow_executors/local_session_workflow_executor.py +17 -170
  9. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/bootstrap/workflow_executors/subprocess_workflow_executor.py +13 -117
  10. griptape_nodes-0.71.0/src/griptape_nodes/bootstrap/workflow_publishers/local_session_workflow_publisher.py +206 -0
  11. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/bootstrap/workflow_publishers/subprocess_workflow_publisher.py +22 -3
  12. griptape_nodes-0.71.0/src/griptape_nodes/bootstrap/workflow_publishers/utils/subprocess_script.py +89 -0
  13. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/common/node_executor.py +60 -13
  14. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/exe_types/base_iterative_nodes.py +1 -1
  15. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/exe_types/node_groups/subflow_node_group.py +18 -0
  16. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/exe_types/param_components/log_parameter.py +1 -2
  17. griptape_nodes-0.71.0/src/griptape_nodes/exe_types/param_components/subflow_execution_component.py +329 -0
  18. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/exe_types/param_types/parameter_audio.py +17 -2
  19. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/exe_types/param_types/parameter_image.py +14 -1
  20. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/exe_types/param_types/parameter_three_d.py +14 -1
  21. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/exe_types/param_types/parameter_video.py +17 -2
  22. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/os_manager.py +1 -1
  23. griptape_nodes-0.71.0/src/griptape_nodes/utils/artifact_normalization.py +245 -0
  24. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/utils/image_preview.py +27 -0
  25. griptape_nodes-0.70.0/src/griptape_nodes/bootstrap/workflow_publishers/utils/subprocess_script.py +0 -69
  26. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/README.md +0 -0
  27. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/__init__.py +0 -0
  28. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/__main__.py +0 -0
  29. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/api_client/__init__.py +0 -0
  30. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/api_client/request_client.py +0 -0
  31. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/app/.python-version +0 -0
  32. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/app/__init__.py +0 -0
  33. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/app/app.py +0 -0
  34. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/app/watch.py +0 -0
  35. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/bootstrap/__init__.py +0 -0
  36. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/bootstrap/utils/__init__.py +0 -0
  37. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/bootstrap/workflow_executors/__init__.py +0 -0
  38. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/bootstrap/workflow_executors/local_workflow_executor.py +0 -0
  39. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/bootstrap/workflow_executors/utils/__init__.py +0 -0
  40. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/bootstrap/workflow_executors/utils/subprocess_script.py +0 -0
  41. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/bootstrap/workflow_executors/workflow_executor.py +0 -0
  42. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/bootstrap/workflow_publishers/__init__.py +0 -0
  43. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/bootstrap/workflow_publishers/local_workflow_publisher.py +0 -0
  44. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/bootstrap/workflow_publishers/utils/__init__.py +0 -0
  45. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/cli/__init__.py +0 -0
  46. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/cli/commands/__init__.py +0 -0
  47. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/cli/commands/config.py +0 -0
  48. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/cli/commands/engine.py +0 -0
  49. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/cli/commands/init.py +0 -0
  50. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/cli/commands/libraries.py +0 -0
  51. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/cli/commands/models.py +0 -0
  52. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/cli/commands/self.py +0 -0
  53. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/cli/main.py +0 -0
  54. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/cli/shared.py +0 -0
  55. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/common/__init__.py +0 -0
  56. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/common/directed_graph.py +0 -0
  57. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/common/macro_parser/__init__.py +0 -0
  58. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/common/macro_parser/core.py +0 -0
  59. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/common/macro_parser/exceptions.py +0 -0
  60. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/common/macro_parser/formats.py +0 -0
  61. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/common/macro_parser/matching.py +0 -0
  62. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/common/macro_parser/parsing.py +0 -0
  63. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/common/macro_parser/resolution.py +0 -0
  64. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/common/macro_parser/segments.py +0 -0
  65. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/common/project_templates/__init__.py +0 -0
  66. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/common/project_templates/default_project_template.py +0 -0
  67. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/common/project_templates/defaults/README.md +0 -0
  68. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/common/project_templates/directory.py +0 -0
  69. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/common/project_templates/loader.py +0 -0
  70. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/common/project_templates/project.py +0 -0
  71. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/common/project_templates/situation.py +0 -0
  72. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/common/project_templates/validation.py +0 -0
  73. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/drivers/__init__.py +0 -0
  74. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/drivers/storage/__init__.py +0 -0
  75. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/drivers/storage/base_storage_driver.py +0 -0
  76. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/drivers/storage/griptape_cloud_storage_driver.py +0 -0
  77. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/drivers/storage/local_storage_driver.py +0 -0
  78. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/drivers/storage/storage_backend.py +0 -0
  79. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/drivers/thread_storage/__init__.py +0 -0
  80. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/drivers/thread_storage/base_thread_storage_driver.py +0 -0
  81. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/drivers/thread_storage/griptape_cloud_thread_storage_driver.py +0 -0
  82. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/drivers/thread_storage/local_thread_storage_driver.py +0 -0
  83. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/drivers/thread_storage/thread_storage_backend.py +0 -0
  84. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/exe_types/__init__.py +0 -0
  85. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/exe_types/connections.py +0 -0
  86. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/exe_types/core_types.py +0 -0
  87. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/exe_types/flow.py +0 -0
  88. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/exe_types/node_groups/__init__.py +0 -0
  89. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/exe_types/node_groups/base_iterative_node_group.py +0 -0
  90. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/exe_types/node_groups/base_node_group.py +0 -0
  91. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/exe_types/node_types.py +0 -0
  92. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/exe_types/param_components/README.md +0 -0
  93. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/exe_types/param_components/__init__.py +0 -0
  94. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/exe_types/param_components/api_key_provider_parameter.py +0 -0
  95. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/exe_types/param_components/artifact_url/__init__.py +0 -0
  96. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/exe_types/param_components/artifact_url/public_artifact_url_parameter.py +0 -0
  97. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/exe_types/param_components/execution_status_component.py +0 -0
  98. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/exe_types/param_components/huggingface/__init__.py +0 -0
  99. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/exe_types/param_components/huggingface/huggingface_model_parameter.py +0 -0
  100. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/exe_types/param_components/huggingface/huggingface_repo_file_parameter.py +0 -0
  101. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/exe_types/param_components/huggingface/huggingface_repo_parameter.py +0 -0
  102. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/exe_types/param_components/huggingface/huggingface_repo_variant_parameter.py +0 -0
  103. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/exe_types/param_components/huggingface/huggingface_utils.py +0 -0
  104. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/exe_types/param_components/progress_bar_component.py +0 -0
  105. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/exe_types/param_components/seed_parameter.py +0 -0
  106. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/exe_types/param_types/__init__.py +0 -0
  107. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/exe_types/param_types/parameter_bool.py +0 -0
  108. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/exe_types/param_types/parameter_button.py +0 -0
  109. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/exe_types/param_types/parameter_dict.py +0 -0
  110. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/exe_types/param_types/parameter_float.py +0 -0
  111. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/exe_types/param_types/parameter_int.py +0 -0
  112. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/exe_types/param_types/parameter_json.py +0 -0
  113. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/exe_types/param_types/parameter_number.py +0 -0
  114. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/exe_types/param_types/parameter_range.py +0 -0
  115. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/exe_types/param_types/parameter_string.py +0 -0
  116. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/exe_types/type_validator.py +0 -0
  117. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/machines/__init__.py +0 -0
  118. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/machines/control_flow.py +0 -0
  119. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/machines/dag_builder.py +0 -0
  120. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/machines/fsm.py +0 -0
  121. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/machines/parallel_resolution.py +0 -0
  122. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/machines/sequential_resolution.py +0 -0
  123. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/mcp_server/__init__.py +0 -0
  124. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/node_library/__init__.py +0 -0
  125. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/node_library/advanced_node_library.py +0 -0
  126. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/node_library/library_registry.py +0 -0
  127. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/node_library/workflow_registry.py +0 -0
  128. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/py.typed +0 -0
  129. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/__init__.py +0 -0
  130. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/events/__init__.py +0 -0
  131. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/events/agent_events.py +0 -0
  132. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/events/app_events.py +0 -0
  133. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/events/arbitrary_python_events.py +0 -0
  134. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/events/base_events.py +0 -0
  135. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/events/config_events.py +0 -0
  136. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/events/connection_events.py +0 -0
  137. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/events/context_events.py +0 -0
  138. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/events/execution_events.py +0 -0
  139. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/events/flow_events.py +0 -0
  140. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/events/generate_request_payload_schemas.py +0 -0
  141. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/events/library_events.py +0 -0
  142. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/events/logger_events.py +0 -0
  143. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/events/mcp_events.py +0 -0
  144. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/events/model_events.py +0 -0
  145. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/events/node_events.py +0 -0
  146. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/events/object_events.py +0 -0
  147. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/events/os_events.py +0 -0
  148. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/events/parameter_events.py +0 -0
  149. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/events/payload_registry.py +0 -0
  150. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/events/project_events.py +0 -0
  151. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/events/resource_events.py +0 -0
  152. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/events/secrets_events.py +0 -0
  153. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/events/static_file_events.py +0 -0
  154. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/events/sync_events.py +0 -0
  155. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/events/validation_events.py +0 -0
  156. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/events/variable_events.py +0 -0
  157. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/events/workflow_events.py +0 -0
  158. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/griptape_nodes.py +0 -0
  159. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/__init__.py +0 -0
  160. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/agent_manager.py +0 -0
  161. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/arbitrary_code_exec_manager.py +0 -0
  162. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/config_manager.py +0 -0
  163. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/context_manager.py +0 -0
  164. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/engine_identity_manager.py +0 -0
  165. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/event_manager.py +0 -0
  166. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/__init__.py +0 -0
  167. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/__init__.py +0 -0
  168. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/advanced_library_load_failure_problem.py +0 -0
  169. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/after_library_callback_problem.py +0 -0
  170. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/before_library_callback_problem.py +0 -0
  171. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/create_config_category_problem.py +0 -0
  172. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/dependency_installation_failed_problem.py +0 -0
  173. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/deprecated_node_warning_problem.py +0 -0
  174. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/duplicate_library_problem.py +0 -0
  175. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/duplicate_node_registration_problem.py +0 -0
  176. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/engine_version_error_problem.py +0 -0
  177. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/incompatible_requirements_problem.py +0 -0
  178. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/insufficient_disk_space_problem.py +0 -0
  179. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/invalid_version_string_problem.py +0 -0
  180. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/library_json_decode_problem.py +0 -0
  181. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/library_load_exception_problem.py +0 -0
  182. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/library_not_found_problem.py +0 -0
  183. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/library_problem.py +0 -0
  184. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/library_schema_exception_problem.py +0 -0
  185. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/library_schema_validation_problem.py +0 -0
  186. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/modified_parameters_set_deprecation_warning_problem.py +0 -0
  187. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/modified_parameters_set_removed_problem.py +0 -0
  188. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/node_class_not_base_node_problem.py +0 -0
  189. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/node_class_not_found_problem.py +0 -0
  190. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/node_module_import_problem.py +0 -0
  191. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/old_xdg_location_warning_problem.py +0 -0
  192. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/sandbox_directory_missing_problem.py +0 -0
  193. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/ui_options_field_modified_incompatible_problem.py +0 -0
  194. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/ui_options_field_modified_warning_problem.py +0 -0
  195. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/update_config_category_problem.py +0 -0
  196. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/libraries/venv_creation_failed_problem.py +0 -0
  197. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/workflows/__init__.py +0 -0
  198. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/workflows/deprecated_node_in_workflow_problem.py +0 -0
  199. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/workflows/invalid_dependency_version_string_problem.py +0 -0
  200. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/workflows/invalid_library_version_string_problem.py +0 -0
  201. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/workflows/invalid_metadata_schema_problem.py +0 -0
  202. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/workflows/invalid_metadata_section_count_problem.py +0 -0
  203. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/workflows/invalid_toml_format_problem.py +0 -0
  204. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/workflows/library_not_registered_problem.py +0 -0
  205. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/workflows/library_version_below_required_problem.py +0 -0
  206. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/workflows/library_version_large_difference_problem.py +0 -0
  207. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/workflows/library_version_major_mismatch_problem.py +0 -0
  208. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/workflows/library_version_minor_difference_problem.py +0 -0
  209. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/workflows/missing_creation_date_problem.py +0 -0
  210. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/workflows/missing_last_modified_date_problem.py +0 -0
  211. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/workflows/missing_toml_section_problem.py +0 -0
  212. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/workflows/node_type_not_found_problem.py +0 -0
  213. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/workflows/workflow_not_found_problem.py +0 -0
  214. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/workflows/workflow_problem.py +0 -0
  215. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/fitness_problems/workflows/workflow_schema_version_problem.py +0 -0
  216. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/flow_manager.py +0 -0
  217. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/library_manager.py +0 -0
  218. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/mcp_manager.py +0 -0
  219. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/model_manager.py +0 -0
  220. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/node_manager.py +0 -0
  221. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/object_manager.py +0 -0
  222. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/operation_manager.py +0 -0
  223. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/project_manager.py +0 -0
  224. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/resource_components/__init__.py +0 -0
  225. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/resource_components/capability_field.py +0 -0
  226. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/resource_components/comparator.py +0 -0
  227. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/resource_components/resource_instance.py +0 -0
  228. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/resource_components/resource_type.py +0 -0
  229. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/resource_manager.py +0 -0
  230. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/resource_types/__init__.py +0 -0
  231. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/resource_types/compute_resource.py +0 -0
  232. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/resource_types/cpu_resource.py +0 -0
  233. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/resource_types/os_resource.py +0 -0
  234. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/secrets_manager.py +0 -0
  235. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/session_manager.py +0 -0
  236. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/settings.py +0 -0
  237. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/static_files_manager.py +0 -0
  238. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/sync_manager.py +0 -0
  239. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/user_manager.py +0 -0
  240. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/variable_manager.py +0 -0
  241. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/version_compatibility_manager.py +0 -0
  242. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/managers/workflow_manager.py +0 -0
  243. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/retained_mode.py +0 -0
  244. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/utils/__init__.py +0 -0
  245. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/utils/name_generator.py +0 -0
  246. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/retained_mode/variable_types.py +0 -0
  247. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/servers/__init__.py +0 -0
  248. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/servers/mcp.py +0 -0
  249. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/servers/static.py +0 -0
  250. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/traits/__init__.py +0 -0
  251. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/traits/add_param_button.py +0 -0
  252. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/traits/button.py +0 -0
  253. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/traits/clamp.py +0 -0
  254. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/traits/color_picker.py +0 -0
  255. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/traits/compare.py +0 -0
  256. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/traits/compare_images.py +0 -0
  257. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/traits/file_system_picker.py +0 -0
  258. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/traits/minmax.py +0 -0
  259. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/traits/multi_options.py +0 -0
  260. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/traits/numbers_selector.py +0 -0
  261. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/traits/options.py +0 -0
  262. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/traits/slider.py +0 -0
  263. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/traits/trait_registry.py +0 -0
  264. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/traits/traits.json +0 -0
  265. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/updater/__init__.py +0 -0
  266. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/updater/__main__.py +0 -0
  267. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/utils/__init__.py +0 -0
  268. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/utils/async_utils.py +0 -0
  269. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/utils/dict_utils.py +0 -0
  270. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/utils/file_utils.py +0 -0
  271. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/utils/git_utils.py +0 -0
  272. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/utils/huggingface_utils.py +0 -0
  273. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/utils/library_utils.py +0 -0
  274. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/utils/metaclasses.py +0 -0
  275. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/utils/uv_utils.py +0 -0
  276. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/utils/version_utils.py +0 -0
  277. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/version_compatibility/__init__.py +0 -0
  278. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/version_compatibility/versions/__init__.py +0 -0
  279. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/version_compatibility/versions/v0_39_0/__init__.py +0 -0
  280. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/version_compatibility/versions/v0_39_0/modified_parameters_set_removal.py +0 -0
  281. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/version_compatibility/versions/v0_63_8/__init__.py +0 -0
  282. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/version_compatibility/versions/v0_63_8/deprecated_nodegroup_parameters.py +0 -0
  283. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/version_compatibility/versions/v0_65_4/__init__.py +0 -0
  284. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/version_compatibility/versions/v0_65_4/run_in_parallel_to_run_in_order.py +0 -0
  285. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/version_compatibility/versions/v0_65_5/__init__.py +0 -0
  286. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/version_compatibility/versions/v0_65_5/flux_2_removed_parameters.py +0 -0
  287. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/version_compatibility/versions/v0_7_0/__init__.py +0 -0
  288. {griptape_nodes-0.70.0 → griptape_nodes-0.71.0}/src/griptape_nodes/version_compatibility/versions/v0_7_0/local_executor_argument_addition.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: griptape-nodes
3
- Version: 0.70.0
3
+ Version: 0.71.0
4
4
  Summary: Add your description here
5
5
  Requires-Dist: griptape>=1.9.0
6
6
  Requires-Dist: pydantic>=2.10.6
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "griptape-nodes"
3
- version = "0.70.0"
3
+ version = "0.71.0"
4
4
  description = "Add your description here"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12.0, <3.13"
@@ -73,7 +73,7 @@ class Client:
73
73
 
74
74
  async def __aenter__(self) -> Self:
75
75
  """Async context manager entry: connect to WebSocket server."""
76
- await self._connect()
76
+ await self.connect()
77
77
  return self
78
78
 
79
79
  async def __aexit__(
@@ -83,7 +83,7 @@ class Client:
83
83
  exc_tb: TracebackType | None,
84
84
  ) -> None:
85
85
  """Async context manager exit: disconnect from WebSocket server."""
86
- await self._disconnect()
86
+ await self.disconnect()
87
87
 
88
88
  def __aiter__(self) -> AsyncIterator[dict[str, Any]]:
89
89
  """Return self as async iterator."""
@@ -150,7 +150,7 @@ class Client:
150
150
  message = {"type": event_type, "payload": payload, "topic": topic}
151
151
  await self._send_message(message)
152
152
 
153
- async def _connect(self) -> None:
153
+ async def connect(self) -> None:
154
154
  """Connect to the WebSocket server and start receiving messages.
155
155
 
156
156
  This method starts the connection manager task.
@@ -175,7 +175,7 @@ class Client:
175
175
  )
176
176
  raise ConnectionError(msg) from e
177
177
 
178
- async def _disconnect(self) -> None:
178
+ async def disconnect(self) -> None:
179
179
  """Disconnect from the WebSocket server and clean up tasks."""
180
180
  # Cancel tasks
181
181
  if self._receiving_task:
@@ -203,7 +203,10 @@ class Client:
203
203
  async for websocket in connect(self.url, additional_headers=self.headers):
204
204
  self._websocket = websocket
205
205
  self._connection_ready.set()
206
- logger.debug("WebSocket connection established: %s", self.url)
206
+ if self._subscribed_topics:
207
+ logger.info("WebSocket reconnected successfully")
208
+ else:
209
+ logger.debug("WebSocket connection established: %s", self.url)
207
210
 
208
211
  # Resubscribe to all topics after reconnection
209
212
  if self._subscribed_topics:
@@ -29,6 +29,42 @@ class PythonSubprocessExecutor:
29
29
  self._process: asyncio.subprocess.Process | None = None
30
30
  self._is_running = False
31
31
 
32
+ async def _stream_output(
33
+ self,
34
+ stream: asyncio.StreamReader | None,
35
+ stream_name: str,
36
+ collected_lines: list[str],
37
+ ) -> None:
38
+ """Read from a stream line-by-line, printing each line in real-time.
39
+
40
+ Output is printed directly with ANSI dim formatting to preserve formatting
41
+ (e.g., rich tables, colors) from the subprocess while making it visually
42
+ distinct from main process logs.
43
+
44
+ Args:
45
+ stream: The async stream reader to read from
46
+ stream_name: Name of the stream for logging (e.g., "stdout", "stderr")
47
+ collected_lines: List to accumulate decoded lines into
48
+ """
49
+ if stream is None:
50
+ return
51
+
52
+ # ANSI escape codes for dimmed output
53
+ ansi_dim = "\033[2m"
54
+ ansi_reset = "\033[0m"
55
+
56
+ # Choose the appropriate output stream
57
+ output_stream = sys.stderr if stream_name == "stderr" else sys.stdout
58
+
59
+ while True:
60
+ line = await stream.readline()
61
+ if not line:
62
+ break
63
+ decoded_line = line.decode(errors="replace").rstrip()
64
+ collected_lines.append(decoded_line)
65
+ # Print with dim formatting to distinguish from main process logs
66
+ print(f"{ansi_dim}{decoded_line}{ansi_reset}", file=output_stream, flush=True)
67
+
32
68
  async def execute_python_script(
33
69
  self,
34
70
  script_path: Path,
@@ -51,6 +87,8 @@ class PythonSubprocessExecutor:
51
87
  args = args or []
52
88
  command = [sys.executable, str(script_path), *args]
53
89
  subprocess_env = _create_subprocess_env(env)
90
+ # Disable Python output buffering so we get real-time output
91
+ subprocess_env["PYTHONUNBUFFERED"] = "1"
54
92
 
55
93
  try:
56
94
  logger.info("Starting subprocess: %s", " ".join(command))
@@ -66,16 +104,17 @@ class PythonSubprocessExecutor:
66
104
  self._is_running = True
67
105
  logger.info("Subprocess started with PID: %s", self._process.pid)
68
106
 
69
- stdout_bytes, stderr_bytes = await self._process.communicate()
107
+ # Stream stdout and stderr concurrently for real-time output
108
+ stdout_lines: list[str] = []
109
+ stderr_lines: list[str] = []
110
+ await asyncio.gather(
111
+ self._stream_output(self._process.stdout, "stdout", stdout_lines),
112
+ self._stream_output(self._process.stderr, "stderr", stderr_lines),
113
+ )
114
+
115
+ # Wait for process to complete and get return code
116
+ await self._process.wait()
70
117
  returncode = self._process.returncode
71
- stdout = stdout_bytes.decode(errors="replace") if stdout_bytes else ""
72
- stderr = stderr_bytes.decode(errors="replace") if stderr_bytes else ""
73
-
74
- # Log all output regardless of return code
75
- if stdout:
76
- logger.info("Subprocess stdout: %s", stdout)
77
- if stderr:
78
- logger.info("Subprocess stderr: %s", stderr)
79
118
 
80
119
  if returncode == 0:
81
120
  logger.info("Subprocess completed successfully with return code: %d", returncode)
@@ -0,0 +1,88 @@
1
+ """Base WebSocket mixin for subprocess communication.
2
+
3
+ This module provides a reusable base mixin with shared WebSocket client
4
+ and background task lifecycle management used by both listener and sender mixins.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import asyncio
10
+ import contextlib
11
+ import logging
12
+ from typing import TYPE_CHECKING
13
+
14
+ from griptape_nodes.api_client import Client
15
+
16
+ if TYPE_CHECKING:
17
+ from collections.abc import Coroutine
18
+ from typing import Any
19
+
20
+ logger = logging.getLogger(__name__)
21
+
22
+
23
+ class SubprocessWebSocketBaseMixin:
24
+ """Base mixin providing shared WebSocket client and task lifecycle management.
25
+
26
+ This mixin handles:
27
+ - Session ID management
28
+ - WebSocket client creation and cleanup
29
+ - Background task lifecycle (creation, cancellation, cleanup)
30
+
31
+ Subclasses should use the protected methods to build their specific functionality.
32
+ """
33
+
34
+ _session_id: str
35
+ _ws_client: Client | None
36
+ _ws_task: asyncio.Task | None
37
+
38
+ def _init_websocket_base(self, session_id: str) -> None:
39
+ """Initialize shared WebSocket state.
40
+
41
+ Args:
42
+ session_id: Unique session ID for WebSocket topic.
43
+ """
44
+ self._session_id = session_id
45
+ self._ws_client = None
46
+ self._ws_task = None
47
+
48
+ def _get_session_id(self) -> str:
49
+ """Get the session ID used for WebSocket communication."""
50
+ return self._session_id
51
+
52
+ async def _start_websocket_client(self) -> None:
53
+ """Start the WebSocket client connection.
54
+
55
+ Creates and connects the WebSocket client.
56
+ Subclasses should call this, then perform additional setup (subscribe, etc.).
57
+ """
58
+ logger.info("Starting WebSocket client for session %s", self._session_id)
59
+ self._ws_client = Client()
60
+ await self._ws_client.connect()
61
+ logger.info("WebSocket client connected for session %s", self._session_id)
62
+
63
+ def _create_websocket_task(self, coro: Coroutine[Any, Any, None]) -> None:
64
+ """Create a background task for WebSocket operations.
65
+
66
+ Args:
67
+ coro: The coroutine to run as a background task.
68
+ """
69
+ self._ws_task = asyncio.create_task(coro)
70
+
71
+ async def _stop_websocket_task(self) -> None:
72
+ """Cancel and clean up the background task."""
73
+ if self._ws_task is None:
74
+ return
75
+
76
+ self._ws_task.cancel()
77
+ with contextlib.suppress(asyncio.CancelledError):
78
+ await self._ws_task
79
+ self._ws_task = None
80
+
81
+ async def _stop_websocket_client(self) -> None:
82
+ """Close the WebSocket client connection."""
83
+ if self._ws_client is None:
84
+ return
85
+
86
+ await self._ws_client.disconnect()
87
+ self._ws_client = None
88
+ logger.info("WebSocket client disconnected for session %s", self._session_id)
@@ -0,0 +1,126 @@
1
+ """WebSocket listener mixin for subprocess communication.
2
+
3
+ This module provides a reusable mixin for listening to WebSocket events
4
+ from subprocess executions using native asyncio. Used by both
5
+ SubprocessWorkflowExecutor and SubprocessWorkflowPublisher.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import asyncio
11
+ import logging
12
+ import uuid
13
+ from typing import TYPE_CHECKING
14
+
15
+ from griptape_nodes.bootstrap.utils.subprocess_websocket_base import SubprocessWebSocketBaseMixin
16
+
17
+ if TYPE_CHECKING:
18
+ from collections.abc import Callable
19
+
20
+ logger = logging.getLogger(__name__)
21
+
22
+
23
+ class SubprocessWebSocketListenerMixin(SubprocessWebSocketBaseMixin):
24
+ """Mixin providing WebSocket listener functionality for subprocess communication.
25
+
26
+ This mixin handles:
27
+ - Starting/stopping a WebSocket listener as a background task
28
+ - Subscribing to session-specific topics
29
+ - Processing incoming events and calling callbacks
30
+
31
+ Subclasses should implement _handle_subprocess_event() for custom event handling.
32
+ """
33
+
34
+ _on_event: Callable[[dict], None] | None
35
+
36
+ def _init_websocket_listener(
37
+ self,
38
+ session_id: str | None = None,
39
+ on_event: Callable[[dict], None] | None = None,
40
+ ) -> None:
41
+ """Initialize WebSocket listener state.
42
+
43
+ Args:
44
+ session_id: Unique session ID for WebSocket topic subscription.
45
+ If None, a random UUID will be generated.
46
+ on_event: Optional callback invoked for each received event.
47
+ """
48
+ self._init_websocket_base(session_id or uuid.uuid4().hex)
49
+ self._on_event = on_event
50
+
51
+ async def _start_websocket_listener(self) -> None:
52
+ """Start WebSocket client and listener background task."""
53
+ logger.info("Starting WebSocket listener for session %s", self._session_id)
54
+
55
+ await self._start_websocket_client()
56
+
57
+ if self._ws_client is None:
58
+ msg = "WebSocket client failed to initialize"
59
+ raise RuntimeError(msg)
60
+
61
+ topic = f"sessions/{self._session_id}/response"
62
+ await self._ws_client.subscribe(topic)
63
+
64
+ self._create_websocket_task(self._ws_listen_loop())
65
+
66
+ logger.info("WebSocket listener started for session %s", self._session_id)
67
+
68
+ async def _ws_listen_loop(self) -> None:
69
+ """Background task to process incoming messages."""
70
+ logger.debug("Starting WebSocket listen loop for session %s", self._session_id)
71
+
72
+ if self._ws_client is None:
73
+ logger.error("WebSocket client not available for listening")
74
+ return
75
+
76
+ try:
77
+ async for message in self._ws_client.messages:
78
+ try:
79
+ logger.debug("Received WebSocket message: %s", message.get("type"))
80
+ await self._process_listener_event(message)
81
+ except Exception:
82
+ logger.exception(
83
+ "Error processing WebSocket message of type '%s' for session %s",
84
+ message.get("type", "unknown"),
85
+ self._session_id,
86
+ )
87
+ except asyncio.CancelledError:
88
+ logger.debug("WebSocket listener cancelled for session %s", self._session_id)
89
+ except Exception as e:
90
+ logger.error("Error in WebSocket message listener: %s", e)
91
+
92
+ logger.debug("WebSocket listen loop ended for session %s", self._session_id)
93
+
94
+ async def _process_listener_event(self, event: dict) -> None:
95
+ """Process events received from the subprocess via WebSocket.
96
+
97
+ This method:
98
+ 1. Calls the on_event callback if provided (for GUI updates)
99
+ 2. Delegates to _handle_subprocess_event for subclass-specific handling
100
+
101
+ Args:
102
+ event: The event dictionary received from the subprocess
103
+ """
104
+ if self._on_event:
105
+ self._on_event(event)
106
+
107
+ await self._handle_subprocess_event(event)
108
+
109
+ async def _stop_websocket_listener(self) -> None:
110
+ """Stop the listener task and close client."""
111
+ logger.info("Stopping WebSocket listener for session %s", self._session_id)
112
+
113
+ await self._stop_websocket_task()
114
+ await self._stop_websocket_client()
115
+
116
+ logger.info("WebSocket listener stopped for session %s", self._session_id)
117
+
118
+ async def _handle_subprocess_event(self, event: dict) -> None:
119
+ """Handle subprocess-specific events.
120
+
121
+ Override this method in subclasses to implement custom event handling.
122
+ The default implementation does nothing.
123
+
124
+ Args:
125
+ event: The event dictionary received from the subprocess
126
+ """
@@ -0,0 +1,121 @@
1
+ """WebSocket sender mixin for subprocess communication.
2
+
3
+ This module provides a reusable mixin for sending WebSocket events
4
+ from subprocess executions back to the parent process using native asyncio.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import asyncio
10
+ import json
11
+ import logging
12
+
13
+ from griptape_nodes.app.app import WebSocketMessage
14
+ from griptape_nodes.bootstrap.utils.subprocess_websocket_base import SubprocessWebSocketBaseMixin
15
+
16
+ logger = logging.getLogger(__name__)
17
+
18
+
19
+ class SubprocessWebSocketSenderMixin(SubprocessWebSocketBaseMixin):
20
+ """Mixin providing WebSocket sender functionality for subprocess communication.
21
+
22
+ This mixin handles:
23
+ - Starting/stopping a WebSocket connection as a background task
24
+ - Queuing and sending events to the parent process
25
+ - Non-blocking event emission from the main event loop
26
+ """
27
+
28
+ _ws_send_queue: asyncio.Queue[WebSocketMessage]
29
+ _ws_shutdown_event: asyncio.Event
30
+
31
+ def _init_websocket_sender(self, session_id: str) -> None:
32
+ """Initialize WebSocket sender state.
33
+
34
+ Args:
35
+ session_id: Unique session ID for WebSocket topic.
36
+ """
37
+ self._init_websocket_base(session_id)
38
+ self._ws_send_queue = asyncio.Queue()
39
+ self._ws_shutdown_event = asyncio.Event()
40
+
41
+ async def _start_websocket_connection(self) -> None:
42
+ """Start WebSocket client and sender background task."""
43
+ logger.info("Starting WebSocket sender for session %s", self._session_id)
44
+
45
+ self._ws_shutdown_event.clear()
46
+ await self._start_websocket_client()
47
+ self._create_websocket_task(self._ws_send_loop())
48
+
49
+ logger.info("WebSocket sender started for session %s", self._session_id)
50
+
51
+ async def _ws_send_loop(self) -> None:
52
+ """Background task to send queued messages."""
53
+ logger.debug("Starting WebSocket send loop for session %s", self._session_id)
54
+
55
+ while not self._ws_shutdown_event.is_set():
56
+ try:
57
+ message = await asyncio.wait_for(self._ws_send_queue.get(), timeout=1.0)
58
+ except TimeoutError:
59
+ continue
60
+ except asyncio.CancelledError:
61
+ break
62
+
63
+ try:
64
+ if self._ws_client is None:
65
+ logger.warning("WebSocket client not available, message dropped")
66
+ continue
67
+
68
+ topic = message.topic if message.topic else f"sessions/{self._session_id}/response"
69
+ payload_dict = json.loads(message.payload)
70
+ await self._ws_client.publish(message.event_type, payload_dict, topic)
71
+ logger.debug("DELIVERED: %s event", message.event_type)
72
+ except Exception as e:
73
+ logger.error("Error sending WebSocket message: %s", e)
74
+ finally:
75
+ self._ws_send_queue.task_done()
76
+
77
+ logger.debug("WebSocket send loop ended for session %s", self._session_id)
78
+
79
+ def send_event(self, event_type: str, payload: str) -> None:
80
+ """Queue an event for sending via WebSocket (non-blocking).
81
+
82
+ Args:
83
+ event_type: Type of event (e.g., "execution_event", "success_result")
84
+ payload: JSON string payload to send
85
+ """
86
+ if self._ws_task is None or self._ws_task.done():
87
+ logger.debug("WebSocket sender not active, event not sent: %s", event_type)
88
+ return
89
+
90
+ topic = f"sessions/{self._session_id}/response"
91
+ message = WebSocketMessage(event_type, payload, topic)
92
+
93
+ try:
94
+ self._ws_send_queue.put_nowait(message)
95
+ logger.debug("QUEUED: %s event via websocket", event_type)
96
+ except asyncio.QueueFull:
97
+ logger.error("WebSocket queue full, event dropped: %s", event_type)
98
+
99
+ async def _stop_websocket_connection(self) -> None:
100
+ """Stop the sender task and close client."""
101
+ logger.info("Stopping WebSocket sender for session %s", self._session_id)
102
+
103
+ self._ws_shutdown_event.set()
104
+ await self._stop_websocket_task()
105
+ await self._stop_websocket_client()
106
+
107
+ logger.info("WebSocket sender stopped for session %s", self._session_id)
108
+
109
+ async def _wait_for_websocket_queue_flush(self, timeout_seconds: float = 5.0) -> None:
110
+ """Wait for all queued messages to be sent.
111
+
112
+ Args:
113
+ timeout_seconds: Maximum time to wait for queue to flush.
114
+ """
115
+ if self._ws_task is None or self._ws_task.done():
116
+ return
117
+
118
+ try:
119
+ await asyncio.wait_for(self._ws_send_queue.join(), timeout=timeout_seconds)
120
+ except TimeoutError:
121
+ logger.warning("Timeout waiting for websocket queue to flush")