vellum-ai 0.13.0__py3-none-any.whl → 0.13.2__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/client/core/pydantic_utilities.py +5 -0
- vellum/client/resources/workflows/client.py +8 -0
- vellum/client/types/logical_operator.py +2 -0
- vellum/workflows/descriptors/base.py +1 -1
- vellum/workflows/descriptors/tests/test_utils.py +3 -0
- vellum/workflows/expressions/accessor.py +8 -2
- vellum/workflows/nodes/core/map_node/node.py +49 -24
- vellum/workflows/nodes/core/map_node/tests/test_node.py +4 -4
- vellum/workflows/nodes/displayable/bases/base_prompt_node/node.py +1 -1
- vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py +5 -3
- vellum/workflows/nodes/displayable/bases/prompt_deployment_node.py +3 -0
- vellum/workflows/nodes/displayable/bases/search_node.py +37 -2
- vellum/workflows/nodes/displayable/bases/tests/__init__.py +0 -0
- vellum/workflows/nodes/displayable/bases/tests/test_utils.py +61 -0
- vellum/workflows/nodes/displayable/bases/types.py +42 -0
- vellum/workflows/nodes/displayable/bases/utils.py +112 -0
- vellum/workflows/nodes/displayable/inline_prompt_node/tests/test_node.py +0 -1
- vellum/workflows/nodes/displayable/search_node/tests/__init__.py +0 -0
- vellum/workflows/nodes/displayable/search_node/tests/test_node.py +164 -0
- vellum/workflows/nodes/displayable/tests/test_inline_text_prompt_node.py +2 -3
- vellum/workflows/nodes/displayable/tests/test_text_prompt_deployment_node.py +0 -1
- vellum/workflows/runner/runner.py +37 -4
- vellum/workflows/types/tests/test_utils.py +5 -2
- vellum/workflows/types/utils.py +4 -0
- vellum/workflows/workflows/base.py +14 -0
- {vellum_ai-0.13.0.dist-info → vellum_ai-0.13.2.dist-info}/METADATA +1 -1
- {vellum_ai-0.13.0.dist-info → vellum_ai-0.13.2.dist-info}/RECORD +53 -42
- vellum_cli/__init__.py +24 -0
- vellum_cli/ping.py +28 -0
- vellum_cli/push.py +62 -12
- vellum_cli/tests/test_ping.py +47 -0
- vellum_cli/tests/test_push.py +76 -0
- vellum_ee/workflows/display/nodes/vellum/base_node.py +59 -11
- vellum_ee/workflows/display/nodes/vellum/inline_prompt_node.py +3 -0
- vellum_ee/workflows/display/nodes/vellum/map_node.py +1 -1
- vellum_ee/workflows/display/nodes/vellum/prompt_deployment_node.py +14 -10
- vellum_ee/workflows/display/nodes/vellum/tests/test_utils.py +2 -2
- vellum_ee/workflows/display/nodes/vellum/utils.py +8 -1
- vellum_ee/workflows/display/tests/test_vellum_workflow_display.py +48 -0
- vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_adornments_serialization.py +67 -0
- vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_attributes_serialization.py +286 -0
- vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_outputs_serialization.py +177 -0
- vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_ports_serialization.py +666 -14
- vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_trigger_serialization.py +7 -8
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_inline_subworkflow_serialization.py +35 -2
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_map_node_serialization.py +29 -2
- vellum_ee/workflows/display/utils/vellum.py +4 -42
- vellum_ee/workflows/display/vellum.py +7 -36
- vellum_ee/workflows/display/workflows/vellum_workflow_display.py +5 -2
- {vellum_ai-0.13.0.dist-info → vellum_ai-0.13.2.dist-info}/LICENSE +0 -0
- {vellum_ai-0.13.0.dist-info → vellum_ai-0.13.2.dist-info}/WHEEL +0 -0
- {vellum_ai-0.13.0.dist-info → vellum_ai-0.13.2.dist-info}/entry_points.txt +0 -0
@@ -1,12 +1,11 @@
|
|
1
|
-
from typing import Any, Generic, TypeVar
|
1
|
+
from typing import Any, Generic, TypeVar, cast
|
2
2
|
|
3
|
+
from vellum.workflows.constants import UNDEF
|
3
4
|
from vellum.workflows.descriptors.base import BaseDescriptor
|
4
|
-
from vellum.workflows.expressions.and_ import AndExpression
|
5
5
|
from vellum.workflows.expressions.between import BetweenExpression
|
6
6
|
from vellum.workflows.expressions.is_not_null import IsNotNullExpression
|
7
7
|
from vellum.workflows.expressions.is_null import IsNullExpression
|
8
8
|
from vellum.workflows.expressions.not_between import NotBetweenExpression
|
9
|
-
from vellum.workflows.expressions.or_ import OrExpression
|
10
9
|
from vellum.workflows.nodes.bases.base import BaseNode
|
11
10
|
from vellum.workflows.references.execution_count import ExecutionCountReference
|
12
11
|
from vellum.workflows.references.output import OutputReference
|
@@ -14,6 +13,7 @@ from vellum.workflows.references.vellum_secret import VellumSecretReference
|
|
14
13
|
from vellum.workflows.references.workflow_input import WorkflowInputReference
|
15
14
|
from vellum.workflows.types.core import JsonArray, JsonObject
|
16
15
|
from vellum.workflows.utils.uuids import uuid4_from_hash
|
16
|
+
from vellum.workflows.utils.vellum_variables import primitive_type_to_vellum_variable_type
|
17
17
|
from vellum_ee.workflows.display.nodes.base_node_vellum_display import BaseNodeVellumDisplay
|
18
18
|
from vellum_ee.workflows.display.nodes.vellum.utils import convert_descriptor_to_operator
|
19
19
|
from vellum_ee.workflows.display.types import WorkflowDisplayContext
|
@@ -28,6 +28,18 @@ class BaseNodeDisplay(BaseNodeVellumDisplay[_BaseNodeType], Generic[_BaseNodeTyp
|
|
28
28
|
node = self._node
|
29
29
|
node_id = self.node_id
|
30
30
|
|
31
|
+
attributes: JsonArray = []
|
32
|
+
for attribute in node:
|
33
|
+
id = str(uuid4_from_hash(f"{node_id}|{attribute.name}"))
|
34
|
+
|
35
|
+
attributes.append(
|
36
|
+
{
|
37
|
+
"id": id,
|
38
|
+
"name": attribute.name,
|
39
|
+
"value": self.serialize_value(display_context, cast(BaseDescriptor, attribute.instance)),
|
40
|
+
}
|
41
|
+
)
|
42
|
+
|
31
43
|
ports: JsonArray = []
|
32
44
|
for idx, port in enumerate(node.Ports):
|
33
45
|
id = str(uuid4_from_hash(f"{node_id}|{idx}"))
|
@@ -36,6 +48,7 @@ class BaseNodeDisplay(BaseNodeVellumDisplay[_BaseNodeType], Generic[_BaseNodeTyp
|
|
36
48
|
ports.append(
|
37
49
|
{
|
38
50
|
"id": id,
|
51
|
+
"name": port.name,
|
39
52
|
"type": port._condition_type.value,
|
40
53
|
"expression": (
|
41
54
|
self.serialize_condition(display_context, port._condition) if port._condition else None
|
@@ -46,10 +59,29 @@ class BaseNodeDisplay(BaseNodeVellumDisplay[_BaseNodeType], Generic[_BaseNodeTyp
|
|
46
59
|
ports.append(
|
47
60
|
{
|
48
61
|
"id": id,
|
62
|
+
"name": port.name,
|
49
63
|
"type": "DEFAULT",
|
50
64
|
}
|
51
65
|
)
|
52
66
|
|
67
|
+
outputs: JsonArray = []
|
68
|
+
for output in node.Outputs:
|
69
|
+
type = primitive_type_to_vellum_variable_type(output)
|
70
|
+
value = (
|
71
|
+
self.serialize_value(display_context, output.instance)
|
72
|
+
if output.instance is not None and output.instance != UNDEF
|
73
|
+
else None
|
74
|
+
)
|
75
|
+
|
76
|
+
outputs.append(
|
77
|
+
{
|
78
|
+
"id": str(uuid4_from_hash(f"{node_id}|{output.name}")),
|
79
|
+
"name": output.name,
|
80
|
+
"type": type,
|
81
|
+
"value": value,
|
82
|
+
}
|
83
|
+
)
|
84
|
+
|
53
85
|
return {
|
54
86
|
"id": str(node_id),
|
55
87
|
"label": node.__qualname__,
|
@@ -63,7 +95,8 @@ class BaseNodeDisplay(BaseNodeVellumDisplay[_BaseNodeType], Generic[_BaseNodeTyp
|
|
63
95
|
},
|
64
96
|
"ports": ports,
|
65
97
|
"adornments": None,
|
66
|
-
"attributes":
|
98
|
+
"attributes": attributes,
|
99
|
+
"outputs": outputs,
|
67
100
|
}
|
68
101
|
|
69
102
|
def get_generic_node_display_data(self) -> GenericNodeDisplayData:
|
@@ -71,12 +104,25 @@ class BaseNodeDisplay(BaseNodeVellumDisplay[_BaseNodeType], Generic[_BaseNodeTyp
|
|
71
104
|
return explicit_value if explicit_value else GenericNodeDisplayData()
|
72
105
|
|
73
106
|
def serialize_condition(self, display_context: WorkflowDisplayContext, condition: BaseDescriptor) -> JsonObject:
|
74
|
-
if isinstance(condition, (
|
75
|
-
|
76
|
-
|
77
|
-
|
107
|
+
if isinstance(condition, (IsNullExpression, IsNotNullExpression)):
|
108
|
+
lhs = self.serialize_value(display_context, condition._expression) # type: ignore[attr-defined]
|
109
|
+
return {
|
110
|
+
"type": "UNARY_EXPRESSION",
|
111
|
+
"lhs": lhs,
|
112
|
+
"operator": convert_descriptor_to_operator(condition),
|
113
|
+
}
|
78
114
|
elif isinstance(condition, (BetweenExpression, NotBetweenExpression)):
|
79
|
-
|
115
|
+
base = self.serialize_value(display_context, condition._value) # type: ignore[attr-defined]
|
116
|
+
lhs = self.serialize_value(display_context, condition._start) # type: ignore[attr-defined]
|
117
|
+
rhs = self.serialize_value(display_context, condition._end) # type: ignore[attr-defined]
|
118
|
+
|
119
|
+
return {
|
120
|
+
"type": "TERNARY_EXPRESSION",
|
121
|
+
"base": base,
|
122
|
+
"operator": convert_descriptor_to_operator(condition),
|
123
|
+
"lhs": lhs,
|
124
|
+
"rhs": rhs,
|
125
|
+
}
|
80
126
|
else:
|
81
127
|
lhs = self.serialize_value(display_context, condition._lhs) # type: ignore[attr-defined]
|
82
128
|
rhs = self.serialize_value(display_context, condition._rhs) # type: ignore[attr-defined]
|
@@ -113,7 +159,7 @@ class BaseNodeDisplay(BaseNodeVellumDisplay[_BaseNodeType], Generic[_BaseNodeTyp
|
|
113
159
|
}
|
114
160
|
|
115
161
|
if isinstance(value, ExecutionCountReference):
|
116
|
-
node_class_display = display_context.
|
162
|
+
node_class_display = display_context.global_node_displays[value.node_class]
|
117
163
|
|
118
164
|
return {
|
119
165
|
"type": "EXECUTION_COUNTER",
|
@@ -127,4 +173,6 @@ class BaseNodeDisplay(BaseNodeVellumDisplay[_BaseNodeType], Generic[_BaseNodeTyp
|
|
127
173
|
"value": vellum_value.dict(),
|
128
174
|
}
|
129
175
|
|
130
|
-
|
176
|
+
# If it's not any of the references we know about,
|
177
|
+
# then try to serialize it as a nested value
|
178
|
+
return self.serialize_condition(display_context, value)
|
@@ -74,6 +74,9 @@ class BaseInlinePromptNodeDisplay(BaseNodeVellumDisplay[_InlinePromptNodeType],
|
|
74
74
|
node_inputs: List[NodeInput] = []
|
75
75
|
prompt_inputs: List[VellumVariable] = []
|
76
76
|
|
77
|
+
if not value:
|
78
|
+
return node_inputs, prompt_inputs
|
79
|
+
|
77
80
|
for variable_name, variable_value in value.items():
|
78
81
|
node_input = create_node_input(
|
79
82
|
node_id=node_id,
|
@@ -69,7 +69,7 @@ class BaseMapNodeDisplay(BaseNodeVellumDisplay[_MapNodeType], Generic[_MapNodeTy
|
|
69
69
|
"workflow_raw_data": serialized_subworkflow["workflow_raw_data"],
|
70
70
|
"input_variables": cast(JsonObject, renamed_input_variables),
|
71
71
|
"output_variables": serialized_subworkflow["output_variables"],
|
72
|
-
"concurrency": raise_if_descriptor(node.
|
72
|
+
"concurrency": raise_if_descriptor(node.max_concurrency),
|
73
73
|
"items_input_id": items_workflow_input_id,
|
74
74
|
"item_input_id": item_workflow_input_id,
|
75
75
|
"index_input_id": index_workflow_input_id,
|
@@ -27,16 +27,20 @@ class BasePromptDeploymentNodeDisplay(
|
|
27
27
|
node_id = self.node_id
|
28
28
|
|
29
29
|
prompt_inputs = raise_if_descriptor(node.prompt_inputs)
|
30
|
-
node_inputs =
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
30
|
+
node_inputs = (
|
31
|
+
[
|
32
|
+
create_node_input(
|
33
|
+
node_id=node_id,
|
34
|
+
input_name=variable_name,
|
35
|
+
value=variable_value,
|
36
|
+
display_context=display_context,
|
37
|
+
input_id=self.prompt_input_ids_by_name.get(variable_name),
|
38
|
+
)
|
39
|
+
for variable_name, variable_value in prompt_inputs.items()
|
40
|
+
]
|
41
|
+
if prompt_inputs
|
42
|
+
else []
|
43
|
+
)
|
40
44
|
|
41
45
|
_, output_display = display_context.global_node_output_displays[cast(OutputReference, node.Outputs.text)]
|
42
46
|
_, array_display = display_context.global_node_output_displays[cast(OutputReference, node.Outputs.results)]
|
@@ -2,6 +2,7 @@ import pytest
|
|
2
2
|
from uuid import UUID, uuid4
|
3
3
|
from typing import List, cast
|
4
4
|
|
5
|
+
from vellum.client.types.string_vellum_value import StringVellumValue
|
5
6
|
from vellum.workflows.descriptors.base import BaseDescriptor
|
6
7
|
from vellum.workflows.inputs import BaseInputs
|
7
8
|
from vellum.workflows.nodes.bases import BaseNode
|
@@ -19,7 +20,6 @@ from vellum_ee.workflows.display.vellum import (
|
|
19
20
|
NodeInputValuePointerRule,
|
20
21
|
NodeOutputData,
|
21
22
|
NodeOutputPointer,
|
22
|
-
StringVellumValue,
|
23
23
|
WorkflowInputsVellumDisplayOverrides,
|
24
24
|
WorkflowMetaVellumDisplay,
|
25
25
|
)
|
@@ -74,7 +74,7 @@ class MyNodeB(BaseNode):
|
|
74
74
|
type="INPUT_VARIABLE",
|
75
75
|
data=InputVariableData(input_variable_id="a154c29d-fac0-4cd0-ba88-bc52034f5470"),
|
76
76
|
),
|
77
|
-
ConstantValuePointer(type="CONSTANT_VALUE", data=StringVellumValue(
|
77
|
+
ConstantValuePointer(type="CONSTANT_VALUE", data=StringVellumValue(value="fallback")),
|
78
78
|
],
|
79
79
|
),
|
80
80
|
],
|
@@ -2,6 +2,7 @@ from uuid import UUID
|
|
2
2
|
from typing import Any, List, Optional, Type, Union, cast
|
3
3
|
|
4
4
|
from vellum.workflows.descriptors.base import BaseDescriptor
|
5
|
+
from vellum.workflows.expressions.and_ import AndExpression
|
5
6
|
from vellum.workflows.expressions.begins_with import BeginsWithExpression
|
6
7
|
from vellum.workflows.expressions.between import BetweenExpression
|
7
8
|
from vellum.workflows.expressions.coalesce_expression import CoalesceExpression
|
@@ -25,11 +26,13 @@ from vellum.workflows.expressions.less_than import LessThanExpression
|
|
25
26
|
from vellum.workflows.expressions.less_than_or_equal_to import LessThanOrEqualToExpression
|
26
27
|
from vellum.workflows.expressions.not_between import NotBetweenExpression
|
27
28
|
from vellum.workflows.expressions.not_in import NotInExpression
|
29
|
+
from vellum.workflows.expressions.or_ import OrExpression
|
30
|
+
from vellum.workflows.nodes.displayable.bases.utils import primitive_to_vellum_value
|
28
31
|
from vellum.workflows.nodes.utils import get_wrapped_node, has_wrapped_node
|
29
32
|
from vellum.workflows.references import NodeReference, OutputReference
|
30
33
|
from vellum.workflows.utils.uuids import uuid4_from_hash
|
31
34
|
from vellum_ee.workflows.display.types import WorkflowDisplayContext
|
32
|
-
from vellum_ee.workflows.display.utils.vellum import create_node_input_value_pointer_rule
|
35
|
+
from vellum_ee.workflows.display.utils.vellum import create_node_input_value_pointer_rule
|
33
36
|
from vellum_ee.workflows.display.vellum import (
|
34
37
|
ConstantValuePointer,
|
35
38
|
ExecutionCounterData,
|
@@ -170,5 +173,9 @@ def convert_descriptor_to_operator(descriptor: BaseDescriptor) -> str:
|
|
170
173
|
return "between"
|
171
174
|
elif isinstance(descriptor, NotBetweenExpression):
|
172
175
|
return "notBetween"
|
176
|
+
elif isinstance(descriptor, AndExpression):
|
177
|
+
return "and"
|
178
|
+
elif isinstance(descriptor, OrExpression):
|
179
|
+
return "or"
|
173
180
|
else:
|
174
181
|
raise ValueError(f"Unsupported descriptor type: {descriptor}")
|
@@ -1,4 +1,10 @@
|
|
1
|
+
from uuid import UUID
|
2
|
+
|
3
|
+
from vellum.workflows.inputs import BaseInputs
|
4
|
+
from vellum.workflows.nodes import BaseNode
|
5
|
+
from vellum.workflows.state import BaseState
|
1
6
|
from vellum.workflows.workflows.base import BaseWorkflow
|
7
|
+
from vellum_ee.workflows.display.vellum import WorkflowInputsVellumDisplayOverrides
|
2
8
|
from vellum_ee.workflows.display.workflows.get_vellum_workflow_display_class import get_workflow_display
|
3
9
|
from vellum_ee.workflows.display.workflows.vellum_workflow_display import VellumWorkflowDisplay
|
4
10
|
|
@@ -40,3 +46,45 @@ def test_vellum_workflow_display__serialize_empty_workflow():
|
|
40
46
|
],
|
41
47
|
},
|
42
48
|
}
|
49
|
+
|
50
|
+
|
51
|
+
def test_vellum_workflow_display__serialize_input_variables_with_capitalized_variable_override():
|
52
|
+
# GIVEN a workflow with input variables
|
53
|
+
class Inputs(BaseInputs):
|
54
|
+
foo: str
|
55
|
+
|
56
|
+
class StartNode(BaseNode):
|
57
|
+
class Outputs(BaseNode.Outputs):
|
58
|
+
output = Inputs.foo
|
59
|
+
|
60
|
+
class ExampleWorkflow(BaseWorkflow[Inputs, BaseState]):
|
61
|
+
graph = StartNode
|
62
|
+
|
63
|
+
class ExampleWorkflowDisplay(VellumWorkflowDisplay[ExampleWorkflow]):
|
64
|
+
inputs_display = {
|
65
|
+
Inputs.foo: WorkflowInputsVellumDisplayOverrides(
|
66
|
+
id=UUID("97b63d71-5413-417f-9cf5-49e1b4fd56e4"), name="Foo", required=True
|
67
|
+
)
|
68
|
+
}
|
69
|
+
|
70
|
+
display = get_workflow_display(
|
71
|
+
base_display_class=ExampleWorkflowDisplay,
|
72
|
+
workflow_class=ExampleWorkflow,
|
73
|
+
)
|
74
|
+
|
75
|
+
# WHEN serializing the workflow
|
76
|
+
exec_config = display.serialize()
|
77
|
+
|
78
|
+
# THEN the input variables are what we expect
|
79
|
+
input_variables = exec_config["input_variables"]
|
80
|
+
|
81
|
+
assert input_variables == [
|
82
|
+
{
|
83
|
+
"id": "97b63d71-5413-417f-9cf5-49e1b4fd56e4",
|
84
|
+
"key": "Foo",
|
85
|
+
"type": "STRING",
|
86
|
+
"default": None,
|
87
|
+
"required": True,
|
88
|
+
"extensions": {"color": None},
|
89
|
+
}
|
90
|
+
]
|
@@ -0,0 +1,67 @@
|
|
1
|
+
import pytest
|
2
|
+
|
3
|
+
from deepdiff import DeepDiff
|
4
|
+
|
5
|
+
from vellum.workflows.inputs.base import BaseInputs
|
6
|
+
from vellum.workflows.nodes.bases.base import BaseNode
|
7
|
+
from vellum.workflows.nodes.core.map_node.node import MapNode
|
8
|
+
from vellum.workflows.outputs.base import BaseOutputs
|
9
|
+
from vellum.workflows.state.base import BaseState
|
10
|
+
|
11
|
+
|
12
|
+
class Inputs(BaseInputs):
|
13
|
+
foo: str
|
14
|
+
|
15
|
+
|
16
|
+
class State(BaseState):
|
17
|
+
bar: str
|
18
|
+
|
19
|
+
|
20
|
+
@MapNode.wrap(items=[1, 2, 3])
|
21
|
+
class MapGenericNode(BaseNode):
|
22
|
+
item = MapNode.SubworkflowInputs.item
|
23
|
+
foo = Inputs.foo
|
24
|
+
bar = State.bar
|
25
|
+
|
26
|
+
class Outputs(BaseOutputs):
|
27
|
+
value: str
|
28
|
+
|
29
|
+
def run(self) -> Outputs:
|
30
|
+
return self.Outputs(value=f"{self.foo} {self.bar} {self.item}")
|
31
|
+
|
32
|
+
|
33
|
+
@pytest.mark.skip(reason="not implemented")
|
34
|
+
def test_serialize_node__try(serialize_node):
|
35
|
+
serialized_node = serialize_node(MapGenericNode)
|
36
|
+
assert not DeepDiff(
|
37
|
+
{
|
38
|
+
"id": "c2ed23f7-f6cb-4a56-a91c-2e5f9d8fda7f",
|
39
|
+
"label": "BasicGenericNode",
|
40
|
+
"type": "GENERIC",
|
41
|
+
"display_data": {"position": {"x": 0.0, "y": 0.0}},
|
42
|
+
"base": {"name": "BaseNode", "module": ["vellum", "workflows", "nodes", "bases", "base"]},
|
43
|
+
"definition": {
|
44
|
+
"name": "BasicGenericNode",
|
45
|
+
"module": [
|
46
|
+
"vellum_ee",
|
47
|
+
"workflows",
|
48
|
+
"display",
|
49
|
+
"tests",
|
50
|
+
"workflow_serialization",
|
51
|
+
"generic_nodes",
|
52
|
+
"test_adornments_serialization",
|
53
|
+
],
|
54
|
+
},
|
55
|
+
"trigger": {"id": "9d3a1b3d-4a38-4f2e-bbf1-dd8be152bce8", "merge_behavior": "AWAIT_ANY"},
|
56
|
+
"ports": [
|
57
|
+
{
|
58
|
+
"id": "4fbf0fff-a42e-4410-852a-238b5059198e",
|
59
|
+
"type": "DEFAULT",
|
60
|
+
}
|
61
|
+
],
|
62
|
+
"adornments": None,
|
63
|
+
"attributes": [],
|
64
|
+
},
|
65
|
+
serialized_node,
|
66
|
+
ignore_order=True,
|
67
|
+
)
|
@@ -0,0 +1,286 @@
|
|
1
|
+
from uuid import uuid4
|
2
|
+
|
3
|
+
from deepdiff import DeepDiff
|
4
|
+
|
5
|
+
from vellum.workflows.inputs.base import BaseInputs
|
6
|
+
from vellum.workflows.nodes.bases.base import BaseNode
|
7
|
+
from vellum.workflows.references.vellum_secret import VellumSecretReference
|
8
|
+
from vellum_ee.workflows.display.base import WorkflowInputsDisplay
|
9
|
+
from vellum_ee.workflows.display.nodes.types import NodeOutputDisplay
|
10
|
+
from vellum_ee.workflows.display.nodes.vellum.base_node import BaseNodeDisplay
|
11
|
+
|
12
|
+
|
13
|
+
class Inputs(BaseInputs):
|
14
|
+
input: str
|
15
|
+
|
16
|
+
|
17
|
+
class ConstantValueGenericNode(BaseNode):
|
18
|
+
attr: str = "hello"
|
19
|
+
|
20
|
+
|
21
|
+
def test_serialize_node__constant_value(serialize_node):
|
22
|
+
input_id = uuid4()
|
23
|
+
serialized_node = serialize_node(
|
24
|
+
node_class=ConstantValueGenericNode,
|
25
|
+
global_workflow_input_displays={Inputs.input: WorkflowInputsDisplay(id=input_id)},
|
26
|
+
)
|
27
|
+
|
28
|
+
assert not DeepDiff(
|
29
|
+
{
|
30
|
+
"id": "be892bc8-e4de-47ef-ab89-dc9d869af1fe",
|
31
|
+
"label": "ConstantValueGenericNode",
|
32
|
+
"type": "GENERIC",
|
33
|
+
"display_data": {"position": {"x": 0.0, "y": 0.0}},
|
34
|
+
"base": {"name": "BaseNode", "module": ["vellum", "workflows", "nodes", "bases", "base"]},
|
35
|
+
"definition": {
|
36
|
+
"name": "ConstantValueGenericNode",
|
37
|
+
"module": [
|
38
|
+
"vellum_ee",
|
39
|
+
"workflows",
|
40
|
+
"display",
|
41
|
+
"tests",
|
42
|
+
"workflow_serialization",
|
43
|
+
"generic_nodes",
|
44
|
+
"test_attributes_serialization",
|
45
|
+
],
|
46
|
+
},
|
47
|
+
"trigger": {"id": "279e8228-9b82-43a3-8c31-affc036e3a0b", "merge_behavior": "AWAIT_ANY"},
|
48
|
+
"ports": [{"id": "e6cf13b0-5590-421c-84f2-5a0b169677e1", "type": "DEFAULT", "name": "default"}],
|
49
|
+
"adornments": None,
|
50
|
+
"attributes": [
|
51
|
+
{
|
52
|
+
"id": "4cbbfd98-9ab6-41a8-bf4e-ae65f0eafe47",
|
53
|
+
"name": "attr",
|
54
|
+
"value": {
|
55
|
+
"type": "CONSTANT_VALUE",
|
56
|
+
"value": {
|
57
|
+
"type": "STRING",
|
58
|
+
"value": "hello",
|
59
|
+
},
|
60
|
+
},
|
61
|
+
}
|
62
|
+
],
|
63
|
+
"outputs": [],
|
64
|
+
},
|
65
|
+
serialized_node,
|
66
|
+
ignore_order=True,
|
67
|
+
)
|
68
|
+
|
69
|
+
|
70
|
+
class WorkflowInputGenericNode(BaseNode):
|
71
|
+
attr: str = Inputs.input
|
72
|
+
|
73
|
+
|
74
|
+
def test_serialize_node__workflow_input(serialize_node):
|
75
|
+
input_id = uuid4()
|
76
|
+
serialized_node = serialize_node(
|
77
|
+
node_class=WorkflowInputGenericNode,
|
78
|
+
global_workflow_input_displays={Inputs.input: WorkflowInputsDisplay(id=input_id)},
|
79
|
+
)
|
80
|
+
assert not DeepDiff(
|
81
|
+
{
|
82
|
+
"id": "ddfa947f-0830-476b-b07e-ac573968f9a7",
|
83
|
+
"label": "WorkflowInputGenericNode",
|
84
|
+
"type": "GENERIC",
|
85
|
+
"display_data": {"position": {"x": 0.0, "y": 0.0}},
|
86
|
+
"base": {"name": "BaseNode", "module": ["vellum", "workflows", "nodes", "bases", "base"]},
|
87
|
+
"definition": {
|
88
|
+
"name": "WorkflowInputGenericNode",
|
89
|
+
"module": [
|
90
|
+
"vellum_ee",
|
91
|
+
"workflows",
|
92
|
+
"display",
|
93
|
+
"tests",
|
94
|
+
"workflow_serialization",
|
95
|
+
"generic_nodes",
|
96
|
+
"test_attributes_serialization",
|
97
|
+
],
|
98
|
+
},
|
99
|
+
"trigger": {"id": "b1a5d749-bac0-4f11-8427-191febb2198e", "merge_behavior": "AWAIT_ANY"},
|
100
|
+
"ports": [{"id": "f013bf3f-49f6-41cd-ac13-7439b71a304a", "type": "DEFAULT", "name": "default"}],
|
101
|
+
"adornments": None,
|
102
|
+
"attributes": [
|
103
|
+
{
|
104
|
+
"id": "56d44313-cfdd-4d75-9b19-0beb94e59c4e",
|
105
|
+
"name": "attr",
|
106
|
+
"value": {
|
107
|
+
"type": "WORKFLOW_INPUT",
|
108
|
+
"input_variable_id": str(input_id),
|
109
|
+
},
|
110
|
+
}
|
111
|
+
],
|
112
|
+
"outputs": [],
|
113
|
+
},
|
114
|
+
serialized_node,
|
115
|
+
ignore_order=True,
|
116
|
+
)
|
117
|
+
|
118
|
+
|
119
|
+
class NodeWithOutput(BaseNode):
|
120
|
+
class Outputs(BaseNode.Outputs):
|
121
|
+
output = Inputs.input
|
122
|
+
|
123
|
+
|
124
|
+
class NodeWithOutputDisplay(BaseNodeDisplay[NodeWithOutput]):
|
125
|
+
pass
|
126
|
+
|
127
|
+
|
128
|
+
class GenericNodeReferencingOutput(BaseNode):
|
129
|
+
attr = NodeWithOutput.Outputs.output
|
130
|
+
|
131
|
+
|
132
|
+
def test_serialize_node__node_output(serialize_node):
|
133
|
+
workflow_input_id = uuid4()
|
134
|
+
node_output_id = uuid4()
|
135
|
+
serialized_node = serialize_node(
|
136
|
+
node_class=GenericNodeReferencingOutput,
|
137
|
+
global_workflow_input_displays={Inputs.input: WorkflowInputsDisplay(id=workflow_input_id)},
|
138
|
+
global_node_displays={NodeWithOutput: NodeWithOutputDisplay()},
|
139
|
+
global_node_output_displays={
|
140
|
+
NodeWithOutput.Outputs.output: (NodeWithOutput, NodeOutputDisplay(id=node_output_id, name="output"))
|
141
|
+
},
|
142
|
+
)
|
143
|
+
|
144
|
+
assert not DeepDiff(
|
145
|
+
{
|
146
|
+
"id": "c1e2ce60-ac3a-4b17-915e-abe861734e03",
|
147
|
+
"label": "GenericNodeReferencingOutput",
|
148
|
+
"type": "GENERIC",
|
149
|
+
"display_data": {"position": {"x": 0.0, "y": 0.0}},
|
150
|
+
"base": {"name": "BaseNode", "module": ["vellum", "workflows", "nodes", "bases", "base"]},
|
151
|
+
"definition": {
|
152
|
+
"name": "GenericNodeReferencingOutput",
|
153
|
+
"module": [
|
154
|
+
"vellum_ee",
|
155
|
+
"workflows",
|
156
|
+
"display",
|
157
|
+
"tests",
|
158
|
+
"workflow_serialization",
|
159
|
+
"generic_nodes",
|
160
|
+
"test_attributes_serialization",
|
161
|
+
],
|
162
|
+
},
|
163
|
+
"trigger": {"id": "449072ba-f7b6-4314-ac96-682123f225e5", "merge_behavior": "AWAIT_ANY"},
|
164
|
+
"ports": [{"id": "ec9a79b8-65c3-4de8-bd29-42c914d72d4f", "type": "DEFAULT", "name": "default"}],
|
165
|
+
"adornments": None,
|
166
|
+
"attributes": [
|
167
|
+
{
|
168
|
+
"id": "73e6a103-1339-41ec-a245-42d43b0637c1",
|
169
|
+
"name": "attr",
|
170
|
+
"value": {
|
171
|
+
"type": "NODE_OUTPUT",
|
172
|
+
"node_id": "cd954d76-0b0a-4d9b-9bdf-347179c38cb6",
|
173
|
+
"node_output_id": str(node_output_id),
|
174
|
+
},
|
175
|
+
}
|
176
|
+
],
|
177
|
+
"outputs": [],
|
178
|
+
},
|
179
|
+
serialized_node,
|
180
|
+
ignore_order=True,
|
181
|
+
)
|
182
|
+
|
183
|
+
|
184
|
+
class VellumSecretGenericNode(BaseNode):
|
185
|
+
attr = VellumSecretReference(name="hello")
|
186
|
+
|
187
|
+
|
188
|
+
def test_serialize_node__vellum_secret(serialize_node):
|
189
|
+
input_id = uuid4()
|
190
|
+
serialized_node = serialize_node(
|
191
|
+
node_class=VellumSecretGenericNode,
|
192
|
+
global_workflow_input_displays={Inputs.input: WorkflowInputsDisplay(id=input_id)},
|
193
|
+
)
|
194
|
+
assert not DeepDiff(
|
195
|
+
{
|
196
|
+
"id": "89aa6faa-b533-4179-8912-70a048bf0712",
|
197
|
+
"label": "VellumSecretGenericNode",
|
198
|
+
"type": "GENERIC",
|
199
|
+
"display_data": {"position": {"x": 0.0, "y": 0.0}},
|
200
|
+
"base": {"name": "BaseNode", "module": ["vellum", "workflows", "nodes", "bases", "base"]},
|
201
|
+
"definition": {
|
202
|
+
"name": "VellumSecretGenericNode",
|
203
|
+
"module": [
|
204
|
+
"vellum_ee",
|
205
|
+
"workflows",
|
206
|
+
"display",
|
207
|
+
"tests",
|
208
|
+
"workflow_serialization",
|
209
|
+
"generic_nodes",
|
210
|
+
"test_attributes_serialization",
|
211
|
+
],
|
212
|
+
},
|
213
|
+
"trigger": {"id": "3ea0305d-d8ea-45fe-8cf1-f6c1c85e6979", "merge_behavior": "AWAIT_ANY"},
|
214
|
+
"ports": [{"id": "69e49322-8f8a-42d2-b36f-3fbe53dad616", "type": "DEFAULT", "name": "default"}],
|
215
|
+
"adornments": None,
|
216
|
+
"attributes": [
|
217
|
+
{
|
218
|
+
"id": "8edd27da-eec1-4539-8bec-629b5ef7a9f9",
|
219
|
+
"name": "attr",
|
220
|
+
"value": {"type": "VELLUM_SECRET", "vellum_secret_name": "hello"},
|
221
|
+
}
|
222
|
+
],
|
223
|
+
"outputs": [],
|
224
|
+
},
|
225
|
+
serialized_node,
|
226
|
+
ignore_order=True,
|
227
|
+
)
|
228
|
+
|
229
|
+
|
230
|
+
class NodeWithExecutions(BaseNode):
|
231
|
+
pass
|
232
|
+
|
233
|
+
|
234
|
+
class NodeWithExecutionsDisplay(BaseNodeDisplay[NodeWithExecutions]):
|
235
|
+
pass
|
236
|
+
|
237
|
+
|
238
|
+
class GenericNodeReferencingExecutions(BaseNode):
|
239
|
+
attr: int = NodeWithExecutions.Execution.count
|
240
|
+
|
241
|
+
|
242
|
+
def test_serialize_node__node_execution(serialize_node):
|
243
|
+
workflow_input_id = uuid4()
|
244
|
+
serialized_node = serialize_node(
|
245
|
+
node_class=GenericNodeReferencingExecutions,
|
246
|
+
global_workflow_input_displays={Inputs.input: WorkflowInputsDisplay(id=workflow_input_id)},
|
247
|
+
global_node_displays={NodeWithExecutions: NodeWithExecutionsDisplay()},
|
248
|
+
)
|
249
|
+
|
250
|
+
assert not DeepDiff(
|
251
|
+
{
|
252
|
+
"id": "6e4d2fb7-891e-492e-97a1-adf44693f518",
|
253
|
+
"label": "GenericNodeReferencingExecutions",
|
254
|
+
"type": "GENERIC",
|
255
|
+
"display_data": {"position": {"x": 0.0, "y": 0.0}},
|
256
|
+
"base": {"name": "BaseNode", "module": ["vellum", "workflows", "nodes", "bases", "base"]},
|
257
|
+
"definition": {
|
258
|
+
"name": "GenericNodeReferencingExecutions",
|
259
|
+
"module": [
|
260
|
+
"vellum_ee",
|
261
|
+
"workflows",
|
262
|
+
"display",
|
263
|
+
"tests",
|
264
|
+
"workflow_serialization",
|
265
|
+
"generic_nodes",
|
266
|
+
"test_attributes_serialization",
|
267
|
+
],
|
268
|
+
},
|
269
|
+
"trigger": {"id": "68a91426-4c30-4194-a4c0-cff224d3c0f3", "merge_behavior": "AWAIT_ANY"},
|
270
|
+
"ports": [{"id": "1794c2eb-5cab-49fe-9354-dfc29f11b374", "type": "DEFAULT", "name": "default"}],
|
271
|
+
"adornments": None,
|
272
|
+
"attributes": [
|
273
|
+
{
|
274
|
+
"id": "090e18d7-d5b9-4d5f-9aec-0f562e4b33a8",
|
275
|
+
"name": "attr",
|
276
|
+
"value": {
|
277
|
+
"type": "EXECUTION_COUNTER",
|
278
|
+
"node_id": "c09bd5a6-dc04-4036-90d4-580acd43c71f",
|
279
|
+
},
|
280
|
+
}
|
281
|
+
],
|
282
|
+
"outputs": [],
|
283
|
+
},
|
284
|
+
serialized_node,
|
285
|
+
ignore_order=True,
|
286
|
+
)
|