griptape-nodes 0.43.1__py3-none-any.whl → 0.45.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. griptape_nodes/__init__.py +46 -52
  2. griptape_nodes/app/.python-version +0 -0
  3. griptape_nodes/app/__init__.py +0 -0
  4. griptape_nodes/app/api.py +37 -41
  5. griptape_nodes/app/app.py +70 -3
  6. griptape_nodes/app/watch.py +5 -2
  7. griptape_nodes/bootstrap/__init__.py +0 -0
  8. griptape_nodes/bootstrap/workflow_executors/__init__.py +0 -0
  9. griptape_nodes/bootstrap/workflow_executors/local_workflow_executor.py +7 -1
  10. griptape_nodes/bootstrap/workflow_executors/subprocess_workflow_executor.py +90 -0
  11. griptape_nodes/bootstrap/workflow_executors/workflow_executor.py +7 -1
  12. griptape_nodes/drivers/__init__.py +0 -0
  13. griptape_nodes/drivers/storage/__init__.py +0 -0
  14. griptape_nodes/drivers/storage/base_storage_driver.py +90 -0
  15. griptape_nodes/drivers/storage/griptape_cloud_storage_driver.py +48 -0
  16. griptape_nodes/drivers/storage/local_storage_driver.py +37 -0
  17. griptape_nodes/drivers/storage/storage_backend.py +0 -0
  18. griptape_nodes/exe_types/__init__.py +0 -0
  19. griptape_nodes/exe_types/connections.py +0 -0
  20. griptape_nodes/exe_types/core_types.py +222 -17
  21. griptape_nodes/exe_types/flow.py +0 -0
  22. griptape_nodes/exe_types/node_types.py +20 -5
  23. griptape_nodes/exe_types/type_validator.py +0 -0
  24. griptape_nodes/machines/__init__.py +0 -0
  25. griptape_nodes/machines/control_flow.py +5 -4
  26. griptape_nodes/machines/fsm.py +0 -0
  27. griptape_nodes/machines/node_resolution.py +110 -74
  28. griptape_nodes/mcp_server/__init__.py +0 -0
  29. griptape_nodes/mcp_server/server.py +16 -8
  30. griptape_nodes/mcp_server/ws_request_manager.py +0 -0
  31. griptape_nodes/node_library/__init__.py +0 -0
  32. griptape_nodes/node_library/advanced_node_library.py +0 -0
  33. griptape_nodes/node_library/library_registry.py +0 -0
  34. griptape_nodes/node_library/workflow_registry.py +29 -0
  35. griptape_nodes/py.typed +0 -0
  36. griptape_nodes/retained_mode/__init__.py +0 -0
  37. griptape_nodes/retained_mode/events/__init__.py +0 -0
  38. griptape_nodes/retained_mode/events/agent_events.py +0 -0
  39. griptape_nodes/retained_mode/events/app_events.py +3 -8
  40. griptape_nodes/retained_mode/events/arbitrary_python_events.py +0 -0
  41. griptape_nodes/retained_mode/events/base_events.py +15 -7
  42. griptape_nodes/retained_mode/events/config_events.py +0 -0
  43. griptape_nodes/retained_mode/events/connection_events.py +0 -0
  44. griptape_nodes/retained_mode/events/context_events.py +0 -0
  45. griptape_nodes/retained_mode/events/execution_events.py +0 -0
  46. griptape_nodes/retained_mode/events/flow_events.py +2 -1
  47. griptape_nodes/retained_mode/events/generate_request_payload_schemas.py +0 -0
  48. griptape_nodes/retained_mode/events/library_events.py +0 -0
  49. griptape_nodes/retained_mode/events/logger_events.py +0 -0
  50. griptape_nodes/retained_mode/events/node_events.py +36 -0
  51. griptape_nodes/retained_mode/events/object_events.py +0 -0
  52. griptape_nodes/retained_mode/events/os_events.py +98 -6
  53. griptape_nodes/retained_mode/events/parameter_events.py +0 -0
  54. griptape_nodes/retained_mode/events/payload_registry.py +0 -0
  55. griptape_nodes/retained_mode/events/secrets_events.py +0 -0
  56. griptape_nodes/retained_mode/events/static_file_events.py +0 -0
  57. griptape_nodes/retained_mode/events/sync_events.py +60 -0
  58. griptape_nodes/retained_mode/events/validation_events.py +0 -0
  59. griptape_nodes/retained_mode/events/workflow_events.py +231 -0
  60. griptape_nodes/retained_mode/griptape_nodes.py +9 -4
  61. griptape_nodes/retained_mode/managers/__init__.py +0 -0
  62. griptape_nodes/retained_mode/managers/agent_manager.py +0 -0
  63. griptape_nodes/retained_mode/managers/arbitrary_code_exec_manager.py +0 -0
  64. griptape_nodes/retained_mode/managers/config_manager.py +1 -1
  65. griptape_nodes/retained_mode/managers/context_manager.py +0 -0
  66. griptape_nodes/retained_mode/managers/engine_identity_manager.py +0 -0
  67. griptape_nodes/retained_mode/managers/event_manager.py +0 -0
  68. griptape_nodes/retained_mode/managers/flow_manager.py +6 -0
  69. griptape_nodes/retained_mode/managers/library_lifecycle/__init__.py +0 -0
  70. griptape_nodes/retained_mode/managers/library_lifecycle/data_models.py +0 -0
  71. griptape_nodes/retained_mode/managers/library_lifecycle/library_directory.py +0 -0
  72. griptape_nodes/retained_mode/managers/library_lifecycle/library_fsm.py +0 -0
  73. griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/__init__.py +0 -0
  74. griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/base.py +0 -0
  75. griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/github.py +0 -0
  76. griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/local_file.py +0 -0
  77. griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/package.py +0 -0
  78. griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/sandbox.py +0 -0
  79. griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance.py +0 -0
  80. griptape_nodes/retained_mode/managers/library_lifecycle/library_status.py +0 -0
  81. griptape_nodes/retained_mode/managers/library_manager.py +8 -26
  82. griptape_nodes/retained_mode/managers/node_manager.py +78 -7
  83. griptape_nodes/retained_mode/managers/object_manager.py +0 -0
  84. griptape_nodes/retained_mode/managers/operation_manager.py +7 -0
  85. griptape_nodes/retained_mode/managers/os_manager.py +133 -8
  86. griptape_nodes/retained_mode/managers/secrets_manager.py +0 -0
  87. griptape_nodes/retained_mode/managers/session_manager.py +0 -0
  88. griptape_nodes/retained_mode/managers/settings.py +5 -0
  89. griptape_nodes/retained_mode/managers/static_files_manager.py +0 -0
  90. griptape_nodes/retained_mode/managers/sync_manager.py +498 -0
  91. griptape_nodes/retained_mode/managers/version_compatibility_manager.py +0 -0
  92. griptape_nodes/retained_mode/managers/workflow_manager.py +736 -33
  93. griptape_nodes/retained_mode/retained_mode.py +23 -0
  94. griptape_nodes/retained_mode/utils/__init__.py +0 -0
  95. griptape_nodes/retained_mode/utils/engine_identity.py +0 -0
  96. griptape_nodes/retained_mode/utils/name_generator.py +0 -0
  97. griptape_nodes/traits/__init__.py +0 -0
  98. griptape_nodes/traits/add_param_button.py +0 -0
  99. griptape_nodes/traits/button.py +0 -0
  100. griptape_nodes/traits/clamp.py +0 -0
  101. griptape_nodes/traits/compare.py +0 -0
  102. griptape_nodes/traits/compare_images.py +0 -0
  103. griptape_nodes/traits/file_system_picker.py +18 -0
  104. griptape_nodes/traits/minmax.py +0 -0
  105. griptape_nodes/traits/options.py +0 -0
  106. griptape_nodes/traits/slider.py +0 -0
  107. griptape_nodes/traits/trait_registry.py +0 -0
  108. griptape_nodes/traits/traits.json +0 -0
  109. griptape_nodes/updater/__init__.py +4 -2
  110. griptape_nodes/updater/__main__.py +0 -0
  111. griptape_nodes/utils/__init__.py +0 -0
  112. griptape_nodes/utils/dict_utils.py +0 -0
  113. griptape_nodes/utils/image_preview.py +0 -0
  114. griptape_nodes/utils/metaclasses.py +0 -0
  115. griptape_nodes/utils/uv_utils.py +18 -0
  116. griptape_nodes/utils/version_utils.py +51 -0
  117. griptape_nodes/version_compatibility/__init__.py +0 -0
  118. griptape_nodes/version_compatibility/versions/__init__.py +0 -0
  119. griptape_nodes/version_compatibility/versions/v0_39_0/__init__.py +0 -0
  120. griptape_nodes/version_compatibility/versions/v0_39_0/modified_parameters_set_removal.py +0 -0
  121. {griptape_nodes-0.43.1.dist-info → griptape_nodes-0.45.0.dist-info}/METADATA +2 -1
  122. {griptape_nodes-0.43.1.dist-info → griptape_nodes-0.45.0.dist-info}/RECORD +42 -47
  123. {griptape_nodes-0.43.1.dist-info → griptape_nodes-0.45.0.dist-info}/WHEEL +1 -1
  124. griptape_nodes/bootstrap/bootstrap_script.py +0 -54
  125. griptape_nodes/bootstrap/post_build_install_script.sh +0 -3
  126. griptape_nodes/bootstrap/pre_build_install_script.sh +0 -4
  127. griptape_nodes/bootstrap/register_libraries_script.py +0 -32
  128. griptape_nodes/bootstrap/structure_config.yaml +0 -15
  129. griptape_nodes/bootstrap/workflow_runners/__init__.py +0 -1
  130. griptape_nodes/bootstrap/workflow_runners/bootstrap_workflow_runner.py +0 -28
  131. griptape_nodes/bootstrap/workflow_runners/local_workflow_runner.py +0 -237
  132. griptape_nodes/bootstrap/workflow_runners/subprocess_workflow_runner.py +0 -62
  133. griptape_nodes/bootstrap/workflow_runners/workflow_runner.py +0 -11
  134. {griptape_nodes-0.43.1.dist-info → griptape_nodes-0.45.0.dist-info}/entry_points.txt +0 -0
@@ -1,237 +0,0 @@
1
- import importlib.util
2
- import logging
3
- import sys
4
- from pathlib import Path
5
- from queue import Queue
6
- from typing import Any
7
-
8
- from griptape.events import BaseEvent, EventBus, EventListener
9
-
10
- from griptape_nodes.bootstrap.register_libraries_script import register_libraries
11
- from griptape_nodes.bootstrap.workflow_runners.workflow_runner import WorkflowRunner
12
- from griptape_nodes.exe_types.node_types import EndNode, StartNode
13
- from griptape_nodes.retained_mode.events.base_events import (
14
- AppEvent,
15
- EventRequest,
16
- ExecutionGriptapeNodeEvent,
17
- GriptapeNodeEvent,
18
- ProgressEvent,
19
- )
20
- from griptape_nodes.retained_mode.events.execution_events import SingleExecutionStepRequest, StartFlowRequest
21
- from griptape_nodes.retained_mode.events.parameter_events import SetParameterValueRequest
22
- from griptape_nodes.retained_mode.griptape_nodes import GriptapeNodes
23
-
24
- logger = logging.getLogger(__name__)
25
-
26
-
27
- class LocalWorkflowRunner(WorkflowRunner):
28
- def __init__(self, libraries: list[Path]) -> None:
29
- self.registered_libraries = False
30
- self.libraries = libraries
31
- self.queue = Queue()
32
-
33
- def _load_user_workflow(self, path_to_workflow: str) -> None:
34
- # Ensure file_path is a Path object
35
- file_path = Path(path_to_workflow)
36
-
37
- # Generate a unique module name
38
- module_name = f"gtn_dynamic_module_{file_path.name.replace('.', '_')}_{hash(str(file_path))}"
39
-
40
- # Load the module specification
41
- spec = importlib.util.spec_from_file_location(module_name, file_path)
42
- if spec is None or spec.loader is None:
43
- msg = f"Could not load module specification from {file_path}"
44
- raise ImportError(msg)
45
-
46
- # Create the module
47
- module = importlib.util.module_from_spec(spec)
48
-
49
- # Add to sys.modules to handle recursive imports
50
- sys.modules[module_name] = module
51
-
52
- # Execute the module
53
- spec.loader.exec_module(module)
54
-
55
- def _load_flow_for_workflow(self) -> str:
56
- context_manager = GriptapeNodes.ContextManager()
57
- return context_manager.get_current_flow().name
58
-
59
- def _set_storage_backend(self, storage_backend: str) -> None:
60
- from griptape_nodes.retained_mode.managers.config_manager import ConfigManager
61
-
62
- config_manager = ConfigManager()
63
- config_manager.set_config_value(
64
- key="storage_backend",
65
- value=storage_backend,
66
- )
67
-
68
- def _register_libraries(self) -> None:
69
- if not self.registered_libraries:
70
- register_libraries([str(p) for p in self.libraries])
71
- self.registered_libraries = True
72
-
73
- def _set_workflow_context(self, workflow_name: str) -> None:
74
- context_manager = GriptapeNodes.ContextManager()
75
- context_manager.push_workflow(workflow_name=workflow_name)
76
-
77
- def _handle_event(self, event: BaseEvent) -> None:
78
- try:
79
- if isinstance(event, GriptapeNodeEvent):
80
- self.__handle_node_event(event)
81
- elif isinstance(event, ExecutionGriptapeNodeEvent):
82
- self.__handle_execution_node_event(event)
83
- elif isinstance(event, ProgressEvent):
84
- self.__handle_progress_event(event)
85
- elif isinstance(event, AppEvent):
86
- self.__handle_app_event(event)
87
- else:
88
- msg = f"Unknown event type: {type(event)}"
89
- logger.info(msg)
90
- self.queue.put(event)
91
- except Exception as e:
92
- logger.info(e)
93
-
94
- def __handle_node_event(self, event: GriptapeNodeEvent) -> None:
95
- result_event = event.wrapped_event
96
- event_json = result_event.json()
97
- event_log = f"GriptapeNodeEvent: {event_json}"
98
- logger.info(event_log)
99
-
100
- def __handle_execution_node_event(self, event: ExecutionGriptapeNodeEvent) -> None:
101
- result_event = event.wrapped_event
102
- if type(result_event.payload).__name__ == "NodeStartProcessEvent":
103
- event_log = f"NodeStartProcessEvent: {result_event.payload}"
104
- logger.info(event_log)
105
-
106
- elif type(result_event.payload).__name__ == "ResumeNodeProcessingEvent":
107
- event_log = f"ResumeNodeProcessingEvent: {result_event.payload}"
108
- logger.info(event_log)
109
-
110
- # Here we need to handle the resume event since this is the callback mechanism
111
- # for the flow to be resumed for any Node that yields a generator in its process method.
112
- node_name = result_event.payload.node_name
113
- flow_name = GriptapeNodes.NodeManager().get_node_parent_flow_by_name(node_name)
114
- event_request = EventRequest(request=SingleExecutionStepRequest(flow_name=flow_name))
115
- GriptapeNodes.handle_request(event_request.request)
116
-
117
- elif type(result_event.payload).__name__ == "NodeFinishProcessEvent":
118
- event_log = f"NodeFinishProcessEvent: {result_event.payload}"
119
- logger.info(event_log)
120
-
121
- else:
122
- event_log = f"ExecutionGriptapeNodeEvent: {result_event.payload}"
123
- logger.info(event_log)
124
-
125
- self.queue.put(event)
126
-
127
- def __handle_progress_event(self, gt_event: ProgressEvent) -> None:
128
- event_log = f"ProgressEvent: {gt_event}"
129
- logger.info(event_log)
130
-
131
- def __handle_app_event(self, event: AppEvent) -> None:
132
- event_log = f"AppEvent: {event.payload}"
133
- logger.info(event_log)
134
-
135
- def _submit_output(self, output: dict) -> None:
136
- self.output = output
137
-
138
- def _set_input_for_flow(self, flow_name: str, flow_input: dict[str, dict]) -> None:
139
- control_flow = GriptapeNodes.FlowManager().get_flow_by_name(flow_name)
140
- nodes = control_flow.nodes
141
- for node_name, node in nodes.items():
142
- if isinstance(node, StartNode):
143
- param_map: dict | None = flow_input.get(node_name)
144
- if param_map is not None:
145
- for parameter_name, parameter_value in param_map.items():
146
- set_parameter_value_request = SetParameterValueRequest(
147
- parameter_name=parameter_name,
148
- value=parameter_value,
149
- node_name=node_name,
150
- )
151
- set_parameter_value_result = GriptapeNodes.handle_request(set_parameter_value_request)
152
-
153
- if set_parameter_value_result.failed():
154
- msg = f"Failed to set parameter {parameter_name} for node {node_name}."
155
- raise ValueError(msg)
156
-
157
- def _get_output_for_flow(self, flow_name: str) -> dict:
158
- control_flow = GriptapeNodes.FlowManager().get_flow_by_name(flow_name)
159
- nodes = control_flow.nodes
160
- output = {}
161
- for node_name, node in nodes.items():
162
- if isinstance(node, EndNode):
163
- output[node_name] = node.parameter_values
164
-
165
- return output
166
-
167
- def run(self, workflow_path: str, workflow_name: str, flow_input: Any, storage_backend: str = "local") -> None:
168
- """Executes a published workflow.
169
-
170
- Executes a workflow by setting up event listeners, registering libraries,
171
- loading the user-defined workflow, and running the specified workflow.
172
-
173
- Parameters:
174
- workflow_name: The name of the workflow to execute.
175
- flow_input: Input data for the flow, typically a dictionary.
176
-
177
- Returns:
178
- None
179
- """
180
- EventBus.add_event_listener(
181
- event_listener=EventListener(
182
- on_event=self._handle_event,
183
- )
184
- )
185
-
186
- # Set the storage backend
187
- self._set_storage_backend(storage_backend=storage_backend)
188
-
189
- # Register all of our relevant libraries
190
- self._register_libraries()
191
-
192
- # Required to set the workflow_context before loading the workflow
193
- # or nothing works. The name can be anything, but how about the workflow_name.
194
- self._set_workflow_context(workflow_name=workflow_name)
195
- self._load_user_workflow(workflow_path)
196
- flow_name = self._load_flow_for_workflow()
197
- # Now let's set the input to the flow
198
- self._set_input_for_flow(flow_name=flow_name, flow_input=flow_input)
199
-
200
- # Now send the run command to actually execute it
201
- start_flow_request = StartFlowRequest(flow_name=flow_name)
202
- start_flow_result = GriptapeNodes.handle_request(start_flow_request)
203
-
204
- if start_flow_result.failed():
205
- msg = f"Failed to start flow {workflow_name}"
206
- raise ValueError(msg)
207
-
208
- logger.info("Workflow started!")
209
-
210
- # Wait for the control flow to finish
211
- is_flow_finished = False
212
- error: Exception | None = None
213
- while not is_flow_finished:
214
- try:
215
- event = self.queue.get(block=True)
216
-
217
- if isinstance(event, ExecutionGriptapeNodeEvent):
218
- result_event = event.wrapped_event
219
-
220
- if type(result_event.payload).__name__ == "ControlFlowResolvedEvent":
221
- self._submit_output(self._get_output_for_flow(flow_name=flow_name))
222
- is_flow_finished = True
223
- logger.info("Workflow finished!")
224
- elif type(result_event.payload).__name__ == "ControlFlowCancelledEvent":
225
- msg = "Control flow cancelled"
226
- is_flow_finished = True
227
- logger.error(msg)
228
- error = ValueError(msg)
229
-
230
- self.queue.task_done()
231
-
232
- except Exception as e:
233
- msg = f"Error handling queue event: {e}"
234
- logger.info(msg)
235
-
236
- if error is not None:
237
- raise error
@@ -1,62 +0,0 @@
1
- import logging
2
- import threading
3
- from multiprocessing import Process, Queue
4
- from multiprocessing import Queue as ProcessQueue
5
- from pathlib import Path
6
- from typing import Any
7
-
8
- from griptape_nodes.app.api import start_api
9
- from griptape_nodes.app.app import _build_static_dir
10
- from griptape_nodes.bootstrap.workflow_runners.local_workflow_runner import LocalWorkflowRunner
11
- from griptape_nodes.bootstrap.workflow_runners.workflow_runner import WorkflowRunner
12
-
13
-
14
- class SubprocessWorkflowRunner(WorkflowRunner):
15
- def __init__(self, libraries: list[Path]) -> None:
16
- self.libraries = libraries
17
-
18
- @staticmethod
19
- def _subprocess_entry(
20
- exception_queue: Queue,
21
- libraries: list[Path],
22
- workflow_path: str,
23
- workflow_name: str,
24
- flow_input: Any,
25
- ) -> None:
26
- # Reset logging to avoid duplicate logs in tests - this does not remove logs
27
- # because griptape nodes is doing some configuration of its own that seems
28
- # difficult to control.
29
- logger = logging.getLogger()
30
- for handler in logger.handlers[:]:
31
- logger.removeHandler(handler)
32
- logger.setLevel(logging.NOTSET)
33
-
34
- try:
35
- static_dir = _build_static_dir()
36
- event_queue = ProcessQueue()
37
- threading.Thread(target=start_api, args=(static_dir, event_queue), daemon=True).start()
38
- workflow_runner = LocalWorkflowRunner(libraries)
39
- workflow_runner.run(workflow_path, workflow_name, flow_input, "local")
40
- except Exception as e:
41
- exception_queue.put(e)
42
- raise
43
-
44
- def run(self, workflow_path: str, workflow_name: str, flow_input: Any, storage_backend: str = "local") -> None: # noqa: ARG002
45
- exception_queue = Queue()
46
- process = Process(
47
- target=self._subprocess_entry,
48
- args=(exception_queue, self.libraries, workflow_path, workflow_name, flow_input),
49
- )
50
- process.start()
51
- process.join()
52
-
53
- if not exception_queue.empty():
54
- exception = exception_queue.get_nowait()
55
- if isinstance(exception, Exception):
56
- raise exception
57
- msg = f"Expected an Exception but got: {type(exception)}"
58
- raise RuntimeError(msg)
59
-
60
- if process.exitcode != 0:
61
- msg = f"Process exited with code {process.exitcode} but no exception was raised."
62
- raise RuntimeError(msg)
@@ -1,11 +0,0 @@
1
- import logging
2
- from abc import ABC, abstractmethod
3
- from typing import Any
4
-
5
- logger = logging.getLogger(__name__)
6
-
7
-
8
- class WorkflowRunner(ABC):
9
- @abstractmethod
10
- def run(self, workflow_path: str, workflow_name: str, flow_input: Any, storage_backend: str = "local") -> None:
11
- pass