griptape-nodes 0.64.10__py3-none-any.whl → 0.65.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/app/app.py +25 -5
- griptape_nodes/cli/commands/init.py +65 -54
- griptape_nodes/cli/commands/libraries.py +92 -85
- griptape_nodes/cli/commands/self.py +121 -0
- griptape_nodes/common/node_executor.py +2142 -101
- griptape_nodes/exe_types/base_iterative_nodes.py +1004 -0
- griptape_nodes/exe_types/connections.py +114 -19
- griptape_nodes/exe_types/core_types.py +225 -7
- griptape_nodes/exe_types/flow.py +3 -3
- griptape_nodes/exe_types/node_types.py +681 -225
- griptape_nodes/exe_types/param_components/README.md +414 -0
- griptape_nodes/exe_types/param_components/api_key_provider_parameter.py +200 -0
- griptape_nodes/exe_types/param_components/huggingface/huggingface_model_parameter.py +2 -0
- griptape_nodes/exe_types/param_components/huggingface/huggingface_repo_file_parameter.py +79 -5
- griptape_nodes/exe_types/param_types/parameter_button.py +443 -0
- griptape_nodes/machines/control_flow.py +77 -38
- griptape_nodes/machines/dag_builder.py +148 -70
- griptape_nodes/machines/parallel_resolution.py +61 -35
- griptape_nodes/machines/sequential_resolution.py +11 -113
- griptape_nodes/retained_mode/events/app_events.py +1 -0
- griptape_nodes/retained_mode/events/base_events.py +16 -13
- griptape_nodes/retained_mode/events/connection_events.py +3 -0
- griptape_nodes/retained_mode/events/execution_events.py +35 -0
- griptape_nodes/retained_mode/events/flow_events.py +15 -2
- griptape_nodes/retained_mode/events/library_events.py +347 -0
- griptape_nodes/retained_mode/events/node_events.py +48 -0
- griptape_nodes/retained_mode/events/os_events.py +86 -3
- griptape_nodes/retained_mode/events/project_events.py +15 -1
- griptape_nodes/retained_mode/events/workflow_events.py +48 -1
- griptape_nodes/retained_mode/griptape_nodes.py +6 -2
- griptape_nodes/retained_mode/managers/config_manager.py +10 -8
- griptape_nodes/retained_mode/managers/event_manager.py +168 -0
- griptape_nodes/retained_mode/managers/fitness_problems/libraries/__init__.py +2 -0
- griptape_nodes/retained_mode/managers/fitness_problems/libraries/old_xdg_location_warning_problem.py +43 -0
- griptape_nodes/retained_mode/managers/flow_manager.py +664 -123
- griptape_nodes/retained_mode/managers/library_manager.py +1143 -139
- griptape_nodes/retained_mode/managers/model_manager.py +2 -3
- griptape_nodes/retained_mode/managers/node_manager.py +148 -25
- griptape_nodes/retained_mode/managers/object_manager.py +3 -1
- griptape_nodes/retained_mode/managers/operation_manager.py +3 -1
- griptape_nodes/retained_mode/managers/os_manager.py +1158 -122
- griptape_nodes/retained_mode/managers/secrets_manager.py +2 -3
- griptape_nodes/retained_mode/managers/settings.py +21 -1
- griptape_nodes/retained_mode/managers/sync_manager.py +2 -3
- griptape_nodes/retained_mode/managers/workflow_manager.py +358 -104
- griptape_nodes/retained_mode/retained_mode.py +3 -3
- griptape_nodes/traits/button.py +44 -2
- griptape_nodes/traits/file_system_picker.py +2 -2
- griptape_nodes/utils/file_utils.py +101 -0
- griptape_nodes/utils/git_utils.py +1226 -0
- griptape_nodes/utils/library_utils.py +122 -0
- {griptape_nodes-0.64.10.dist-info → griptape_nodes-0.65.0.dist-info}/METADATA +2 -1
- {griptape_nodes-0.64.10.dist-info → griptape_nodes-0.65.0.dist-info}/RECORD +55 -47
- {griptape_nodes-0.64.10.dist-info → griptape_nodes-0.65.0.dist-info}/WHEEL +1 -1
- {griptape_nodes-0.64.10.dist-info → griptape_nodes-0.65.0.dist-info}/entry_points.txt +0 -0
|
@@ -181,10 +181,14 @@ class LoadLibraryMetadataFromFileResultSuccess(WorkflowNotAlteredMixin, ResultPa
|
|
|
181
181
|
library_schema: The validated LibrarySchema object containing all metadata
|
|
182
182
|
about the library including nodes, categories, and settings.
|
|
183
183
|
file_path: The file path from which the library metadata was loaded.
|
|
184
|
+
git_remote: The git remote URL if the library is in a git repository, None otherwise.
|
|
185
|
+
git_ref: The current git reference (branch, tag, or commit) if the library is in a git repository, None otherwise.
|
|
184
186
|
"""
|
|
185
187
|
|
|
186
188
|
library_schema: LibrarySchema
|
|
187
189
|
file_path: str
|
|
190
|
+
git_remote: str | None
|
|
191
|
+
git_ref: str | None
|
|
188
192
|
|
|
189
193
|
|
|
190
194
|
@dataclass
|
|
@@ -539,3 +543,346 @@ class LoadLibrariesResultSuccess(WorkflowNotAlteredMixin, ResultPayloadSuccess):
|
|
|
539
543
|
@PayloadRegistry.register
|
|
540
544
|
class LoadLibrariesResultFailure(WorkflowNotAlteredMixin, ResultPayloadFailure):
|
|
541
545
|
"""Library loading failed. Common causes: library loading errors, configuration issues, initialization failures."""
|
|
546
|
+
|
|
547
|
+
|
|
548
|
+
@dataclass
|
|
549
|
+
@PayloadRegistry.register
|
|
550
|
+
class CheckLibraryUpdateRequest(RequestPayload):
|
|
551
|
+
"""Check if a library has updates available via git.
|
|
552
|
+
|
|
553
|
+
Use when: Checking for library updates, displaying update status,
|
|
554
|
+
validating library versions, implementing update notifications.
|
|
555
|
+
|
|
556
|
+
Args:
|
|
557
|
+
library_name: Name of the library to check for updates
|
|
558
|
+
|
|
559
|
+
Results: CheckLibraryUpdateResultSuccess (with update info) | CheckLibraryUpdateResultFailure (library not found, not a git repo, check error)
|
|
560
|
+
"""
|
|
561
|
+
|
|
562
|
+
library_name: str
|
|
563
|
+
|
|
564
|
+
|
|
565
|
+
@dataclass
|
|
566
|
+
@PayloadRegistry.register
|
|
567
|
+
class CheckLibraryUpdateResultSuccess(WorkflowNotAlteredMixin, ResultPayloadSuccess):
|
|
568
|
+
"""Library update check completed successfully.
|
|
569
|
+
|
|
570
|
+
Updates are detected based on either version changes or commit differences:
|
|
571
|
+
- If remote version > local version: update available (semantic versioning)
|
|
572
|
+
- If remote version < local version: no update (prevent regression)
|
|
573
|
+
- If versions equal: compare commits; if different, update available
|
|
574
|
+
|
|
575
|
+
Args:
|
|
576
|
+
has_update: True if an update is available, False otherwise
|
|
577
|
+
current_version: The current library version
|
|
578
|
+
latest_version: The latest library version from remote
|
|
579
|
+
git_remote: The git remote URL
|
|
580
|
+
git_ref: The current git reference (branch, tag, or commit)
|
|
581
|
+
local_commit: The local HEAD commit SHA (None if not a git repository)
|
|
582
|
+
remote_commit: The remote HEAD commit SHA (None if not available)
|
|
583
|
+
"""
|
|
584
|
+
|
|
585
|
+
has_update: bool
|
|
586
|
+
current_version: str | None
|
|
587
|
+
latest_version: str | None
|
|
588
|
+
git_remote: str | None
|
|
589
|
+
git_ref: str | None
|
|
590
|
+
local_commit: str | None
|
|
591
|
+
remote_commit: str | None
|
|
592
|
+
|
|
593
|
+
|
|
594
|
+
@dataclass
|
|
595
|
+
@PayloadRegistry.register
|
|
596
|
+
class CheckLibraryUpdateResultFailure(WorkflowNotAlteredMixin, ResultPayloadFailure):
|
|
597
|
+
"""Library update check failed. Common causes: library not found, not a git repository, git remote error, network error."""
|
|
598
|
+
|
|
599
|
+
|
|
600
|
+
@dataclass
|
|
601
|
+
@PayloadRegistry.register
|
|
602
|
+
class UpdateLibraryRequest(RequestPayload):
|
|
603
|
+
"""Update a library to the latest version using the appropriate git strategy.
|
|
604
|
+
|
|
605
|
+
Automatically detects whether the library uses branch-based or tag-based workflow:
|
|
606
|
+
- Branch-based: Uses git fetch + git reset --hard (forces local to match remote)
|
|
607
|
+
- Tag-based: Uses git fetch --tags --force + git checkout (for moving tags like 'latest')
|
|
608
|
+
|
|
609
|
+
Use when: Applying library updates, synchronizing with remote changes,
|
|
610
|
+
updating library versions, implementing auto-update features.
|
|
611
|
+
|
|
612
|
+
Args:
|
|
613
|
+
library_name: Name of the library to update
|
|
614
|
+
overwrite_existing: If True, discard any uncommitted local changes. If False, fail if uncommitted changes exist (default: False)
|
|
615
|
+
|
|
616
|
+
Results: UpdateLibraryResultSuccess (with version info) | UpdateLibraryResultFailure (library not found, git error, update failure)
|
|
617
|
+
"""
|
|
618
|
+
|
|
619
|
+
library_name: str
|
|
620
|
+
overwrite_existing: bool = False
|
|
621
|
+
|
|
622
|
+
|
|
623
|
+
@dataclass
|
|
624
|
+
@PayloadRegistry.register
|
|
625
|
+
class UpdateLibraryResultSuccess(WorkflowAlteredMixin, ResultPayloadSuccess):
|
|
626
|
+
"""Library updated successfully.
|
|
627
|
+
|
|
628
|
+
Args:
|
|
629
|
+
old_version: The previous library version
|
|
630
|
+
new_version: The new library version after update
|
|
631
|
+
"""
|
|
632
|
+
|
|
633
|
+
old_version: str
|
|
634
|
+
new_version: str
|
|
635
|
+
|
|
636
|
+
|
|
637
|
+
@dataclass
|
|
638
|
+
@PayloadRegistry.register
|
|
639
|
+
class UpdateLibraryResultFailure(ResultPayloadFailure):
|
|
640
|
+
"""Library update failed. Common causes: library not found, not a git repository, git pull error, uncommitted changes.
|
|
641
|
+
|
|
642
|
+
Args:
|
|
643
|
+
retryable: If True, the operation can be retried with overwrite_existing=True
|
|
644
|
+
"""
|
|
645
|
+
|
|
646
|
+
retryable: bool = False
|
|
647
|
+
|
|
648
|
+
|
|
649
|
+
@dataclass
|
|
650
|
+
@PayloadRegistry.register
|
|
651
|
+
class SwitchLibraryRefRequest(RequestPayload):
|
|
652
|
+
"""Switch a library to a different git branch or tag.
|
|
653
|
+
|
|
654
|
+
Supports switching to both branches and tags (e.g., 'main', 'develop', 'latest', 'v1.0.0').
|
|
655
|
+
|
|
656
|
+
Use when: Switching between branches for development, testing different versions,
|
|
657
|
+
reverting to stable branches, checking out feature branches, or switching to specific tags.
|
|
658
|
+
|
|
659
|
+
Args:
|
|
660
|
+
library_name: Name of the library to switch
|
|
661
|
+
ref_name: Name of the branch or tag to switch to
|
|
662
|
+
|
|
663
|
+
Results: SwitchLibraryRefResultSuccess (with ref/version info) | SwitchLibraryRefResultFailure (library not found, git error, ref not found)
|
|
664
|
+
"""
|
|
665
|
+
|
|
666
|
+
library_name: str
|
|
667
|
+
ref_name: str
|
|
668
|
+
|
|
669
|
+
|
|
670
|
+
@dataclass
|
|
671
|
+
@PayloadRegistry.register
|
|
672
|
+
class SwitchLibraryRefResultSuccess(WorkflowAlteredMixin, ResultPayloadSuccess):
|
|
673
|
+
"""Library branch or tag switched successfully.
|
|
674
|
+
|
|
675
|
+
Args:
|
|
676
|
+
old_ref: The previous branch or tag name
|
|
677
|
+
new_ref: The new branch or tag name after switch
|
|
678
|
+
old_version: The previous library version
|
|
679
|
+
new_version: The new library version after switch
|
|
680
|
+
"""
|
|
681
|
+
|
|
682
|
+
old_ref: str
|
|
683
|
+
new_ref: str
|
|
684
|
+
old_version: str
|
|
685
|
+
new_version: str
|
|
686
|
+
|
|
687
|
+
|
|
688
|
+
@dataclass
|
|
689
|
+
@PayloadRegistry.register
|
|
690
|
+
class SwitchLibraryRefResultFailure(ResultPayloadFailure):
|
|
691
|
+
"""Library ref switch failed. Common causes: library not found, not a git repository, ref not found, git checkout error."""
|
|
692
|
+
|
|
693
|
+
|
|
694
|
+
@dataclass
|
|
695
|
+
@PayloadRegistry.register
|
|
696
|
+
class DownloadLibraryRequest(RequestPayload):
|
|
697
|
+
"""Download a library from a git repository.
|
|
698
|
+
|
|
699
|
+
Use when: Installing new libraries from git repositories, downloading third-party libraries,
|
|
700
|
+
setting up development libraries, adding community libraries.
|
|
701
|
+
|
|
702
|
+
Args:
|
|
703
|
+
git_url: The git repository URL to clone
|
|
704
|
+
branch_tag_commit: Optional branch, tag, or commit to checkout (defaults to default branch)
|
|
705
|
+
target_directory_name: Optional name for the target directory (defaults to repository name)
|
|
706
|
+
download_directory: Optional parent directory path for download (defaults to workspace/libraries)
|
|
707
|
+
overwrite_existing: If True, delete existing directory before cloning (default: False)
|
|
708
|
+
auto_register: If True, automatically register library after download (default: True)
|
|
709
|
+
fail_on_exists: If True, fail with retryable error when directory exists and overwrite_existing=False.
|
|
710
|
+
If False, skip clone and register existing library (idempotent). (default: True)
|
|
711
|
+
|
|
712
|
+
Results: DownloadLibraryResultSuccess (with library info) | DownloadLibraryResultFailure (clone error, directory exists)
|
|
713
|
+
"""
|
|
714
|
+
|
|
715
|
+
git_url: str
|
|
716
|
+
branch_tag_commit: str | None = None
|
|
717
|
+
target_directory_name: str | None = None
|
|
718
|
+
download_directory: str | None = None
|
|
719
|
+
overwrite_existing: bool = False
|
|
720
|
+
auto_register: bool = True
|
|
721
|
+
fail_on_exists: bool = True
|
|
722
|
+
|
|
723
|
+
|
|
724
|
+
@dataclass
|
|
725
|
+
@PayloadRegistry.register
|
|
726
|
+
class DownloadLibraryResultSuccess(WorkflowAlteredMixin, ResultPayloadSuccess):
|
|
727
|
+
"""Library downloaded successfully.
|
|
728
|
+
|
|
729
|
+
Args:
|
|
730
|
+
library_name: Name of the library extracted from griptape_nodes_library.json
|
|
731
|
+
library_path: Full path where the library was downloaded
|
|
732
|
+
"""
|
|
733
|
+
|
|
734
|
+
library_name: str
|
|
735
|
+
library_path: str
|
|
736
|
+
|
|
737
|
+
|
|
738
|
+
@dataclass
|
|
739
|
+
@PayloadRegistry.register
|
|
740
|
+
class DownloadLibraryResultFailure(ResultPayloadFailure):
|
|
741
|
+
"""Library download failed. Common causes: invalid git URL, network error, target directory already exists, no griptape_nodes_library.json found.
|
|
742
|
+
|
|
743
|
+
Args:
|
|
744
|
+
retryable: If True, the operation can be retried with overwrite_existing=True
|
|
745
|
+
"""
|
|
746
|
+
|
|
747
|
+
retryable: bool = False
|
|
748
|
+
|
|
749
|
+
|
|
750
|
+
@dataclass
|
|
751
|
+
@PayloadRegistry.register
|
|
752
|
+
class InstallLibraryDependenciesRequest(RequestPayload):
|
|
753
|
+
"""Install dependencies for a library.
|
|
754
|
+
|
|
755
|
+
Use when: Installing or reinstalling dependencies for a library,
|
|
756
|
+
setting up a library's environment, updating dependencies after changes.
|
|
757
|
+
|
|
758
|
+
This operation:
|
|
759
|
+
1. Loads library metadata from the file
|
|
760
|
+
2. Gets library dependencies from metadata
|
|
761
|
+
3. Initializes the library's virtual environment
|
|
762
|
+
4. Installs pip dependencies specified in the library metadata
|
|
763
|
+
5. Always installs dependencies without version checks
|
|
764
|
+
|
|
765
|
+
Args:
|
|
766
|
+
library_file_path: Path to the library JSON file
|
|
767
|
+
|
|
768
|
+
Results: InstallLibraryDependenciesResultSuccess | InstallLibraryDependenciesResultFailure
|
|
769
|
+
"""
|
|
770
|
+
|
|
771
|
+
library_file_path: str
|
|
772
|
+
|
|
773
|
+
|
|
774
|
+
@dataclass
|
|
775
|
+
@PayloadRegistry.register
|
|
776
|
+
class InstallLibraryDependenciesResultSuccess(ResultPayloadSuccess):
|
|
777
|
+
"""Library dependencies installed successfully.
|
|
778
|
+
|
|
779
|
+
Args:
|
|
780
|
+
library_name: Name of the library whose dependencies were installed
|
|
781
|
+
dependencies_installed: Number of dependencies that were installed
|
|
782
|
+
"""
|
|
783
|
+
|
|
784
|
+
library_name: str
|
|
785
|
+
dependencies_installed: int
|
|
786
|
+
|
|
787
|
+
|
|
788
|
+
@dataclass
|
|
789
|
+
@PayloadRegistry.register
|
|
790
|
+
class InstallLibraryDependenciesResultFailure(ResultPayloadFailure):
|
|
791
|
+
"""Library dependency installation failed. Common causes: library not found, no dependencies defined, venv initialization failed, pip install error."""
|
|
792
|
+
|
|
793
|
+
|
|
794
|
+
@dataclass
|
|
795
|
+
@PayloadRegistry.register
|
|
796
|
+
class SyncLibrariesRequest(RequestPayload):
|
|
797
|
+
"""Sync all libraries to latest versions and ensure dependencies are installed.
|
|
798
|
+
|
|
799
|
+
Similar to `uv sync` - ensures workspace is in a consistent, up-to-date state.
|
|
800
|
+
This operation:
|
|
801
|
+
1. Downloads missing libraries from git URLs specified in config
|
|
802
|
+
2. Gets all registered libraries (including newly downloaded)
|
|
803
|
+
3. Checks each library for available updates
|
|
804
|
+
4. Updates libraries that have updates available
|
|
805
|
+
5. Installs/updates dependencies for all libraries
|
|
806
|
+
6. Returns comprehensive summary of changes
|
|
807
|
+
|
|
808
|
+
Use when: Updating workspace to latest versions, ensuring all libraries are
|
|
809
|
+
up-to-date, setting up development environment, periodic maintenance.
|
|
810
|
+
|
|
811
|
+
Args:
|
|
812
|
+
overwrite_existing: If True, discard any uncommitted local changes when updating libraries. If False, fail if uncommitted changes exist (default: False)
|
|
813
|
+
|
|
814
|
+
Results: SyncLibrariesResultSuccess (with summary) | SyncLibrariesResultFailure (sync errors)
|
|
815
|
+
"""
|
|
816
|
+
|
|
817
|
+
overwrite_existing: bool = False
|
|
818
|
+
|
|
819
|
+
|
|
820
|
+
@dataclass
|
|
821
|
+
@PayloadRegistry.register
|
|
822
|
+
class SyncLibrariesResultSuccess(WorkflowAlteredMixin, ResultPayloadSuccess):
|
|
823
|
+
"""Libraries synced successfully.
|
|
824
|
+
|
|
825
|
+
Args:
|
|
826
|
+
libraries_downloaded: Number of libraries that were downloaded from git URLs
|
|
827
|
+
libraries_checked: Number of libraries checked for updates
|
|
828
|
+
libraries_updated: Number of libraries that were updated
|
|
829
|
+
update_summary: Dict mapping library names to their update info (old_version -> new_version, or status for downloads)
|
|
830
|
+
"""
|
|
831
|
+
|
|
832
|
+
libraries_downloaded: int
|
|
833
|
+
libraries_checked: int
|
|
834
|
+
libraries_updated: int
|
|
835
|
+
update_summary: dict[str, dict[str, str]]
|
|
836
|
+
|
|
837
|
+
|
|
838
|
+
@dataclass
|
|
839
|
+
@PayloadRegistry.register
|
|
840
|
+
class SyncLibrariesResultFailure(ResultPayloadFailure):
|
|
841
|
+
"""Library sync failed. Common causes: git errors, network errors, dependency installation failures."""
|
|
842
|
+
|
|
843
|
+
|
|
844
|
+
@dataclass
|
|
845
|
+
@PayloadRegistry.register
|
|
846
|
+
class InspectLibraryRepoRequest(RequestPayload):
|
|
847
|
+
"""Inspect a library's metadata from a git repository without downloading the full repository.
|
|
848
|
+
|
|
849
|
+
Performs a sparse checkout to fetch only the library JSON file, which is efficient for
|
|
850
|
+
previewing library information, checking compatibility, or validating git URLs before
|
|
851
|
+
full download.
|
|
852
|
+
|
|
853
|
+
Use when: Previewing library details, displaying library information in UI,
|
|
854
|
+
validating library compatibility, checking library versions remotely.
|
|
855
|
+
|
|
856
|
+
Args:
|
|
857
|
+
git_url: Git repository URL (supports GitHub shorthand like "user/repo")
|
|
858
|
+
ref: Branch, tag, or commit to inspect (defaults to "HEAD")
|
|
859
|
+
|
|
860
|
+
Results: InspectLibraryRepoResultSuccess (with library metadata) | InspectLibraryRepoResultFailure (invalid URL, network error, no library JSON found)
|
|
861
|
+
"""
|
|
862
|
+
|
|
863
|
+
git_url: str
|
|
864
|
+
ref: str = "HEAD"
|
|
865
|
+
|
|
866
|
+
|
|
867
|
+
@dataclass
|
|
868
|
+
@PayloadRegistry.register
|
|
869
|
+
class InspectLibraryRepoResultSuccess(WorkflowNotAlteredMixin, ResultPayloadSuccess):
|
|
870
|
+
"""Library repository inspection completed successfully.
|
|
871
|
+
|
|
872
|
+
Args:
|
|
873
|
+
library_schema: Complete library schema with all metadata (name, version, nodes, categories, dependencies, settings, etc.)
|
|
874
|
+
commit_sha: Git commit SHA that was inspected
|
|
875
|
+
git_url: Git URL that was inspected (normalized)
|
|
876
|
+
ref: Git reference that was inspected
|
|
877
|
+
"""
|
|
878
|
+
|
|
879
|
+
library_schema: LibrarySchema
|
|
880
|
+
commit_sha: str
|
|
881
|
+
git_url: str
|
|
882
|
+
ref: str
|
|
883
|
+
|
|
884
|
+
|
|
885
|
+
@dataclass
|
|
886
|
+
@PayloadRegistry.register
|
|
887
|
+
class InspectLibraryRepoResultFailure(WorkflowNotAlteredMixin, ResultPayloadFailure):
|
|
888
|
+
"""Library repository inspection failed. Common causes: invalid git URL, network error, no library JSON found, invalid JSON format."""
|
|
@@ -1060,3 +1060,51 @@ class DeleteNodeGroupResultFailure(ResultPayloadFailure):
|
|
|
1060
1060
|
|
|
1061
1061
|
Common causes: NodeGroup not found, deletion cleanup failed, node is not a NodeGroup.
|
|
1062
1062
|
"""
|
|
1063
|
+
|
|
1064
|
+
|
|
1065
|
+
@dataclass
|
|
1066
|
+
@PayloadRegistry.register
|
|
1067
|
+
class MoveNodeToNewFlowRequest(RequestPayload):
|
|
1068
|
+
"""Move a node from one flow to another flow.
|
|
1069
|
+
|
|
1070
|
+
Use when: Reorganizing nodes between flows, adding nodes to NodeGroup subflows,
|
|
1071
|
+
removing nodes from NodeGroup subflows. Node connections are preserved since
|
|
1072
|
+
connections are global and work across flows.
|
|
1073
|
+
|
|
1074
|
+
Args:
|
|
1075
|
+
node_name: Name of the node to move (None for current context)
|
|
1076
|
+
target_flow_name: Name of the destination flow
|
|
1077
|
+
source_flow_name: Name of the source flow (None to use node's current flow)
|
|
1078
|
+
|
|
1079
|
+
Results: MoveNodeToNewFlowResultSuccess | MoveNodeToNewFlowResultFailure (node not found, flow not found, node not in source flow)
|
|
1080
|
+
"""
|
|
1081
|
+
|
|
1082
|
+
target_flow_name: str
|
|
1083
|
+
node_name: str | None = None
|
|
1084
|
+
source_flow_name: str | None = None
|
|
1085
|
+
|
|
1086
|
+
|
|
1087
|
+
@dataclass
|
|
1088
|
+
@PayloadRegistry.register
|
|
1089
|
+
class MoveNodeToNewFlowResultSuccess(WorkflowAlteredMixin, ResultPayloadSuccess):
|
|
1090
|
+
"""Node moved successfully between flows. Connections preserved.
|
|
1091
|
+
|
|
1092
|
+
Args:
|
|
1093
|
+
node_name: Name of the node that was moved
|
|
1094
|
+
source_flow_name: Name of the flow the node was moved from
|
|
1095
|
+
target_flow_name: Name of the flow the node was moved to
|
|
1096
|
+
"""
|
|
1097
|
+
|
|
1098
|
+
node_name: str
|
|
1099
|
+
source_flow_name: str
|
|
1100
|
+
target_flow_name: str
|
|
1101
|
+
|
|
1102
|
+
|
|
1103
|
+
@dataclass
|
|
1104
|
+
@PayloadRegistry.register
|
|
1105
|
+
class MoveNodeToNewFlowResultFailure(ResultPayloadFailure):
|
|
1106
|
+
"""Node move failed.
|
|
1107
|
+
|
|
1108
|
+
Common causes: node not found, source flow not found, target flow not found,
|
|
1109
|
+
node not in source flow, node is a NodeGroup with subflow conflicts.
|
|
1110
|
+
"""
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
from dataclasses import dataclass
|
|
2
4
|
from enum import StrEnum
|
|
5
|
+
from typing import TYPE_CHECKING
|
|
3
6
|
|
|
4
7
|
from griptape_nodes.retained_mode.events.base_events import (
|
|
5
8
|
RequestPayload,
|
|
@@ -9,6 +12,9 @@ from griptape_nodes.retained_mode.events.base_events import (
|
|
|
9
12
|
)
|
|
10
13
|
from griptape_nodes.retained_mode.events.payload_registry import PayloadRegistry
|
|
11
14
|
|
|
15
|
+
if TYPE_CHECKING:
|
|
16
|
+
from griptape_nodes.retained_mode.events.project_events import MacroPath
|
|
17
|
+
|
|
12
18
|
|
|
13
19
|
class ExistingFilePolicy(StrEnum):
|
|
14
20
|
"""Policy for handling existing files during write operations."""
|
|
@@ -31,6 +37,7 @@ class FileIOFailureReason(StrEnum):
|
|
|
31
37
|
# Permission/access errors
|
|
32
38
|
PERMISSION_DENIED = "permission_denied" # No read/write permission
|
|
33
39
|
FILE_NOT_FOUND = "file_not_found" # File doesn't exist (read operations)
|
|
40
|
+
FILE_LOCKED = "file_locked" # File is locked by another process
|
|
34
41
|
|
|
35
42
|
# Resource errors
|
|
36
43
|
DISK_FULL = "disk_full" # Insufficient disk space
|
|
@@ -38,6 +45,7 @@ class FileIOFailureReason(StrEnum):
|
|
|
38
45
|
# Path errors
|
|
39
46
|
INVALID_PATH = "invalid_path" # Malformed or invalid path
|
|
40
47
|
IS_DIRECTORY = "is_directory" # Path is a directory, not a file
|
|
48
|
+
MISSING_MACRO_VARIABLES = "missing_macro_variables" # MacroPath has unresolved required variables
|
|
41
49
|
|
|
42
50
|
# Content errors
|
|
43
51
|
ENCODING_ERROR = "encoding_error" # Text encoding/decoding failed
|
|
@@ -162,6 +170,8 @@ class ReadFileRequest(RequestPayload):
|
|
|
162
170
|
workspace_only: If True, constrain to workspace directory. If False, allow system-wide access.
|
|
163
171
|
If None, workspace constraints don't apply (e.g., cloud environments).
|
|
164
172
|
TODO: Remove workspace_only parameter - see https://github.com/griptape-ai/griptape-nodes/issues/2753
|
|
173
|
+
should_transform_image_content_to_thumbnail: If True, convert image files to thumbnail data URLs.
|
|
174
|
+
If False, return raw image bytes. Default True for backwards compatibility.
|
|
165
175
|
|
|
166
176
|
Results: ReadFileResultSuccess (with content) | ReadFileResultFailure (file not found, permission denied)
|
|
167
177
|
"""
|
|
@@ -170,6 +180,7 @@ class ReadFileRequest(RequestPayload):
|
|
|
170
180
|
file_entry: FileSystemEntry | None = None
|
|
171
181
|
encoding: str = "utf-8"
|
|
172
182
|
workspace_only: bool | None = True # TODO: Remove - see https://github.com/griptape-ai/griptape-nodes/issues/2753
|
|
183
|
+
should_transform_image_content_to_thumbnail: bool = True
|
|
173
184
|
|
|
174
185
|
|
|
175
186
|
@dataclass
|
|
@@ -310,6 +321,76 @@ class RenameFileResultFailure(WorkflowNotAlteredMixin, ResultPayloadFailure):
|
|
|
310
321
|
failure_reason: FileIOFailureReason
|
|
311
322
|
|
|
312
323
|
|
|
324
|
+
@dataclass
|
|
325
|
+
@PayloadRegistry.register
|
|
326
|
+
class GetNextUnusedFilenameRequest(RequestPayload):
|
|
327
|
+
"""Find the next available filename with auto-incrementing index (preview only - no file creation).
|
|
328
|
+
|
|
329
|
+
Use when: Finding available filenames without file collision before actual write operations.
|
|
330
|
+
|
|
331
|
+
This request scans the filesystem and returns the next available filename.
|
|
332
|
+
This is a preview operation that DOES NOT create any files or acquire any locks.
|
|
333
|
+
|
|
334
|
+
Args:
|
|
335
|
+
file_path: Path to the file (str for direct path, MacroPath for macro resolution)
|
|
336
|
+
|
|
337
|
+
Results: GetNextUnusedFilenameResultSuccess | GetNextUnusedFilenameResultFailure
|
|
338
|
+
|
|
339
|
+
Examples:
|
|
340
|
+
# Simple string path - cleanest for most use cases
|
|
341
|
+
file_path = "/outputs/render.png"
|
|
342
|
+
# Returns: "/outputs/render.png" if available
|
|
343
|
+
# "/outputs/render_1.png" if render.png exists
|
|
344
|
+
# "/outputs/render_2.png" if render_1.png exists, etc.
|
|
345
|
+
|
|
346
|
+
# MacroPath with required {_index} and padding
|
|
347
|
+
file_path = MacroPath(
|
|
348
|
+
parsed_macro=ParsedMacro("{outputs}/frame_{_index:05}.png"),
|
|
349
|
+
variables={"outputs": "/abs/path"}
|
|
350
|
+
)
|
|
351
|
+
# Returns: "/abs/path/frame_00001.png", "/abs/path/frame_00002.png", etc.
|
|
352
|
+
# Note: Always includes index, cannot return "frame.png"
|
|
353
|
+
|
|
354
|
+
# MacroPath with optional {_index} - limited by separator position
|
|
355
|
+
file_path = MacroPath(
|
|
356
|
+
parsed_macro=ParsedMacro("{outputs}/frame{_index?:_}.png"),
|
|
357
|
+
variables={"outputs": "/abs/path"}
|
|
358
|
+
)
|
|
359
|
+
# Returns: "/abs/path/frame.png" if {_index} omitted
|
|
360
|
+
# "/abs/path/frame1_.png" if {_index}=1 (separator goes after value)
|
|
361
|
+
# Note: Cannot achieve "frame.png" → "frame_1.png" with optional variable
|
|
362
|
+
"""
|
|
363
|
+
|
|
364
|
+
file_path: str | MacroPath
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
@dataclass
|
|
368
|
+
@PayloadRegistry.register
|
|
369
|
+
class GetNextUnusedFilenameResultSuccess(WorkflowNotAlteredMixin, ResultPayloadSuccess):
|
|
370
|
+
"""Next unused filename found (preview only - no file created).
|
|
371
|
+
|
|
372
|
+
Attributes:
|
|
373
|
+
available_filename: Absolute path to the available filename
|
|
374
|
+
index_used: The index number that was used (e.g., 1, 2, 3...), or None if base filename is available
|
|
375
|
+
"""
|
|
376
|
+
|
|
377
|
+
available_filename: str
|
|
378
|
+
index_used: int | None
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
@dataclass
|
|
382
|
+
@PayloadRegistry.register
|
|
383
|
+
class GetNextUnusedFilenameResultFailure(WorkflowNotAlteredMixin, ResultPayloadFailure):
|
|
384
|
+
"""Failed to find available filename.
|
|
385
|
+
|
|
386
|
+
Attributes:
|
|
387
|
+
failure_reason: Classification of why the operation failed
|
|
388
|
+
result_details: Human-readable error message (inherited from ResultPayloadFailure)
|
|
389
|
+
"""
|
|
390
|
+
|
|
391
|
+
failure_reason: FileIOFailureReason
|
|
392
|
+
|
|
393
|
+
|
|
313
394
|
@dataclass
|
|
314
395
|
@PayloadRegistry.register
|
|
315
396
|
class WriteFileRequest(RequestPayload):
|
|
@@ -321,14 +402,14 @@ class WriteFileRequest(RequestPayload):
|
|
|
321
402
|
creating configuration files, writing binary data.
|
|
322
403
|
|
|
323
404
|
Args:
|
|
324
|
-
file_path: Path to the file to write
|
|
405
|
+
file_path: Path to the file to write (str for direct path, MacroPath for macro resolution)
|
|
325
406
|
content: Content to write (str for text files, bytes for binary files)
|
|
326
407
|
encoding: Text encoding for str content (default: 'utf-8', ignored for bytes)
|
|
327
408
|
append: If True, append to existing file; if False, use existing_file_policy (default: False)
|
|
328
409
|
existing_file_policy: How to handle existing files when append=False:
|
|
329
410
|
- "overwrite": Replace file content (default)
|
|
330
411
|
- "fail": Return failure if file exists
|
|
331
|
-
- "create_new": Create new file with
|
|
412
|
+
- "create_new": Create new file with auto-incrementing index (e.g., file_1.txt, file_2.txt)
|
|
332
413
|
create_parents: If True, create parent directories if missing (default: True)
|
|
333
414
|
|
|
334
415
|
Results: WriteFileResultSuccess | WriteFileResultFailure
|
|
@@ -336,7 +417,7 @@ class WriteFileRequest(RequestPayload):
|
|
|
336
417
|
Note: existing_file_policy is ignored when append=True (append always allows existing files)
|
|
337
418
|
"""
|
|
338
419
|
|
|
339
|
-
file_path: str
|
|
420
|
+
file_path: str | MacroPath
|
|
340
421
|
content: str | bytes
|
|
341
422
|
encoding: str = "utf-8" # Ignored for bytes
|
|
342
423
|
append: bool = False
|
|
@@ -366,10 +447,12 @@ class WriteFileResultFailure(WorkflowNotAlteredMixin, ResultPayloadFailure):
|
|
|
366
447
|
|
|
367
448
|
Attributes:
|
|
368
449
|
failure_reason: Classification of why the write failed
|
|
450
|
+
missing_variables: Set of missing variable names (for MISSING_MACRO_VARIABLES failures)
|
|
369
451
|
result_details: Human-readable error message (inherited from ResultPayloadFailure)
|
|
370
452
|
"""
|
|
371
453
|
|
|
372
454
|
failure_reason: FileIOFailureReason
|
|
455
|
+
missing_variables: set[str] | None = None
|
|
373
456
|
|
|
374
457
|
|
|
375
458
|
@dataclass
|
|
@@ -4,7 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
from dataclasses import dataclass
|
|
6
6
|
from enum import StrEnum
|
|
7
|
-
from typing import TYPE_CHECKING, Any
|
|
7
|
+
from typing import TYPE_CHECKING, Any, NamedTuple
|
|
8
8
|
|
|
9
9
|
from griptape_nodes.retained_mode.events.base_events import (
|
|
10
10
|
RequestPayload,
|
|
@@ -25,6 +25,20 @@ if TYPE_CHECKING:
|
|
|
25
25
|
MacroVariables = dict[str, str | int]
|
|
26
26
|
|
|
27
27
|
|
|
28
|
+
class MacroPath(NamedTuple):
|
|
29
|
+
"""A macro path with its parsed template and variable values.
|
|
30
|
+
|
|
31
|
+
Used when file paths need macro resolution before filesystem operations.
|
|
32
|
+
|
|
33
|
+
Attributes:
|
|
34
|
+
parsed_macro: The parsed macro template
|
|
35
|
+
variables: Variable values for macro substitution
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
parsed_macro: ParsedMacro
|
|
39
|
+
variables: MacroVariables
|
|
40
|
+
|
|
41
|
+
|
|
28
42
|
class PathResolutionFailureReason(StrEnum):
|
|
29
43
|
"""Reason why path resolution from macro failed."""
|
|
30
44
|
|
|
@@ -632,6 +632,49 @@ class MoveWorkflowResultFailure(ResultPayloadFailure):
|
|
|
632
632
|
"""Workflow move failed. Common causes: workflow not found, invalid target directory, file system error."""
|
|
633
633
|
|
|
634
634
|
|
|
635
|
+
@dataclass
|
|
636
|
+
@PayloadRegistry.register
|
|
637
|
+
class GetWorkflowMetadataRequest(RequestPayload):
|
|
638
|
+
"""Get selected metadata for a workflow by name from the registry."""
|
|
639
|
+
|
|
640
|
+
workflow_name: str
|
|
641
|
+
|
|
642
|
+
|
|
643
|
+
@dataclass
|
|
644
|
+
@PayloadRegistry.register
|
|
645
|
+
class GetWorkflowMetadataResultSuccess(WorkflowNotAlteredMixin, ResultPayloadSuccess):
|
|
646
|
+
"""Workflow metadata retrieved successfully."""
|
|
647
|
+
|
|
648
|
+
workflow_metadata: WorkflowMetadata
|
|
649
|
+
|
|
650
|
+
|
|
651
|
+
@dataclass
|
|
652
|
+
@PayloadRegistry.register
|
|
653
|
+
class GetWorkflowMetadataResultFailure(WorkflowNotAlteredMixin, ResultPayloadFailure):
|
|
654
|
+
"""Workflow metadata retrieval failed. Common causes: workflow not found, registry error, file load error."""
|
|
655
|
+
|
|
656
|
+
|
|
657
|
+
@dataclass
|
|
658
|
+
@PayloadRegistry.register
|
|
659
|
+
class SetWorkflowMetadataRequest(RequestPayload):
|
|
660
|
+
"""Replace the workflow's metadata entirely and persist to file."""
|
|
661
|
+
|
|
662
|
+
workflow_name: str
|
|
663
|
+
workflow_metadata: WorkflowMetadata
|
|
664
|
+
|
|
665
|
+
|
|
666
|
+
@dataclass
|
|
667
|
+
@PayloadRegistry.register
|
|
668
|
+
class SetWorkflowMetadataResultSuccess(WorkflowAlteredMixin, ResultPayloadSuccess):
|
|
669
|
+
"""Workflow metadata updated successfully."""
|
|
670
|
+
|
|
671
|
+
|
|
672
|
+
@dataclass
|
|
673
|
+
@PayloadRegistry.register
|
|
674
|
+
class SetWorkflowMetadataResultFailure(ResultPayloadFailure):
|
|
675
|
+
"""Workflow metadata update failed. Common causes: workflow not found, invalid keys/types, file system error."""
|
|
676
|
+
|
|
677
|
+
|
|
635
678
|
@dataclass
|
|
636
679
|
@PayloadRegistry.register
|
|
637
680
|
class RegisterWorkflowsFromConfigRequest(RequestPayload):
|
|
@@ -681,7 +724,9 @@ class SaveWorkflowFileFromSerializedFlowRequest(RequestPayload):
|
|
|
681
724
|
serialized_flow_commands: The serialized commands representing the workflow structure
|
|
682
725
|
file_name: Name for the workflow file (without .py extension)
|
|
683
726
|
creation_date: Optional creation date for the workflow metadata (defaults to current time if not provided)
|
|
684
|
-
image_path: Optional path to workflow image/thumbnail
|
|
727
|
+
image_path: Optional path to workflow image/thumbnail. If None, callers may preserve existing image.
|
|
728
|
+
description: Optional workflow description text. If None, callers may preserve existing description.
|
|
729
|
+
is_template: Optional template status flag. If None, callers may preserve existing template status.
|
|
685
730
|
execution_flow_name: Optional flow name to use for execution code (defaults to file_name if not provided)
|
|
686
731
|
branched_from: Optional branched from information to preserve workflow lineage
|
|
687
732
|
workflow_shape: Optional workflow shape defining inputs and outputs for external callers
|
|
@@ -696,6 +741,8 @@ class SaveWorkflowFileFromSerializedFlowRequest(RequestPayload):
|
|
|
696
741
|
file_path: str | None = None
|
|
697
742
|
creation_date: datetime | None = None
|
|
698
743
|
image_path: str | None = None
|
|
744
|
+
description: str | None = None
|
|
745
|
+
is_template: bool | None = None
|
|
699
746
|
execution_flow_name: str | None = None
|
|
700
747
|
branched_from: str | None = None
|
|
701
748
|
workflow_shape: WorkflowShape | None = None
|