vellum-ai 0.14.11__py3-none-any.whl → 0.14.13__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.
- vellum/client/core/client_wrapper.py +1 -1
- vellum/workflows/descriptors/base.py +3 -0
- vellum/workflows/events/workflow.py +23 -0
- vellum/workflows/inputs/base.py +26 -18
- vellum/workflows/inputs/tests/test_inputs.py +1 -1
- vellum/workflows/nodes/bases/base.py +7 -0
- vellum/workflows/nodes/core/inline_subworkflow_node/node.py +7 -0
- vellum/workflows/nodes/core/inline_subworkflow_node/tests/test_node.py +32 -0
- vellum/workflows/nodes/core/map_node/node.py +28 -7
- vellum/workflows/nodes/core/map_node/tests/test_node.py +31 -0
- vellum/workflows/nodes/core/try_node/node.py +7 -0
- vellum/workflows/nodes/core/try_node/tests/test_node.py +32 -0
- vellum/workflows/nodes/displayable/subworkflow_deployment_node/node.py +5 -4
- vellum/workflows/nodes/displayable/subworkflow_deployment_node/tests/test_node.py +111 -0
- vellum/workflows/nodes/mocks.py +229 -2
- vellum/workflows/nodes/tests/__init__.py +0 -0
- vellum/workflows/nodes/tests/test_mocks.py +207 -0
- vellum/workflows/outputs/base.py +1 -1
- {vellum_ai-0.14.11.dist-info → vellum_ai-0.14.13.dist-info}/METADATA +2 -2
- {vellum_ai-0.14.11.dist-info → vellum_ai-0.14.13.dist-info}/RECORD +28 -26
- vellum_ee/workflows/display/nodes/base_node_display.py +20 -4
- vellum_ee/workflows/display/nodes/get_node_display_class.py +9 -0
- vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_adornments_serialization.py +24 -1
- vellum_ee/workflows/display/workflows/base_workflow_display.py +2 -2
- vellum_ee/workflows/display/workflows/tests/test_workflow_display.py +20 -0
- {vellum_ai-0.14.11.dist-info → vellum_ai-0.14.13.dist-info}/LICENSE +0 -0
- {vellum_ai-0.14.11.dist-info → vellum_ai-0.14.13.dist-info}/WHEEL +0 -0
- {vellum_ai-0.14.11.dist-info → vellum_ai-0.14.13.dist-info}/entry_points.txt +0 -0
@@ -59,11 +59,27 @@ _NodeDisplayAttrType = TypeVar("_NodeDisplayAttrType")
|
|
59
59
|
class BaseNodeDisplayMeta(type):
|
60
60
|
def __new__(mcs, name: str, bases: Tuple[Type, ...], dct: Dict[str, Any]) -> Any:
|
61
61
|
cls = super().__new__(mcs, name, bases, dct)
|
62
|
-
|
62
|
+
base_node_display_class = cast(Type["BaseNodeDisplay"], cls)
|
63
|
+
node_class = base_node_display_class.infer_node_class()
|
64
|
+
if not issubclass(node_class, BaseNode):
|
65
|
+
return cls
|
66
|
+
|
67
|
+
display_node_id = dct.get("node_id")
|
68
|
+
if isinstance(display_node_id, UUID):
|
63
69
|
# Display classes are able to override the id of the node class it's parameterized by
|
64
|
-
|
65
|
-
|
66
|
-
|
70
|
+
node_class.__id__ = display_node_id
|
71
|
+
|
72
|
+
output_display = dct.get("output_display")
|
73
|
+
if isinstance(output_display, dict):
|
74
|
+
# And the node class' output ids
|
75
|
+
for reference, node_output_display in output_display.items():
|
76
|
+
if not isinstance(reference, OutputReference):
|
77
|
+
continue
|
78
|
+
if not isinstance(node_output_display, NodeOutputDisplay):
|
79
|
+
continue
|
80
|
+
|
81
|
+
node_class.__output_ids__[reference.name] = node_output_display.id
|
82
|
+
|
67
83
|
return cls
|
68
84
|
|
69
85
|
|
@@ -2,6 +2,7 @@ import types
|
|
2
2
|
from typing import TYPE_CHECKING, Optional, Type
|
3
3
|
|
4
4
|
from vellum.workflows.types.generics import NodeType
|
5
|
+
from vellum_ee.workflows.display.nodes.types import NodeOutputDisplay
|
5
6
|
|
6
7
|
if TYPE_CHECKING:
|
7
8
|
from vellum_ee.workflows.display.types import NodeDisplayType
|
@@ -29,4 +30,12 @@ def get_node_display_class(
|
|
29
30
|
f"{node_class.__name__}Display",
|
30
31
|
bases=(NodeDisplayBaseClass,),
|
31
32
|
)
|
33
|
+
output_display = {
|
34
|
+
ref: NodeOutputDisplay(id=node_class.__output_ids__[ref.name], name=ref.name)
|
35
|
+
for ref in node_class.Outputs
|
36
|
+
if ref.name in node_class.__output_ids__
|
37
|
+
}
|
38
|
+
if output_display:
|
39
|
+
setattr(NodeDisplayClass, "output_display", output_display)
|
40
|
+
|
32
41
|
return NodeDisplayClass
|
@@ -115,7 +115,8 @@ def test_serialize_node__retry(serialize_node):
|
|
115
115
|
)
|
116
116
|
|
117
117
|
|
118
|
-
def test_serialize_node__retry__no_display():
|
118
|
+
def test_serialize_node__retry__no_display():
|
119
|
+
# GIVEN an adornment node
|
119
120
|
@RetryNode.wrap(max_attempts=5)
|
120
121
|
class StartNode(BaseNode):
|
121
122
|
pass
|
@@ -212,6 +213,28 @@ def test_serialize_node__try(serialize_node):
|
|
212
213
|
)
|
213
214
|
|
214
215
|
|
216
|
+
def test_serialize_node__try__no_display():
|
217
|
+
# GIVEN an adornment node
|
218
|
+
@TryNode.wrap()
|
219
|
+
class StartNode(BaseNode):
|
220
|
+
pass
|
221
|
+
|
222
|
+
# AND a workflow that uses the adornment node
|
223
|
+
class MyWorkflow(BaseWorkflow):
|
224
|
+
graph = StartNode
|
225
|
+
|
226
|
+
# WHEN we serialize the workflow
|
227
|
+
workflow_display = get_workflow_display(
|
228
|
+
base_display_class=VellumWorkflowDisplay,
|
229
|
+
workflow_class=MyWorkflow,
|
230
|
+
)
|
231
|
+
|
232
|
+
exec_config = workflow_display.serialize()
|
233
|
+
|
234
|
+
# THEN the workflow display is created successfully
|
235
|
+
assert exec_config is not None
|
236
|
+
|
237
|
+
|
215
238
|
def test_serialize_node__stacked():
|
216
239
|
@TryNode.wrap()
|
217
240
|
@RetryNode.wrap(max_attempts=5)
|
@@ -411,7 +411,7 @@ class BaseWorkflowDisplay(
|
|
411
411
|
input_display = {}
|
412
412
|
if isinstance(current_node_display, BaseNodeVellumDisplay):
|
413
413
|
input_display = current_node_display.node_input_ids_by_name
|
414
|
-
|
414
|
+
output_display = {
|
415
415
|
output.name: current_node_display.output_display[output].id
|
416
416
|
for output in current_node_display.output_display
|
417
417
|
}
|
@@ -434,7 +434,7 @@ class BaseWorkflowDisplay(
|
|
434
434
|
|
435
435
|
node_event_displays[node_id] = NodeEventDisplayContext(
|
436
436
|
input_display=input_display,
|
437
|
-
output_display=
|
437
|
+
output_display=output_display,
|
438
438
|
port_display=port_display_meta,
|
439
439
|
subworkflow_display=subworkflow_display_context,
|
440
440
|
)
|
@@ -95,6 +95,26 @@ def test_serialize_workflow__node_display_class_not_registered():
|
|
95
95
|
assert data is not None
|
96
96
|
|
97
97
|
|
98
|
+
def test_get_event_display_context__node_display_filled_without_base_display():
|
99
|
+
# GIVEN a simple workflow
|
100
|
+
class StartNode(BaseNode):
|
101
|
+
class Outputs(BaseNode.Outputs):
|
102
|
+
foo: str
|
103
|
+
|
104
|
+
class MyWorkflow(BaseWorkflow):
|
105
|
+
graph = StartNode
|
106
|
+
|
107
|
+
# WHEN we gather the event display context
|
108
|
+
display_context = VellumWorkflowDisplay(MyWorkflow).get_event_display_context()
|
109
|
+
|
110
|
+
# THEN the node display should be included
|
111
|
+
assert str(StartNode.__id__) in display_context.node_displays
|
112
|
+
node_event_display = display_context.node_displays[str(StartNode.__id__)]
|
113
|
+
|
114
|
+
# AND so should their output ids
|
115
|
+
assert StartNode.__output_ids__ == node_event_display.output_display
|
116
|
+
|
117
|
+
|
98
118
|
def test_get_event_display_context__node_display_to_include_subworkflow_display():
|
99
119
|
# GIVEN a simple workflow
|
100
120
|
class InnerNode(BaseNode):
|
File without changes
|
File without changes
|
File without changes
|