griptape-nodes 0.55.1__py3-none-any.whl → 0.56.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 (35) hide show
  1. griptape_nodes/cli/commands/init.py +88 -0
  2. griptape_nodes/cli/commands/models.py +2 -0
  3. griptape_nodes/cli/shared.py +1 -0
  4. griptape_nodes/exe_types/core_types.py +104 -0
  5. griptape_nodes/exe_types/node_types.py +9 -12
  6. griptape_nodes/machines/control_flow.py +10 -0
  7. griptape_nodes/machines/dag_builder.py +21 -2
  8. griptape_nodes/machines/parallel_resolution.py +25 -10
  9. griptape_nodes/node_library/workflow_registry.py +73 -3
  10. griptape_nodes/retained_mode/events/execution_events.py +12 -2
  11. griptape_nodes/retained_mode/events/flow_events.py +58 -0
  12. griptape_nodes/retained_mode/events/resource_events.py +290 -0
  13. griptape_nodes/retained_mode/events/workflow_events.py +57 -2
  14. griptape_nodes/retained_mode/griptape_nodes.py +9 -1
  15. griptape_nodes/retained_mode/managers/flow_manager.py +678 -12
  16. griptape_nodes/retained_mode/managers/library_manager.py +13 -19
  17. griptape_nodes/retained_mode/managers/model_manager.py +184 -83
  18. griptape_nodes/retained_mode/managers/node_manager.py +3 -3
  19. griptape_nodes/retained_mode/managers/os_manager.py +118 -1
  20. griptape_nodes/retained_mode/managers/resource_components/__init__.py +1 -0
  21. griptape_nodes/retained_mode/managers/resource_components/capability_field.py +41 -0
  22. griptape_nodes/retained_mode/managers/resource_components/comparator.py +18 -0
  23. griptape_nodes/retained_mode/managers/resource_components/resource_instance.py +236 -0
  24. griptape_nodes/retained_mode/managers/resource_components/resource_type.py +79 -0
  25. griptape_nodes/retained_mode/managers/resource_manager.py +306 -0
  26. griptape_nodes/retained_mode/managers/resource_types/__init__.py +1 -0
  27. griptape_nodes/retained_mode/managers/resource_types/cpu_resource.py +108 -0
  28. griptape_nodes/retained_mode/managers/resource_types/os_resource.py +87 -0
  29. griptape_nodes/retained_mode/managers/settings.py +5 -0
  30. griptape_nodes/retained_mode/managers/sync_manager.py +10 -3
  31. griptape_nodes/retained_mode/managers/workflow_manager.py +359 -261
  32. {griptape_nodes-0.55.1.dist-info → griptape_nodes-0.56.0.dist-info}/METADATA +1 -1
  33. {griptape_nodes-0.55.1.dist-info → griptape_nodes-0.56.0.dist-info}/RECORD +35 -25
  34. {griptape_nodes-0.55.1.dist-info → griptape_nodes-0.56.0.dist-info}/WHEEL +1 -1
  35. {griptape_nodes-0.55.1.dist-info → griptape_nodes-0.56.0.dist-info}/entry_points.txt +0 -0
@@ -2,6 +2,7 @@ from dataclasses import dataclass
2
2
  from typing import Any
3
3
 
4
4
  from griptape_nodes.node_library.library_registry import LibraryNameAndVersion
5
+ from griptape_nodes.node_library.workflow_registry import WorkflowShape
5
6
  from griptape_nodes.retained_mode.events.base_events import (
6
7
  RequestPayload,
7
8
  ResultPayloadFailure,
@@ -382,3 +383,60 @@ class SetFlowMetadataResultSuccess(WorkflowAlteredMixin, ResultPayloadSuccess):
382
383
  @PayloadRegistry.register
383
384
  class SetFlowMetadataResultFailure(WorkflowNotAlteredMixin, ResultPayloadFailure):
384
385
  """Flow metadata update failed. Common causes: flow not found, no current context, invalid metadata."""
386
+
387
+
388
+ @dataclass
389
+ @PayloadRegistry.register
390
+ class PackageNodeAsSerializedFlowRequest(RequestPayload):
391
+ """Package a single node as a complete flow with artificial start and end nodes.
392
+
393
+ Creates a serialized flow where:
394
+ - Start node has output parameters matching the packaged node's incoming connections
395
+ - End node has input parameters matching the packaged node's outgoing connections
396
+ - All connections are properly mapped through Start -> Node -> End
397
+
398
+ Use when: Creating reusable components, exporting nodes for templates,
399
+ building sub-workflows from existing nodes, creating packaged functionality.
400
+
401
+ Args:
402
+ node_name: Name of the node to package as a flow (None for current context node)
403
+ start_node_type: Node type name for the artificial start node (defaults to "StartFlow")
404
+ end_node_type: Node type name for the artificial end node (defaults to "EndFlow")
405
+ start_end_specific_library_name: Library name containing the start/end nodes (defaults to "Griptape Nodes Library")
406
+ entry_control_parameter_name: Name of the control parameter that the package node should be entered from. The generated start node will create a connection to this control parameter. NOTE: if no entry_control_parameter_name is specified, the package will be entered from the first available control input parameter.
407
+ output_parameter_prefix: Prefix for parameter names on the generated end node to avoid collisions (defaults to "packaged_node_")
408
+
409
+ Results: PackageNodeAsSerializedFlowResultSuccess (with serialized flow) | PackageNodeAsSerializedFlowResultFailure (node not found, packaging error)
410
+ """
411
+
412
+ # If None is passed, assumes we're packaging the node in the Current Context
413
+ node_name: str | None = None
414
+ start_node_type: str = "StartFlow"
415
+ end_node_type: str = "EndFlow"
416
+ start_end_specific_library_name: str = "Griptape Nodes Library"
417
+ entry_control_parameter_name: str | None = None
418
+ output_parameter_prefix: str = "packaged_node_"
419
+
420
+
421
+ @dataclass
422
+ @PayloadRegistry.register
423
+ class PackageNodeAsSerializedFlowResultSuccess(WorkflowNotAlteredMixin, ResultPayloadSuccess):
424
+ """Node successfully packaged as serialized flow.
425
+
426
+ Args:
427
+ serialized_flow_commands: The complete serialized flow with StartFlow, target node, and EndFlow
428
+ workflow_shape: The workflow shape defining inputs and outputs for external callers
429
+ """
430
+
431
+ serialized_flow_commands: SerializedFlowCommands
432
+ workflow_shape: WorkflowShape
433
+
434
+
435
+ @dataclass
436
+ @PayloadRegistry.register
437
+ class PackageNodeAsSerializedFlowResultFailure(WorkflowNotAlteredMixin, ResultPayloadFailure):
438
+ """Node packaging failed.
439
+
440
+ Common causes: node not found, no current context, serialization error,
441
+ connection analysis failed, node has no valid flow context.
442
+ """
@@ -0,0 +1,290 @@
1
+ from dataclasses import dataclass
2
+ from typing import TYPE_CHECKING, Any
3
+
4
+ from griptape_nodes.retained_mode.events.base_events import (
5
+ RequestPayload,
6
+ ResultPayloadFailure,
7
+ ResultPayloadSuccess,
8
+ WorkflowNotAlteredMixin,
9
+ )
10
+ from griptape_nodes.retained_mode.events.payload_registry import PayloadRegistry
11
+
12
+ if TYPE_CHECKING:
13
+ from griptape_nodes.retained_mode.managers.resource_components.resource_instance import Requirements
14
+ from griptape_nodes.retained_mode.managers.resource_components.resource_type import ResourceType
15
+ from griptape_nodes.retained_mode.managers.resource_manager import ResourceStatus
16
+
17
+
18
+ # List Registered Resource Types Events
19
+ @dataclass
20
+ @PayloadRegistry.register
21
+ class ListRegisteredResourceTypesRequest(RequestPayload):
22
+ """List all registered resource types.
23
+
24
+ Use when: Discovering what types of resources are available for allocation
25
+ and management.
26
+ """
27
+
28
+
29
+ @dataclass
30
+ @PayloadRegistry.register
31
+ class ListRegisteredResourceTypesResultSuccess(WorkflowNotAlteredMixin, ResultPayloadSuccess):
32
+ """Registered resource types listed successfully."""
33
+
34
+ resource_type_names: list[str]
35
+
36
+
37
+ @dataclass
38
+ @PayloadRegistry.register
39
+ class ListRegisteredResourceTypesResultFailure(WorkflowNotAlteredMixin, ResultPayloadFailure):
40
+ """Registered resource types listing failed."""
41
+
42
+
43
+ # Register Resource Type Events
44
+ @dataclass
45
+ @PayloadRegistry.register
46
+ class RegisterResourceTypeRequest(RequestPayload):
47
+ """Register a new resource type handler.
48
+
49
+ Use when: Adding support for a new type of resource (GPU, CPU, Pipeline, etc.)
50
+ that the ResourceManager should be able to allocate and manage.
51
+
52
+ Args:
53
+ resource_type: The ResourceType instance to register
54
+ """
55
+
56
+ resource_type: "ResourceType"
57
+
58
+
59
+ @dataclass
60
+ @PayloadRegistry.register
61
+ class RegisterResourceTypeResultSuccess(WorkflowNotAlteredMixin, ResultPayloadSuccess):
62
+ """Resource type registered successfully."""
63
+
64
+
65
+ @dataclass
66
+ @PayloadRegistry.register
67
+ class RegisterResourceTypeResultFailure(WorkflowNotAlteredMixin, ResultPayloadFailure):
68
+ """Resource type registration failed. Common causes: resource type already registered, invalid resource type."""
69
+
70
+
71
+ # Create Resource Instance Events
72
+ @dataclass
73
+ @PayloadRegistry.register
74
+ class CreateResourceInstanceRequest(RequestPayload):
75
+ """Create a new resource instance.
76
+
77
+ Use when: Creating a new instance of a resource that can be tracked, locked,
78
+ and managed by the ResourceManager.
79
+
80
+ Args:
81
+ resource_type_name: The name of the resource type to create an instance of
82
+ capabilities: Dict of capabilities for the new instance
83
+ """
84
+
85
+ resource_type_name: str
86
+ capabilities: dict[str, Any]
87
+
88
+
89
+ @dataclass
90
+ @PayloadRegistry.register
91
+ class CreateResourceInstanceResultSuccess(WorkflowNotAlteredMixin, ResultPayloadSuccess):
92
+ """Resource instance created successfully."""
93
+
94
+ instance_id: str
95
+
96
+
97
+ @dataclass
98
+ @PayloadRegistry.register
99
+ class CreateResourceInstanceResultFailure(WorkflowNotAlteredMixin, ResultPayloadFailure):
100
+ """Resource instance creation failed. Common causes: invalid capabilities, resource creation error."""
101
+
102
+
103
+ # Free Resource Instance Events
104
+ @dataclass
105
+ @PayloadRegistry.register
106
+ class FreeResourceInstanceRequest(RequestPayload):
107
+ """Free a resource instance.
108
+
109
+ Use when: Permanently removing a resource instance from tracking and freeing
110
+ its resources.
111
+
112
+ Args:
113
+ instance_id: The ID of the instance to free
114
+ force_unlock: If True, force unlock locked instances. If False, raise exception for locked instances.
115
+ """
116
+
117
+ instance_id: str
118
+ force_unlock: bool = False
119
+
120
+
121
+ @dataclass
122
+ @PayloadRegistry.register
123
+ class FreeResourceInstanceResultSuccess(WorkflowNotAlteredMixin, ResultPayloadSuccess):
124
+ """Resource instance freed successfully."""
125
+
126
+
127
+ @dataclass
128
+ @PayloadRegistry.register
129
+ class FreeResourceInstanceResultFailure(WorkflowNotAlteredMixin, ResultPayloadFailure):
130
+ """Resource instance freeing failed. Common causes: instance not found, instance locked and force_unlock=False."""
131
+
132
+
133
+ # Acquire Resource Lock Events
134
+ @dataclass
135
+ @PayloadRegistry.register
136
+ class AcquireResourceInstanceLockRequest(RequestPayload):
137
+ """Acquire a lock on an existing resource instance.
138
+
139
+ Use when: Attempting to acquire exclusive access to a resource instance that
140
+ matches specific requirements.
141
+
142
+ Args:
143
+ owner_id: The ID of the entity requesting the lock
144
+ resource_type_name: The name of the resource type to acquire
145
+ requirements: Optional requirements the resource must satisfy
146
+ """
147
+
148
+ owner_id: str
149
+ resource_type_name: str
150
+ requirements: "Requirements | None" = None
151
+
152
+
153
+ @dataclass
154
+ @PayloadRegistry.register
155
+ class AcquireResourceInstanceLockResultSuccess(WorkflowNotAlteredMixin, ResultPayloadSuccess):
156
+ """Resource instance lock acquired successfully."""
157
+
158
+ instance_id: str
159
+
160
+
161
+ @dataclass
162
+ @PayloadRegistry.register
163
+ class AcquireResourceInstanceLockResultFailure(WorkflowNotAlteredMixin, ResultPayloadFailure):
164
+ """Resource instance lock acquisition failed. Common causes: no compatible instances available, all instances locked."""
165
+
166
+
167
+ # Release Resource Lock Events
168
+ @dataclass
169
+ @PayloadRegistry.register
170
+ class ReleaseResourceInstanceLockRequest(RequestPayload):
171
+ """Release a lock on a resource instance.
172
+
173
+ Use when: Releasing exclusive access to a resource instance that was
174
+ previously acquired.
175
+
176
+ Args:
177
+ instance_id: The ID of the resource instance to release
178
+ owner_id: The ID of the entity releasing the lock
179
+ """
180
+
181
+ instance_id: str
182
+ owner_id: str
183
+
184
+
185
+ @dataclass
186
+ @PayloadRegistry.register
187
+ class ReleaseResourceInstanceLockResultSuccess(WorkflowNotAlteredMixin, ResultPayloadSuccess):
188
+ """Resource instance lock released successfully."""
189
+
190
+
191
+ @dataclass
192
+ @PayloadRegistry.register
193
+ class ReleaseResourceInstanceLockResultFailure(WorkflowNotAlteredMixin, ResultPayloadFailure):
194
+ """Resource instance lock release failed. Common causes: instance not found, not locked by specified owner."""
195
+
196
+
197
+ # List Compatible Resource Instances Events
198
+ @dataclass
199
+ @PayloadRegistry.register
200
+ class ListCompatibleResourceInstancesRequest(RequestPayload):
201
+ """List resource instances compatible with requirements.
202
+
203
+ Use when: Discovering what resource instances are available that match
204
+ specific criteria, without acquiring locks.
205
+
206
+ Args:
207
+ resource_type_name: The name of the resource type to filter by
208
+ requirements: Optional requirements to match. If None, returns all instances of the type.
209
+ include_locked: If True, also include locked instances
210
+ """
211
+
212
+ resource_type_name: str
213
+ requirements: "Requirements | None" = None
214
+ include_locked: bool = False
215
+
216
+
217
+ @dataclass
218
+ @PayloadRegistry.register
219
+ class ListCompatibleResourceInstancesResultSuccess(WorkflowNotAlteredMixin, ResultPayloadSuccess):
220
+ """Compatible resource instances listed successfully."""
221
+
222
+ instance_ids: list[str]
223
+
224
+
225
+ @dataclass
226
+ @PayloadRegistry.register
227
+ class ListCompatibleResourceInstancesResultFailure(WorkflowNotAlteredMixin, ResultPayloadFailure):
228
+ """Compatible resource instances listing failed. Common causes: invalid resource type, invalid requirements."""
229
+
230
+
231
+ # Get Resource Instance Status Events
232
+ @dataclass
233
+ @PayloadRegistry.register
234
+ class GetResourceInstanceStatusRequest(RequestPayload):
235
+ """Get status information for a resource instance.
236
+
237
+ Use when: Checking the current state of a specific resource instance,
238
+ including capabilities and lock status.
239
+
240
+ Args:
241
+ instance_id: The ID of the instance to get status for
242
+ """
243
+
244
+ instance_id: str
245
+
246
+
247
+ @dataclass
248
+ @PayloadRegistry.register
249
+ class GetResourceInstanceStatusResultSuccess(WorkflowNotAlteredMixin, ResultPayloadSuccess):
250
+ """Resource instance status retrieved successfully."""
251
+
252
+ status: "ResourceStatus"
253
+
254
+
255
+ @dataclass
256
+ @PayloadRegistry.register
257
+ class GetResourceInstanceStatusResultFailure(WorkflowNotAlteredMixin, ResultPayloadFailure):
258
+ """Resource instance status retrieval failed. Common causes: instance not found."""
259
+
260
+
261
+ # List Resource Instances By Type Events
262
+ @dataclass
263
+ @PayloadRegistry.register
264
+ class ListResourceInstancesByTypeRequest(RequestPayload):
265
+ """List resource instances of a specific type.
266
+
267
+ Use when: Listing all instances of a particular resource type for
268
+ management or monitoring purposes.
269
+
270
+ Args:
271
+ resource_type_name: The name of the resource type to list instances for
272
+ include_locked: If True, also include locked instances
273
+ """
274
+
275
+ resource_type_name: str
276
+ include_locked: bool = True
277
+
278
+
279
+ @dataclass
280
+ @PayloadRegistry.register
281
+ class ListResourceInstancesByTypeResultSuccess(WorkflowNotAlteredMixin, ResultPayloadSuccess):
282
+ """Resource instances by type listed successfully."""
283
+
284
+ instance_ids: list[str]
285
+
286
+
287
+ @dataclass
288
+ @PayloadRegistry.register
289
+ class ListResourceInstancesByTypeResultFailure(WorkflowNotAlteredMixin, ResultPayloadFailure):
290
+ """Resource instances by type listing failed. Common causes: invalid resource type."""
@@ -1,7 +1,8 @@
1
1
  from dataclasses import dataclass
2
- from typing import Literal
2
+ from datetime import datetime
3
+ from typing import TYPE_CHECKING, Literal
3
4
 
4
- from griptape_nodes.node_library.workflow_registry import WorkflowMetadata
5
+ from griptape_nodes.node_library.workflow_registry import WorkflowMetadata, WorkflowShape
5
6
  from griptape_nodes.retained_mode.events.base_events import (
6
7
  RequestPayload,
7
8
  ResultPayloadFailure,
@@ -11,6 +12,9 @@ from griptape_nodes.retained_mode.events.base_events import (
11
12
  )
12
13
  from griptape_nodes.retained_mode.events.payload_registry import PayloadRegistry
13
14
 
15
+ if TYPE_CHECKING:
16
+ from griptape_nodes.retained_mode.events.flow_events import SerializedFlowCommands
17
+
14
18
 
15
19
  @dataclass
16
20
  @PayloadRegistry.register
@@ -632,3 +636,54 @@ class RegisterWorkflowsFromConfigResultSuccess(WorkflowNotAlteredMixin, ResultPa
632
636
  @PayloadRegistry.register
633
637
  class RegisterWorkflowsFromConfigResultFailure(WorkflowNotAlteredMixin, ResultPayloadFailure):
634
638
  """Workflow registration from configuration failed. Common causes: configuration not found, invalid paths, registration errors."""
639
+
640
+
641
+ @dataclass
642
+ @PayloadRegistry.register
643
+ class SaveWorkflowFileFromSerializedFlowRequest(RequestPayload):
644
+ """Save a workflow file from serialized flow commands without registry overhead.
645
+
646
+ Use when: Creating workflow files from user-supplied subsets of existing workflows,
647
+ exporting partial workflows, creating standalone workflow files without registration.
648
+
649
+ Args:
650
+ serialized_flow_commands: The serialized commands representing the workflow structure
651
+ file_name: Name for the workflow file (without .py extension)
652
+ creation_date: Optional creation date for the workflow metadata (defaults to current time if not provided)
653
+ image_path: Optional path to workflow image/thumbnail
654
+ execution_flow_name: Optional flow name to use for execution code (defaults to file_name if not provided)
655
+ branched_from: Optional branched from information to preserve workflow lineage
656
+ workflow_shape: Optional workflow shape defining inputs and outputs for external callers
657
+ file_path: Optional specific file path to use (defaults to workspace path if not provided)
658
+
659
+ Results: SaveWorkflowFileFromSerializedFlowResultSuccess (with file path) | SaveWorkflowFileFromSerializedFlowResultFailure (save error)
660
+ """
661
+
662
+ serialized_flow_commands: "SerializedFlowCommands"
663
+ file_name: str
664
+ file_path: str | None = None
665
+ creation_date: datetime | None = None
666
+ image_path: str | None = None
667
+ execution_flow_name: str | None = None
668
+ branched_from: str | None = None
669
+ workflow_shape: WorkflowShape | None = None
670
+
671
+
672
+ @dataclass
673
+ @PayloadRegistry.register
674
+ class SaveWorkflowFileFromSerializedFlowResultSuccess(WorkflowNotAlteredMixin, ResultPayloadSuccess):
675
+ """Workflow file saved successfully from serialized flow commands.
676
+
677
+ Args:
678
+ file_path: Path where the workflow file was written
679
+ workflow_metadata: The metadata that was generated for the workflow
680
+ """
681
+
682
+ file_path: str
683
+ workflow_metadata: WorkflowMetadata
684
+
685
+
686
+ @dataclass
687
+ @PayloadRegistry.register
688
+ class SaveWorkflowFileFromSerializedFlowResultFailure(WorkflowNotAlteredMixin, ResultPayloadFailure):
689
+ """Workflow file save failed. Common causes: file system error, permission denied, invalid serialized commands."""
@@ -69,6 +69,7 @@ if TYPE_CHECKING:
69
69
  OperationDepthManager,
70
70
  )
71
71
  from griptape_nodes.retained_mode.managers.os_manager import OSManager
72
+ from griptape_nodes.retained_mode.managers.resource_manager import ResourceManager
72
73
  from griptape_nodes.retained_mode.managers.secrets_manager import SecretsManager
73
74
  from griptape_nodes.retained_mode.managers.session_manager import SessionManager
74
75
  from griptape_nodes.retained_mode.managers.static_files_manager import (
@@ -149,9 +150,10 @@ class GriptapeNodes(metaclass=SingletonMeta):
149
150
  _version_compatibility_manager: VersionCompatibilityManager
150
151
  _session_manager: SessionManager
151
152
  _engine_identity_manager: EngineIdentityManager
153
+ _resource_manager: ResourceManager
152
154
  _sync_manager: SyncManager
153
155
 
154
- def __init__(self) -> None:
156
+ def __init__(self) -> None: # noqa: PLR0915
155
157
  from griptape_nodes.retained_mode.managers.agent_manager import AgentManager
156
158
  from griptape_nodes.retained_mode.managers.arbitrary_code_exec_manager import (
157
159
  ArbitraryCodeExecManager,
@@ -169,6 +171,7 @@ class GriptapeNodes(metaclass=SingletonMeta):
169
171
  OperationDepthManager,
170
172
  )
171
173
  from griptape_nodes.retained_mode.managers.os_manager import OSManager
174
+ from griptape_nodes.retained_mode.managers.resource_manager import ResourceManager
172
175
  from griptape_nodes.retained_mode.managers.secrets_manager import SecretsManager
173
176
  from griptape_nodes.retained_mode.managers.session_manager import SessionManager
174
177
  from griptape_nodes.retained_mode.managers.static_files_manager import (
@@ -188,6 +191,7 @@ class GriptapeNodes(metaclass=SingletonMeta):
188
191
  # Initialize only if our managers haven't been created yet
189
192
  if not hasattr(self, "_event_manager"):
190
193
  self._event_manager = EventManager()
194
+ self._resource_manager = ResourceManager(self._event_manager)
191
195
  self._config_manager = ConfigManager(self._event_manager)
192
196
  self._os_manager = OSManager(self._event_manager)
193
197
  self._secrets_manager = SecretsManager(self._config_manager, self._event_manager)
@@ -374,6 +378,10 @@ class GriptapeNodes(metaclass=SingletonMeta):
374
378
  def EngineIdentityManager(cls) -> EngineIdentityManager:
375
379
  return GriptapeNodes.get_instance()._engine_identity_manager
376
380
 
381
+ @classmethod
382
+ def ResourceManager(cls) -> ResourceManager:
383
+ return GriptapeNodes.get_instance()._resource_manager
384
+
377
385
  @classmethod
378
386
  def SyncManager(cls) -> SyncManager:
379
387
  return GriptapeNodes.get_instance()._sync_manager