griptape-nodes 0.52.0__py3-none-any.whl → 0.53.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 (48) hide show
  1. griptape_nodes/__init__.py +6 -943
  2. griptape_nodes/__main__.py +6 -0
  3. griptape_nodes/app/api.py +1 -12
  4. griptape_nodes/app/app.py +256 -209
  5. griptape_nodes/cli/__init__.py +1 -0
  6. griptape_nodes/cli/commands/__init__.py +1 -0
  7. griptape_nodes/cli/commands/config.py +71 -0
  8. griptape_nodes/cli/commands/engine.py +80 -0
  9. griptape_nodes/cli/commands/init.py +548 -0
  10. griptape_nodes/cli/commands/libraries.py +90 -0
  11. griptape_nodes/cli/commands/self.py +117 -0
  12. griptape_nodes/cli/main.py +46 -0
  13. griptape_nodes/cli/shared.py +84 -0
  14. griptape_nodes/common/__init__.py +1 -0
  15. griptape_nodes/common/directed_graph.py +55 -0
  16. griptape_nodes/drivers/storage/local_storage_driver.py +7 -2
  17. griptape_nodes/exe_types/core_types.py +60 -2
  18. griptape_nodes/exe_types/node_types.py +38 -24
  19. griptape_nodes/machines/control_flow.py +86 -22
  20. griptape_nodes/machines/fsm.py +10 -1
  21. griptape_nodes/machines/parallel_resolution.py +570 -0
  22. griptape_nodes/machines/{node_resolution.py → sequential_resolution.py} +22 -51
  23. griptape_nodes/mcp_server/server.py +1 -1
  24. griptape_nodes/retained_mode/events/base_events.py +2 -2
  25. griptape_nodes/retained_mode/events/node_events.py +4 -3
  26. griptape_nodes/retained_mode/griptape_nodes.py +25 -12
  27. griptape_nodes/retained_mode/managers/agent_manager.py +9 -5
  28. griptape_nodes/retained_mode/managers/arbitrary_code_exec_manager.py +3 -1
  29. griptape_nodes/retained_mode/managers/context_manager.py +6 -5
  30. griptape_nodes/retained_mode/managers/flow_manager.py +117 -204
  31. griptape_nodes/retained_mode/managers/library_lifecycle/library_directory.py +1 -1
  32. griptape_nodes/retained_mode/managers/library_manager.py +35 -25
  33. griptape_nodes/retained_mode/managers/node_manager.py +81 -199
  34. griptape_nodes/retained_mode/managers/object_manager.py +11 -5
  35. griptape_nodes/retained_mode/managers/os_manager.py +24 -9
  36. griptape_nodes/retained_mode/managers/secrets_manager.py +8 -4
  37. griptape_nodes/retained_mode/managers/settings.py +32 -1
  38. griptape_nodes/retained_mode/managers/static_files_manager.py +8 -3
  39. griptape_nodes/retained_mode/managers/sync_manager.py +8 -5
  40. griptape_nodes/retained_mode/managers/workflow_manager.py +110 -122
  41. griptape_nodes/traits/add_param_button.py +1 -1
  42. griptape_nodes/traits/button.py +216 -6
  43. griptape_nodes/traits/color_picker.py +66 -0
  44. griptape_nodes/traits/traits.json +4 -0
  45. {griptape_nodes-0.52.0.dist-info → griptape_nodes-0.53.0.dist-info}/METADATA +2 -1
  46. {griptape_nodes-0.52.0.dist-info → griptape_nodes-0.53.0.dist-info}/RECORD +48 -34
  47. {griptape_nodes-0.52.0.dist-info → griptape_nodes-0.53.0.dist-info}/WHEEL +0 -0
  48. {griptape_nodes-0.52.0.dist-info → griptape_nodes-0.53.0.dist-info}/entry_points.txt +0 -0
@@ -169,7 +169,7 @@ class LibraryDirectory:
169
169
  return blockers
170
170
 
171
171
  # Check if library is in evaluated state
172
- if fsm.get_current_state() != EvaluatedState:
172
+ if fsm.current_state != EvaluatedState:
173
173
  blockers.append(
174
174
  LifecycleIssue(
175
175
  message=f"Library not in evaluated state: {fsm.get_current_state_name()}",
@@ -38,6 +38,9 @@ from griptape_nodes.retained_mode.events.app_events import (
38
38
  GetEngineVersionRequest,
39
39
  GetEngineVersionResultSuccess,
40
40
  )
41
+
42
+ # Runtime imports for ResultDetails since it's used at runtime
43
+ from griptape_nodes.retained_mode.events.base_events import ResultDetails
41
44
  from griptape_nodes.retained_mode.events.config_events import (
42
45
  GetConfigCategoryRequest,
43
46
  GetConfigCategoryResultSuccess,
@@ -319,7 +322,10 @@ class LibraryManager:
319
322
  details = f"Request type '{request.request_type}' is not registered in the PayloadRegistry."
320
323
  return ListCapableLibraryEventHandlersResultFailure(exception=KeyError(details), result_details=details)
321
324
  handler_mappings = self.get_registered_event_handlers(request_type)
322
- return ListCapableLibraryEventHandlersResultSuccess(handlers=list(handler_mappings.keys()))
325
+ return ListCapableLibraryEventHandlersResultSuccess(
326
+ handlers=list(handler_mappings.keys()),
327
+ result_details=f"Successfully listed {len(handler_mappings)} capable library event handlers",
328
+ )
323
329
 
324
330
  def on_list_registered_libraries_request(self, _request: ListRegisteredLibrariesRequest) -> ResultPayload:
325
331
  # Make a COPY of the list
@@ -327,10 +333,10 @@ class LibraryManager:
327
333
  event_copy = snapshot_list.copy()
328
334
 
329
335
  details = "Successfully retrieved the list of registered libraries."
330
- logger.debug(details)
331
336
 
332
337
  result = ListRegisteredLibrariesResultSuccess(
333
338
  libraries=event_copy,
339
+ result_details=details,
334
340
  )
335
341
  return result
336
342
 
@@ -350,10 +356,10 @@ class LibraryManager:
350
356
  event_copy = snapshot_list.copy()
351
357
 
352
358
  details = f"Successfully retrieved the list of node types in the Library named '{request.library}'."
353
- logger.debug(details)
354
359
 
355
360
  result = ListNodeTypesInLibraryResultSuccess(
356
361
  node_types=event_copy,
362
+ result_details=details,
357
363
  )
358
364
  return result
359
365
 
@@ -371,9 +377,8 @@ class LibraryManager:
371
377
  # Get the metadata off of it.
372
378
  metadata = library.get_metadata()
373
379
  details = f"Successfully retrieved metadata for Library '{request.library}'."
374
- logger.debug(details)
375
380
 
376
- result = GetLibraryMetadataResultSuccess(metadata=metadata)
381
+ result = GetLibraryMetadataResultSuccess(metadata=metadata, result_details=details)
377
382
  return result
378
383
 
379
384
  def load_library_metadata_from_file_request(self, request: LoadLibraryMetadataFromFileRequest) -> ResultPayload:
@@ -462,8 +467,9 @@ class LibraryManager:
462
467
  )
463
468
 
464
469
  details = f"Successfully loaded library metadata from JSON file at {json_path}"
465
- logger.debug(details)
466
- return LoadLibraryMetadataFromFileResultSuccess(library_schema=library_data, file_path=file_path)
470
+ return LoadLibraryMetadataFromFileResultSuccess(
471
+ library_schema=library_data, file_path=file_path, result_details=details
472
+ )
467
473
 
468
474
  def load_metadata_for_all_libraries_request(self, request: LoadMetadataForAllLibrariesRequest) -> ResultPayload: # noqa: ARG002
469
475
  """Load metadata for all libraries from configuration without loading node modules.
@@ -504,10 +510,10 @@ class LibraryManager:
504
510
  details = (
505
511
  f"Successfully loaded metadata for {len(successful_libraries)} libraries, {len(failed_libraries)} failed"
506
512
  )
507
- logger.debug(details)
508
513
  return LoadMetadataForAllLibrariesResultSuccess(
509
514
  successful_libraries=successful_libraries,
510
515
  failed_libraries=failed_libraries,
516
+ result_details=details,
511
517
  )
512
518
 
513
519
  def _generate_sandbox_library_metadata(
@@ -615,9 +621,8 @@ class LibraryManager:
615
621
  )
616
622
 
617
623
  details = f"Successfully generated sandbox library metadata with {len(node_definitions)} nodes from {sandbox_library_dir}"
618
- logger.debug(details)
619
624
  return LoadLibraryMetadataFromFileResultSuccess(
620
- library_schema=library_schema, file_path=str(sandbox_library_dir)
625
+ library_schema=library_schema, file_path=str(sandbox_library_dir), result_details=details
621
626
  )
622
627
 
623
628
  def get_node_metadata_from_library_request(self, request: GetNodeMetadataFromLibraryRequest) -> ResultPayload:
@@ -642,10 +647,10 @@ class LibraryManager:
642
647
  return result
643
648
 
644
649
  details = f"Successfully retrieved node metadata for a node type '{request.node_type}' in a Library named '{request.library}'."
645
- logger.debug(details)
646
650
 
647
651
  result = GetNodeMetadataFromLibraryResultSuccess(
648
652
  metadata=metadata,
653
+ result_details=details,
649
654
  )
650
655
  return result
651
656
 
@@ -660,7 +665,9 @@ class LibraryManager:
660
665
  return result
661
666
 
662
667
  categories = library.get_categories()
663
- result = ListCategoriesInLibraryResultSuccess(categories=categories)
668
+ result = ListCategoriesInLibraryResultSuccess(
669
+ categories=categories, result_details=f"Successfully retrieved categories for library '{request.library}'."
670
+ )
664
671
  return result
665
672
 
666
673
  async def register_library_from_file_request(self, request: RegisterLibraryFromFileRequest) -> ResultPayload: # noqa: C901, PLR0911, PLR0912, PLR0915 (complex logic needs branches)
@@ -906,15 +913,16 @@ class LibraryManager:
906
913
  match library_load_results.status:
907
914
  case LibraryStatus.GOOD:
908
915
  details = f"Successfully loaded Library '{library_data.name}' from JSON file at {json_path}"
909
- logger.info(details)
910
- return RegisterLibraryFromFileResultSuccess(library_name=library_data.name)
916
+ return RegisterLibraryFromFileResultSuccess(
917
+ library_name=library_data.name, result_details=ResultDetails(message=details, level="INFO")
918
+ )
911
919
  case LibraryStatus.FLAWED:
912
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."
913
- logger.warning(details)
914
- return RegisterLibraryFromFileResultSuccess(library_name=library_data.name)
921
+ return RegisterLibraryFromFileResultSuccess(
922
+ library_name=library_data.name, result_details=ResultDetails(message=details, level="WARNING")
923
+ )
915
924
  case LibraryStatus.UNUSABLE:
916
925
  details = f"Attempted to load Library JSON file from '{json_path}'. Failed because no nodes were loaded. Check the log for more details."
917
- logger.error(details)
918
926
  return RegisterLibraryFromFileResultFailure(result_details=details)
919
927
  case _:
920
928
  details = f"Attempted to load Library JSON file from '{json_path}'. Failed because an unknown/unexpected status '{library_load_results.status}' was returned."
@@ -985,7 +993,10 @@ class LibraryManager:
985
993
  logger.error(details)
986
994
  return RegisterLibraryFromRequirementSpecifierResultFailure(result_details=details)
987
995
 
988
- return RegisterLibraryFromRequirementSpecifierResultSuccess(library_name=request.requirement_specifier)
996
+ return RegisterLibraryFromRequirementSpecifierResultSuccess(
997
+ library_name=request.requirement_specifier,
998
+ result_details=f"Successfully registered library from requirement specifier: {request.requirement_specifier}",
999
+ )
989
1000
 
990
1001
  async def _init_library_venv(self, library_venv_path: Path) -> Path:
991
1002
  """Initialize a virtual environment for the library.
@@ -1122,8 +1133,7 @@ class LibraryManager:
1122
1133
  del self._library_file_path_to_info[lib_info.library_path]
1123
1134
 
1124
1135
  details = f"Successfully unloaded (and unregistered) library '{request.library_name}'."
1125
- logger.debug(details)
1126
- return UnloadLibraryFromRegistryResultSuccess()
1136
+ return UnloadLibraryFromRegistryResultSuccess(result_details=details)
1127
1137
 
1128
1138
  def get_all_info_for_all_libraries_request(self, request: GetAllInfoForAllLibrariesRequest) -> ResultPayload: # noqa: ARG002
1129
1139
  list_libraries_request = ListRegisteredLibrariesRequest()
@@ -1159,8 +1169,9 @@ class LibraryManager:
1159
1169
 
1160
1170
  # We're home free now
1161
1171
  details = "Successfully retrieved all info for all libraries."
1162
- logger.debug(details)
1163
- result = GetAllInfoForAllLibrariesResultSuccess(library_name_to_library_info=library_name_to_all_info)
1172
+ result = GetAllInfoForAllLibrariesResultSuccess(
1173
+ library_name_to_library_info=library_name_to_all_info, result_details=details
1174
+ )
1164
1175
  return result
1165
1176
 
1166
1177
  def get_all_info_for_library_request(self, request: GetAllInfoForLibraryRequest) -> ResultPayload: # noqa: PLR0911
@@ -1231,11 +1242,11 @@ class LibraryManager:
1231
1242
  node_type_name_to_node_metadata_details[node_type_name] = node_metadata_result_success
1232
1243
 
1233
1244
  details = f"Successfully got all library info for a Library named '{request.library}'."
1234
- logger.debug(details)
1235
1245
  result = GetAllInfoForLibraryResultSuccess(
1236
1246
  library_metadata_details=library_metadata_result_success,
1237
1247
  category_details=list_categories_result_success,
1238
1248
  node_type_name_to_node_metadata_details=node_type_name_to_node_metadata_details,
1249
+ result_details=details,
1239
1250
  )
1240
1251
  return result
1241
1252
 
@@ -2029,5 +2040,4 @@ class LibraryManager:
2029
2040
  details = (
2030
2041
  "Successfully reloaded all libraries. All object state was cleared and previous libraries were unloaded."
2031
2042
  )
2032
- logger.info(details)
2033
- return ReloadAllLibrariesResultSuccess()
2043
+ return ReloadAllLibrariesResultSuccess(result_details=ResultDetails(message=details, level="INFO"))