griptape-nodes 0.52.1__tar.gz → 0.53.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.
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/PKG-INFO +2 -1
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/pyproject.toml +2 -1
- griptape_nodes-0.53.0/src/griptape_nodes/__init__.py +21 -0
- griptape_nodes-0.53.0/src/griptape_nodes/__main__.py +6 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/app/app.py +45 -61
- griptape_nodes-0.53.0/src/griptape_nodes/cli/__init__.py +1 -0
- griptape_nodes-0.53.0/src/griptape_nodes/cli/commands/__init__.py +1 -0
- griptape_nodes-0.53.0/src/griptape_nodes/cli/commands/config.py +71 -0
- griptape_nodes-0.53.0/src/griptape_nodes/cli/commands/engine.py +80 -0
- griptape_nodes-0.53.0/src/griptape_nodes/cli/commands/init.py +548 -0
- griptape_nodes-0.53.0/src/griptape_nodes/cli/commands/libraries.py +90 -0
- griptape_nodes-0.53.0/src/griptape_nodes/cli/commands/self.py +117 -0
- griptape_nodes-0.53.0/src/griptape_nodes/cli/main.py +46 -0
- griptape_nodes-0.53.0/src/griptape_nodes/cli/shared.py +84 -0
- griptape_nodes-0.53.0/src/griptape_nodes/common/__init__.py +1 -0
- griptape_nodes-0.53.0/src/griptape_nodes/common/directed_graph.py +55 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/drivers/storage/local_storage_driver.py +7 -2
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/exe_types/core_types.py +60 -2
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/exe_types/node_types.py +38 -24
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/machines/control_flow.py +86 -22
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/machines/fsm.py +10 -1
- griptape_nodes-0.53.0/src/griptape_nodes/machines/parallel_resolution.py +570 -0
- griptape_nodes-0.52.1/src/griptape_nodes/machines/node_resolution.py → griptape_nodes-0.53.0/src/griptape_nodes/machines/sequential_resolution.py +22 -51
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/events/base_events.py +2 -2
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/events/node_events.py +4 -3
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/griptape_nodes.py +25 -12
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/managers/agent_manager.py +9 -5
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/managers/arbitrary_code_exec_manager.py +3 -1
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/managers/context_manager.py +6 -5
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/managers/flow_manager.py +117 -204
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/managers/library_lifecycle/library_directory.py +1 -1
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/managers/library_manager.py +35 -25
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/managers/node_manager.py +81 -199
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/managers/object_manager.py +11 -5
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/managers/os_manager.py +24 -9
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/managers/secrets_manager.py +8 -4
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/managers/settings.py +32 -1
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/managers/static_files_manager.py +8 -3
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/managers/sync_manager.py +8 -5
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/managers/workflow_manager.py +110 -122
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/traits/add_param_button.py +1 -1
- griptape_nodes-0.53.0/src/griptape_nodes/traits/button.py +231 -0
- griptape_nodes-0.53.0/src/griptape_nodes/traits/color_picker.py +66 -0
- griptape_nodes-0.53.0/src/griptape_nodes/traits/traits.json +8 -0
- griptape_nodes-0.52.1/src/griptape_nodes/__init__.py +0 -958
- griptape_nodes-0.52.1/src/griptape_nodes/traits/button.py +0 -21
- griptape_nodes-0.52.1/src/griptape_nodes/traits/traits.json +0 -4
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/README.md +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/app/.python-version +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/app/__init__.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/app/api.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/app/watch.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/bootstrap/__init__.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/bootstrap/workflow_executors/__init__.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/bootstrap/workflow_executors/local_workflow_executor.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/bootstrap/workflow_executors/workflow_executor.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/drivers/__init__.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/drivers/storage/__init__.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/drivers/storage/base_storage_driver.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/drivers/storage/griptape_cloud_storage_driver.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/drivers/storage/storage_backend.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/exe_types/__init__.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/exe_types/connections.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/exe_types/flow.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/exe_types/type_validator.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/machines/__init__.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/mcp_server/__init__.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/mcp_server/server.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/mcp_server/ws_request_manager.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/node_library/__init__.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/node_library/advanced_node_library.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/node_library/library_registry.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/node_library/workflow_registry.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/py.typed +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/__init__.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/events/__init__.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/events/agent_events.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/events/app_events.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/events/arbitrary_python_events.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/events/config_events.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/events/connection_events.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/events/context_events.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/events/execution_events.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/events/flow_events.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/events/generate_request_payload_schemas.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/events/library_events.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/events/logger_events.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/events/object_events.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/events/os_events.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/events/parameter_events.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/events/payload_registry.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/events/secrets_events.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/events/static_file_events.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/events/sync_events.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/events/validation_events.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/events/variable_events.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/events/workflow_events.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/managers/__init__.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/managers/config_manager.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/managers/engine_identity_manager.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/managers/event_manager.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/managers/library_lifecycle/__init__.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/managers/library_lifecycle/data_models.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/managers/library_lifecycle/library_fsm.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/__init__.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/base.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/github.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/local_file.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/package.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/sandbox.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/managers/library_lifecycle/library_status.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/managers/operation_manager.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/managers/session_manager.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/managers/variable_manager.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/managers/version_compatibility_manager.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/retained_mode.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/utils/__init__.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/utils/engine_identity.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/utils/name_generator.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/retained_mode/variable_types.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/traits/__init__.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/traits/clamp.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/traits/compare.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/traits/compare_images.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/traits/file_system_picker.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/traits/minmax.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/traits/options.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/traits/slider.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/traits/trait_registry.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/updater/__init__.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/updater/__main__.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/utils/__init__.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/utils/async_utils.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/utils/dict_utils.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/utils/image_preview.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/utils/metaclasses.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/utils/uv_utils.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/utils/version_utils.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/version_compatibility/__init__.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/version_compatibility/versions/__init__.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/version_compatibility/versions/v0_39_0/__init__.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/version_compatibility/versions/v0_39_0/modified_parameters_set_removal.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/version_compatibility/workflow_versions/__init__.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/version_compatibility/workflow_versions/v0_7_0/__init__.py +0 -0
- {griptape_nodes-0.52.1 → griptape_nodes-0.53.0}/src/griptape_nodes/version_compatibility/workflow_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.
|
|
3
|
+
Version: 0.53.0
|
|
4
4
|
Summary: Add your description here
|
|
5
5
|
Requires-Dist: griptape>=1.8.2
|
|
6
6
|
Requires-Dist: pydantic>=2.10.6
|
|
@@ -19,6 +19,7 @@ Requires-Dist: mcp[ws]>=1.10.1
|
|
|
19
19
|
Requires-Dist: binaryornot>=0.4.4
|
|
20
20
|
Requires-Dist: pillow>=11.3.0
|
|
21
21
|
Requires-Dist: watchfiles>=1.1.0
|
|
22
|
+
Requires-Dist: typer>=0.15.0
|
|
22
23
|
Requires-Dist: austin-dist>=3.7.0 ; extra == 'profiling'
|
|
23
24
|
Requires-Python: >=3.12.0, <3.13
|
|
24
25
|
Provides-Extra: profiling
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "griptape-nodes"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.53.0"
|
|
4
4
|
description = "Add your description here"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.12.0, <3.13"
|
|
@@ -23,6 +23,7 @@ dependencies = [
|
|
|
23
23
|
"binaryornot>=0.4.4",
|
|
24
24
|
"pillow>=11.3.0",
|
|
25
25
|
"watchfiles>=1.1.0",
|
|
26
|
+
"typer>=0.15.0",
|
|
26
27
|
]
|
|
27
28
|
|
|
28
29
|
[project.optional-dependencies]
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""Griptape Nodes package."""
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def main() -> None:
|
|
8
|
+
"""Main entry point for the Griptape Nodes CLI."""
|
|
9
|
+
# Hack to make paths "just work". # noqa: FIX004
|
|
10
|
+
# Without this, packages like `nodes` don't properly import.
|
|
11
|
+
# Long term solution could be to make `nodes` a proper src-layout package
|
|
12
|
+
# but current engine relies on importing files rather than packages.
|
|
13
|
+
sys.path.append(str(Path.cwd()))
|
|
14
|
+
|
|
15
|
+
# Import and run the new CLI
|
|
16
|
+
from griptape_nodes.cli.main import app
|
|
17
|
+
|
|
18
|
+
app()
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
__all__ = ["main"]
|
|
@@ -16,7 +16,7 @@ from rich.console import Console
|
|
|
16
16
|
from rich.logging import RichHandler
|
|
17
17
|
from rich.panel import Panel
|
|
18
18
|
from websockets.asyncio.client import connect
|
|
19
|
-
from websockets.exceptions import ConnectionClosed, WebSocketException
|
|
19
|
+
from websockets.exceptions import ConnectionClosed, ConnectionClosedError, WebSocketException
|
|
20
20
|
|
|
21
21
|
from griptape_nodes.app.api import start_static_server
|
|
22
22
|
from griptape_nodes.mcp_server.server import start_mcp_server
|
|
@@ -63,6 +63,11 @@ class UnsubscribeCommand:
|
|
|
63
63
|
topic: str
|
|
64
64
|
|
|
65
65
|
|
|
66
|
+
# Important to bootstrap singleton here so that we don't
|
|
67
|
+
# get any weird circular import issues from the EventLogHandler
|
|
68
|
+
# initializing it from a log during it's own initialization.
|
|
69
|
+
griptape_nodes: GriptapeNodes = GriptapeNodes()
|
|
70
|
+
|
|
66
71
|
# WebSocket outgoing queue for messages and commands.
|
|
67
72
|
# Appears to be fine to create outside event loop
|
|
68
73
|
# https://discuss.python.org/t/can-asyncio-queue-be-safely-created-outside-of-the-event-loop-thread/49215/8
|
|
@@ -82,12 +87,6 @@ STATIC_SERVER_ENABLED = os.getenv("STATIC_SERVER_ENABLED", "true").lower() == "t
|
|
|
82
87
|
REQUEST_SEMAPHORE = asyncio.Semaphore(100)
|
|
83
88
|
|
|
84
89
|
|
|
85
|
-
# Important to bootstrap singleton here so that we don't
|
|
86
|
-
# get any weird circular import issues from the EventLogHandler
|
|
87
|
-
# initializing it from a log during it's own initialization.
|
|
88
|
-
griptape_nodes: GriptapeNodes = GriptapeNodes()
|
|
89
|
-
|
|
90
|
-
|
|
91
90
|
class EventLogHandler(logging.Handler):
|
|
92
91
|
"""Custom logging handler that emits log messages as AppEvents.
|
|
93
92
|
|
|
@@ -105,10 +104,12 @@ class EventLogHandler(logging.Handler):
|
|
|
105
104
|
logger = logging.getLogger("griptape_nodes_app")
|
|
106
105
|
|
|
107
106
|
griptape_nodes_logger = logging.getLogger("griptape_nodes")
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
107
|
+
logging.basicConfig(
|
|
108
|
+
level=logging.INFO,
|
|
109
|
+
format="%(message)s",
|
|
110
|
+
datefmt="[%X]",
|
|
111
|
+
handlers=[EventLogHandler(), RichHandler(show_time=True, show_path=False, markup=True, rich_tracebacks=True)],
|
|
112
|
+
)
|
|
112
113
|
|
|
113
114
|
console = Console()
|
|
114
115
|
|
|
@@ -186,6 +187,7 @@ async def _run_websocket_tasks(api_key: str, main_loop: asyncio.AbstractEventLoo
|
|
|
186
187
|
initialized = False
|
|
187
188
|
|
|
188
189
|
async for ws_connection in connection_stream:
|
|
190
|
+
logger.info("WebSocket connection established")
|
|
189
191
|
try:
|
|
190
192
|
# Emit initialization event only for the first connection
|
|
191
193
|
if not initialized:
|
|
@@ -202,9 +204,13 @@ async def _run_websocket_tasks(api_key: str, main_loop: asyncio.AbstractEventLoo
|
|
|
202
204
|
async with asyncio.TaskGroup() as tg:
|
|
203
205
|
tg.create_task(_process_incoming_messages(ws_connection, main_loop))
|
|
204
206
|
tg.create_task(_send_outgoing_messages(ws_connection))
|
|
205
|
-
except
|
|
206
|
-
logger.
|
|
207
|
+
except (ExceptionGroup, ConnectionClosed, ConnectionClosedError):
|
|
208
|
+
logger.info("WebSocket connection closed, reconnecting...")
|
|
209
|
+
continue
|
|
210
|
+
except Exception:
|
|
211
|
+
logger.exception("WebSocket tasks failed")
|
|
207
212
|
await asyncio.sleep(2.0) # Wait before retry
|
|
213
|
+
continue
|
|
208
214
|
|
|
209
215
|
|
|
210
216
|
def _ensure_api_key() -> str:
|
|
@@ -235,28 +241,14 @@ def _build_static_dir() -> Path:
|
|
|
235
241
|
|
|
236
242
|
async def _process_incoming_messages(ws_connection: Any, main_loop: asyncio.AbstractEventLoop) -> None:
|
|
237
243
|
"""Process incoming WebSocket requests from Nodes API."""
|
|
238
|
-
logger.
|
|
244
|
+
logger.debug("Processing incoming WebSocket requests from WebSocket connection")
|
|
239
245
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
logger.exception("Error processing event, skipping.")
|
|
247
|
-
|
|
248
|
-
except ConnectionClosed:
|
|
249
|
-
logger.info("WebSocket connection closed, will retry")
|
|
250
|
-
except asyncio.CancelledError:
|
|
251
|
-
# Clean shutdown when task is cancelled
|
|
252
|
-
logger.info("WebSocket listener shutdown complete")
|
|
253
|
-
raise
|
|
254
|
-
except Exception as e:
|
|
255
|
-
logger.error("Error in WebSocket connection. Retrying in 2 seconds... %s", e)
|
|
256
|
-
await asyncio.sleep(2.0)
|
|
257
|
-
raise
|
|
258
|
-
finally:
|
|
259
|
-
logger.info("WebSocket listener shutdown complete")
|
|
246
|
+
async for message in ws_connection:
|
|
247
|
+
try:
|
|
248
|
+
data = json.loads(message)
|
|
249
|
+
await _process_api_event(data, main_loop)
|
|
250
|
+
except Exception:
|
|
251
|
+
logger.exception("Error processing event, skipping.")
|
|
260
252
|
|
|
261
253
|
|
|
262
254
|
def _create_websocket_connection(api_key: str) -> Any:
|
|
@@ -313,33 +305,25 @@ async def _process_api_event(event: dict, main_loop: asyncio.AbstractEventLoop)
|
|
|
313
305
|
|
|
314
306
|
async def _send_outgoing_messages(ws_connection: Any) -> None:
|
|
315
307
|
"""Send outgoing WebSocket requests from queue on background thread."""
|
|
316
|
-
logger.
|
|
308
|
+
logger.debug("Starting outgoing WebSocket request sender")
|
|
317
309
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
message = await ws_outgoing_queue.get()
|
|
322
|
-
|
|
323
|
-
try:
|
|
324
|
-
if isinstance(message, WebSocketMessage):
|
|
325
|
-
await _send_websocket_message(ws_connection, message.event_type, message.payload, message.topic)
|
|
326
|
-
elif isinstance(message, SubscribeCommand):
|
|
327
|
-
await _send_subscribe_command(ws_connection, message.topic)
|
|
328
|
-
elif isinstance(message, UnsubscribeCommand):
|
|
329
|
-
await _send_unsubscribe_command(ws_connection, message.topic)
|
|
330
|
-
else:
|
|
331
|
-
logger.warning("Unknown outgoing message type: %s", type(message))
|
|
332
|
-
except Exception as e:
|
|
333
|
-
logger.error("Error sending outgoing WebSocket request: %s", e)
|
|
334
|
-
finally:
|
|
335
|
-
ws_outgoing_queue.task_done()
|
|
310
|
+
while True:
|
|
311
|
+
# Get message from outgoing queue
|
|
312
|
+
message = await ws_outgoing_queue.get()
|
|
336
313
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
314
|
+
try:
|
|
315
|
+
if isinstance(message, WebSocketMessage):
|
|
316
|
+
await _send_websocket_message(ws_connection, message.event_type, message.payload, message.topic)
|
|
317
|
+
elif isinstance(message, SubscribeCommand):
|
|
318
|
+
await _send_subscribe_command(ws_connection, message.topic)
|
|
319
|
+
elif isinstance(message, UnsubscribeCommand):
|
|
320
|
+
await _send_unsubscribe_command(ws_connection, message.topic)
|
|
321
|
+
else:
|
|
322
|
+
logger.warning("Unknown outgoing message type: %s", type(message))
|
|
323
|
+
except Exception as e:
|
|
324
|
+
logger.error("Error sending outgoing WebSocket request: %s", e)
|
|
325
|
+
finally:
|
|
326
|
+
ws_outgoing_queue.task_done()
|
|
343
327
|
|
|
344
328
|
|
|
345
329
|
async def _send_websocket_message(ws_connection: Any, event_type: str, payload: str, topic: str | None) -> None:
|
|
@@ -361,7 +345,7 @@ async def _send_subscribe_command(ws_connection: Any, topic: str) -> None:
|
|
|
361
345
|
try:
|
|
362
346
|
body = {"type": "subscribe", "topic": topic, "payload": {}}
|
|
363
347
|
await ws_connection.send(json.dumps(body))
|
|
364
|
-
logger.
|
|
348
|
+
logger.debug("Subscribed to topic: %s", topic)
|
|
365
349
|
except WebSocketException as e:
|
|
366
350
|
logger.error("Error subscribing to topic %s: %s", topic, e)
|
|
367
351
|
except Exception as e:
|
|
@@ -373,7 +357,7 @@ async def _send_unsubscribe_command(ws_connection: Any, topic: str) -> None:
|
|
|
373
357
|
try:
|
|
374
358
|
body = {"type": "unsubscribe", "topic": topic, "payload": {}}
|
|
375
359
|
await ws_connection.send(json.dumps(body))
|
|
376
|
-
logger.
|
|
360
|
+
logger.debug("Unsubscribed from topic: %s", topic)
|
|
377
361
|
except WebSocketException as e:
|
|
378
362
|
logger.error("Error unsubscribing from topic %s: %s", topic, e)
|
|
379
363
|
except Exception as e:
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Griptape Nodes CLI module."""
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Griptape Nodes CLI commands."""
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"""Config command for Griptape Nodes CLI."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
import typer
|
|
7
|
+
|
|
8
|
+
from griptape_nodes.cli.shared import config_manager, console
|
|
9
|
+
|
|
10
|
+
app = typer.Typer(help="Manage configuration.")
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@app.command()
|
|
14
|
+
def show(
|
|
15
|
+
config_path: str = typer.Argument(
|
|
16
|
+
None,
|
|
17
|
+
help="Optional config path to show specific value (e.g., 'workspace_directory').",
|
|
18
|
+
),
|
|
19
|
+
) -> None:
|
|
20
|
+
"""Show configuration values."""
|
|
21
|
+
_print_user_config(config_path)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@app.command("list")
|
|
25
|
+
def list_configs() -> None:
|
|
26
|
+
"""List configuration values."""
|
|
27
|
+
_list_user_configs()
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@app.command()
|
|
31
|
+
def reset() -> None:
|
|
32
|
+
"""Reset configuration to defaults."""
|
|
33
|
+
_reset_user_config()
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _print_user_config(config_path: str | None = None) -> None:
|
|
37
|
+
"""Prints the user configuration from the config file.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
config_path: Optional path to specific config value. If None, prints entire config.
|
|
41
|
+
"""
|
|
42
|
+
if config_path is None:
|
|
43
|
+
config = config_manager.merged_config
|
|
44
|
+
sys.stdout.write(json.dumps(config, indent=2))
|
|
45
|
+
else:
|
|
46
|
+
try:
|
|
47
|
+
value = config_manager.get_config_value(config_path)
|
|
48
|
+
if isinstance(value, (dict, list)):
|
|
49
|
+
sys.stdout.write(json.dumps(value, indent=2))
|
|
50
|
+
else:
|
|
51
|
+
sys.stdout.write(str(value))
|
|
52
|
+
except (KeyError, AttributeError, ValueError):
|
|
53
|
+
console.print(f"[bold red]Config path '{config_path}' not found[/bold red]")
|
|
54
|
+
sys.exit(1)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def _list_user_configs() -> None:
|
|
58
|
+
"""Lists user configuration files in ascending precedence."""
|
|
59
|
+
num_config_files = len(config_manager.config_files)
|
|
60
|
+
console.print(
|
|
61
|
+
f"[bold]User Configuration Files (lowest precedence (1.) ⟶ highest precedence ({num_config_files}.)):[/bold]"
|
|
62
|
+
)
|
|
63
|
+
for idx, config in enumerate(config_manager.config_files):
|
|
64
|
+
console.print(f"[green]{idx + 1}. {config}[/green]")
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def _reset_user_config() -> None:
|
|
68
|
+
"""Resets the user configuration to the default values."""
|
|
69
|
+
console.print("[bold]Resetting user configuration to default values...[/bold]")
|
|
70
|
+
config_manager.reset_user_config()
|
|
71
|
+
console.print("[bold green]User configuration reset complete![/bold green]")
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"""Engine command for Griptape Nodes CLI."""
|
|
2
|
+
|
|
3
|
+
import typer
|
|
4
|
+
from rich.prompt import Confirm
|
|
5
|
+
|
|
6
|
+
from griptape_nodes.app import start_app
|
|
7
|
+
from griptape_nodes.cli.commands.init import _run_init
|
|
8
|
+
from griptape_nodes.cli.commands.self import _get_latest_version, _update_self
|
|
9
|
+
from griptape_nodes.cli.shared import (
|
|
10
|
+
CONFIG_DIR,
|
|
11
|
+
ENV_API_KEY,
|
|
12
|
+
ENV_GTN_BUCKET_NAME,
|
|
13
|
+
ENV_LIBRARIES_SYNC,
|
|
14
|
+
ENV_REGISTER_ADVANCED_LIBRARY,
|
|
15
|
+
ENV_STORAGE_BACKEND,
|
|
16
|
+
ENV_WORKSPACE_DIRECTORY,
|
|
17
|
+
PACKAGE_NAME,
|
|
18
|
+
InitConfig,
|
|
19
|
+
console,
|
|
20
|
+
)
|
|
21
|
+
from griptape_nodes.utils.version_utils import get_current_version, get_install_source
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def engine_command(
|
|
25
|
+
no_update: bool = typer.Option(False, "--no-update", help="Skip the auto-update check."), # noqa: FBT001
|
|
26
|
+
) -> None:
|
|
27
|
+
"""Run the Griptape Nodes engine."""
|
|
28
|
+
_start_engine(no_update=no_update)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _start_engine(*, no_update: bool = False) -> None:
|
|
32
|
+
"""Starts the Griptape Nodes engine.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
no_update (bool): If True, skips the auto-update check.
|
|
36
|
+
"""
|
|
37
|
+
if not CONFIG_DIR.exists():
|
|
38
|
+
# Default init flow if there is no config directory
|
|
39
|
+
console.print("[bold green]Config directory not found. Initializing...[/bold green]")
|
|
40
|
+
_run_init(
|
|
41
|
+
InitConfig(
|
|
42
|
+
workspace_directory=ENV_WORKSPACE_DIRECTORY,
|
|
43
|
+
api_key=ENV_API_KEY,
|
|
44
|
+
storage_backend=ENV_STORAGE_BACKEND,
|
|
45
|
+
register_advanced_library=ENV_REGISTER_ADVANCED_LIBRARY,
|
|
46
|
+
interactive=True,
|
|
47
|
+
config_values=None,
|
|
48
|
+
secret_values=None,
|
|
49
|
+
libraries_sync=ENV_LIBRARIES_SYNC,
|
|
50
|
+
bucket_name=ENV_GTN_BUCKET_NAME,
|
|
51
|
+
)
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
# Confusing double negation -- If `no_update` is set, we want to skip the update
|
|
55
|
+
if not no_update:
|
|
56
|
+
_auto_update_self()
|
|
57
|
+
|
|
58
|
+
console.print("[bold green]Starting Griptape Nodes engine...[/bold green]")
|
|
59
|
+
start_app()
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def _auto_update_self() -> None:
|
|
63
|
+
"""Automatically updates the script to the latest version if the user confirms."""
|
|
64
|
+
console.print("[bold green]Checking for updates...[/bold green]")
|
|
65
|
+
source, commit_id = get_install_source()
|
|
66
|
+
current_version = get_current_version()
|
|
67
|
+
latest_version = _get_latest_version(PACKAGE_NAME, source)
|
|
68
|
+
|
|
69
|
+
if source == "git" and commit_id is not None:
|
|
70
|
+
can_update = commit_id != latest_version
|
|
71
|
+
update_message = f"Your current engine version, {current_version} ({source} - {commit_id}), doesn't match the latest release, {latest_version}. Update now?"
|
|
72
|
+
else:
|
|
73
|
+
can_update = current_version < latest_version
|
|
74
|
+
update_message = f"Your current engine version, {current_version}, is behind the latest release, {latest_version}. Update now?"
|
|
75
|
+
|
|
76
|
+
if can_update:
|
|
77
|
+
update = Confirm.ask(update_message, default=True)
|
|
78
|
+
|
|
79
|
+
if update:
|
|
80
|
+
_update_self()
|