vellum-ai 0.13.0__py3-none-any.whl → 0.13.2__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
)
|