griptape-nodes 0.53.0__py3-none-any.whl → 0.54.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.
- griptape_nodes/__init__.py +5 -2
- griptape_nodes/app/app.py +4 -26
- griptape_nodes/bootstrap/workflow_executors/local_workflow_executor.py +35 -5
- griptape_nodes/bootstrap/workflow_executors/workflow_executor.py +15 -1
- griptape_nodes/cli/commands/config.py +4 -1
- griptape_nodes/cli/commands/init.py +5 -3
- griptape_nodes/cli/commands/libraries.py +14 -8
- griptape_nodes/cli/commands/models.py +504 -0
- griptape_nodes/cli/commands/self.py +5 -2
- griptape_nodes/cli/main.py +11 -1
- griptape_nodes/cli/shared.py +0 -9
- griptape_nodes/common/directed_graph.py +17 -1
- griptape_nodes/drivers/storage/base_storage_driver.py +40 -20
- griptape_nodes/drivers/storage/griptape_cloud_storage_driver.py +24 -29
- griptape_nodes/drivers/storage/local_storage_driver.py +17 -13
- griptape_nodes/exe_types/node_types.py +219 -14
- griptape_nodes/exe_types/param_components/__init__.py +1 -0
- griptape_nodes/exe_types/param_components/execution_status_component.py +138 -0
- griptape_nodes/machines/control_flow.py +129 -92
- griptape_nodes/machines/dag_builder.py +207 -0
- griptape_nodes/machines/parallel_resolution.py +264 -276
- griptape_nodes/machines/sequential_resolution.py +9 -7
- griptape_nodes/node_library/library_registry.py +34 -1
- griptape_nodes/retained_mode/events/app_events.py +5 -1
- griptape_nodes/retained_mode/events/base_events.py +7 -7
- griptape_nodes/retained_mode/events/config_events.py +30 -0
- griptape_nodes/retained_mode/events/execution_events.py +2 -2
- griptape_nodes/retained_mode/events/model_events.py +296 -0
- griptape_nodes/retained_mode/griptape_nodes.py +10 -1
- griptape_nodes/retained_mode/managers/agent_manager.py +14 -0
- griptape_nodes/retained_mode/managers/config_manager.py +44 -3
- griptape_nodes/retained_mode/managers/event_manager.py +8 -2
- griptape_nodes/retained_mode/managers/flow_manager.py +45 -14
- griptape_nodes/retained_mode/managers/library_manager.py +3 -3
- griptape_nodes/retained_mode/managers/model_manager.py +1107 -0
- griptape_nodes/retained_mode/managers/node_manager.py +26 -26
- griptape_nodes/retained_mode/managers/object_manager.py +1 -1
- griptape_nodes/retained_mode/managers/os_manager.py +6 -6
- griptape_nodes/retained_mode/managers/settings.py +87 -9
- griptape_nodes/retained_mode/managers/static_files_manager.py +77 -9
- griptape_nodes/retained_mode/managers/sync_manager.py +10 -5
- griptape_nodes/retained_mode/managers/workflow_manager.py +98 -92
- griptape_nodes/retained_mode/retained_mode.py +19 -0
- griptape_nodes/servers/__init__.py +1 -0
- griptape_nodes/{mcp_server/server.py → servers/mcp.py} +1 -1
- griptape_nodes/{app/api.py → servers/static.py} +43 -40
- griptape_nodes/traits/button.py +124 -6
- griptape_nodes/traits/multi_options.py +188 -0
- griptape_nodes/traits/numbers_selector.py +77 -0
- griptape_nodes/traits/options.py +93 -2
- griptape_nodes/utils/async_utils.py +31 -0
- {griptape_nodes-0.53.0.dist-info → griptape_nodes-0.54.0.dist-info}/METADATA +3 -1
- {griptape_nodes-0.53.0.dist-info → griptape_nodes-0.54.0.dist-info}/RECORD +56 -47
- {griptape_nodes-0.53.0.dist-info → griptape_nodes-0.54.0.dist-info}/WHEEL +1 -1
- /griptape_nodes/{mcp_server → servers}/ws_request_manager.py +0 -0
- {griptape_nodes-0.53.0.dist-info → griptape_nodes-0.54.0.dist-info}/entry_points.txt +0 -0
|
@@ -294,5 +294,11 @@ class EventManager:
|
|
|
294
294
|
app_event_type = type(app_event)
|
|
295
295
|
if app_event_type in self._app_event_listeners:
|
|
296
296
|
listener_set = self._app_event_listeners[app_event_type]
|
|
297
|
-
|
|
298
|
-
|
|
297
|
+
|
|
298
|
+
await asyncio.gather(
|
|
299
|
+
*[
|
|
300
|
+
asyncio.create_task(call_function(listener_callback, app_event))
|
|
301
|
+
for listener_callback in listener_set
|
|
302
|
+
],
|
|
303
|
+
return_exceptions=True,
|
|
304
|
+
)
|
|
@@ -16,6 +16,9 @@ from griptape_nodes.exe_types.core_types import (
|
|
|
16
16
|
from griptape_nodes.exe_types.flow import ControlFlow
|
|
17
17
|
from griptape_nodes.exe_types.node_types import BaseNode, ErrorProxyNode, NodeResolutionState, StartLoopNode, StartNode
|
|
18
18
|
from griptape_nodes.machines.control_flow import CompleteState, ControlFlowMachine
|
|
19
|
+
from griptape_nodes.machines.dag_builder import DagBuilder
|
|
20
|
+
from griptape_nodes.machines.parallel_resolution import ParallelResolutionMachine
|
|
21
|
+
from griptape_nodes.machines.sequential_resolution import SequentialResolutionMachine
|
|
19
22
|
from griptape_nodes.retained_mode.events.base_events import (
|
|
20
23
|
ExecutionEvent,
|
|
21
24
|
ExecutionGriptapeNodeEvent,
|
|
@@ -144,6 +147,7 @@ class FlowManager:
|
|
|
144
147
|
_global_flow_queue: Queue[QueueItem]
|
|
145
148
|
_global_control_flow_machine: ControlFlowMachine | None
|
|
146
149
|
_global_single_node_resolution: bool
|
|
150
|
+
_global_dag_builder: DagBuilder
|
|
147
151
|
|
|
148
152
|
def __init__(self, event_manager: EventManager) -> None:
|
|
149
153
|
event_manager.assign_manager_to_request_type(CreateFlowRequest, self.on_create_flow_request)
|
|
@@ -187,11 +191,20 @@ class FlowManager:
|
|
|
187
191
|
self._global_flow_queue = Queue[QueueItem]()
|
|
188
192
|
self._global_control_flow_machine = None # Track the current control flow machine
|
|
189
193
|
self._global_single_node_resolution = False
|
|
194
|
+
self._global_dag_builder = DagBuilder()
|
|
195
|
+
|
|
196
|
+
@property
|
|
197
|
+
def global_single_node_resolution(self) -> bool:
|
|
198
|
+
return self._global_single_node_resolution
|
|
190
199
|
|
|
191
200
|
@property
|
|
192
201
|
def global_flow_queue(self) -> Queue[QueueItem]:
|
|
193
202
|
return self._global_flow_queue
|
|
194
203
|
|
|
204
|
+
@property
|
|
205
|
+
def global_dag_builder(self) -> DagBuilder:
|
|
206
|
+
return self._global_dag_builder
|
|
207
|
+
|
|
195
208
|
def get_connections(self) -> Connections:
|
|
196
209
|
"""Get the connections instance."""
|
|
197
210
|
return self._connections
|
|
@@ -416,10 +429,10 @@ class FlowManager:
|
|
|
416
429
|
|
|
417
430
|
# Success
|
|
418
431
|
details = f"Successfully created Flow '{final_flow_name}'."
|
|
419
|
-
log_level =
|
|
432
|
+
log_level = logging.DEBUG
|
|
420
433
|
if (request.flow_name is not None) and (final_flow_name != request.flow_name):
|
|
421
434
|
details = f"{details} WARNING: Had to rename from original Flow requested '{request.flow_name}' as an object with this name already existed."
|
|
422
|
-
log_level =
|
|
435
|
+
log_level = logging.WARNING
|
|
423
436
|
|
|
424
437
|
result = CreateFlowResultSuccess(
|
|
425
438
|
flow_name=final_flow_name, result_details=ResultDetails(message=details, level=log_level)
|
|
@@ -513,6 +526,7 @@ class FlowManager:
|
|
|
513
526
|
|
|
514
527
|
# Clean up ControlFlowMachine and DAG orchestrator for this flow
|
|
515
528
|
self._global_control_flow_machine = None
|
|
529
|
+
self._global_dag_builder.clear()
|
|
516
530
|
|
|
517
531
|
details = f"Successfully deleted Flow '{flow_name}'."
|
|
518
532
|
result = DeleteFlowResultSuccess(result_details=details)
|
|
@@ -1076,14 +1090,14 @@ class FlowManager:
|
|
|
1076
1090
|
details = f"Could not get flow state. Error: {err}"
|
|
1077
1091
|
return GetFlowStateResultFailure(result_details=details)
|
|
1078
1092
|
try:
|
|
1079
|
-
|
|
1093
|
+
control_nodes, resolving_nodes = self.flow_state(flow)
|
|
1080
1094
|
except Exception as e:
|
|
1081
1095
|
details = f"Failed to get flow state of flow with name {flow_name}. Exception occurred: {e} "
|
|
1082
1096
|
logger.exception(details)
|
|
1083
1097
|
return GetFlowStateResultFailure(result_details=details)
|
|
1084
1098
|
details = f"Successfully got flow state for flow with name {flow_name}."
|
|
1085
1099
|
return GetFlowStateResultSuccess(
|
|
1086
|
-
|
|
1100
|
+
control_nodes=control_nodes, resolving_node=resolving_nodes, result_details=details
|
|
1087
1101
|
)
|
|
1088
1102
|
|
|
1089
1103
|
def on_cancel_flow_request(self, request: CancelFlowRequest) -> ResultPayload:
|
|
@@ -1588,7 +1602,8 @@ class FlowManager:
|
|
|
1588
1602
|
start_node = queue_item.node
|
|
1589
1603
|
self._global_flow_queue.task_done()
|
|
1590
1604
|
|
|
1591
|
-
# Initialize global control flow machine
|
|
1605
|
+
# Initialize global control flow machine and DAG builder
|
|
1606
|
+
|
|
1592
1607
|
self._global_control_flow_machine = ControlFlowMachine(flow.name)
|
|
1593
1608
|
try:
|
|
1594
1609
|
await self._global_control_flow_machine.start_flow(start_node, debug_mode)
|
|
@@ -1618,6 +1633,7 @@ class FlowManager:
|
|
|
1618
1633
|
if self._global_control_flow_machine is not None:
|
|
1619
1634
|
self._global_control_flow_machine.reset_machine(cancel=True)
|
|
1620
1635
|
self._global_single_node_resolution = False
|
|
1636
|
+
self._global_dag_builder.clear()
|
|
1621
1637
|
logger.debug("Cancelling flow run")
|
|
1622
1638
|
|
|
1623
1639
|
GriptapeNodes.EventManager().put_event(
|
|
@@ -1702,19 +1718,23 @@ class FlowManager:
|
|
|
1702
1718
|
# If flow already exists, throw an error
|
|
1703
1719
|
errormsg = f"This workflow is already in progress. Please wait for the current process to finish before starting {node.name} again."
|
|
1704
1720
|
raise RuntimeError(errormsg)
|
|
1721
|
+
|
|
1705
1722
|
self._global_single_node_resolution = True
|
|
1706
1723
|
|
|
1707
1724
|
# Get or create machine
|
|
1708
1725
|
self._global_control_flow_machine = ControlFlowMachine(flow.name)
|
|
1709
|
-
self._global_control_flow_machine.context.
|
|
1726
|
+
self._global_control_flow_machine.context.current_nodes = [node]
|
|
1710
1727
|
resolution_machine = self._global_control_flow_machine.resolution_machine
|
|
1711
1728
|
resolution_machine.change_debug_mode(debug_mode=debug_mode)
|
|
1712
1729
|
node.state = NodeResolutionState.UNRESOLVED
|
|
1713
|
-
#
|
|
1730
|
+
# Build the DAG for the node
|
|
1731
|
+
if isinstance(resolution_machine, ParallelResolutionMachine):
|
|
1732
|
+
self._global_dag_builder.add_node_with_dependencies(node)
|
|
1733
|
+
resolution_machine.context.dag_builder = self._global_dag_builder
|
|
1714
1734
|
await resolution_machine.resolve_node(node)
|
|
1715
1735
|
if resolution_machine.is_complete():
|
|
1716
1736
|
self._global_single_node_resolution = False
|
|
1717
|
-
self._global_control_flow_machine.context.
|
|
1737
|
+
self._global_control_flow_machine.context.current_nodes = []
|
|
1718
1738
|
|
|
1719
1739
|
async def single_execution_step(self, flow: ControlFlow, change_debug_mode: bool) -> None: # noqa: FBT001
|
|
1720
1740
|
# do a granular step
|
|
@@ -1772,19 +1792,30 @@ class FlowManager:
|
|
|
1772
1792
|
# Clear entry control parameter for new execution
|
|
1773
1793
|
node.set_entry_control_parameter(None)
|
|
1774
1794
|
|
|
1775
|
-
def flow_state(self, flow: ControlFlow) -> tuple[str | None, str | None]: # noqa: ARG002
|
|
1795
|
+
def flow_state(self, flow: ControlFlow) -> tuple[list[str] | None, list[str] | None]: # noqa: ARG002
|
|
1776
1796
|
if not self.check_for_existing_running_flow():
|
|
1777
1797
|
msg = "Flow hasn't started."
|
|
1778
1798
|
raise RuntimeError(msg)
|
|
1779
1799
|
if self._global_control_flow_machine is None:
|
|
1780
1800
|
return None, None
|
|
1781
1801
|
control_flow_context = self._global_control_flow_machine.context
|
|
1782
|
-
|
|
1783
|
-
|
|
1802
|
+
current_control_nodes = (
|
|
1803
|
+
[control_flow_node.name for control_flow_node in control_flow_context.current_nodes]
|
|
1804
|
+
if control_flow_context.current_nodes is not None
|
|
1805
|
+
else None
|
|
1784
1806
|
)
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1807
|
+
# focus_stack is no longer available in the new architecture
|
|
1808
|
+
if isinstance(control_flow_context.resolution_machine, ParallelResolutionMachine):
|
|
1809
|
+
current_resolving_nodes = [
|
|
1810
|
+
node.node_reference.name
|
|
1811
|
+
for node in control_flow_context.resolution_machine.context.task_to_node.values()
|
|
1812
|
+
]
|
|
1813
|
+
return current_control_nodes, current_resolving_nodes
|
|
1814
|
+
if isinstance(control_flow_context.resolution_machine, SequentialResolutionMachine):
|
|
1815
|
+
focus_stack_for_node = control_flow_context.resolution_machine.context.focus_stack
|
|
1816
|
+
current_resolving_node = focus_stack_for_node[-1].node.name if len(focus_stack_for_node) else None
|
|
1817
|
+
return current_control_nodes, [current_resolving_node] if current_resolving_node else None
|
|
1818
|
+
return current_control_nodes, None
|
|
1788
1819
|
|
|
1789
1820
|
def get_start_node_from_node(self, flow: ControlFlow, node: BaseNode) -> BaseNode | None:
|
|
1790
1821
|
# backwards chain in control outputs.
|
|
@@ -914,12 +914,12 @@ class LibraryManager:
|
|
|
914
914
|
case LibraryStatus.GOOD:
|
|
915
915
|
details = f"Successfully loaded Library '{library_data.name}' from JSON file at {json_path}"
|
|
916
916
|
return RegisterLibraryFromFileResultSuccess(
|
|
917
|
-
library_name=library_data.name, result_details=ResultDetails(message=details, level=
|
|
917
|
+
library_name=library_data.name, result_details=ResultDetails(message=details, level=logging.INFO)
|
|
918
918
|
)
|
|
919
919
|
case LibraryStatus.FLAWED:
|
|
920
920
|
details = f"Successfully loaded Library JSON file from '{json_path}', but one or more nodes failed to load. Check the log for more details."
|
|
921
921
|
return RegisterLibraryFromFileResultSuccess(
|
|
922
|
-
library_name=library_data.name, result_details=ResultDetails(message=details, level=
|
|
922
|
+
library_name=library_data.name, result_details=ResultDetails(message=details, level=logging.WARNING)
|
|
923
923
|
)
|
|
924
924
|
case LibraryStatus.UNUSABLE:
|
|
925
925
|
details = f"Attempted to load Library JSON file from '{json_path}'. Failed because no nodes were loaded. Check the log for more details."
|
|
@@ -2040,4 +2040,4 @@ class LibraryManager:
|
|
|
2040
2040
|
details = (
|
|
2041
2041
|
"Successfully reloaded all libraries. All object state was cleared and previous libraries were unloaded."
|
|
2042
2042
|
)
|
|
2043
|
-
return ReloadAllLibrariesResultSuccess(result_details=ResultDetails(message=details, level=
|
|
2043
|
+
return ReloadAllLibrariesResultSuccess(result_details=ResultDetails(message=details, level=logging.INFO))
|