vellum-ai 0.10.6__py3-none-any.whl → 0.10.8__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/__init__.py +2 -0
- vellum/client/README.md +7 -52
- vellum/client/__init__.py +16 -136
- vellum/client/core/client_wrapper.py +1 -1
- vellum/client/resources/ad_hoc/client.py +14 -104
- vellum/client/resources/metric_definitions/client.py +113 -0
- vellum/client/resources/test_suites/client.py +8 -16
- vellum/client/resources/workflows/client.py +0 -32
- vellum/client/types/__init__.py +2 -0
- vellum/client/types/metric_definition_history_item.py +39 -0
- vellum/types/metric_definition_history_item.py +3 -0
- vellum/workflows/events/node.py +36 -3
- vellum/workflows/events/tests/test_event.py +89 -9
- vellum/workflows/events/types.py +1 -1
- vellum/workflows/nodes/core/inline_subworkflow_node/node.py +1 -0
- vellum/workflows/nodes/core/templating_node/node.py +5 -0
- vellum/workflows/nodes/displayable/api_node/node.py +1 -1
- vellum/workflows/nodes/displayable/bases/prompt_deployment_node.py +1 -2
- vellum/workflows/nodes/displayable/code_execution_node/node.py +1 -2
- vellum/workflows/nodes/displayable/code_execution_node/utils.py +13 -2
- vellum/workflows/nodes/displayable/conditional_node/node.py +2 -2
- vellum/workflows/nodes/displayable/inline_prompt_node/node.py +10 -3
- vellum/workflows/nodes/displayable/prompt_deployment_node/node.py +6 -1
- vellum/workflows/nodes/displayable/subworkflow_deployment_node/node.py +1 -2
- vellum/workflows/nodes/displayable/tests/test_text_prompt_deployment_node.py +1 -2
- vellum/workflows/ports/node_ports.py +2 -2
- vellum/workflows/ports/port.py +14 -0
- vellum/workflows/references/__init__.py +2 -0
- vellum/workflows/runner/runner.py +49 -8
- vellum/workflows/runner/types.py +1 -3
- vellum/workflows/state/encoder.py +2 -1
- vellum/workflows/types/__init__.py +5 -0
- vellum/workflows/types/tests/test_utils.py +6 -3
- vellum/workflows/types/utils.py +3 -0
- {vellum_ai-0.10.6.dist-info → vellum_ai-0.10.8.dist-info}/METADATA +1 -1
- {vellum_ai-0.10.6.dist-info → vellum_ai-0.10.8.dist-info}/RECORD +49 -47
- vellum_cli/__init__.py +23 -4
- vellum_cli/pull.py +28 -13
- vellum_cli/tests/test_pull.py +45 -2
- vellum_ee/workflows/display/nodes/base_node_display.py +1 -1
- vellum_ee/workflows/display/nodes/vellum/code_execution_node.py +17 -2
- vellum_ee/workflows/display/nodes/vellum/final_output_node.py +4 -2
- vellum_ee/workflows/display/nodes/vellum/map_node.py +20 -48
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_conditional_node_serialization.py +5 -16
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_map_node_serialization.py +11 -8
- vellum_ee/workflows/display/utils/vellum.py +3 -2
- {vellum_ai-0.10.6.dist-info → vellum_ai-0.10.8.dist-info}/LICENSE +0 -0
- {vellum_ai-0.10.6.dist-info → vellum_ai-0.10.8.dist-info}/WHEEL +0 -0
- {vellum_ai-0.10.6.dist-info → vellum_ai-0.10.8.dist-info}/entry_points.txt +0 -0
vellum_cli/pull.py
CHANGED
@@ -7,28 +7,38 @@ from typing import Optional
|
|
7
7
|
from dotenv import load_dotenv
|
8
8
|
|
9
9
|
from vellum.workflows.vellum_client import create_vellum_client
|
10
|
-
from vellum_cli.config import load_vellum_cli_config
|
10
|
+
from vellum_cli.config import WorkflowConfig, load_vellum_cli_config
|
11
11
|
from vellum_cli.logger import load_cli_logger
|
12
12
|
|
13
13
|
|
14
14
|
def pull_command(
|
15
|
-
module: Optional[str]
|
15
|
+
module: Optional[str] = None,
|
16
|
+
workflow_sandbox_id: Optional[str] = None,
|
17
|
+
include_json: Optional[bool] = None,
|
18
|
+
exclude_code: Optional[bool] = None,
|
16
19
|
) -> None:
|
17
20
|
load_dotenv()
|
18
21
|
logger = load_cli_logger()
|
19
22
|
config = load_vellum_cli_config()
|
20
23
|
|
21
|
-
if not config.workflows:
|
22
|
-
raise ValueError("No Workflows found in project to pull.")
|
23
|
-
|
24
|
-
if len(config.workflows) > 1 and not module:
|
25
|
-
raise ValueError("Multiple workflows found in project to pull. Pulling only a single workflow is supported.")
|
26
|
-
|
27
24
|
workflow_config = (
|
28
|
-
next((w for w in config.workflows if w.module == module), None)
|
25
|
+
next((w for w in config.workflows if w.module == module), None)
|
26
|
+
if module
|
27
|
+
else (config.workflows[0] if config.workflows else None)
|
29
28
|
)
|
29
|
+
save_lock_file = False
|
30
30
|
if workflow_config is None:
|
31
|
-
|
31
|
+
if module:
|
32
|
+
raise ValueError(f"No workflow config for '{module}' found in project to pull.")
|
33
|
+
elif workflow_sandbox_id:
|
34
|
+
workflow_config = WorkflowConfig(
|
35
|
+
workflow_sandbox_id=workflow_sandbox_id,
|
36
|
+
module=f"workflow_{workflow_sandbox_id.split('-')[0]}",
|
37
|
+
)
|
38
|
+
config.workflows.append(workflow_config)
|
39
|
+
save_lock_file = True
|
40
|
+
else:
|
41
|
+
raise ValueError("No workflow config found in project to pull from.")
|
32
42
|
|
33
43
|
if not workflow_config.workflow_sandbox_id:
|
34
44
|
raise ValueError("No workflow sandbox ID found in project to pull from.")
|
@@ -36,10 +46,10 @@ def pull_command(
|
|
36
46
|
logger.info(f"Pulling workflow into {workflow_config.module}")
|
37
47
|
client = create_vellum_client()
|
38
48
|
query_parameters = {}
|
39
|
-
if legacy_module:
|
40
|
-
query_parameters["legacyModule"] = legacy_module
|
41
49
|
if include_json:
|
42
50
|
query_parameters["include_json"] = include_json
|
51
|
+
if exclude_code:
|
52
|
+
query_parameters["exclude_code"] = exclude_code
|
43
53
|
|
44
54
|
response = client.workflows.pull(
|
45
55
|
workflow_config.workflow_sandbox_id,
|
@@ -81,6 +91,11 @@ def pull_command(
|
|
81
91
|
target.write(source.read().decode("utf-8"))
|
82
92
|
|
83
93
|
if include_json:
|
84
|
-
logger.warning(
|
94
|
+
logger.warning(
|
95
|
+
"The pulled JSON representation of the Workflow should be used for debugging purposely only. Its schema should be considered unstable and subject to change at any time."
|
96
|
+
)
|
97
|
+
|
98
|
+
if save_lock_file:
|
99
|
+
config.save()
|
85
100
|
|
86
101
|
logger.info(f"Successfully pulled Workflow into {workflow_config.module}")
|
vellum_cli/tests/test_pull.py
CHANGED
@@ -69,8 +69,33 @@ def test_pull(vellum_client, mock_module):
|
|
69
69
|
pull_command(module)
|
70
70
|
|
71
71
|
# THEN the workflow.py file is written to the module directory
|
72
|
-
|
73
|
-
|
72
|
+
workflow_py = os.path.join(temp_dir, *module.split("."), "workflow.py")
|
73
|
+
assert os.path.exists(workflow_py)
|
74
|
+
with open(workflow_py) as f:
|
75
|
+
assert f.read() == "print('hello')"
|
76
|
+
|
77
|
+
|
78
|
+
def test_pull__sandbox_id_with_no_config(vellum_client):
|
79
|
+
# GIVEN a workflow sandbox id
|
80
|
+
workflow_sandbox_id = "87654321-0000-0000-0000-000000000000"
|
81
|
+
|
82
|
+
# AND the workflow pull API call returns a zip file
|
83
|
+
vellum_client.workflows.pull.return_value = iter([zip_file_map({"workflow.py": "print('hello')"})])
|
84
|
+
|
85
|
+
# AND we are currently in a new directory
|
86
|
+
current_dir = os.getcwd()
|
87
|
+
temp_dir = tempfile.mkdtemp()
|
88
|
+
os.chdir(temp_dir)
|
89
|
+
|
90
|
+
# WHEN the user runs the pull command with the workflow sandbox id and no module
|
91
|
+
pull_command(workflow_sandbox_id=workflow_sandbox_id)
|
92
|
+
os.chdir(current_dir)
|
93
|
+
|
94
|
+
# THEN the pull api is called with exclude_code=True
|
95
|
+
vellum_client.workflows.pull.assert_called_once()
|
96
|
+
workflow_py = os.path.join(temp_dir, "workflow_87654321", "workflow.py")
|
97
|
+
assert os.path.exists(workflow_py)
|
98
|
+
with open(workflow_py) as f:
|
74
99
|
assert f.read() == "print('hello')"
|
75
100
|
|
76
101
|
|
@@ -168,3 +193,21 @@ def test_pull__include_json(vellum_client, mock_module):
|
|
168
193
|
vellum_client.workflows.pull.assert_called_once()
|
169
194
|
call_args = vellum_client.workflows.pull.call_args.kwargs
|
170
195
|
assert call_args["request_options"]["additional_query_parameters"] == {"include_json": True}
|
196
|
+
|
197
|
+
|
198
|
+
def test_pull__exclude_code(vellum_client, mock_module):
|
199
|
+
# GIVEN a module on the user's filesystem
|
200
|
+
_, module = mock_module
|
201
|
+
|
202
|
+
# AND the workflow pull API call returns a zip file
|
203
|
+
vellum_client.workflows.pull.return_value = iter(
|
204
|
+
[zip_file_map({"workflow.py": "print('hello')", "workflow.json": "{}"})]
|
205
|
+
)
|
206
|
+
|
207
|
+
# WHEN the user runs the pull command
|
208
|
+
pull_command(module, exclude_code=True)
|
209
|
+
|
210
|
+
# THEN the pull api is called with exclude_code=True
|
211
|
+
vellum_client.workflows.pull.assert_called_once()
|
212
|
+
call_args = vellum_client.workflows.pull.call_args.kwargs
|
213
|
+
assert call_args["request_options"]["additional_query_parameters"] == {"exclude_code": True}
|
@@ -1,7 +1,7 @@
|
|
1
1
|
from functools import cached_property
|
2
2
|
import inspect
|
3
3
|
from uuid import UUID
|
4
|
-
from typing import TYPE_CHECKING, Any, Dict, Generic, Optional, Type, TypeVar, get_args, get_origin
|
4
|
+
from typing import TYPE_CHECKING, Any, Dict, Generic, Optional, Type, TypeVar, cast, get_args, get_origin
|
5
5
|
|
6
6
|
from vellum.workflows.nodes.bases.base import BaseNode
|
7
7
|
from vellum.workflows.nodes.utils import get_wrapped_node, has_wrapped_node
|
@@ -1,5 +1,5 @@
|
|
1
1
|
from uuid import UUID
|
2
|
-
from typing import ClassVar, Generic, Optional, TypeVar
|
2
|
+
from typing import ClassVar, Dict, Generic, Optional, TypeVar
|
3
3
|
|
4
4
|
from vellum.workflows.nodes.displayable.code_execution_node import CodeExecutionNode
|
5
5
|
from vellum.workflows.nodes.displayable.code_execution_node.utils import read_file_from_path
|
@@ -20,6 +20,8 @@ class BaseCodeExecutionNodeDisplay(BaseNodeVellumDisplay[_CodeExecutionNodeType]
|
|
20
20
|
output_id: ClassVar[Optional[UUID]] = None
|
21
21
|
log_output_id: ClassVar[Optional[UUID]] = None
|
22
22
|
|
23
|
+
node_input_ids_by_name: ClassVar[Dict[str, UUID]] = {}
|
24
|
+
|
23
25
|
def serialize(
|
24
26
|
self, display_context: WorkflowDisplayContext, error_output_id: Optional[UUID] = None, **kwargs
|
25
27
|
) -> JsonObject:
|
@@ -27,6 +29,19 @@ class BaseCodeExecutionNodeDisplay(BaseNodeVellumDisplay[_CodeExecutionNodeType]
|
|
27
29
|
node_id = self.node_id
|
28
30
|
|
29
31
|
code = read_file_from_path(raise_if_descriptor(node.filepath))
|
32
|
+
code_inputs = raise_if_descriptor(node.code_inputs)
|
33
|
+
|
34
|
+
inputs = [
|
35
|
+
create_node_input(
|
36
|
+
node_id=node_id,
|
37
|
+
input_name=variable_name,
|
38
|
+
value=variable_value,
|
39
|
+
display_context=display_context,
|
40
|
+
input_id=self.node_input_ids_by_name.get(variable_name),
|
41
|
+
)
|
42
|
+
for variable_name, variable_value in code_inputs.items()
|
43
|
+
]
|
44
|
+
|
30
45
|
code_node_input = create_node_input(
|
31
46
|
node_id=node_id,
|
32
47
|
input_name="code",
|
@@ -41,7 +56,7 @@ class BaseCodeExecutionNodeDisplay(BaseNodeVellumDisplay[_CodeExecutionNodeType]
|
|
41
56
|
display_context=display_context,
|
42
57
|
input_id=self.runtime_input_id,
|
43
58
|
)
|
44
|
-
inputs
|
59
|
+
inputs.extend([code_node_input, runtime_node_input])
|
45
60
|
|
46
61
|
packages = raise_if_descriptor(node.packages)
|
47
62
|
|
@@ -1,14 +1,16 @@
|
|
1
1
|
from uuid import UUID
|
2
2
|
from typing import Any, ClassVar, Generic, Optional, TypeVar
|
3
3
|
|
4
|
+
from vellum.workflows.nodes.core.map_node.node import MapNode
|
5
|
+
from vellum.workflows.nodes.displayable.final_output_node import FinalOutputNode
|
6
|
+
from vellum.workflows.references.output import OutputReference
|
7
|
+
from vellum.workflows.types.core import JsonObject
|
4
8
|
from vellum_ee.workflows.display.nodes.base_node_vellum_display import BaseNodeVellumDisplay
|
5
9
|
from vellum_ee.workflows.display.nodes.utils import to_kebab_case
|
6
10
|
from vellum_ee.workflows.display.nodes.vellum.utils import create_node_input
|
7
11
|
from vellum_ee.workflows.display.types import WorkflowDisplayContext
|
8
12
|
from vellum_ee.workflows.display.utils.uuids import uuid4_from_hash
|
9
13
|
from vellum_ee.workflows.display.utils.vellum import infer_vellum_variable_type
|
10
|
-
from vellum.workflows.nodes.displayable.final_output_node import FinalOutputNode
|
11
|
-
from vellum.workflows.types.core import JsonObject
|
12
14
|
|
13
15
|
_FinalOutputNodeType = TypeVar("_FinalOutputNodeType", bound=FinalOutputNode)
|
14
16
|
|
@@ -1,59 +1,32 @@
|
|
1
1
|
from uuid import UUID
|
2
|
-
from typing import
|
2
|
+
from typing import Collection, Dict, Generic, List, Optional, TypeVar, cast
|
3
3
|
|
4
|
-
from vellum import VellumVariable
|
5
4
|
from vellum.workflows.nodes import MapNode
|
6
5
|
from vellum.workflows.types.core import JsonObject
|
7
6
|
from vellum_ee.workflows.display.nodes.base_node_vellum_display import BaseNodeVellumDisplay
|
8
7
|
from vellum_ee.workflows.display.nodes.utils import raise_if_descriptor
|
9
8
|
from vellum_ee.workflows.display.nodes.vellum.utils import create_node_input
|
10
9
|
from vellum_ee.workflows.display.types import WorkflowDisplayContext
|
11
|
-
from vellum_ee.workflows.display.utils.uuids import uuid4_from_hash
|
12
|
-
from vellum_ee.workflows.display.utils.vellum import infer_vellum_variable_type
|
13
10
|
from vellum_ee.workflows.display.workflows.get_vellum_workflow_display_class import get_workflow_display
|
14
11
|
|
15
12
|
_MapNodeType = TypeVar("_MapNodeType", bound=MapNode)
|
16
13
|
|
17
14
|
|
18
15
|
class BaseMapNodeDisplay(BaseNodeVellumDisplay[_MapNodeType], Generic[_MapNodeType]):
|
19
|
-
workflow_input_ids_by_name: ClassVar[Dict[str, UUID]] = {}
|
20
|
-
|
21
16
|
def serialize(
|
22
17
|
self, display_context: WorkflowDisplayContext, error_output_id: Optional[UUID] = None, **kwargs
|
23
18
|
) -> JsonObject:
|
24
19
|
node = self._node
|
25
20
|
node_id = self.node_id
|
26
21
|
|
27
|
-
workflow_inputs: List[VellumVariable] = []
|
28
22
|
subworkflow = raise_if_descriptor(node.subworkflow)
|
29
|
-
for descriptor in subworkflow.get_inputs_class():
|
30
|
-
# In WaC it's always 'all_items'
|
31
|
-
# In Vellum it's always 'items'
|
32
|
-
variable_name = descriptor.name if descriptor.name != "all_items" else "items"
|
33
|
-
variable_id = str(
|
34
|
-
self.workflow_input_ids_by_name.get(variable_name)
|
35
|
-
or uuid4_from_hash(f"{self.node_id}|{variable_name}")
|
36
|
-
)
|
37
|
-
workflow_inputs.append(
|
38
|
-
VellumVariable(
|
39
|
-
id=variable_id,
|
40
|
-
key=variable_name,
|
41
|
-
type=infer_vellum_variable_type(descriptor),
|
42
|
-
)
|
43
|
-
)
|
44
|
-
|
45
|
-
items_workflow_input = next(input for input in workflow_inputs if input.key == "items")
|
46
|
-
item_workflow_input = next(input for input in workflow_inputs if input.key == "item")
|
47
|
-
index_workflow_input = next(input for input in workflow_inputs if input.key == "index")
|
48
|
-
|
49
|
-
workflow_outputs = self._generate_workflow_outputs(node)
|
50
23
|
|
51
24
|
items_node_input = create_node_input(
|
52
25
|
node_id=node_id,
|
53
26
|
input_name="items",
|
54
27
|
value=node.items,
|
55
28
|
display_context=display_context,
|
56
|
-
input_id=
|
29
|
+
input_id=self.node_input_ids_by_name.get("items"),
|
57
30
|
)
|
58
31
|
node_inputs = [items_node_input]
|
59
32
|
|
@@ -63,6 +36,19 @@ class BaseMapNodeDisplay(BaseNodeVellumDisplay[_MapNodeType], Generic[_MapNodeTy
|
|
63
36
|
)
|
64
37
|
serialized_subworkflow = subworkflow_display.serialize()
|
65
38
|
|
39
|
+
renamed_input_variables = []
|
40
|
+
for input_variable in cast(List[Dict[str, str]], serialized_subworkflow["input_variables"]):
|
41
|
+
if input_variable["key"] == "all_items":
|
42
|
+
renamed_item = { **input_variable, "key": "items" }
|
43
|
+
renamed_input_variables.append(renamed_item)
|
44
|
+
else:
|
45
|
+
renamed_input_variables.append(input_variable)
|
46
|
+
|
47
|
+
# Note: This must match the items input ID for the map node's node input
|
48
|
+
items_workflow_input_id = next(input_variable["id"] for input_variable in renamed_input_variables if input_variable["key"] == "items")
|
49
|
+
item_workflow_input_id = next(input_variable["id"] for input_variable in renamed_input_variables if input_variable["key"] == "item")
|
50
|
+
index_workflow_input_id = next(input_variable["id"] for input_variable in renamed_input_variables if input_variable["key"] == "index")
|
51
|
+
|
66
52
|
return {
|
67
53
|
"id": str(node_id),
|
68
54
|
"type": "MAP",
|
@@ -74,27 +60,13 @@ class BaseMapNodeDisplay(BaseNodeVellumDisplay[_MapNodeType], Generic[_MapNodeTy
|
|
74
60
|
"target_handle_id": str(self.get_target_handle_id()),
|
75
61
|
"variant": "INLINE",
|
76
62
|
"workflow_raw_data": serialized_subworkflow["workflow_raw_data"],
|
77
|
-
"input_variables":
|
78
|
-
"output_variables": [
|
63
|
+
"input_variables": cast(JsonObject, renamed_input_variables),
|
64
|
+
"output_variables": serialized_subworkflow["output_variables"],
|
79
65
|
"concurrency": raise_if_descriptor(node.concurrency),
|
80
|
-
"items_input_id":
|
81
|
-
"item_input_id":
|
82
|
-
"index_input_id":
|
66
|
+
"items_input_id": items_workflow_input_id,
|
67
|
+
"item_input_id": item_workflow_input_id,
|
68
|
+
"index_input_id": index_workflow_input_id,
|
83
69
|
},
|
84
70
|
"display_data": self.get_display_data().dict(),
|
85
71
|
"definition": self.get_definition().dict(),
|
86
72
|
}
|
87
|
-
|
88
|
-
def _generate_workflow_outputs(
|
89
|
-
self,
|
90
|
-
node: Type[MapNode],
|
91
|
-
) -> List[VellumVariable]:
|
92
|
-
workflow_outputs: List[VellumVariable] = []
|
93
|
-
for output_descriptor in raise_if_descriptor(node.subworkflow).Outputs: # type: ignore[union-attr]
|
94
|
-
node_output_display = self.get_node_output_display(output_descriptor)
|
95
|
-
output_type = infer_vellum_variable_type(output_descriptor)
|
96
|
-
workflow_outputs.append(
|
97
|
-
VellumVariable(id=str(node_output_display.id), key=node_output_display.name, type=output_type)
|
98
|
-
)
|
99
|
-
|
100
|
-
return workflow_outputs
|
@@ -13,30 +13,20 @@ from vellum.workflows.expressions.does_not_equal import DoesNotEqualExpression
|
|
13
13
|
from vellum.workflows.expressions.ends_with import EndsWithExpression
|
14
14
|
from vellum.workflows.expressions.equals import EqualsExpression
|
15
15
|
from vellum.workflows.expressions.greater_than import GreaterThanExpression
|
16
|
-
from vellum.workflows.expressions.greater_than_or_equal_to import
|
17
|
-
GreaterThanOrEqualToExpression,
|
18
|
-
)
|
16
|
+
from vellum.workflows.expressions.greater_than_or_equal_to import GreaterThanOrEqualToExpression
|
19
17
|
from vellum.workflows.expressions.in_ import InExpression
|
20
18
|
from vellum.workflows.expressions.is_not_null import IsNotNullExpression
|
21
19
|
from vellum.workflows.expressions.is_null import IsNullExpression
|
22
20
|
from vellum.workflows.expressions.less_than import LessThanExpression
|
23
|
-
from vellum.workflows.expressions.less_than_or_equal_to import
|
24
|
-
LessThanOrEqualToExpression,
|
25
|
-
)
|
21
|
+
from vellum.workflows.expressions.less_than_or_equal_to import LessThanOrEqualToExpression
|
26
22
|
from vellum.workflows.expressions.not_between import NotBetweenExpression
|
27
23
|
from vellum.workflows.expressions.not_in import NotInExpression
|
28
|
-
from vellum_ee.workflows.display.nodes.base_node_vellum_display import
|
29
|
-
BaseNodeVellumDisplay,
|
30
|
-
)
|
24
|
+
from vellum_ee.workflows.display.nodes.base_node_vellum_display import BaseNodeVellumDisplay
|
31
25
|
from vellum_ee.workflows.display.workflows import VellumWorkflowDisplay
|
32
|
-
from vellum_ee.workflows.display.workflows.get_vellum_workflow_display_class import
|
33
|
-
get_workflow_display,
|
34
|
-
)
|
26
|
+
from vellum_ee.workflows.display.workflows.get_vellum_workflow_display_class import get_workflow_display
|
35
27
|
|
36
28
|
from tests.workflows.basic_conditional_node.workflow import CategoryWorkflow
|
37
|
-
from tests.workflows.basic_conditional_node.workflow_with_only_one_conditional_node import
|
38
|
-
create_simple_workflow,
|
39
|
-
)
|
29
|
+
from tests.workflows.basic_conditional_node.workflow_with_only_one_conditional_node import create_simple_workflow
|
40
30
|
|
41
31
|
|
42
32
|
def test_serialize_workflow():
|
@@ -965,7 +955,6 @@ def test_conditional_node_serialize_all_operators_with_lhs_and_rhs(
|
|
965
955
|
|
966
956
|
# AND the conditional node should be what we expect
|
967
957
|
conditional_node = workflow_raw_data["nodes"][1]
|
968
|
-
print(conditional_node)
|
969
958
|
assert not DeepDiff(
|
970
959
|
{
|
971
960
|
"id": "a9143814-6bb0-4cb3-a817-4fc076417121",
|
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_map_node_serialization.py
CHANGED
@@ -228,15 +228,15 @@ def test_serialize_workflow():
|
|
228
228
|
},
|
229
229
|
},
|
230
230
|
"input_variables": [
|
231
|
-
{"id": "
|
232
|
-
{"id": "
|
233
|
-
{"id": "
|
231
|
+
{"id": "b29bb546-9bc8-4136-857d-8c7a464ba9d4", "key": "item", "type": "JSON", "required": True, "default": None, "extensions": {"color": None}},
|
232
|
+
{"id": "17e7ca49-668f-450d-a792-e1f97d13db67", "key": "index", "type": "NUMBER", "required": True, "default": None, "extensions": {"color": None}},
|
233
|
+
{"id": "d6fc6c7a-235f-4b98-86f3-e258d1198f93", "key": "items", "type": "JSON", "required": True, "default": None, "extensions": {"color": None}},
|
234
234
|
],
|
235
|
-
"output_variables": [{"id": "
|
235
|
+
"output_variables": [{"id": "2a957315-fae0-4366-8a35-f0b315c5eade", "key": "count", "type": "NUMBER"}],
|
236
236
|
"concurrency": None,
|
237
|
-
"items_input_id": "
|
238
|
-
"item_input_id": "
|
239
|
-
"index_input_id": "
|
237
|
+
"items_input_id": "d6fc6c7a-235f-4b98-86f3-e258d1198f93",
|
238
|
+
"item_input_id": "b29bb546-9bc8-4136-857d-8c7a464ba9d4",
|
239
|
+
"index_input_id": "17e7ca49-668f-450d-a792-e1f97d13db67",
|
240
240
|
},
|
241
241
|
"display_data": {"position": {"x": 0.0, "y": 0.0}},
|
242
242
|
"definition": {
|
@@ -288,7 +288,7 @@ def test_serialize_workflow():
|
|
288
288
|
"type": "NODE_OUTPUT",
|
289
289
|
"data": {
|
290
290
|
"node_id": "bf83099a-40df-4445-b90d-1f6f1067ebe3",
|
291
|
-
"output_id": "
|
291
|
+
"output_id": "2a957315-fae0-4366-8a35-f0b315c5eade",
|
292
292
|
},
|
293
293
|
}
|
294
294
|
],
|
@@ -323,6 +323,9 @@ def test_serialize_workflow():
|
|
323
323
|
},
|
324
324
|
},
|
325
325
|
workflow_raw_data["nodes"][2],
|
326
|
+
# TODO: Fix output ID not referencing map node workflow output
|
327
|
+
# https://app.shortcut.com/vellum/story/5667/fix-output-display-reference-on-map-nodes
|
328
|
+
exclude_regex_paths=r"root\['inputs'\]\[0\]\['value'\]\['rules'\]\[0\]\['data'\]\['output_id'\]",
|
326
329
|
)
|
327
330
|
|
328
331
|
# AND each edge should be serialized correctly
|
@@ -4,7 +4,9 @@ import typing
|
|
4
4
|
from typing import Any, List, Union, cast
|
5
5
|
|
6
6
|
from vellum import ChatMessage, SearchResult, SearchResultRequest, VellumVariableType
|
7
|
+
from vellum.client.types.array_vellum_value import ArrayVellumValue
|
7
8
|
from vellum.workflows.descriptors.base import BaseDescriptor
|
9
|
+
from vellum.workflows.nodes.core.map_node.node import MapNodeItemType
|
8
10
|
from vellum.workflows.references import OutputReference, WorkflowInputReference
|
9
11
|
from vellum.workflows.references.execution_count import ExecutionCountReference
|
10
12
|
from vellum.workflows.references.node import NodeReference
|
@@ -45,9 +47,8 @@ def infer_vellum_variable_type(value: Any) -> VellumVariableType:
|
|
45
47
|
raise ValueError(
|
46
48
|
f"Expected NodeReference {descriptor.name} to have an instance pointing to a descriptor"
|
47
49
|
)
|
48
|
-
|
49
50
|
descriptor = descriptor.instance
|
50
|
-
|
51
|
+
|
51
52
|
inferred_type = primitive_type_to_vellum_variable_type(descriptor)
|
52
53
|
else:
|
53
54
|
vellum_variable_value = primitive_to_vellum_value(value)
|
File without changes
|
File without changes
|
File without changes
|