griptape-nodes 0.51.2__py3-none-any.whl → 0.52.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 (46) hide show
  1. griptape_nodes/__init__.py +5 -4
  2. griptape_nodes/app/api.py +27 -24
  3. griptape_nodes/app/app.py +243 -221
  4. griptape_nodes/app/watch.py +17 -2
  5. griptape_nodes/bootstrap/workflow_executors/local_workflow_executor.py +66 -103
  6. griptape_nodes/bootstrap/workflow_executors/workflow_executor.py +16 -4
  7. griptape_nodes/exe_types/core_types.py +16 -4
  8. griptape_nodes/exe_types/node_types.py +74 -16
  9. griptape_nodes/machines/control_flow.py +21 -26
  10. griptape_nodes/machines/fsm.py +16 -16
  11. griptape_nodes/machines/node_resolution.py +30 -119
  12. griptape_nodes/mcp_server/server.py +14 -10
  13. griptape_nodes/mcp_server/ws_request_manager.py +2 -2
  14. griptape_nodes/node_library/workflow_registry.py +5 -0
  15. griptape_nodes/retained_mode/events/base_events.py +12 -7
  16. griptape_nodes/retained_mode/events/execution_events.py +0 -6
  17. griptape_nodes/retained_mode/events/node_events.py +38 -0
  18. griptape_nodes/retained_mode/events/parameter_events.py +11 -0
  19. griptape_nodes/retained_mode/events/variable_events.py +361 -0
  20. griptape_nodes/retained_mode/events/workflow_events.py +35 -0
  21. griptape_nodes/retained_mode/griptape_nodes.py +61 -26
  22. griptape_nodes/retained_mode/managers/agent_manager.py +8 -9
  23. griptape_nodes/retained_mode/managers/event_manager.py +215 -74
  24. griptape_nodes/retained_mode/managers/flow_manager.py +39 -33
  25. griptape_nodes/retained_mode/managers/library_lifecycle/library_directory.py +14 -14
  26. griptape_nodes/retained_mode/managers/library_lifecycle/library_fsm.py +20 -20
  27. griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/base.py +1 -1
  28. griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/github.py +1 -1
  29. griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/local_file.py +4 -3
  30. griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/package.py +1 -1
  31. griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/sandbox.py +1 -1
  32. griptape_nodes/retained_mode/managers/library_manager.py +20 -19
  33. griptape_nodes/retained_mode/managers/node_manager.py +83 -8
  34. griptape_nodes/retained_mode/managers/object_manager.py +4 -0
  35. griptape_nodes/retained_mode/managers/settings.py +1 -0
  36. griptape_nodes/retained_mode/managers/sync_manager.py +3 -9
  37. griptape_nodes/retained_mode/managers/variable_manager.py +529 -0
  38. griptape_nodes/retained_mode/managers/workflow_manager.py +156 -50
  39. griptape_nodes/retained_mode/variable_types.py +18 -0
  40. griptape_nodes/utils/__init__.py +4 -0
  41. griptape_nodes/utils/async_utils.py +89 -0
  42. {griptape_nodes-0.51.2.dist-info → griptape_nodes-0.52.0.dist-info}/METADATA +2 -3
  43. {griptape_nodes-0.51.2.dist-info → griptape_nodes-0.52.0.dist-info}/RECORD +45 -42
  44. {griptape_nodes-0.51.2.dist-info → griptape_nodes-0.52.0.dist-info}/WHEEL +1 -1
  45. griptape_nodes/bootstrap/workflow_executors/subprocess_workflow_executor.py +0 -90
  46. {griptape_nodes-0.51.2.dist-info → griptape_nodes-0.52.0.dist-info}/entry_points.txt +0 -0
@@ -7,7 +7,6 @@ from dataclasses import asdict, dataclass, field, is_dataclass
7
7
  from typing import TYPE_CHECKING, Any, ClassVar, Literal, TypeVar
8
8
 
9
9
  from griptape.artifacts import BaseArtifact
10
- from griptape.events import BaseEvent as GtBaseEvent
11
10
  from griptape.mixins.serializable_mixin import SerializableMixin
12
11
  from griptape.structures import Structure
13
12
  from griptape.tools import BaseTool
@@ -632,18 +631,24 @@ class AppEvent[A: AppPayload](BaseEvent):
632
631
  return cls(payload=event_payload, **event_data)
633
632
 
634
633
 
635
- @dataclass
636
- class GriptapeNodeEvent(GtBaseEvent):
634
+ class GriptapeNodeEvent(BaseEvent):
637
635
  wrapped_event: EventResult
638
636
 
637
+ def get_request(self) -> Payload:
638
+ """Get the request from the wrapped event."""
639
+ return self.wrapped_event.get_request()
639
640
 
640
- @dataclass
641
- class ExecutionGriptapeNodeEvent(GtBaseEvent):
642
- wrapped_event: ExecutionEvent = field()
641
+
642
+ class ExecutionGriptapeNodeEvent(BaseEvent):
643
+ wrapped_event: ExecutionEvent
644
+
645
+ def get_request(self) -> Payload:
646
+ """Get the request from the wrapped event."""
647
+ return self.wrapped_event.get_request()
643
648
 
644
649
 
645
650
  @dataclass
646
- class ProgressEvent(GtBaseEvent):
651
+ class ProgressEvent:
647
652
  value: Any = field()
648
653
  node_name: str = field()
649
654
  parameter_name: str = field()
@@ -340,12 +340,6 @@ class NodeStartProcessEvent(ExecutionPayload):
340
340
  node_name: str
341
341
 
342
342
 
343
- @dataclass
344
- @PayloadRegistry.register
345
- class ResumeNodeProcessingEvent(ExecutionPayload):
346
- node_name: str
347
-
348
-
349
343
  @dataclass
350
344
  @PayloadRegistry.register
351
345
  class NodeFinishProcessEvent(ExecutionPayload):
@@ -774,3 +774,41 @@ class SendNodeMessageResultFailure(ResultPayloadFailure):
774
774
  """
775
775
 
776
776
  response: Any = None
777
+
778
+
779
+ @dataclass
780
+ @PayloadRegistry.register
781
+ class GetFlowForNodeRequest(RequestPayload):
782
+ """Get the flow name that contains a specific node.
783
+
784
+ Use when: Need to determine which flow a node belongs to for variable scoping,
785
+ flow-specific operations, or hierarchical lookups.
786
+
787
+ Args:
788
+ node_name: Name of the node to get the flow for
789
+
790
+ Results: GetFlowForNodeResultSuccess (with flow name) | GetFlowForNodeResultFailure (node not found)
791
+ """
792
+
793
+ node_name: str
794
+
795
+
796
+ @dataclass
797
+ @PayloadRegistry.register
798
+ class GetFlowForNodeResultSuccess(WorkflowNotAlteredMixin, ResultPayloadSuccess):
799
+ """Flow for node retrieved successfully.
800
+
801
+ Args:
802
+ flow_name: Name of the flow that contains the node
803
+ """
804
+
805
+ flow_name: str
806
+
807
+
808
+ @dataclass
809
+ @PayloadRegistry.register
810
+ class GetFlowForNodeResultFailure(WorkflowNotAlteredMixin, ResultPayloadFailure):
811
+ """Flow for node retrieval failed.
812
+
813
+ Common causes: node not found, node not assigned to any flow.
814
+ """
@@ -43,6 +43,7 @@ class AddParameterToNodeRequest(RequestPayload):
43
43
  is_user_defined: Whether this is a user-defined parameter (affects serialization)
44
44
  parent_container_name: Name of parent container if nested
45
45
  initial_setup: Skip setup work when loading from file
46
+ settable: Whether parameter can be set directly by the user or not
46
47
 
47
48
  Results: AddParameterToNodeResultSuccess (with parameter name) | AddParameterToNodeResultFailure
48
49
  """
@@ -63,6 +64,7 @@ class AddParameterToNodeRequest(RequestPayload):
63
64
  mode_allowed_property: bool = Field(default=True)
64
65
  mode_allowed_output: bool = Field(default=True)
65
66
  is_user_defined: bool = Field(default=True)
67
+ settable: bool = Field(default=True)
66
68
  parent_container_name: str | None = None
67
69
  # initial_setup prevents unnecessary work when we are loading a workflow from a file.
68
70
  initial_setup: bool = False
@@ -160,6 +162,10 @@ class SetParameterValueRequest(RequestPayload):
160
162
  initial_setup: bool = False
161
163
  # is_output is true when the value being saved is from an output value. Used when loading a workflow from a file.
162
164
  is_output: bool = False
165
+ # incoming_connection_source fields identify when this request comes from upstream node value passing during resolution
166
+ # Both must be None (manual/user request) or both must be set (incoming connection source request)
167
+ incoming_connection_source_node_name: str | None = None
168
+ incoming_connection_source_parameter_name: str | None = None
163
169
 
164
170
 
165
171
  @dataclass
@@ -221,6 +227,7 @@ class GetParameterDetailsResultSuccess(WorkflowNotAlteredMixin, ResultPayloadSuc
221
227
  tooltip_as_input/property/output: Mode-specific tooltips
222
228
  mode_allowed_input/property/output: Which modes are allowed
223
229
  is_user_defined: Whether this is a user-defined parameter
230
+ settable: Whether parameter can be set directly by the user or not (None for non-Parameters)
224
231
  ui_options: UI configuration options
225
232
  """
226
233
 
@@ -237,6 +244,7 @@ class GetParameterDetailsResultSuccess(WorkflowNotAlteredMixin, ResultPayloadSuc
237
244
  mode_allowed_property: bool
238
245
  mode_allowed_output: bool
239
246
  is_user_defined: bool
247
+ settable: bool | None
240
248
  ui_options: dict | None
241
249
 
242
250
 
@@ -268,6 +276,7 @@ class AlterParameterDetailsRequest(RequestPayload):
268
276
  mode_allowed_input: Whether parameter can be used as input
269
277
  mode_allowed_property: Whether parameter can be used as property
270
278
  mode_allowed_output: Whether parameter can be used as output
279
+ settable: Whether parameter can be set directly by the user or not
271
280
  ui_options: New UI configuration options
272
281
  traits: Set of parameter traits
273
282
  initial_setup: Skip setup work when loading from file
@@ -289,6 +298,7 @@ class AlterParameterDetailsRequest(RequestPayload):
289
298
  mode_allowed_input: bool | None = None
290
299
  mode_allowed_property: bool | None = None
291
300
  mode_allowed_output: bool | None = None
301
+ settable: bool | None = None
292
302
  ui_options: dict | None = None
293
303
  traits: set[str] | None = None
294
304
  # initial_setup prevents unnecessary work when we are loading a workflow from a file.
@@ -326,6 +336,7 @@ class AlterParameterDetailsRequest(RequestPayload):
326
336
  "mode_allowed_input",
327
337
  "mode_allowed_property",
328
338
  "mode_allowed_output",
339
+ "settable",
329
340
  "ui_options",
330
341
  "traits",
331
342
  ]
@@ -0,0 +1,361 @@
1
+ from dataclasses import dataclass
2
+ from typing import Any
3
+
4
+ from griptape_nodes.retained_mode.events.base_events import (
5
+ RequestPayload,
6
+ ResultPayloadFailure,
7
+ ResultPayloadSuccess,
8
+ WorkflowAlteredMixin,
9
+ WorkflowNotAlteredMixin,
10
+ )
11
+ from griptape_nodes.retained_mode.events.payload_registry import PayloadRegistry
12
+ from griptape_nodes.retained_mode.variable_types import FlowVariable, VariableScope
13
+
14
+
15
+ # Variable Events
16
+ @dataclass
17
+ @PayloadRegistry.register
18
+ class CreateVariableRequest(RequestPayload):
19
+ """Create a new variable.
20
+
21
+ Args:
22
+ name: The name of the variable
23
+ type: The user-defined type (e.g., "JSON", "str", "int")
24
+ is_global: Whether this is a global variable (True) or current flow variable (False)
25
+ value: The initial value of the variable
26
+ owning_flow: Flow that should own this variable (None for current flow in the Context Manager)
27
+ """
28
+
29
+ name: str
30
+ type: str
31
+ is_global: bool = False
32
+ value: Any = None
33
+ owning_flow: str | None = None
34
+
35
+
36
+ @dataclass
37
+ @PayloadRegistry.register
38
+ class CreateVariableResultSuccess(WorkflowAlteredMixin, ResultPayloadSuccess):
39
+ """Variable created successfully."""
40
+
41
+
42
+ @dataclass
43
+ @PayloadRegistry.register
44
+ class CreateVariableResultFailure(WorkflowAlteredMixin, ResultPayloadFailure):
45
+ """Variable creation failed."""
46
+
47
+
48
+ # Get Variable Events
49
+ @dataclass
50
+ @PayloadRegistry.register
51
+ class GetVariableRequest(RequestPayload):
52
+ """Get a complete variable by name.
53
+
54
+ Args:
55
+ name: Variable name to lookup
56
+ lookup_scope: Variable lookup strategy (default: hierarchical search through starting flow, ancestor flows, then global)
57
+ starting_flow: Starting flow name (None for current flow in the Context Manager)
58
+ """
59
+
60
+ name: str
61
+ lookup_scope: VariableScope = VariableScope.HIERARCHICAL
62
+ starting_flow: str | None = None
63
+
64
+
65
+ @dataclass
66
+ @PayloadRegistry.register
67
+ class GetVariableResultSuccess(WorkflowNotAlteredMixin, ResultPayloadSuccess):
68
+ """Variable retrieved successfully."""
69
+
70
+ variable: FlowVariable
71
+
72
+
73
+ @dataclass
74
+ @PayloadRegistry.register
75
+ class GetVariableResultFailure(WorkflowNotAlteredMixin, ResultPayloadFailure):
76
+ """Variable retrieval failed."""
77
+
78
+
79
+ # Get Variable Value Events
80
+ @dataclass
81
+ @PayloadRegistry.register
82
+ class GetVariableValueRequest(RequestPayload):
83
+ """Get the value of a variable by name.
84
+
85
+ Args:
86
+ name: Variable name to lookup
87
+ lookup_scope: Variable lookup strategy (default: hierarchical search through starting flow, ancestor flows, then global)
88
+ starting_flow: Starting flow name (None for current flow in the Context Manager)
89
+ """
90
+
91
+ name: str
92
+ lookup_scope: VariableScope = VariableScope.HIERARCHICAL
93
+ starting_flow: str | None = None
94
+
95
+
96
+ @dataclass
97
+ @PayloadRegistry.register
98
+ class GetVariableValueResultSuccess(WorkflowNotAlteredMixin, ResultPayloadSuccess):
99
+ """Variable value retrieved successfully."""
100
+
101
+ value: Any
102
+
103
+
104
+ @dataclass
105
+ @PayloadRegistry.register
106
+ class GetVariableValueResultFailure(WorkflowNotAlteredMixin, ResultPayloadFailure):
107
+ """Variable value retrieval failed."""
108
+
109
+
110
+ # Set Variable Value Events
111
+ @dataclass
112
+ @PayloadRegistry.register
113
+ class SetVariableValueRequest(RequestPayload):
114
+ """Set the value of a variable by name.
115
+
116
+ Args:
117
+ value: The new value to set
118
+ name: Variable name to lookup
119
+ lookup_scope: Variable lookup strategy (default: hierarchical search through starting flow, ancestor flows, then global)
120
+ starting_flow: Starting flow name (None for current flow in the Context Manager)
121
+ """
122
+
123
+ value: Any
124
+ name: str
125
+ lookup_scope: VariableScope = VariableScope.HIERARCHICAL
126
+ starting_flow: str | None = None
127
+
128
+
129
+ @dataclass
130
+ @PayloadRegistry.register
131
+ class SetVariableValueResultSuccess(WorkflowAlteredMixin, ResultPayloadSuccess):
132
+ """Variable value set successfully."""
133
+
134
+
135
+ @dataclass
136
+ @PayloadRegistry.register
137
+ class SetVariableValueResultFailure(WorkflowAlteredMixin, ResultPayloadFailure):
138
+ """Variable value setting failed."""
139
+
140
+
141
+ # Get Variable Type Events
142
+ @dataclass
143
+ @PayloadRegistry.register
144
+ class GetVariableTypeRequest(RequestPayload):
145
+ """Get the type of a variable by name.
146
+
147
+ Args:
148
+ name: Variable name to lookup
149
+ lookup_scope: Variable lookup strategy (default: hierarchical search through starting flow, ancestor flows, then global)
150
+ starting_flow: Starting flow name (None for current flow in the Context Manager)
151
+ """
152
+
153
+ name: str
154
+ lookup_scope: VariableScope = VariableScope.HIERARCHICAL
155
+ starting_flow: str | None = None
156
+
157
+
158
+ @dataclass
159
+ @PayloadRegistry.register
160
+ class GetVariableTypeResultSuccess(WorkflowNotAlteredMixin, ResultPayloadSuccess):
161
+ """Variable type retrieved successfully."""
162
+
163
+ type: str
164
+
165
+
166
+ @dataclass
167
+ @PayloadRegistry.register
168
+ class GetVariableTypeResultFailure(WorkflowNotAlteredMixin, ResultPayloadFailure):
169
+ """Variable type retrieval failed."""
170
+
171
+
172
+ # Set Variable Type Events
173
+ @dataclass
174
+ @PayloadRegistry.register
175
+ class SetVariableTypeRequest(RequestPayload):
176
+ """Set the type of a variable by name.
177
+
178
+ Args:
179
+ type: The new user-defined type (e.g., "JSON", "str", "int")
180
+ name: Variable name to lookup
181
+ lookup_scope: Variable lookup strategy (default: hierarchical search through starting flow, ancestor flows, then global)
182
+ starting_flow: Starting flow name (None for current flow in the Context Manager)
183
+ """
184
+
185
+ type: str
186
+ name: str
187
+ lookup_scope: VariableScope = VariableScope.HIERARCHICAL
188
+ starting_flow: str | None = None
189
+
190
+
191
+ @dataclass
192
+ @PayloadRegistry.register
193
+ class SetVariableTypeResultSuccess(WorkflowAlteredMixin, ResultPayloadSuccess):
194
+ """Variable type set successfully."""
195
+
196
+
197
+ @dataclass
198
+ @PayloadRegistry.register
199
+ class SetVariableTypeResultFailure(WorkflowAlteredMixin, ResultPayloadFailure):
200
+ """Variable type setting failed."""
201
+
202
+
203
+ # Delete Variable Events
204
+ @dataclass
205
+ @PayloadRegistry.register
206
+ class DeleteVariableRequest(RequestPayload):
207
+ """Delete a variable by name.
208
+
209
+ Args:
210
+ name: Variable name to lookup
211
+ lookup_scope: Variable lookup strategy (default: hierarchical search through starting flow, ancestor flows, then global)
212
+ starting_flow: Starting flow name (None for current flow in the Context Manager)
213
+ """
214
+
215
+ name: str
216
+ lookup_scope: VariableScope = VariableScope.HIERARCHICAL
217
+ starting_flow: str | None = None
218
+
219
+
220
+ @dataclass
221
+ @PayloadRegistry.register
222
+ class DeleteVariableResultSuccess(WorkflowAlteredMixin, ResultPayloadSuccess):
223
+ """Variable deleted successfully."""
224
+
225
+
226
+ @dataclass
227
+ @PayloadRegistry.register
228
+ class DeleteVariableResultFailure(WorkflowAlteredMixin, ResultPayloadFailure):
229
+ """Variable deletion failed."""
230
+
231
+
232
+ # Rename Variable Events
233
+ @dataclass
234
+ @PayloadRegistry.register
235
+ class RenameVariableRequest(RequestPayload):
236
+ """Rename a variable by name.
237
+
238
+ Args:
239
+ new_name: The new name for the variable
240
+ name: Current variable name
241
+ lookup_scope: Variable lookup strategy (default: hierarchical search through starting flow, ancestor flows, then global)
242
+ starting_flow: Starting flow name (None for current flow in the Context Manager)
243
+ """
244
+
245
+ new_name: str
246
+ name: str
247
+ lookup_scope: VariableScope = VariableScope.HIERARCHICAL
248
+ starting_flow: str | None = None
249
+
250
+
251
+ @dataclass
252
+ @PayloadRegistry.register
253
+ class RenameVariableResultSuccess(WorkflowAlteredMixin, ResultPayloadSuccess):
254
+ """Variable renamed successfully."""
255
+
256
+
257
+ @dataclass
258
+ @PayloadRegistry.register
259
+ class RenameVariableResultFailure(WorkflowAlteredMixin, ResultPayloadFailure):
260
+ """Variable renaming failed."""
261
+
262
+
263
+ # Has Variable Events
264
+ @dataclass
265
+ @PayloadRegistry.register
266
+ class HasVariableRequest(RequestPayload):
267
+ """Check if a variable exists by name.
268
+
269
+ Args:
270
+ name: Variable name to lookup
271
+ lookup_scope: Variable lookup strategy (default: hierarchical search through starting flow, ancestor flows, then global)
272
+ starting_flow: Starting flow name (None for current flow in the Context Manager)
273
+ """
274
+
275
+ name: str
276
+ lookup_scope: VariableScope = VariableScope.HIERARCHICAL
277
+ starting_flow: str | None = None
278
+
279
+
280
+ @dataclass
281
+ @PayloadRegistry.register
282
+ class HasVariableResultSuccess(WorkflowNotAlteredMixin, ResultPayloadSuccess):
283
+ """Variable existence check completed."""
284
+
285
+ exists: bool
286
+ found_scope: VariableScope | None = None
287
+
288
+
289
+ @dataclass
290
+ @PayloadRegistry.register
291
+ class HasVariableResultFailure(WorkflowNotAlteredMixin, ResultPayloadFailure):
292
+ """Variable existence check failed."""
293
+
294
+
295
+ # List Variables Events
296
+ @dataclass
297
+ @PayloadRegistry.register
298
+ class ListVariablesRequest(RequestPayload):
299
+ """List all variables in the specified scope.
300
+
301
+ Args:
302
+ lookup_scope: Variable lookup strategy (default: hierarchical search through starting flow, ancestor flows, then global; use ALL to get variables from all flows for GUI enumeration)
303
+ starting_flow: Starting flow name (None for current flow in the Context Manager)
304
+ """
305
+
306
+ lookup_scope: VariableScope = VariableScope.HIERARCHICAL
307
+ starting_flow: str | None = None
308
+
309
+
310
+ @dataclass
311
+ @PayloadRegistry.register
312
+ class ListVariablesResultSuccess(WorkflowNotAlteredMixin, ResultPayloadSuccess):
313
+ """Variables listed successfully."""
314
+
315
+ variables: list[FlowVariable]
316
+
317
+
318
+ @dataclass
319
+ @PayloadRegistry.register
320
+ class ListVariablesResultFailure(WorkflowNotAlteredMixin, ResultPayloadFailure):
321
+ """Variables listing failed."""
322
+
323
+
324
+ # Get Variable Details Events
325
+ @dataclass
326
+ @PayloadRegistry.register
327
+ class GetVariableDetailsRequest(RequestPayload):
328
+ """Get variable details (metadata only, no heavy values).
329
+
330
+ Args:
331
+ name: Variable name to lookup
332
+ lookup_scope: Variable lookup strategy (default: hierarchical search through starting flow, ancestor flows, then global)
333
+ starting_flow: Starting flow name (None for current flow in the Context Manager)
334
+ """
335
+
336
+ name: str
337
+ lookup_scope: VariableScope = VariableScope.HIERARCHICAL
338
+ starting_flow: str | None = None
339
+
340
+
341
+ @dataclass
342
+ class VariableDetails:
343
+ """Lightweight variable details without heavy values."""
344
+
345
+ name: str
346
+ owning_flow_name: str | None # None for global variables
347
+ type: str
348
+
349
+
350
+ @dataclass
351
+ @PayloadRegistry.register
352
+ class GetVariableDetailsResultSuccess(WorkflowNotAlteredMixin, ResultPayloadSuccess):
353
+ """Variable details retrieved successfully."""
354
+
355
+ details: VariableDetails
356
+
357
+
358
+ @dataclass
359
+ @PayloadRegistry.register
360
+ class GetVariableDetailsResultFailure(WorkflowNotAlteredMixin, ResultPayloadFailure):
361
+ """Variable details retrieval failed."""
@@ -138,6 +138,41 @@ class RegisterWorkflowResultFailure(WorkflowNotAlteredMixin, ResultPayloadFailur
138
138
  """Workflow registration failed. Common causes: invalid metadata, file not found, name conflict."""
139
139
 
140
140
 
141
+ @dataclass
142
+ @PayloadRegistry.register
143
+ class ImportWorkflowRequest(RequestPayload):
144
+ """Import and register a workflow from a file.
145
+
146
+ Use when: Importing workflows from external sources, batch workflow imports,
147
+ command-line workflow registration, loading workflows from shared locations.
148
+
149
+ Args:
150
+ file_path: Path to the workflow file to import and register
151
+
152
+ Results: ImportWorkflowResultSuccess (with workflow name) | ImportWorkflowResultFailure (import error)
153
+ """
154
+
155
+ file_path: str
156
+
157
+
158
+ @dataclass
159
+ @PayloadRegistry.register
160
+ class ImportWorkflowResultSuccess(WorkflowNotAlteredMixin, ResultPayloadSuccess):
161
+ """Workflow imported and registered successfully.
162
+
163
+ Args:
164
+ workflow_name: Name of the imported workflow
165
+ """
166
+
167
+ workflow_name: str
168
+
169
+
170
+ @dataclass
171
+ @PayloadRegistry.register
172
+ class ImportWorkflowResultFailure(WorkflowNotAlteredMixin, ResultPayloadFailure):
173
+ """Workflow import failed. Common causes: file not found, invalid workflow format, metadata extraction error, registration error."""
174
+
175
+
141
176
  @dataclass
142
177
  @PayloadRegistry.register
143
178
  class ListAllWorkflowsRequest(RequestPayload):