griptape-nodes 0.42.0__py3-none-any.whl → 0.43.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 +0 -0
- griptape_nodes/app/.python-version +0 -0
- griptape_nodes/app/__init__.py +1 -6
- griptape_nodes/app/api.py +199 -0
- griptape_nodes/app/app.py +140 -225
- griptape_nodes/app/watch.py +1 -1
- griptape_nodes/bootstrap/__init__.py +0 -0
- griptape_nodes/bootstrap/bootstrap_script.py +0 -0
- griptape_nodes/bootstrap/register_libraries_script.py +0 -0
- griptape_nodes/bootstrap/structure_config.yaml +0 -0
- griptape_nodes/bootstrap/workflow_executors/__init__.py +0 -0
- griptape_nodes/bootstrap/workflow_executors/local_workflow_executor.py +0 -0
- griptape_nodes/bootstrap/workflow_executors/workflow_executor.py +0 -0
- griptape_nodes/bootstrap/workflow_runners/__init__.py +0 -0
- griptape_nodes/bootstrap/workflow_runners/bootstrap_workflow_runner.py +0 -0
- griptape_nodes/bootstrap/workflow_runners/local_workflow_runner.py +0 -0
- griptape_nodes/bootstrap/workflow_runners/subprocess_workflow_runner.py +6 -2
- griptape_nodes/bootstrap/workflow_runners/workflow_runner.py +0 -0
- griptape_nodes/drivers/__init__.py +0 -0
- griptape_nodes/drivers/storage/__init__.py +0 -0
- griptape_nodes/drivers/storage/base_storage_driver.py +0 -0
- griptape_nodes/drivers/storage/griptape_cloud_storage_driver.py +0 -0
- griptape_nodes/drivers/storage/local_storage_driver.py +2 -1
- griptape_nodes/drivers/storage/storage_backend.py +0 -0
- griptape_nodes/exe_types/__init__.py +0 -0
- griptape_nodes/exe_types/connections.py +0 -0
- griptape_nodes/exe_types/core_types.py +0 -0
- griptape_nodes/exe_types/flow.py +0 -0
- griptape_nodes/exe_types/node_types.py +17 -1
- griptape_nodes/exe_types/type_validator.py +0 -0
- griptape_nodes/machines/__init__.py +0 -0
- griptape_nodes/machines/control_flow.py +41 -12
- griptape_nodes/machines/fsm.py +16 -2
- griptape_nodes/machines/node_resolution.py +0 -0
- griptape_nodes/mcp_server/__init__.py +1 -0
- griptape_nodes/mcp_server/server.py +126 -0
- griptape_nodes/mcp_server/ws_request_manager.py +268 -0
- griptape_nodes/node_library/__init__.py +0 -0
- griptape_nodes/node_library/advanced_node_library.py +0 -0
- griptape_nodes/node_library/library_registry.py +0 -0
- griptape_nodes/node_library/workflow_registry.py +1 -1
- griptape_nodes/py.typed +0 -0
- griptape_nodes/retained_mode/__init__.py +0 -0
- griptape_nodes/retained_mode/events/__init__.py +0 -0
- griptape_nodes/retained_mode/events/agent_events.py +0 -0
- griptape_nodes/retained_mode/events/app_events.py +6 -2
- griptape_nodes/retained_mode/events/arbitrary_python_events.py +0 -0
- griptape_nodes/retained_mode/events/base_events.py +6 -6
- griptape_nodes/retained_mode/events/config_events.py +0 -0
- griptape_nodes/retained_mode/events/connection_events.py +0 -0
- griptape_nodes/retained_mode/events/context_events.py +0 -0
- griptape_nodes/retained_mode/events/execution_events.py +0 -0
- griptape_nodes/retained_mode/events/flow_events.py +0 -0
- griptape_nodes/retained_mode/events/generate_request_payload_schemas.py +0 -0
- griptape_nodes/retained_mode/events/library_events.py +2 -2
- griptape_nodes/retained_mode/events/logger_events.py +0 -0
- griptape_nodes/retained_mode/events/node_events.py +0 -0
- griptape_nodes/retained_mode/events/object_events.py +0 -0
- griptape_nodes/retained_mode/events/os_events.py +104 -2
- griptape_nodes/retained_mode/events/parameter_events.py +0 -0
- griptape_nodes/retained_mode/events/payload_registry.py +0 -0
- griptape_nodes/retained_mode/events/secrets_events.py +0 -0
- griptape_nodes/retained_mode/events/static_file_events.py +0 -0
- griptape_nodes/retained_mode/events/validation_events.py +0 -0
- griptape_nodes/retained_mode/events/workflow_events.py +0 -0
- griptape_nodes/retained_mode/griptape_nodes.py +43 -40
- griptape_nodes/retained_mode/managers/__init__.py +0 -0
- griptape_nodes/retained_mode/managers/agent_manager.py +48 -22
- griptape_nodes/retained_mode/managers/arbitrary_code_exec_manager.py +0 -0
- griptape_nodes/retained_mode/managers/config_manager.py +0 -0
- griptape_nodes/retained_mode/managers/context_manager.py +0 -0
- griptape_nodes/retained_mode/managers/engine_identity_manager.py +0 -0
- griptape_nodes/retained_mode/managers/event_manager.py +0 -0
- griptape_nodes/retained_mode/managers/flow_manager.py +2 -0
- griptape_nodes/retained_mode/managers/library_lifecycle/__init__.py +45 -0
- griptape_nodes/retained_mode/managers/library_lifecycle/data_models.py +191 -0
- griptape_nodes/retained_mode/managers/library_lifecycle/library_directory.py +346 -0
- griptape_nodes/retained_mode/managers/library_lifecycle/library_fsm.py +439 -0
- griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/__init__.py +17 -0
- griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/base.py +82 -0
- griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/github.py +116 -0
- griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/local_file.py +352 -0
- griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/package.py +104 -0
- griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/sandbox.py +155 -0
- griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance.py +18 -0
- griptape_nodes/retained_mode/managers/library_lifecycle/library_status.py +12 -0
- griptape_nodes/retained_mode/managers/library_manager.py +144 -39
- griptape_nodes/retained_mode/managers/node_manager.py +86 -72
- griptape_nodes/retained_mode/managers/object_manager.py +0 -0
- griptape_nodes/retained_mode/managers/operation_manager.py +0 -0
- griptape_nodes/retained_mode/managers/os_manager.py +517 -12
- griptape_nodes/retained_mode/managers/secrets_manager.py +0 -0
- griptape_nodes/retained_mode/managers/session_manager.py +0 -0
- griptape_nodes/retained_mode/managers/settings.py +0 -0
- griptape_nodes/retained_mode/managers/static_files_manager.py +0 -0
- griptape_nodes/retained_mode/managers/version_compatibility_manager.py +2 -2
- griptape_nodes/retained_mode/managers/workflow_manager.py +199 -2
- griptape_nodes/retained_mode/retained_mode.py +0 -0
- griptape_nodes/retained_mode/utils/__init__.py +0 -0
- griptape_nodes/retained_mode/utils/engine_identity.py +0 -0
- griptape_nodes/retained_mode/utils/name_generator.py +0 -0
- griptape_nodes/traits/__init__.py +0 -0
- griptape_nodes/traits/add_param_button.py +0 -0
- griptape_nodes/traits/button.py +0 -0
- griptape_nodes/traits/clamp.py +0 -0
- griptape_nodes/traits/compare.py +0 -0
- griptape_nodes/traits/compare_images.py +0 -0
- griptape_nodes/traits/file_system_picker.py +127 -0
- griptape_nodes/traits/minmax.py +0 -0
- griptape_nodes/traits/options.py +0 -0
- griptape_nodes/traits/slider.py +0 -0
- griptape_nodes/traits/trait_registry.py +0 -0
- griptape_nodes/traits/traits.json +0 -0
- griptape_nodes/updater/__init__.py +2 -2
- griptape_nodes/updater/__main__.py +0 -0
- griptape_nodes/utils/__init__.py +0 -0
- griptape_nodes/utils/dict_utils.py +0 -0
- griptape_nodes/utils/image_preview.py +128 -0
- griptape_nodes/utils/metaclasses.py +0 -0
- griptape_nodes/version_compatibility/__init__.py +0 -0
- griptape_nodes/version_compatibility/versions/__init__.py +0 -0
- griptape_nodes/version_compatibility/versions/v0_39_0/__init__.py +0 -0
- griptape_nodes/version_compatibility/versions/v0_39_0/modified_parameters_set_removal.py +5 -5
- griptape_nodes-0.43.0.dist-info/METADATA +90 -0
- griptape_nodes-0.43.0.dist-info/RECORD +129 -0
- griptape_nodes-0.43.0.dist-info/WHEEL +4 -0
- {griptape_nodes-0.42.0.dist-info → griptape_nodes-0.43.0.dist-info}/entry_points.txt +1 -0
- griptape_nodes/app/app_sessions.py +0 -554
- griptape_nodes-0.42.0.dist-info/METADATA +0 -78
- griptape_nodes-0.42.0.dist-info/RECORD +0 -113
- griptape_nodes-0.42.0.dist-info/WHEEL +0 -4
- griptape_nodes-0.42.0.dist-info/licenses/LICENSE +0 -201
griptape_nodes/__init__.py
CHANGED
|
File without changes
|
|
File without changes
|
griptape_nodes/app/__init__.py
CHANGED
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
"""App package."""
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
if os.getenv("GTN_USE_SESSIONS", "True").lower() == "true":
|
|
6
|
-
from griptape_nodes.app.app_sessions import start_app
|
|
7
|
-
else:
|
|
8
|
-
from griptape_nodes.app.app import start_app
|
|
3
|
+
from griptape_nodes.app.app import start_app
|
|
9
4
|
|
|
10
5
|
__all__ = ["start_app"]
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import binascii
|
|
4
|
+
import logging
|
|
5
|
+
import os
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import TYPE_CHECKING, Annotated
|
|
8
|
+
from urllib.parse import urljoin
|
|
9
|
+
|
|
10
|
+
import uvicorn
|
|
11
|
+
from fastapi import Depends, FastAPI, HTTPException, Request
|
|
12
|
+
from fastapi.middleware.cors import CORSMiddleware
|
|
13
|
+
from fastapi.staticfiles import StaticFiles
|
|
14
|
+
from rich.logging import RichHandler
|
|
15
|
+
|
|
16
|
+
from griptape_nodes.retained_mode.events.base_events import EventRequest, deserialize_event
|
|
17
|
+
|
|
18
|
+
if TYPE_CHECKING:
|
|
19
|
+
from queue import Queue
|
|
20
|
+
|
|
21
|
+
# Whether to enable the static server
|
|
22
|
+
STATIC_SERVER_ENABLED = os.getenv("STATIC_SERVER_ENABLED", "true").lower() == "true"
|
|
23
|
+
# Host of the static server
|
|
24
|
+
STATIC_SERVER_HOST = os.getenv("STATIC_SERVER_HOST", "localhost")
|
|
25
|
+
# Port of the static server
|
|
26
|
+
STATIC_SERVER_PORT = int(os.getenv("STATIC_SERVER_PORT", "8124"))
|
|
27
|
+
# URL path for the static server
|
|
28
|
+
STATIC_SERVER_URL = os.getenv("STATIC_SERVER_URL", "/static")
|
|
29
|
+
# Log level for the static server
|
|
30
|
+
STATIC_SERVER_LOG_LEVEL = os.getenv("STATIC_SERVER_LOG_LEVEL", "info").lower()
|
|
31
|
+
|
|
32
|
+
logger = logging.getLogger("griptape_nodes_api")
|
|
33
|
+
|
|
34
|
+
# Global event queue - initialized as None and set when starting the API
|
|
35
|
+
event_queue: Queue | None = None
|
|
36
|
+
|
|
37
|
+
# Global static directory - initialized as None and set when starting the API
|
|
38
|
+
static_dir: Path | None = None
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def get_event_queue() -> Queue:
|
|
42
|
+
"""FastAPI dependency to get the event queue."""
|
|
43
|
+
if event_queue is None:
|
|
44
|
+
msg = "Event queue is not initialized"
|
|
45
|
+
raise HTTPException(status_code=500, detail=msg)
|
|
46
|
+
return event_queue
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def get_static_dir() -> Path:
|
|
50
|
+
"""FastAPI dependency to get the static directory."""
|
|
51
|
+
if static_dir is None:
|
|
52
|
+
msg = "Static directory is not initialized"
|
|
53
|
+
raise HTTPException(status_code=500, detail=msg)
|
|
54
|
+
return static_dir
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
"""Create and configure the FastAPI application."""
|
|
58
|
+
app = FastAPI()
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
@app.post("/static-upload-urls")
|
|
62
|
+
async def _create_static_file_upload_url(request: Request) -> dict:
|
|
63
|
+
"""Create a URL for uploading a static file.
|
|
64
|
+
|
|
65
|
+
Similar to a presigned URL, but for uploading files to the static server.
|
|
66
|
+
"""
|
|
67
|
+
base_url = request.base_url
|
|
68
|
+
body = await request.json()
|
|
69
|
+
file_name = body["file_name"]
|
|
70
|
+
url = urljoin(str(base_url), f"/static-uploads/{file_name}")
|
|
71
|
+
|
|
72
|
+
return {"url": url}
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
@app.put("/static-uploads/{file_path:path}")
|
|
76
|
+
async def _create_static_file(
|
|
77
|
+
request: Request, file_path: str, static_directory: Annotated[Path, Depends(get_static_dir)]
|
|
78
|
+
) -> dict:
|
|
79
|
+
"""Upload a static file to the static server."""
|
|
80
|
+
if not STATIC_SERVER_ENABLED:
|
|
81
|
+
msg = "Static server is not enabled. Please set STATIC_SERVER_ENABLED to True."
|
|
82
|
+
raise ValueError(msg)
|
|
83
|
+
|
|
84
|
+
file_full_path = Path(static_directory / file_path)
|
|
85
|
+
|
|
86
|
+
# Create parent directories if they don't exist
|
|
87
|
+
file_full_path.parent.mkdir(parents=True, exist_ok=True)
|
|
88
|
+
|
|
89
|
+
data = await request.body()
|
|
90
|
+
try:
|
|
91
|
+
file_full_path.write_bytes(data)
|
|
92
|
+
except binascii.Error as e:
|
|
93
|
+
msg = f"Invalid base64 encoding for file {file_path}."
|
|
94
|
+
logger.error(msg)
|
|
95
|
+
raise HTTPException(status_code=400, detail=msg) from e
|
|
96
|
+
except (OSError, PermissionError) as e:
|
|
97
|
+
msg = f"Failed to write file {file_path} to {static_dir}: {e}"
|
|
98
|
+
logger.error(msg)
|
|
99
|
+
raise HTTPException(status_code=500, detail=msg) from e
|
|
100
|
+
|
|
101
|
+
static_url = f"http://{STATIC_SERVER_HOST}:{STATIC_SERVER_PORT}{STATIC_SERVER_URL}/{file_path}"
|
|
102
|
+
return {"url": static_url}
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
@app.get("/static-uploads/")
|
|
106
|
+
async def _list_static_files(static_directory: Annotated[Path, Depends(get_static_dir)]) -> dict:
|
|
107
|
+
"""List all static files in the static server."""
|
|
108
|
+
if not STATIC_SERVER_ENABLED:
|
|
109
|
+
msg = "Static server is not enabled. Please set STATIC_SERVER_ENABLED to True."
|
|
110
|
+
raise HTTPException(status_code=500, detail=msg)
|
|
111
|
+
|
|
112
|
+
try:
|
|
113
|
+
file_names = []
|
|
114
|
+
if static_directory.exists():
|
|
115
|
+
for file_path in static_directory.rglob("*"):
|
|
116
|
+
if file_path.is_file():
|
|
117
|
+
relative_path = file_path.relative_to(static_directory)
|
|
118
|
+
file_names.append(str(relative_path))
|
|
119
|
+
except (OSError, PermissionError) as e:
|
|
120
|
+
msg = f"Failed to list files in static directory: {e}"
|
|
121
|
+
logger.error(msg)
|
|
122
|
+
raise HTTPException(status_code=500, detail=msg) from e
|
|
123
|
+
else:
|
|
124
|
+
return {"files": file_names}
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
@app.post("/engines/request")
|
|
128
|
+
async def _create_event(request: Request, queue: Annotated[Queue, Depends(get_event_queue)]) -> None:
|
|
129
|
+
body = await request.json()
|
|
130
|
+
_process_api_event(body, queue)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def start_api(static_directory: Path, queue: Queue) -> None:
|
|
134
|
+
"""Run FastAPI with Uvicorn in order to serve static files produced by nodes."""
|
|
135
|
+
global event_queue, static_dir # noqa: PLW0603
|
|
136
|
+
event_queue = queue
|
|
137
|
+
static_dir = static_directory
|
|
138
|
+
|
|
139
|
+
logging.getLogger("uvicorn").addHandler(
|
|
140
|
+
RichHandler(show_time=True, show_path=False, markup=True, rich_tracebacks=True)
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
if not static_dir.exists():
|
|
144
|
+
static_dir.mkdir(parents=True, exist_ok=True)
|
|
145
|
+
|
|
146
|
+
app.add_middleware(
|
|
147
|
+
CORSMiddleware,
|
|
148
|
+
allow_origins=[
|
|
149
|
+
os.getenv("GRIPTAPE_NODES_UI_BASE_URL", "https://app.nodes.griptape.ai"),
|
|
150
|
+
"https://app.nodes-staging.griptape.ai",
|
|
151
|
+
"http://localhost:5173",
|
|
152
|
+
],
|
|
153
|
+
allow_credentials=True,
|
|
154
|
+
allow_methods=["OPTIONS", "GET", "POST", "PUT"],
|
|
155
|
+
allow_headers=["*"],
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
app.mount(
|
|
159
|
+
STATIC_SERVER_URL,
|
|
160
|
+
StaticFiles(directory=static_directory),
|
|
161
|
+
name="static",
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
uvicorn.run(
|
|
165
|
+
app, host=STATIC_SERVER_HOST, port=STATIC_SERVER_PORT, log_level=STATIC_SERVER_LOG_LEVEL, log_config=None
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def _process_api_event(event: dict, event_queue: Queue) -> None:
|
|
170
|
+
"""Process API events and send them to the event queue."""
|
|
171
|
+
payload = event.get("payload", {})
|
|
172
|
+
|
|
173
|
+
try:
|
|
174
|
+
payload["request"]
|
|
175
|
+
except KeyError:
|
|
176
|
+
msg = "Error: 'request' was expected but not found."
|
|
177
|
+
raise RuntimeError(msg) from None
|
|
178
|
+
|
|
179
|
+
try:
|
|
180
|
+
event_type = payload["event_type"]
|
|
181
|
+
if event_type != "EventRequest":
|
|
182
|
+
msg = "Error: 'event_type' was found on request, but did not match 'EventRequest' as expected."
|
|
183
|
+
raise RuntimeError(msg) from None
|
|
184
|
+
except KeyError:
|
|
185
|
+
msg = "Error: 'event_type' not found in request."
|
|
186
|
+
raise RuntimeError(msg) from None
|
|
187
|
+
|
|
188
|
+
# Now attempt to convert it into an EventRequest.
|
|
189
|
+
try:
|
|
190
|
+
request_event = deserialize_event(json_data=payload)
|
|
191
|
+
if not isinstance(request_event, EventRequest):
|
|
192
|
+
msg = f"Deserialized event is not an EventRequest: {type(request_event)}"
|
|
193
|
+
raise TypeError(msg) # noqa: TRY301
|
|
194
|
+
except Exception as e:
|
|
195
|
+
msg = f"Unable to convert request JSON into a valid EventRequest object. Error Message: '{e}'"
|
|
196
|
+
raise RuntimeError(msg) from None
|
|
197
|
+
|
|
198
|
+
# Add the event to the queue
|
|
199
|
+
event_queue.put(request_event)
|