vellum-ai 0.10.9__py3-none-any.whl → 0.11.1__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- vellum/__init__.py +16 -0
- vellum/client/core/client_wrapper.py +1 -1
- vellum/client/types/__init__.py +28 -0
- vellum/client/types/test_suite_run_exec_config.py +7 -1
- vellum/client/types/test_suite_run_exec_config_request.py +8 -0
- vellum/client/types/test_suite_run_prompt_sandbox_history_item_exec_config.py +31 -0
- vellum/client/types/test_suite_run_prompt_sandbox_history_item_exec_config_data.py +27 -0
- vellum/client/types/test_suite_run_prompt_sandbox_history_item_exec_config_data_request.py +27 -0
- vellum/client/types/test_suite_run_prompt_sandbox_history_item_exec_config_request.py +31 -0
- vellum/client/types/test_suite_run_workflow_sandbox_history_item_exec_config.py +31 -0
- vellum/client/types/test_suite_run_workflow_sandbox_history_item_exec_config_data.py +27 -0
- vellum/client/types/test_suite_run_workflow_sandbox_history_item_exec_config_data_request.py +27 -0
- vellum/client/types/test_suite_run_workflow_sandbox_history_item_exec_config_request.py +31 -0
- vellum/evaluations/resources.py +7 -12
- vellum/evaluations/utils/env.py +1 -3
- vellum/evaluations/utils/paginator.py +0 -1
- vellum/evaluations/utils/typing.py +1 -1
- vellum/evaluations/utils/uuid.py +1 -1
- vellum/plugins/vellum_mypy.py +3 -1
- vellum/types/test_suite_run_prompt_sandbox_history_item_exec_config.py +3 -0
- vellum/types/test_suite_run_prompt_sandbox_history_item_exec_config_data.py +3 -0
- vellum/types/test_suite_run_prompt_sandbox_history_item_exec_config_data_request.py +3 -0
- vellum/types/test_suite_run_prompt_sandbox_history_item_exec_config_request.py +3 -0
- vellum/types/test_suite_run_workflow_sandbox_history_item_exec_config.py +3 -0
- vellum/types/test_suite_run_workflow_sandbox_history_item_exec_config_data.py +3 -0
- vellum/types/test_suite_run_workflow_sandbox_history_item_exec_config_data_request.py +3 -0
- vellum/types/test_suite_run_workflow_sandbox_history_item_exec_config_request.py +3 -0
- vellum/workflows/context.py +42 -0
- vellum/workflows/events/node.py +7 -6
- vellum/workflows/events/tests/test_event.py +0 -1
- vellum/workflows/events/types.py +0 -1
- vellum/workflows/events/workflow.py +19 -1
- vellum/workflows/nodes/bases/base.py +17 -56
- vellum/workflows/nodes/bases/tests/test_base_node.py +0 -1
- vellum/workflows/nodes/core/inline_subworkflow_node/node.py +13 -7
- vellum/workflows/nodes/core/templating_node/node.py +1 -0
- vellum/workflows/nodes/core/try_node/node.py +2 -2
- vellum/workflows/nodes/core/try_node/tests/test_node.py +1 -3
- vellum/workflows/nodes/displayable/api_node/node.py +3 -2
- vellum/workflows/nodes/displayable/bases/api_node/node.py +1 -1
- vellum/workflows/nodes/displayable/bases/base_prompt_node/node.py +0 -1
- vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py +9 -1
- vellum/workflows/nodes/displayable/bases/prompt_deployment_node.py +12 -2
- vellum/workflows/nodes/displayable/bases/search_node.py +0 -1
- vellum/workflows/nodes/displayable/code_execution_node/tests/test_code_execution_node.py +0 -1
- vellum/workflows/nodes/displayable/code_execution_node/utils.py +3 -2
- vellum/workflows/nodes/displayable/conditional_node/node.py +1 -1
- vellum/workflows/nodes/displayable/guardrail_node/node.py +0 -1
- vellum/workflows/nodes/displayable/inline_prompt_node/node.py +1 -0
- vellum/workflows/nodes/displayable/prompt_deployment_node/node.py +3 -1
- vellum/workflows/nodes/displayable/search_node/node.py +1 -0
- vellum/workflows/nodes/displayable/subworkflow_deployment_node/node.py +13 -3
- vellum/workflows/nodes/displayable/tests/test_inline_text_prompt_node.py +10 -7
- vellum/workflows/nodes/displayable/tests/test_search_node_wth_text_output.py +0 -1
- vellum/workflows/nodes/displayable/tests/test_text_prompt_deployment_node.py +1 -1
- vellum/workflows/outputs/base.py +2 -4
- vellum/workflows/ports/node_ports.py +1 -1
- vellum/workflows/runner/runner.py +167 -202
- vellum/workflows/state/base.py +0 -2
- vellum/workflows/types/core.py +1 -0
- vellum/workflows/types/tests/test_utils.py +1 -0
- vellum/workflows/types/utils.py +0 -1
- vellum/workflows/utils/functions.py +74 -0
- vellum/workflows/utils/tests/test_functions.py +171 -0
- vellum/workflows/utils/tests/test_vellum_variables.py +0 -1
- vellum/workflows/utils/vellum_variables.py +2 -2
- vellum/workflows/workflows/base.py +74 -34
- vellum/workflows/workflows/event_filters.py +7 -12
- {vellum_ai-0.10.9.dist-info → vellum_ai-0.11.1.dist-info}/METADATA +1 -1
- {vellum_ai-0.10.9.dist-info → vellum_ai-0.11.1.dist-info}/RECORD +122 -99
- vellum_cli/__init__.py +147 -13
- vellum_cli/config.py +0 -1
- vellum_cli/image_push.py +1 -1
- vellum_cli/pull.py +31 -19
- vellum_cli/push.py +9 -10
- vellum_cli/tests/__init__.py +0 -0
- vellum_cli/tests/conftest.py +40 -0
- vellum_cli/tests/test_main.py +11 -0
- vellum_cli/tests/test_pull.py +143 -71
- vellum_cli/tests/test_push.py +173 -0
- vellum_ee/workflows/display/base.py +1 -0
- vellum_ee/workflows/display/nodes/base_node_display.py +3 -2
- vellum_ee/workflows/display/nodes/base_node_vellum_display.py +2 -2
- vellum_ee/workflows/display/nodes/get_node_display_class.py +1 -1
- vellum_ee/workflows/display/nodes/tests/test_base_node_display.py +1 -1
- vellum_ee/workflows/display/nodes/vellum/__init__.py +1 -1
- vellum_ee/workflows/display/nodes/vellum/api_node.py +54 -58
- vellum_ee/workflows/display/nodes/vellum/conditional_node.py +39 -22
- vellum_ee/workflows/display/nodes/vellum/error_node.py +3 -3
- vellum_ee/workflows/display/nodes/vellum/final_output_node.py +0 -2
- vellum_ee/workflows/display/nodes/vellum/guardrail_node.py +1 -1
- vellum_ee/workflows/display/nodes/vellum/inline_prompt_node.py +1 -1
- vellum_ee/workflows/display/nodes/vellum/inline_subworkflow_node.py +4 -2
- vellum_ee/workflows/display/nodes/vellum/map_node.py +11 -5
- vellum_ee/workflows/display/nodes/vellum/merge_node.py +2 -2
- vellum_ee/workflows/display/nodes/vellum/note_node.py +1 -3
- vellum_ee/workflows/display/nodes/vellum/prompt_deployment_node.py +1 -1
- vellum_ee/workflows/display/nodes/vellum/search_node.py +1 -1
- vellum_ee/workflows/display/nodes/vellum/subworkflow_deployment_node.py +1 -1
- vellum_ee/workflows/display/nodes/vellum/templating_node.py +1 -1
- vellum_ee/workflows/display/nodes/vellum/tests/test_utils.py +5 -5
- vellum_ee/workflows/display/nodes/vellum/utils.py +30 -10
- vellum_ee/workflows/display/tests/test_vellum_workflow_display.py +45 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_api_node_serialization.py +42 -25
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_conditional_node_serialization.py +13 -39
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_guardrail_node_serialization.py +2 -2
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_inline_subworkflow_serialization.py +62 -58
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_map_node_serialization.py +25 -4
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_merge_node_serialization.py +2 -1
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_prompt_deployment_serialization.py +2 -2
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_subworkflow_deployment_serialization.py +2 -2
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_terminal_node_serialization.py +1 -1
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_try_node_serialization.py +2 -1
- vellum_ee/workflows/display/tests/workflow_serialization/test_complex_terminal_node_serialization.py +2 -2
- vellum_ee/workflows/display/types.py +4 -4
- vellum_ee/workflows/display/utils/vellum.py +2 -6
- vellum_ee/workflows/display/vellum.py +1 -1
- vellum_ee/workflows/display/workflows/get_vellum_workflow_display_class.py +4 -1
- vellum_ee/workflows/display/workflows/vellum_workflow_display.py +12 -5
- vellum/workflows/runner/types.py +0 -16
- {vellum_ai-0.10.9.dist-info → vellum_ai-0.11.1.dist-info}/LICENSE +0 -0
- {vellum_ai-0.10.9.dist-info → vellum_ai-0.11.1.dist-info}/WHEEL +0 -0
- {vellum_ai-0.10.9.dist-info → vellum_ai-0.11.1.dist-info}/entry_points.txt +0 -0
@@ -8,6 +8,7 @@ from vellum_ee.workflows.display.nodes.base_node_vellum_display import BaseNodeV
|
|
8
8
|
from vellum_ee.workflows.display.nodes.utils import raise_if_descriptor
|
9
9
|
from vellum_ee.workflows.display.nodes.vellum.utils import create_node_input
|
10
10
|
from vellum_ee.workflows.display.types import WorkflowDisplayContext
|
11
|
+
from vellum_ee.workflows.display.vellum import WorkspaceSecretPointer
|
11
12
|
|
12
13
|
_APINodeType = TypeVar("_APINodeType", bound=APINode)
|
13
14
|
|
@@ -22,10 +23,6 @@ class BaseAPINodeDisplay(BaseNodeVellumDisplay[_APINodeType], Generic[_APINodeTy
|
|
22
23
|
api_key_header_key_input_id: ClassVar[Optional[UUID]] = None
|
23
24
|
api_key_header_value_input_id: ClassVar[Optional[UUID]] = None
|
24
25
|
|
25
|
-
text_output_id: ClassVar[Optional[UUID]] = None
|
26
|
-
json_output_id: ClassVar[Optional[UUID]] = None
|
27
|
-
status_code_output_id: ClassVar[Optional[UUID]] = None
|
28
|
-
|
29
26
|
# A mapping between node input keys and their ids for inputs representing additional header keys
|
30
27
|
additional_header_key_input_ids: ClassVar[Optional[Dict[str, UUID]]] = None
|
31
28
|
|
@@ -68,6 +65,7 @@ class BaseAPINodeDisplay(BaseNodeVellumDisplay[_APINodeType], Generic[_APINodeTy
|
|
68
65
|
|
69
66
|
headers = raise_if_descriptor(node.headers)
|
70
67
|
api_key_header_key = raise_if_descriptor(node.api_key_header_key)
|
68
|
+
api_key_header_value = raise_if_descriptor(node.api_key_header_value)
|
71
69
|
authorization_type = raise_if_descriptor(node.authorization_type)
|
72
70
|
bearer_token_value = raise_if_descriptor(node.bearer_token_value)
|
73
71
|
|
@@ -82,16 +80,13 @@ class BaseAPINodeDisplay(BaseNodeVellumDisplay[_APINodeType], Generic[_APINodeTy
|
|
82
80
|
if authorization_type
|
83
81
|
else None
|
84
82
|
)
|
85
|
-
bearer_token_value_node_input = (
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
)
|
93
|
-
if bearer_token_value
|
94
|
-
else None
|
83
|
+
bearer_token_value_node_input = create_node_input(
|
84
|
+
node_id=node_id,
|
85
|
+
input_name="bearer_token_value",
|
86
|
+
value=bearer_token_value,
|
87
|
+
display_context=display_context,
|
88
|
+
input_id=self.bearer_token_value_input_id,
|
89
|
+
pointer_type=WorkspaceSecretPointer,
|
95
90
|
)
|
96
91
|
api_key_header_key_node_input = (
|
97
92
|
create_node_input(
|
@@ -104,52 +99,52 @@ class BaseAPINodeDisplay(BaseNodeVellumDisplay[_APINodeType], Generic[_APINodeTy
|
|
104
99
|
if api_key_header_key
|
105
100
|
else None
|
106
101
|
)
|
107
|
-
api_key_header_value_node_input = (
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
)
|
115
|
-
if headers and api_key_header_key
|
116
|
-
else None
|
102
|
+
api_key_header_value_node_input = create_node_input(
|
103
|
+
node_id=node_id,
|
104
|
+
input_name="api_key_header_value",
|
105
|
+
value=api_key_header_value,
|
106
|
+
display_context=display_context,
|
107
|
+
input_id=self.api_key_header_value_input_id,
|
108
|
+
pointer_type=WorkspaceSecretPointer,
|
117
109
|
)
|
118
110
|
|
119
|
-
|
120
|
-
|
121
|
-
additional_headers: JsonArray =
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
)
|
134
|
-
)
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
)
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
111
|
+
additional_header_inputs = []
|
112
|
+
|
113
|
+
additional_headers: JsonArray = []
|
114
|
+
if headers:
|
115
|
+
for key, value in headers.items():
|
116
|
+
if key in {api_key_header_key, "Authorization"}:
|
117
|
+
continue
|
118
|
+
|
119
|
+
header_key_input = create_node_input(
|
120
|
+
node_id=node_id,
|
121
|
+
input_name="additional_header_key",
|
122
|
+
value=key,
|
123
|
+
display_context=display_context,
|
124
|
+
input_id=(
|
125
|
+
self.additional_header_key_input_ids.get(key) if self.additional_header_key_input_ids else None
|
126
|
+
),
|
127
|
+
)
|
128
|
+
header_value_input = create_node_input(
|
129
|
+
node_id=node_id,
|
130
|
+
input_name="additional_header_value",
|
131
|
+
value=value,
|
132
|
+
display_context=display_context,
|
133
|
+
input_id=(
|
134
|
+
self.additional_header_value_input_ids.get(key)
|
135
|
+
if self.additional_header_value_input_ids
|
136
|
+
else None
|
137
|
+
),
|
138
|
+
)
|
139
|
+
|
140
|
+
additional_header_inputs.extend([header_key_input, header_value_input])
|
141
|
+
|
142
|
+
additional_headers.append(
|
143
|
+
{
|
144
|
+
"header_key_input_id": header_key_input.id,
|
145
|
+
"header_value_input_id": header_value_input.id,
|
146
|
+
}
|
147
|
+
)
|
153
148
|
|
154
149
|
inputs = [
|
155
150
|
input
|
@@ -164,6 +159,7 @@ class BaseAPINodeDisplay(BaseNodeVellumDisplay[_APINodeType], Generic[_APINodeTy
|
|
164
159
|
]
|
165
160
|
if input is not None
|
166
161
|
]
|
162
|
+
inputs.extend(additional_header_inputs)
|
167
163
|
|
168
164
|
_, text_output_display = display_context.node_output_displays[cast(OutputReference, node.Outputs.text)]
|
169
165
|
_, json_output_display = display_context.node_output_displays[cast(OutputReference, node.Outputs.json)]
|
@@ -1,12 +1,7 @@
|
|
1
1
|
from dataclasses import dataclass
|
2
2
|
from uuid import UUID
|
3
|
-
from typing import Any, ClassVar, Dict, Generic, List, Optional, TypeVar, Union
|
3
|
+
from typing import Any, ClassVar, Dict, Generic, List, Optional, Tuple, TypeVar, Union
|
4
4
|
|
5
|
-
from vellum_ee.workflows.display.nodes.base_node_vellum_display import BaseNodeVellumDisplay
|
6
|
-
from vellum_ee.workflows.display.nodes.vellum.utils import create_node_input
|
7
|
-
from vellum_ee.workflows.display.types import WorkflowDisplayContext
|
8
|
-
from vellum_ee.workflows.display.utils.uuids import uuid4_from_hash
|
9
|
-
from vellum_ee.workflows.display.vellum import NodeInput
|
10
5
|
from vellum.workflows.descriptors.base import BaseDescriptor
|
11
6
|
from vellum.workflows.expressions.and_ import AndExpression
|
12
7
|
from vellum.workflows.expressions.begins_with import BeginsWithExpression
|
@@ -29,7 +24,12 @@ from vellum.workflows.expressions.not_between import NotBetweenExpression
|
|
29
24
|
from vellum.workflows.expressions.not_in import NotInExpression
|
30
25
|
from vellum.workflows.expressions.or_ import OrExpression
|
31
26
|
from vellum.workflows.nodes.displayable import ConditionalNode
|
32
|
-
from vellum.workflows.types.core import
|
27
|
+
from vellum.workflows.types.core import ConditionType, JsonObject
|
28
|
+
from vellum_ee.workflows.display.nodes.base_node_vellum_display import BaseNodeVellumDisplay
|
29
|
+
from vellum_ee.workflows.display.nodes.vellum.utils import create_node_input
|
30
|
+
from vellum_ee.workflows.display.types import WorkflowDisplayContext
|
31
|
+
from vellum_ee.workflows.display.utils.uuids import uuid4_from_hash
|
32
|
+
from vellum_ee.workflows.display.vellum import NodeInput
|
33
33
|
|
34
34
|
_ConditionalNodeType = TypeVar("_ConditionalNodeType", bound=ConditionalNode)
|
35
35
|
|
@@ -42,6 +42,7 @@ class RuleIdMap:
|
|
42
42
|
field_node_input_id: Optional[UUID]
|
43
43
|
value_node_input_id: Optional[UUID]
|
44
44
|
|
45
|
+
|
45
46
|
@dataclass
|
46
47
|
class ConditionId:
|
47
48
|
id: UUID
|
@@ -65,7 +66,9 @@ class BaseConditionalNodeDisplay(BaseNodeVellumDisplay[_ConditionalNodeType], Ge
|
|
65
66
|
|
66
67
|
if len(condition_ids) > ports_size:
|
67
68
|
raise ValueError(
|
68
|
-
f"Too many defined condition ids. Ports are size {ports_size}
|
69
|
+
f"""Too many defined condition ids. Ports are size {ports_size} \
|
70
|
+
but the defined conditions have length {len(condition_ids)}"""
|
71
|
+
)
|
69
72
|
|
70
73
|
def serialize_rule(
|
71
74
|
descriptor: BaseDescriptor, path: List[int], rule_id_map: Optional[RuleIdMap]
|
@@ -113,7 +116,11 @@ class BaseConditionalNodeDisplay(BaseNodeVellumDisplay[_ConditionalNodeType], Ge
|
|
113
116
|
node_id, f"{current_id}.field", descriptor._value, display_context, field_node_input_id
|
114
117
|
)
|
115
118
|
value_node_input = create_node_input(
|
116
|
-
node_id,
|
119
|
+
node_id,
|
120
|
+
f"{current_id}.value",
|
121
|
+
f"{descriptor._start},{descriptor._end}",
|
122
|
+
display_context,
|
123
|
+
value_node_input_id,
|
117
124
|
)
|
118
125
|
node_inputs.extend([field_node_input, value_node_input])
|
119
126
|
operator = self._convert_descriptor_to_operator(descriptor)
|
@@ -124,11 +131,15 @@ class BaseConditionalNodeDisplay(BaseNodeVellumDisplay[_ConditionalNodeType], Ge
|
|
124
131
|
lhs = descriptor._lhs # type: ignore[attr-defined]
|
125
132
|
rhs = descriptor._rhs # type: ignore[attr-defined]
|
126
133
|
|
127
|
-
lhs_node_input = create_node_input(
|
134
|
+
lhs_node_input = create_node_input(
|
135
|
+
node_id, f"{current_id}.field", lhs, display_context, field_node_input_id
|
136
|
+
)
|
128
137
|
node_inputs.append(lhs_node_input)
|
129
138
|
|
130
139
|
if descriptor._rhs is not None: # type: ignore[attr-defined]
|
131
|
-
rhs_node_input = create_node_input(
|
140
|
+
rhs_node_input = create_node_input(
|
141
|
+
node_id, f"{current_id}.value", rhs, display_context, value_node_input_id
|
142
|
+
)
|
132
143
|
node_inputs.append(rhs_node_input)
|
133
144
|
value_node_input_id = UUID(rhs_node_input.id)
|
134
145
|
|
@@ -148,18 +159,24 @@ class BaseConditionalNodeDisplay(BaseNodeVellumDisplay[_ConditionalNodeType], Ge
|
|
148
159
|
conditions = []
|
149
160
|
for idx, port in enumerate(node.Ports):
|
150
161
|
|
151
|
-
condition_id = str(
|
152
|
-
|
162
|
+
condition_id = str(
|
163
|
+
condition_ids[idx].id if condition_ids else uuid4_from_hash(f"{node_id}|conditions|{idx}")
|
164
|
+
)
|
165
|
+
rule_group_id = str(
|
166
|
+
condition_ids[idx].rule_group_id if condition_ids else uuid4_from_hash(f"{condition_id}|rule_group")
|
167
|
+
)
|
153
168
|
source_handle_id = str(source_handle_ids.get(idx) or uuid4_from_hash(f"{node_id}|handles|{idx}"))
|
154
169
|
|
155
170
|
if port._condition is None:
|
156
171
|
if port._condition_type == ConditionType.ELSE:
|
157
|
-
conditions.append(
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
172
|
+
conditions.append(
|
173
|
+
{
|
174
|
+
"id": condition_id,
|
175
|
+
"type": ConditionType.ELSE.value,
|
176
|
+
"source_handle_id": source_handle_id,
|
177
|
+
"data": None,
|
178
|
+
}
|
179
|
+
)
|
163
180
|
else:
|
164
181
|
continue
|
165
182
|
|
@@ -241,7 +258,7 @@ class BaseConditionalNodeDisplay(BaseNodeVellumDisplay[_ConditionalNodeType], Ge
|
|
241
258
|
raise ValueError(f"Unsupported descriptor type: {descriptor}")
|
242
259
|
|
243
260
|
def get_nested_rule_details_by_path(
|
244
|
-
|
261
|
+
self, rule_ids: List[RuleIdMap], path: List[int]
|
245
262
|
) -> Union[Tuple[UUID, Optional[UUID], Optional[UUID]], None]:
|
246
263
|
current_rule = rule_ids[path[0]]
|
247
264
|
|
@@ -267,7 +284,7 @@ class BaseConditionalNodeDisplay(BaseNodeVellumDisplay[_ConditionalNodeType], Ge
|
|
267
284
|
return (
|
268
285
|
uuid4_from_hash(f"{node_id}|{rule_id}|current"),
|
269
286
|
uuid4_from_hash(f"{node_id}|{rule_id}||field"),
|
270
|
-
uuid4_from_hash(f"{node_id}|{rule_id}||value")
|
287
|
+
uuid4_from_hash(f"{node_id}|{rule_id}||value"),
|
271
288
|
)
|
272
289
|
|
273
290
|
def _get_source_handle_ids(self) -> Dict[int, UUID]:
|
@@ -276,5 +293,5 @@ class BaseConditionalNodeDisplay(BaseNodeVellumDisplay[_ConditionalNodeType], Ge
|
|
276
293
|
def _get_rule_ids(self) -> List[RuleIdMap]:
|
277
294
|
return self._get_explicit_node_display_attr("rule_ids", List[RuleIdMap]) or []
|
278
295
|
|
279
|
-
def _get_condition_ids(self)-> List[ConditionId]:
|
296
|
+
def _get_condition_ids(self) -> List[ConditionId]:
|
280
297
|
return self._get_explicit_node_display_attr("condition_ids", List[ConditionId]) or []
|
@@ -2,22 +2,22 @@ from uuid import UUID
|
|
2
2
|
from typing import Any, ClassVar, Dict, Generic, Optional, TypeVar
|
3
3
|
|
4
4
|
from vellum.workflows.nodes import ErrorNode
|
5
|
-
from vellum.workflows.types.core import
|
5
|
+
from vellum.workflows.types.core import JsonObject
|
6
6
|
from vellum_ee.workflows.display.nodes.base_node_vellum_display import BaseNodeVellumDisplay
|
7
7
|
from vellum_ee.workflows.display.nodes.vellum.utils import create_node_input
|
8
8
|
from vellum_ee.workflows.display.types import WorkflowDisplayContext
|
9
9
|
|
10
10
|
_ErrorNodeType = TypeVar("_ErrorNodeType", bound=ErrorNode)
|
11
11
|
|
12
|
+
|
12
13
|
class BaseErrorNodeDisplay(BaseNodeVellumDisplay[_ErrorNodeType], Generic[_ErrorNodeType]):
|
13
14
|
error_output_id: ClassVar[Optional[UUID]] = None
|
14
15
|
error_inputs_by_name: ClassVar[Dict[str, Any]] = {}
|
15
16
|
name: ClassVar[str] = "error-node"
|
16
17
|
|
17
18
|
def serialize(
|
18
|
-
|
19
|
+
self, display_context: WorkflowDisplayContext, error_output_id: Optional[UUID] = None, **kwargs
|
19
20
|
) -> JsonObject:
|
20
|
-
node = self._node
|
21
21
|
node_id = self.node_id
|
22
22
|
error_source_input_id = self.node_input_ids_by_name.get("error_source_input_id")
|
23
23
|
|
@@ -1,9 +1,7 @@
|
|
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
4
|
from vellum.workflows.nodes.displayable.final_output_node import FinalOutputNode
|
6
|
-
from vellum.workflows.references.output import OutputReference
|
7
5
|
from vellum.workflows.types.core import JsonObject
|
8
6
|
from vellum_ee.workflows.display.nodes.base_node_vellum_display import BaseNodeVellumDisplay
|
9
7
|
from vellum_ee.workflows.display.nodes.utils import to_kebab_case
|
@@ -1,5 +1,5 @@
|
|
1
1
|
from uuid import UUID
|
2
|
-
from typing import
|
2
|
+
from typing import ClassVar, Dict, Generic, List, Optional, Tuple, Type, TypeVar, Union, cast
|
3
3
|
|
4
4
|
from vellum import PromptBlock, RichTextChildBlock, VellumVariable
|
5
5
|
from vellum.workflows.nodes import InlinePromptNode
|
@@ -1,5 +1,5 @@
|
|
1
1
|
from uuid import UUID
|
2
|
-
from typing import
|
2
|
+
from typing import ClassVar, Dict, Generic, List, Optional, Tuple, Type, TypeVar, cast
|
3
3
|
|
4
4
|
from vellum import VellumVariable
|
5
5
|
from vellum.workflows.nodes import InlineSubworkflowNode
|
@@ -90,7 +90,9 @@ class BaseInlineSubworkflowNodeDisplay(
|
|
90
90
|
) -> List[VellumVariable]:
|
91
91
|
workflow_outputs: List[VellumVariable] = []
|
92
92
|
for output_descriptor in raise_if_descriptor(node.subworkflow).Outputs: # type: ignore[union-attr]
|
93
|
-
workflow_output_display = cast(
|
93
|
+
workflow_output_display = cast(
|
94
|
+
WorkflowOutputVellumDisplay, display_context.workflow_output_displays[output_descriptor]
|
95
|
+
)
|
94
96
|
output_type = infer_vellum_variable_type(output_descriptor)
|
95
97
|
workflow_outputs.append(
|
96
98
|
VellumVariable(id=str(workflow_output_display.id), key=workflow_output_display.name, type=output_type)
|
@@ -1,5 +1,5 @@
|
|
1
1
|
from uuid import UUID
|
2
|
-
from typing import
|
2
|
+
from typing import Dict, Generic, List, Optional, TypeVar, cast
|
3
3
|
|
4
4
|
from vellum.workflows.nodes import MapNode
|
5
5
|
from vellum.workflows.types.core import JsonObject
|
@@ -39,15 +39,21 @@ class BaseMapNodeDisplay(BaseNodeVellumDisplay[_MapNodeType], Generic[_MapNodeTy
|
|
39
39
|
renamed_input_variables = []
|
40
40
|
for input_variable in cast(List[Dict[str, str]], serialized_subworkflow["input_variables"]):
|
41
41
|
if input_variable["key"] == "all_items":
|
42
|
-
renamed_item = {
|
42
|
+
renamed_item = {**input_variable, "key": "items"}
|
43
43
|
renamed_input_variables.append(renamed_item)
|
44
44
|
else:
|
45
45
|
renamed_input_variables.append(input_variable)
|
46
46
|
|
47
47
|
# Note: This must match the items input ID for the map node's node input
|
48
|
-
items_workflow_input_id = next(
|
49
|
-
|
50
|
-
|
48
|
+
items_workflow_input_id = next(
|
49
|
+
input_variable["id"] for input_variable in renamed_input_variables if input_variable["key"] == "items"
|
50
|
+
)
|
51
|
+
item_workflow_input_id = next(
|
52
|
+
input_variable["id"] for input_variable in renamed_input_variables if input_variable["key"] == "item"
|
53
|
+
)
|
54
|
+
index_workflow_input_id = next(
|
55
|
+
input_variable["id"] for input_variable in renamed_input_variables if input_variable["key"] == "index"
|
56
|
+
)
|
51
57
|
|
52
58
|
return {
|
53
59
|
"id": str(node_id),
|
@@ -1,12 +1,12 @@
|
|
1
1
|
from uuid import UUID
|
2
2
|
from typing import Any, ClassVar, Generic, List, Optional, TypeVar
|
3
3
|
|
4
|
+
from vellum.workflows.nodes.displayable import MergeNode
|
5
|
+
from vellum.workflows.types.core import JsonObject
|
4
6
|
from vellum_ee.workflows.display.nodes.base_node_vellum_display import BaseNodeVellumDisplay
|
5
7
|
from vellum_ee.workflows.display.types import WorkflowDisplayContext
|
6
8
|
from vellum_ee.workflows.display.utils.uuids import uuid4_from_hash
|
7
9
|
from vellum_ee.workflows.display.vellum import EdgeVellumDisplay
|
8
|
-
from vellum.workflows.nodes.displayable import MergeNode
|
9
|
-
from vellum.workflows.types.core import JsonObject
|
10
10
|
|
11
11
|
_MergeNodeType = TypeVar("_MergeNodeType", bound=MergeNode)
|
12
12
|
|
@@ -13,9 +13,7 @@ class BaseNoteNodeDisplay(BaseNodeVellumDisplay[_NoteNodeType], Generic[_NoteNod
|
|
13
13
|
text: ClassVar[str] = ""
|
14
14
|
style: ClassVar[Union[Dict[str, Any], None]] = None
|
15
15
|
|
16
|
-
def serialize(
|
17
|
-
self, display_context: WorkflowDisplayContext, **kwargs: Any
|
18
|
-
) -> JsonObject:
|
16
|
+
def serialize(self, display_context: WorkflowDisplayContext, **kwargs: Any) -> JsonObject:
|
19
17
|
node_id = self.node_id
|
20
18
|
|
21
19
|
return {
|
@@ -1,5 +1,5 @@
|
|
1
1
|
from uuid import UUID
|
2
|
-
from typing import
|
2
|
+
from typing import ClassVar, Dict, Generic, Optional, TypeVar, cast
|
3
3
|
|
4
4
|
from vellum.workflows.nodes.displayable.prompt_deployment_node import PromptDeploymentNode
|
5
5
|
from vellum.workflows.references import OutputReference
|
@@ -1,6 +1,6 @@
|
|
1
1
|
from dataclasses import dataclass
|
2
2
|
from uuid import UUID
|
3
|
-
from typing import
|
3
|
+
from typing import Dict, Generic, List, Optional, Tuple, Type, TypeVar, Union, cast
|
4
4
|
|
5
5
|
from vellum import (
|
6
6
|
MetadataFilterConfigRequest,
|
@@ -1,5 +1,5 @@
|
|
1
1
|
from uuid import UUID
|
2
|
-
from typing import
|
2
|
+
from typing import ClassVar, Dict, Generic, Optional, TypeVar
|
3
3
|
|
4
4
|
from vellum.workflows.nodes import SubworkflowDeploymentNode
|
5
5
|
from vellum.workflows.types.core import JsonObject
|
@@ -1,5 +1,5 @@
|
|
1
1
|
from uuid import UUID
|
2
|
-
from typing import
|
2
|
+
from typing import ClassVar, Dict, Generic, Optional, TypeVar
|
3
3
|
|
4
4
|
from vellum.workflows.nodes.core.templating_node import TemplatingNode
|
5
5
|
from vellum.workflows.types.core import JsonObject
|
@@ -2,6 +2,11 @@ import pytest
|
|
2
2
|
from uuid import UUID, uuid4
|
3
3
|
from typing import List, cast
|
4
4
|
|
5
|
+
from vellum.workflows.descriptors.base import BaseDescriptor
|
6
|
+
from vellum.workflows.inputs import BaseInputs
|
7
|
+
from vellum.workflows.nodes.bases import BaseNode
|
8
|
+
from vellum.workflows.outputs import BaseOutputs
|
9
|
+
from vellum.workflows.references import OutputReference, WorkflowInputReference
|
5
10
|
from vellum_ee.workflows.display.nodes.base_node_vellum_display import BaseNodeVellumDisplay
|
6
11
|
from vellum_ee.workflows.display.nodes.types import NodeOutputDisplay
|
7
12
|
from vellum_ee.workflows.display.nodes.vellum.utils import create_node_input_value_pointer_rules
|
@@ -19,11 +24,6 @@ from vellum_ee.workflows.display.vellum import (
|
|
19
24
|
WorkflowMetaVellumDisplay,
|
20
25
|
)
|
21
26
|
from vellum_ee.workflows.display.workflows.vellum_workflow_display import VellumWorkflowDisplay
|
22
|
-
from vellum.workflows.descriptors.base import BaseDescriptor
|
23
|
-
from vellum.workflows.inputs import BaseInputs
|
24
|
-
from vellum.workflows.nodes.bases import BaseNode
|
25
|
-
from vellum.workflows.outputs import BaseOutputs
|
26
|
-
from vellum.workflows.references import OutputReference, WorkflowInputReference
|
27
27
|
|
28
28
|
|
29
29
|
class Inputs(BaseInputs):
|
@@ -1,6 +1,10 @@
|
|
1
1
|
from uuid import UUID
|
2
|
-
from typing import Any, List, Optional, cast
|
2
|
+
from typing import Any, List, Optional, Type, cast
|
3
3
|
|
4
|
+
from vellum.workflows.descriptors.base import BaseDescriptor
|
5
|
+
from vellum.workflows.expressions.coalesce_expression import CoalesceExpression
|
6
|
+
from vellum.workflows.nodes.utils import get_wrapped_node, has_wrapped_node
|
7
|
+
from vellum.workflows.references import NodeReference, OutputReference
|
4
8
|
from vellum_ee.workflows.display.types import WorkflowDisplayContext
|
5
9
|
from vellum_ee.workflows.display.utils.uuids import uuid4_from_hash
|
6
10
|
from vellum_ee.workflows.display.utils.vellum import create_node_input_value_pointer_rule, primitive_to_vellum_value
|
@@ -9,11 +13,9 @@ from vellum_ee.workflows.display.vellum import (
|
|
9
13
|
NodeInput,
|
10
14
|
NodeInputValuePointer,
|
11
15
|
NodeInputValuePointerRule,
|
16
|
+
WorkspaceSecretData,
|
17
|
+
WorkspaceSecretPointer,
|
12
18
|
)
|
13
|
-
from vellum.workflows.descriptors.base import BaseDescriptor
|
14
|
-
from vellum.workflows.expressions.coalesce_expression import CoalesceExpression
|
15
|
-
from vellum.workflows.nodes.utils import get_wrapped_node, has_wrapped_node
|
16
|
-
from vellum.workflows.references import NodeReference, OutputReference
|
17
19
|
|
18
20
|
|
19
21
|
def create_node_input(
|
@@ -22,6 +24,7 @@ def create_node_input(
|
|
22
24
|
value: Any,
|
23
25
|
display_context: WorkflowDisplayContext,
|
24
26
|
input_id: Optional[UUID],
|
27
|
+
pointer_type: Optional[Type[NodeInputValuePointerRule]] = ConstantValuePointer,
|
25
28
|
) -> NodeInput:
|
26
29
|
input_id = input_id or uuid4_from_hash(f"{node_id}|{input_name}")
|
27
30
|
if (
|
@@ -33,7 +36,7 @@ def create_node_input(
|
|
33
36
|
if wrapped_node._is_wrapped_node:
|
34
37
|
value = getattr(wrapped_node.Outputs, value.name)
|
35
38
|
|
36
|
-
rules = create_node_input_value_pointer_rules(value, display_context)
|
39
|
+
rules = create_node_input_value_pointer_rules(value, display_context, pointer_type=pointer_type)
|
37
40
|
return NodeInput(
|
38
41
|
id=str(input_id),
|
39
42
|
key=input_name,
|
@@ -48,6 +51,7 @@ def create_node_input_value_pointer_rules(
|
|
48
51
|
value: Any,
|
49
52
|
display_context: WorkflowDisplayContext,
|
50
53
|
existing_rules: Optional[List[NodeInputValuePointerRule]] = None,
|
54
|
+
pointer_type: Optional[Type[NodeInputValuePointerRule]] = None,
|
51
55
|
) -> List[NodeInputValuePointerRule]:
|
52
56
|
node_input_value_pointer_rules: List[NodeInputValuePointerRule] = existing_rules or []
|
53
57
|
|
@@ -59,18 +63,34 @@ def create_node_input_value_pointer_rules(
|
|
59
63
|
|
60
64
|
if isinstance(value, CoalesceExpression):
|
61
65
|
# Recursively handle the left-hand side
|
62
|
-
lhs_rules = create_node_input_value_pointer_rules(value.lhs, display_context, [])
|
66
|
+
lhs_rules = create_node_input_value_pointer_rules(value.lhs, display_context, [], pointer_type=pointer_type)
|
63
67
|
node_input_value_pointer_rules.extend(lhs_rules)
|
64
68
|
|
65
69
|
# Handle the right-hand side
|
66
70
|
if not isinstance(value.rhs, CoalesceExpression):
|
67
|
-
rhs_rules = create_node_input_value_pointer_rules(
|
71
|
+
rhs_rules = create_node_input_value_pointer_rules(
|
72
|
+
value.rhs, display_context, [], pointer_type=pointer_type
|
73
|
+
)
|
68
74
|
node_input_value_pointer_rules.extend(rhs_rules)
|
69
75
|
else:
|
70
76
|
# Non-CoalesceExpression case
|
71
77
|
node_input_value_pointer_rules.append(create_node_input_value_pointer_rule(value, display_context))
|
72
78
|
else:
|
73
|
-
|
74
|
-
node_input_value_pointer_rules.append(
|
79
|
+
pointer = create_pointer(value, pointer_type)
|
80
|
+
node_input_value_pointer_rules.append(pointer)
|
75
81
|
|
76
82
|
return node_input_value_pointer_rules
|
83
|
+
|
84
|
+
|
85
|
+
def create_pointer(
|
86
|
+
value: Any,
|
87
|
+
pointer_type: Optional[Type[NodeInputValuePointerRule]] = None,
|
88
|
+
) -> NodeInputValuePointerRule:
|
89
|
+
if value is None:
|
90
|
+
if pointer_type is WorkspaceSecretPointer:
|
91
|
+
return WorkspaceSecretPointer(
|
92
|
+
type="WORKSPACE_SECRET", data=WorkspaceSecretData(type="STRING", workspace_secret_id=None)
|
93
|
+
)
|
94
|
+
|
95
|
+
vellum_variable_value = primitive_to_vellum_value(value)
|
96
|
+
return ConstantValuePointer(type="CONSTANT_VALUE", data=vellum_variable_value)
|
@@ -0,0 +1,45 @@
|
|
1
|
+
from vellum.workflows.workflows.base import BaseWorkflow
|
2
|
+
from vellum_ee.workflows.display.workflows.get_vellum_workflow_display_class import get_workflow_display
|
3
|
+
from vellum_ee.workflows.display.workflows.vellum_workflow_display import VellumWorkflowDisplay
|
4
|
+
|
5
|
+
|
6
|
+
def test_vellum_workflow_display__serialize_empty_workflow():
|
7
|
+
# GIVEN an empty workflow
|
8
|
+
class ExampleWorkflow(BaseWorkflow):
|
9
|
+
pass
|
10
|
+
|
11
|
+
display = get_workflow_display(
|
12
|
+
base_display_class=VellumWorkflowDisplay,
|
13
|
+
workflow_class=ExampleWorkflow,
|
14
|
+
)
|
15
|
+
|
16
|
+
# WHEN serializing the workflow
|
17
|
+
exec_config = display.serialize()
|
18
|
+
|
19
|
+
# THEN it should return the expected config
|
20
|
+
assert exec_config == {
|
21
|
+
"input_variables": [],
|
22
|
+
"output_variables": [],
|
23
|
+
"workflow_raw_data": {
|
24
|
+
"definition": {
|
25
|
+
"module": ["vellum_ee", "workflows", "display", "tests", "test_vellum_workflow_display"],
|
26
|
+
"name": "ExampleWorkflow",
|
27
|
+
},
|
28
|
+
"display_data": {"viewport": {"x": 0.0, "y": 0.0, "zoom": 1.0}},
|
29
|
+
"edges": [],
|
30
|
+
"nodes": [
|
31
|
+
{
|
32
|
+
"data": {"label": "Entrypoint Node", "source_handle_id": "508b8b82-3517-4672-a155-18c9c7b9c545"},
|
33
|
+
"definition": {
|
34
|
+
"bases": [],
|
35
|
+
"module": ["vellum", "workflows", "nodes", "bases", "base"],
|
36
|
+
"name": "BaseNode",
|
37
|
+
},
|
38
|
+
"display_data": {"position": {"x": 0.0, "y": 0.0}},
|
39
|
+
"id": "9eef0c18-f322-4d56-aa89-f088d3e53f6a",
|
40
|
+
"inputs": [],
|
41
|
+
"type": "ENTRYPOINT",
|
42
|
+
}
|
43
|
+
],
|
44
|
+
},
|
45
|
+
}
|