griptape-nodes 0.35.1__py3-none-any.whl → 0.36.1__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 (25) hide show
  1. griptape_nodes/__init__.py +259 -92
  2. griptape_nodes/app/__init__.py +6 -1
  3. griptape_nodes/app/app.py +2 -2
  4. griptape_nodes/app/app_websocket.py +481 -0
  5. griptape_nodes/bootstrap/bootstrap_script.py +12 -231
  6. griptape_nodes/bootstrap/workflow_runners/__init__.py +1 -0
  7. griptape_nodes/bootstrap/workflow_runners/bootstrap_workflow_runner.py +28 -0
  8. griptape_nodes/bootstrap/workflow_runners/local_workflow_runner.py +237 -0
  9. griptape_nodes/bootstrap/workflow_runners/subprocess_workflow_runner.py +58 -0
  10. griptape_nodes/bootstrap/workflow_runners/workflow_runner.py +11 -0
  11. griptape_nodes/exe_types/core_types.py +50 -0
  12. griptape_nodes/machines/node_resolution.py +3 -3
  13. griptape_nodes/node_library/library_registry.py +18 -7
  14. griptape_nodes/retained_mode/events/node_events.py +2 -2
  15. griptape_nodes/retained_mode/events/parameter_events.py +4 -49
  16. griptape_nodes/retained_mode/managers/config_manager.py +6 -6
  17. griptape_nodes/retained_mode/managers/flow_manager.py +5 -5
  18. griptape_nodes/retained_mode/managers/node_manager.py +192 -21
  19. griptape_nodes/retained_mode/managers/object_manager.py +2 -0
  20. griptape_nodes/retained_mode/managers/workflow_manager.py +3 -4
  21. {griptape_nodes-0.35.1.dist-info → griptape_nodes-0.36.1.dist-info}/METADATA +1 -1
  22. {griptape_nodes-0.35.1.dist-info → griptape_nodes-0.36.1.dist-info}/RECORD +25 -19
  23. {griptape_nodes-0.35.1.dist-info → griptape_nodes-0.36.1.dist-info}/WHEEL +0 -0
  24. {griptape_nodes-0.35.1.dist-info → griptape_nodes-0.36.1.dist-info}/entry_points.txt +0 -0
  25. {griptape_nodes-0.35.1.dist-info → griptape_nodes-0.36.1.dist-info}/licenses/LICENSE +0 -0
@@ -19,9 +19,11 @@ with console.status("Loading Griptape Nodes...") as status:
19
19
 
20
20
  import httpx
21
21
  from dotenv import load_dotenv
22
+ from rich.box import HEAVY_EDGE
22
23
  from rich.panel import Panel
23
24
  from rich.progress import Progress
24
25
  from rich.prompt import Confirm, Prompt
26
+ from rich.table import Table
25
27
  from xdg_base_dirs import xdg_config_home, xdg_data_home
26
28
 
27
29
  from griptape_nodes.app import start_app
@@ -40,6 +42,18 @@ NODES_APP_URL = "https://nodes.griptape.ai"
40
42
  NODES_TARBALL_URL = "https://github.com/griptape-ai/griptape-nodes/archive/refs/tags/{tag}.tar.gz"
41
43
  PYPI_UPDATE_URL = "https://pypi.org/pypi/{package}/json"
42
44
  GITHUB_UPDATE_URL = "https://api.github.com/repos/griptape-ai/{package}/git/refs/tags/{revision}"
45
+ GT_CLOUD_BASE_URL = os.getenv("GT_CLOUD_BASE_URL", "https://cloud.griptape.ai")
46
+
47
+ # Environment variable defaults for init configuration
48
+ ENV_WORKSPACE_DIRECTORY = os.getenv("GTN_WORKSPACE_DIRECTORY")
49
+ ENV_API_KEY = os.getenv("GTN_API_KEY")
50
+ ENV_STORAGE_BACKEND = os.getenv("GTN_STORAGE_BACKEND")
51
+ ENV_STORAGE_BACKEND_BUCKET_ID = os.getenv("GTN_STORAGE_BACKEND_BUCKET_ID")
52
+ ENV_REGISTER_ADVANCED_LIBRARY = (
53
+ os.getenv("GTN_REGISTER_ADVANCED_LIBRARY", "false").lower() == "true"
54
+ if os.getenv("GTN_REGISTER_ADVANCED_LIBRARY") is not None
55
+ else None
56
+ )
43
57
 
44
58
 
45
59
  config_manager = ConfigManager()
@@ -61,20 +75,63 @@ def main() -> None:
61
75
  _process_args(args)
62
76
 
63
77
 
64
- def _run_init(
65
- *, workspace_directory: str | None = None, api_key: str | None = None, register_advanced_library: bool | None = None
78
+ def _run_init( # noqa: PLR0913
79
+ *,
80
+ interactive: bool = True,
81
+ workspace_directory: str | None = None,
82
+ api_key: str | None = None,
83
+ storage_backend: str | None = None,
84
+ storage_backend_bucket_id: str | None = None,
85
+ register_advanced_library: bool | None = None,
66
86
  ) -> None:
67
87
  """Runs through the engine init steps.
68
88
 
69
89
  Args:
90
+ interactive (bool): If True, prompts the user for input; otherwise uses provided values.
70
91
  workspace_directory (str | None): The workspace directory to set.
71
92
  api_key (str | None): The API key to set.
93
+ storage_backend (str | None): The storage backend to set.
94
+ storage_backend_bucket_id (str | None): The storage backend bucket ID to set.
72
95
  register_advanced_library (bool | None): Whether to register the advanced library.
73
96
  """
74
97
  __init_system_config()
75
- _prompt_for_workspace(workspace_directory=workspace_directory)
76
- _prompt_for_api_key(api_key=api_key)
77
- _prompt_for_libraries_to_register(register_advanced_library=register_advanced_library)
98
+
99
+ if interactive:
100
+ workspace_directory = _prompt_for_workspace(default_workspace_directory=workspace_directory)
101
+ api_key = _prompt_for_api_key(default_api_key=api_key)
102
+ storage_backend = _prompt_for_storage_backend(default_storage_backend=storage_backend)
103
+ if storage_backend == "gtc":
104
+ storage_backend_bucket_id = _prompt_for_storage_backend_bucket_id(
105
+ default_storage_backend_bucket_id=storage_backend_bucket_id
106
+ )
107
+ register_advanced_library = _prompt_for_advanced_media_library(
108
+ default_prompt_for_advanced_media_library=register_advanced_library
109
+ )
110
+ libraries_to_register = __build_libraries_list(register_advanced_library=register_advanced_library)
111
+
112
+ if workspace_directory is not None:
113
+ config_manager.set_config_value("workspace_directory", workspace_directory)
114
+ console.print(f"[bold green]Workspace directory set to: {workspace_directory}[/bold green]")
115
+
116
+ if api_key is not None:
117
+ secrets_manager.set_secret("GT_CLOUD_API_KEY", api_key)
118
+ console.print("[bold green]Griptape API Key set")
119
+
120
+ if storage_backend is not None:
121
+ config_manager.set_config_value("storage_backend", storage_backend)
122
+ console.print(f"[bold green]Storage backend set to: {storage_backend}")
123
+
124
+ if storage_backend_bucket_id is not None:
125
+ secrets_manager.set_secret("GT_CLOUD_BUCKET_ID", storage_backend_bucket_id)
126
+ console.print(f"[bold green]Storage backend bucket ID set to: {storage_backend_bucket_id}[/bold green]")
127
+
128
+ if register_advanced_library is not None:
129
+ libraries_to_register = __build_libraries_list(register_advanced_library=register_advanced_library)
130
+ config_manager.set_config_value(
131
+ "app_events.on_app_initialization_complete.libraries_to_register", libraries_to_register
132
+ )
133
+ console.print(f"[bold green]Libraries to register set to: {', '.join(libraries_to_register)}[/bold green]")
134
+
78
135
  _sync_assets()
79
136
  console.print("[bold green]Initialization complete![/bold green]")
80
137
 
@@ -89,9 +146,12 @@ def _start_engine(*, no_update: bool = False) -> None:
89
146
  # Default init flow if there is no config directory
90
147
  console.print("[bold green]Config directory not found. Initializing...[/bold green]")
91
148
  _run_init(
92
- workspace_directory=os.getenv("GTN_WORKSPACE_DIRECTORY"),
93
- api_key=os.getenv("GTN_API_KEY"),
94
- register_advanced_library=os.getenv("GTN_REGISTER_ADVANCED_LIBRARY", "false").lower() == "true",
149
+ workspace_directory=ENV_WORKSPACE_DIRECTORY,
150
+ api_key=ENV_API_KEY,
151
+ storage_backend=ENV_STORAGE_BACKEND,
152
+ storage_backend_bucket_id=ENV_STORAGE_BACKEND_BUCKET_ID,
153
+ register_advanced_library=ENV_REGISTER_ADVANCED_LIBRARY,
154
+ interactive=True,
95
155
  )
96
156
 
97
157
  # Confusing double negation -- If `no_update` is set, we want to skip the update
@@ -126,18 +186,33 @@ def _get_args() -> argparse.Namespace:
126
186
  init_parser.add_argument(
127
187
  "--api-key",
128
188
  help="Set the Griptape Nodes API key.",
129
- default=os.getenv("GTN_API_KEY", None),
189
+ default=ENV_API_KEY,
130
190
  )
131
191
  init_parser.add_argument(
132
192
  "--workspace-directory",
133
193
  help="Set the Griptape Nodes workspace directory.",
134
- default=os.getenv("GTN_WORKSPACE_DIRECTORY", None),
194
+ default=ENV_WORKSPACE_DIRECTORY,
195
+ )
196
+ init_parser.add_argument(
197
+ "--storage-backend",
198
+ help="Set the storage backend ('local' or 'gtc').",
199
+ choices=["local", "gtc"],
200
+ default=ENV_STORAGE_BACKEND,
201
+ )
202
+ init_parser.add_argument(
203
+ "--storage-backend-bucket-id",
204
+ help="Set the Griptape Cloud bucket ID (only used with 'gtc' storage backend).",
205
+ default=ENV_STORAGE_BACKEND_BUCKET_ID,
135
206
  )
136
- register_advanced_library = os.getenv("GTN_REGISTER_ADVANCED_LIBRARY", None)
137
207
  init_parser.add_argument(
138
208
  "--register-advanced-library",
139
- default=register_advanced_library.lower() == "true" if register_advanced_library is not None else None,
140
209
  help="Install the Griptape Nodes Advanced Image Library.",
210
+ default=ENV_REGISTER_ADVANCED_LIBRARY,
211
+ )
212
+ init_parser.add_argument(
213
+ "--no-interactive",
214
+ action="store_true",
215
+ help="Run init in non-interactive mode (no prompts).",
141
216
  )
142
217
 
143
218
  # engine
@@ -183,102 +258,191 @@ def _get_args() -> argparse.Namespace:
183
258
  return args
184
259
 
185
260
 
186
- def _prompt_for_api_key(api_key: str | None = None) -> None:
261
+ def _prompt_for_api_key(default_api_key: str | None = None) -> str:
187
262
  """Prompts the user for their GT_CLOUD_API_KEY unless it's provided."""
188
- if api_key is None:
189
- explainer = f"""[bold cyan]Griptape API Key[/bold cyan]
190
- A Griptape API Key is needed to proceed.
191
- This key allows the Griptape Nodes Engine to communicate with the Griptape Nodes Editor.
192
- In order to get your key, return to the [link={NODES_APP_URL}]{NODES_APP_URL}[/link] tab in your browser and click the button
193
- "Generate API Key".
194
- Once the key is generated, copy and paste its value here to proceed."""
195
- console.print(Panel(explainer, expand=False))
196
-
263
+ if default_api_key is None:
197
264
  default_api_key = secrets_manager.get_secret("GT_CLOUD_API_KEY", should_error_on_not_found=False)
198
- while api_key is None:
199
- api_key = Prompt.ask(
200
- "Griptape API Key",
201
- default=default_api_key,
265
+ explainer = f"""[bold cyan]Griptape API Key[/bold cyan]
266
+ A Griptape API Key is needed to proceed.
267
+ This key allows the Griptape Nodes Engine to communicate with the Griptape Nodes Editor.
268
+ In order to get your key, return to the [link={NODES_APP_URL}]{NODES_APP_URL}[/link] tab in your browser and click the button
269
+ "Generate API Key".
270
+ Once the key is generated, copy and paste its value here to proceed."""
271
+ console.print(Panel(explainer, expand=False))
272
+
273
+ while True:
274
+ api_key = Prompt.ask(
275
+ "Griptape API Key",
276
+ default=default_api_key,
277
+ show_default=True,
278
+ )
279
+ if api_key:
280
+ break
281
+
282
+ return api_key
283
+
284
+
285
+ def _prompt_for_workspace(*, default_workspace_directory: str | None = None) -> str:
286
+ """Prompts the user for their workspace directory."""
287
+ if default_workspace_directory is None:
288
+ default_workspace_directory = config_manager.get_config_value("workspace_directory")
289
+ explainer = """[bold cyan]Workspace Directory[/bold cyan]
290
+ Select the workspace directory. This is the location where Griptape Nodes will store your saved workflows.
291
+ You may enter a custom directory or press Return to accept the default workspace directory"""
292
+ console.print(Panel(explainer, expand=False))
293
+
294
+ while True:
295
+ try:
296
+ workspace_to_test = Prompt.ask(
297
+ "Workspace Directory",
298
+ default=default_workspace_directory,
299
+ show_default=True,
300
+ )
301
+ if workspace_to_test:
302
+ workspace_directory = str(Path(workspace_to_test).expanduser().resolve())
303
+ break
304
+ except OSError as e:
305
+ console.print(f"[bold red]Invalid workspace directory: {e}[/bold red]")
306
+ except json.JSONDecodeError as e:
307
+ console.print(f"[bold red]Error reading config file: {e}[/bold red]")
308
+
309
+ return workspace_directory
310
+
311
+
312
+ def _prompt_for_storage_backend(*, default_storage_backend: str | None = None) -> str:
313
+ """Prompts the user for their storage backend."""
314
+ if default_storage_backend is None:
315
+ default_storage_backend = config_manager.get_config_value("storage_backend")
316
+ explainer = """[bold cyan]Storage Backend[/bold cyan]
317
+ Select the storage backend. This is where Griptape Nodes will store your static files.
318
+ Enter 'gtc' to use Griptape Cloud Bucket Storage, or press Return to accept the default of the local static file server."""
319
+ console.print(Panel(explainer, expand=False))
320
+
321
+ while True:
322
+ try:
323
+ storage_backend = Prompt.ask(
324
+ "Storage Backend",
325
+ choices=["gtc", "local"],
326
+ default=default_storage_backend,
202
327
  show_default=True,
203
328
  )
329
+ if storage_backend:
330
+ break
331
+ except json.JSONDecodeError as e:
332
+ console.print(f"[bold red]Error reading config file: {e}[/bold red]")
333
+
334
+ return storage_backend
335
+
336
+
337
+ def _get_griptape_cloud_bucket_ids_and_display_table() -> tuple[list[str], Table]:
338
+ """Fetches the list of Griptape Cloud Bucket IDs from the API."""
339
+ url = f"{GT_CLOUD_BASE_URL}/api/buckets"
340
+ headers = {
341
+ "Authorization": f"Bearer {secrets_manager.get_secret('GT_CLOUD_API_KEY')}",
342
+ }
343
+ bucket_ids: list[str] = []
344
+
345
+ table = Table(show_header=True, box=HEAVY_EDGE, show_lines=True, expand=True)
346
+ table.add_column("Bucket Name", style="green")
347
+ table.add_column("Bucket ID", style="green")
348
+
349
+ with httpx.Client() as client:
350
+ response = client.get(url, headers=headers)
351
+ try:
352
+ response.raise_for_status()
353
+ data = response.json()
354
+ for bucket in data["buckets"]:
355
+ bucket_ids.append(bucket["bucket_id"])
356
+ table.add_row(bucket["name"], bucket["bucket_id"])
357
+
358
+ except httpx.HTTPStatusError as e:
359
+ console.print(f"[red]Error fetching bucket IDs: {e}[/red]")
360
+
361
+ return bucket_ids, table
362
+
363
+
364
+ def _prompt_for_storage_backend_bucket_id(*, default_storage_backend_bucket_id: str | None = None) -> str:
365
+ """Prompts the user for their storage backend bucket ID."""
366
+ if default_storage_backend_bucket_id is None:
367
+ default_storage_backend_bucket_id = secrets_manager.get_secret(
368
+ "GT_CLOUD_BUCKET_ID", should_error_on_not_found=False
369
+ )
370
+ explainer = """[bold cyan]Storage Backend Bucket ID[/bold cyan]
371
+ Enter the Griptape Cloud Bucket ID to use for Griptape Cloud Storage. This is the location where Griptape Nodes will store your static files."""
372
+ console.print(Panel(explainer, expand=False))
204
373
 
205
- secrets_manager.set_secret("GT_CLOUD_API_KEY", api_key)
206
- console.print("[bold green]Griptape API Key set")
374
+ choices, table = _get_griptape_cloud_bucket_ids_and_display_table()
207
375
 
376
+ # This should not be possible
377
+ if len(choices) < 1:
378
+ msg = "No Griptape Cloud Buckets found!"
379
+ raise RuntimeError(msg)
208
380
 
209
- def _prompt_for_workspace(*, workspace_directory: str | None) -> None:
210
- """Prompts the user for their workspace directory and stores it in config directory."""
211
- if workspace_directory is None:
212
- explainer = """[bold cyan]Workspace Directory[/bold cyan]
213
- Select the workspace directory. This is the location where Griptape Nodes will store your saved workflows.
214
- You may enter a custom directory or press Return to accept the default workspace directory"""
215
- console.print(Panel(explainer, expand=False))
381
+ console.print(table)
216
382
 
217
- default_workspace_directory = workspace_directory or config_manager.get_config_value("workspace_directory")
218
- while workspace_directory is None:
219
- try:
220
- workspace_to_test = Prompt.ask(
221
- "Workspace Directory",
222
- default=default_workspace_directory,
223
- show_default=True,
224
- )
225
- # Try to resolve the path to check if it exists
226
- if workspace_to_test is not None:
227
- Path(workspace_to_test).expanduser().resolve()
228
- workspace_directory = workspace_to_test
229
- except OSError as e:
230
- console.print(f"[bold red]Invalid workspace directory: {e}[/bold red]")
231
- except json.JSONDecodeError as e:
232
- console.print(f"[bold red]Error reading config file: {e}[/bold red]")
233
-
234
- workspace_path = Path(workspace_directory).expanduser().resolve()
235
- config_manager.set_config_value("workspace_directory", str(workspace_path))
236
-
237
- console.print(f"[bold green]Workspace directory set to: {config_manager.workspace_path}[/bold green]")
238
-
239
-
240
- def _prompt_for_libraries_to_register(*, register_advanced_library: bool | None = None) -> None:
241
- """Prompts the user for the libraries to register and stores them in config directory."""
242
- if register_advanced_library is None:
243
- explainer = """[bold cyan]Advanced Media Library[/bold cyan]
244
- Would you like to install the Griptape Nodes Advanced Media Library?
245
- This node library makes advanced media generation and manipulation nodes available.
246
- For example, nodes are available for Flux AI image upscaling, or to leverage CUDA for GPU-accelerated image generation.
247
- CAVEAT: Installing this library requires additional dependencies to download and install, which can take several minutes.
248
- The Griptape Nodes Advanced Media Library can be added later by following instructions here: [bold blue][link=https://docs.griptapenodes.com]https://docs.griptapenodes.com[/link][/bold blue].
249
- """
250
- console.print(Panel(explainer, expand=False))
383
+ while True:
384
+ try:
385
+ storage_backend_bucket_id = Prompt.ask(
386
+ "Storage Backend Bucket ID",
387
+ default=default_storage_backend_bucket_id,
388
+ show_default=True,
389
+ choices=choices,
390
+ )
391
+ if storage_backend_bucket_id:
392
+ break
393
+ except json.JSONDecodeError as e:
394
+ console.print(f"[bold red]Error reading config file: {e}[/bold red]")
395
+
396
+ return storage_backend_bucket_id
397
+
398
+
399
+ def _prompt_for_advanced_media_library(*, default_prompt_for_advanced_media_library: bool | None = None) -> bool:
400
+ """Prompts the user whether to register the advanced media library."""
401
+ if default_prompt_for_advanced_media_library is None:
402
+ default_prompt_for_advanced_media_library = False
403
+ explainer = """[bold cyan]Advanced Media Library[/bold cyan]
404
+ Would you like to install the Griptape Nodes Advanced Media Library?
405
+ This node library makes advanced media generation and manipulation nodes available.
406
+ For example, nodes are available for Flux AI image upscaling, or to leverage CUDA for GPU-accelerated image generation.
407
+ CAVEAT: Installing this library requires additional dependencies to download and install, which can take several minutes.
408
+ The Griptape Nodes Advanced Media Library can be added later by following instructions here: [bold blue][link=https://docs.griptapenodes.com]https://docs.griptapenodes.com[/link][/bold blue].
409
+ """
410
+ console.print(Panel(explainer, expand=False))
251
411
 
412
+ return Confirm.ask("Register Advanced Media Library?", default=default_prompt_for_advanced_media_library)
413
+
414
+
415
+ def __build_libraries_list(*, register_advanced_library: bool) -> list[str]:
416
+ """Builds the list of libraries to register based on the advanced library setting."""
252
417
  # TODO: https://github.com/griptape-ai/griptape-nodes/issues/929
253
- key = "app_events.on_app_initialization_complete.libraries_to_register"
418
+ libraries_key = "app_events.on_app_initialization_complete.libraries_to_register"
419
+ library_base_dir = xdg_data_home() / "griptape_nodes/libraries"
420
+
254
421
  current_libraries = config_manager.get_config_value(
255
- key,
422
+ libraries_key,
256
423
  config_source="user_config",
257
- default=config_manager.get_config_value(key, config_source="default_config", default=[]),
424
+ default=config_manager.get_config_value(libraries_key, config_source="default_config", default=[]),
258
425
  )
259
- default_library = str(
260
- xdg_data_home() / "griptape_nodes/libraries/griptape_nodes_library/griptape_nodes_library.json"
261
- )
262
- extra_libraries = [
263
- str(
264
- xdg_data_home()
265
- / "griptape_nodes/libraries/griptape_nodes_advanced_media_library/griptape_nodes_library.json"
266
- )
267
- ]
268
- libraries_to_merge = [default_library]
269
-
270
- if register_advanced_library is None:
271
- register_extras = Confirm.ask("Register Advanced Media Library?", default=False)
272
- else:
273
- register_extras = register_advanced_library
426
+ new_libraries = current_libraries
274
427
 
275
- if register_extras:
276
- libraries_to_merge.extend(extra_libraries)
428
+ default_library = str(library_base_dir / "griptape_nodes_library/griptape_nodes_library.json")
429
+ # If somehow the user removed the default library, add it back
430
+ if default_library not in current_libraries:
431
+ current_libraries.append(default_library)
277
432
 
278
- # Remove duplicates
279
- merged_libraries = list(set(current_libraries + libraries_to_merge))
433
+ advanced_media_library = str(
434
+ library_base_dir / "griptape_nodes_advanced_media_library/griptape_nodes_advanced_media_library.json"
435
+ )
436
+ if register_advanced_library:
437
+ # If the advanced media library is not registered, add it
438
+ if advanced_media_library not in current_libraries:
439
+ new_libraries.append(advanced_media_library)
440
+ else: # noqa: PLR5501 easier to reason about this way
441
+ # If the advanced media library is registered, remove it
442
+ if advanced_media_library in current_libraries:
443
+ new_libraries.remove(advanced_media_library)
280
444
 
281
- config_manager.set_config_value("app_events.on_app_initialization_complete.libraries_to_register", merged_libraries)
445
+ return new_libraries
282
446
 
283
447
 
284
448
  def _get_latest_version(package: str, install_source: str) -> str:
@@ -476,8 +640,11 @@ def _uninstall_self() -> None:
476
640
  def _process_args(args: argparse.Namespace) -> None: # noqa: C901, PLR0912
477
641
  if args.command == "init":
478
642
  _run_init(
643
+ interactive=not args.no_interactive,
479
644
  workspace_directory=args.workspace_directory,
480
645
  api_key=args.api_key,
646
+ storage_backend=args.storage_backend,
647
+ storage_backend_bucket_id=args.storage_backend_bucket_id,
481
648
  register_advanced_library=args.register_advanced_library,
482
649
  )
483
650
  elif args.command == "engine":
@@ -1,5 +1,10 @@
1
1
  """App package."""
2
2
 
3
- from griptape_nodes.app.app import start_app
3
+ import os
4
+
5
+ if os.getenv("GTN_USE_WEBSOCKETS", "false").lower() == "true":
6
+ from griptape_nodes.app.app_websocket import start_app
7
+ else:
8
+ from griptape_nodes.app.app import start_app
4
9
 
5
10
  __all__ = ["start_app"]
griptape_nodes/app/app.py CHANGED
@@ -125,8 +125,8 @@ def _serve_static_server() -> None:
125
125
  app.add_middleware(
126
126
  CORSMiddleware,
127
127
  allow_origins=[
128
- os.getenv("GRIPTAPE_NODES_UI_BASE_URL", "https://nodes.griptape.ai"),
129
- "https://nodes-staging.griptape.ai",
128
+ os.getenv("GRIPTAPE_NODES_UI_BASE_URL", "https://app.nodes.griptape.ai"),
129
+ "https://app.nodes-staging.griptape.ai",
130
130
  "http://localhost:5173",
131
131
  ],
132
132
  allow_credentials=True,